作业设计:框架梳理
This commit is contained in:
parent
6b24749db9
commit
54a24ed077
|
@ -26,6 +26,14 @@
|
||||||
"@electron/remote": "^2.1.2",
|
"@electron/remote": "^2.1.2",
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
|
"@antv/x6": "^2.18.1",
|
||||||
|
"@antv/x6-plugin-clipboard": "^2.1.6",
|
||||||
|
"@antv/x6-plugin-dnd": "^2.1.1",
|
||||||
|
"@antv/x6-plugin-export": "^2.1.6",
|
||||||
|
"@antv/x6-plugin-keyboard": "^2.2.3",
|
||||||
|
"@antv/x6-plugin-selection": "^2.2.2",
|
||||||
|
"@antv/x6-plugin-snapline": "^2.1.7",
|
||||||
|
"@antv/x6-plugin-transform": "^2.1.8",
|
||||||
"@vue-office/docx": "^1.6.2",
|
"@vue-office/docx": "^1.6.2",
|
||||||
"@vue-office/excel": "^1.7.11",
|
"@vue-office/excel": "^1.7.11",
|
||||||
"@vue-office/pdf": "^2.0.2",
|
"@vue-office/pdf": "^2.0.2",
|
||||||
|
|
|
@ -71,3 +71,99 @@ export function updateClasswork(data) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 查询evaluationclue列表
|
||||||
|
export function listEvaluationclue(query) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询evaluationclue详细
|
||||||
|
export function getEvaluationclue(id) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增evaluationclue
|
||||||
|
export function addEvaluationclueReturnId(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/addReturnId',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增evaluationclue
|
||||||
|
export function addEvaluationclue(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改evaluationclue
|
||||||
|
export function updateEvaluationclue(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除evaluationclue
|
||||||
|
export function delEvaluationclue(id) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增evaluationclue,保存base64图片
|
||||||
|
export function saveBase64File(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/saveBase64File',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增evaluationclue,上传
|
||||||
|
export function saveEvaluationClueUploadFile(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/evaluationclue/saveUploadFile',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取文件内容
|
||||||
|
export function readFile(data) {
|
||||||
|
return fetch(import.meta.env.VITE_APP_RES_FILE_PATH + data.cluelink, {
|
||||||
|
method: "get",
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain', // 请求头设置为纯文本
|
||||||
|
'Accept': 'text/plain' // 接受头设置为纯文本
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(text => {
|
||||||
|
return Promise.resolve(text);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('读取文件出错:', error);
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
/*return request({
|
||||||
|
url: '/education/evaluationclue/readFile',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})*/
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-card
|
||||||
|
class="flow-contextmenu"
|
||||||
|
ref="flowMenu"
|
||||||
|
v-show="visible"
|
||||||
|
:style="menuStyle"
|
||||||
|
body-style="padding: 12px 0 12px 12px"
|
||||||
|
>
|
||||||
|
<el-cascader-panel
|
||||||
|
:props="{ expandTrigger: 'hover' }"
|
||||||
|
:options="options"
|
||||||
|
:border="false"
|
||||||
|
v-model="select"
|
||||||
|
@change="handleMenuClick"
|
||||||
|
>
|
||||||
|
<template v-slot="{ node, data }">
|
||||||
|
<span class="flow-contextmenu__node">{{ data.label }}</span>
|
||||||
|
</template>
|
||||||
|
</el-cascader-panel>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 隐藏/显示
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 位置
|
||||||
|
position: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
menuStyle() {
|
||||||
|
return {
|
||||||
|
...this.position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible: {
|
||||||
|
handler() {
|
||||||
|
this.select = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
select: [],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'name',
|
||||||
|
label: '随机name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'color',
|
||||||
|
label: '随机color'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'remove',
|
||||||
|
label: '删除'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleMenuClick(action) {
|
||||||
|
this.$emit('onMenuClick', action)
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.flow-contextmenu {
|
||||||
|
min-width: 150px;
|
||||||
|
position: fixed;
|
||||||
|
user-select: none;
|
||||||
|
z-index: 99;
|
||||||
|
:deep(.el-cascader-menu) {
|
||||||
|
min-width: auto;
|
||||||
|
.el-cascader-node {
|
||||||
|
z-index: 10;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 12px;
|
||||||
|
padding-left: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flow-contextmenu__node {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,91 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-drawer
|
||||||
|
:model-value="drawer"
|
||||||
|
:title="drawerTitle"
|
||||||
|
:modal="false"
|
||||||
|
:before-close="handleClose"
|
||||||
|
direction="rtl">
|
||||||
|
<el-form :model="form" size="large">
|
||||||
|
<el-form-item label="节点名称">
|
||||||
|
<el-input v-model="form.label" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="节点背景色">
|
||||||
|
<el-color-picker v-model="form.bgcolor" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="节点边框颜色">
|
||||||
|
<el-color-picker v-model="form.borderColor"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="节点文字颜色">
|
||||||
|
<el-color-picker v-model="form.textColor"/>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="save-row">
|
||||||
|
<el-space :size="30">
|
||||||
|
<el-button type="primary" @click="updateNode" size="default">保存</el-button>
|
||||||
|
<el-button @click="closeDrawer" size="default">关闭</el-button>
|
||||||
|
</el-space>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'flow-drawer',
|
||||||
|
props: {
|
||||||
|
drawerTitle: {
|
||||||
|
type: String,
|
||||||
|
default: '节点编辑'
|
||||||
|
},
|
||||||
|
drawer: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
default: ()=>{
|
||||||
|
return {
|
||||||
|
label: '',
|
||||||
|
bgcolor: '',
|
||||||
|
borderColor: '',
|
||||||
|
textColor: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleClose(done){
|
||||||
|
this.closeDrawer()
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
closeDrawer(){
|
||||||
|
this.$emit('closeDrawer', false)
|
||||||
|
},
|
||||||
|
updateNode(){
|
||||||
|
this.$emit('updateNode', this.form)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.el-form-item__label) {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.save-row {
|
||||||
|
margin-top: 100px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,235 @@
|
||||||
|
<template>
|
||||||
|
<div class="flow-library">
|
||||||
|
<div class="flow-library-title">节点库</div>
|
||||||
|
<div class="flow-library-list">
|
||||||
|
<div class="node-item" v-for="item in list" :key="item.name" :data-shape="item.shape"
|
||||||
|
:data-name="item.name"
|
||||||
|
@mousedown.stop="handleonAddNode"
|
||||||
|
@touchstart.stop="handleonAddNode">
|
||||||
|
<div
|
||||||
|
:class="item.class"
|
||||||
|
>
|
||||||
|
<template v-if="item.class == 'parallelogram' || item.class == 'diamond'">
|
||||||
|
<div :class="item.class + '-text'"> {{ item.name }} </div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ item.name }}
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <el-space wrap :size="30" class="ant-flow-save">
|
||||||
|
<el-button type="success" @click="handleSave('img')">下载为图片</el-button>
|
||||||
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||||
|
</el-space> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FlowLibrary',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 过滤数据
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
name: '开始',
|
||||||
|
shape: 'custom-rect',
|
||||||
|
class: 'elliptic'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '过程',
|
||||||
|
shape: 'custom-rect',
|
||||||
|
class: 'rectangle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '可选过程',
|
||||||
|
shape: 'custom-rect',
|
||||||
|
class: 'quadrilateral'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '决策',
|
||||||
|
shape: 'custom-polygon',
|
||||||
|
class: 'diamond'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '数据',
|
||||||
|
shape: 'custom-polygon',
|
||||||
|
class: 'parallelogram'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '连接',
|
||||||
|
shape: 'custom-circle',
|
||||||
|
class: 'round'
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleonAddNode(e) {
|
||||||
|
this.$emit('onAddNode', e)
|
||||||
|
},
|
||||||
|
// 保存
|
||||||
|
handleSave(str){
|
||||||
|
this.$emit('handleSave', str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@mixin nodeColor {
|
||||||
|
background: #EFF4FF;
|
||||||
|
display: flex;
|
||||||
|
border: solid 1px #5F95FF;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.flow-library {
|
||||||
|
user-select: none;
|
||||||
|
width: 250px;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-right: 1px solid #dcdfe6;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 15px;
|
||||||
|
&-title {
|
||||||
|
line-height: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 8px 0 8px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
width: 72px;
|
||||||
|
float: left;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
margin-top: 8px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&--setting-shape {
|
||||||
|
background-size: 32px;
|
||||||
|
background-color: #5f95ff;
|
||||||
|
background-position: 50% 15%;
|
||||||
|
|
||||||
|
.flow-library-item__name {
|
||||||
|
position: absolute;
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
bottom: 4px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-list {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-flow-save {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.node-item{
|
||||||
|
width: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.elliptic{
|
||||||
|
width: 70px;
|
||||||
|
height: 35px;
|
||||||
|
border-radius: 20px;
|
||||||
|
@include nodeColor;
|
||||||
|
|
||||||
|
}
|
||||||
|
.quadrilateral{
|
||||||
|
width: 60px;
|
||||||
|
height: 35px;
|
||||||
|
@include nodeColor;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.rectangle{
|
||||||
|
width: 80px;
|
||||||
|
height: 35px;
|
||||||
|
@include nodeColor;
|
||||||
|
}
|
||||||
|
.round{
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
border-radius: 50%;
|
||||||
|
@include nodeColor;
|
||||||
|
}
|
||||||
|
.parallelogram{
|
||||||
|
width: 55px;
|
||||||
|
height: 35px;
|
||||||
|
transform: skewX(-45deg);
|
||||||
|
@include nodeColor;
|
||||||
|
position: relative;
|
||||||
|
line-height: 35px;
|
||||||
|
.parallelogram-text{
|
||||||
|
transform: skewX(45deg);
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.diamond {
|
||||||
|
@include nodeColor;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
transform: rotateZ(45deg)skew(-12deg, -12deg);
|
||||||
|
.diamond-text{
|
||||||
|
transform: rotate(-45deg)skew(0deg,0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,333 @@
|
||||||
|
|
||||||
|
import { Shape } from '@antv/x6'
|
||||||
|
/**
|
||||||
|
* @desc 初始化面板配置
|
||||||
|
* @param check 查看模式
|
||||||
|
*/
|
||||||
|
export const graphOptions = (check = false) => {
|
||||||
|
return {
|
||||||
|
container: document.getElementById('flow-container'),
|
||||||
|
// 定制节点和边的交互行为 ==> boolean 节点或边是否可交互
|
||||||
|
interacting: check
|
||||||
|
? {
|
||||||
|
nodeMovable: false,
|
||||||
|
edgeMovable: false,
|
||||||
|
magnetConnectable: false,
|
||||||
|
vertexDeletable: false
|
||||||
|
}
|
||||||
|
: true,
|
||||||
|
// 对齐线
|
||||||
|
snapline: true,
|
||||||
|
// 显示网格 // 'dot' | 'fixedDot' | 'mesh'
|
||||||
|
grid: {
|
||||||
|
visible: true,
|
||||||
|
size: 20, // 网格大小
|
||||||
|
type: 'mesh',
|
||||||
|
args: {
|
||||||
|
color: '#e9e9e9',
|
||||||
|
thickness: 2 // 网格线宽度/网格点大小
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平移
|
||||||
|
panning: true,
|
||||||
|
// 滚轮缩放 MouseWheel
|
||||||
|
mousewheel: {
|
||||||
|
enabled: true,
|
||||||
|
zoomAtMousePosition: true,
|
||||||
|
modifiers: ['ctrl', 'meta'],
|
||||||
|
maxScale: 3,
|
||||||
|
minScale: 0.3
|
||||||
|
},
|
||||||
|
// 连线规则
|
||||||
|
connecting: {
|
||||||
|
// 路由类型
|
||||||
|
router: {
|
||||||
|
// 连线类型在此修改
|
||||||
|
// 曼哈顿路由 'manhattan' 路由是正交路由 'orth' 的智能版本,该路由由水平或垂直的正交线段组成,并自动避开路径上的其他节点(障碍)。
|
||||||
|
name: 'manhattan',
|
||||||
|
args: {
|
||||||
|
padding: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 圆角连接器,将起点、路由点、终点通过直线按顺序连接,并在线段连接处通过圆弧连接(倒圆角)。
|
||||||
|
connector: {
|
||||||
|
name: 'rounded',
|
||||||
|
args: {
|
||||||
|
radius: 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
anchor: 'center',
|
||||||
|
connectionPoint: 'anchor',
|
||||||
|
// 是否允许连接到画布空白位置的点,默认为 true。
|
||||||
|
allowBlank: false,
|
||||||
|
// 距离节点或者连接桩 20px 时会触发自动吸附
|
||||||
|
snap: {
|
||||||
|
radius: 20
|
||||||
|
},
|
||||||
|
// 拽出新的边
|
||||||
|
createEdge() {
|
||||||
|
return new Shape.Edge({
|
||||||
|
// markup: [
|
||||||
|
// {
|
||||||
|
// tagName: 'path',
|
||||||
|
// selector: 'stroke'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// connector: { name: 'rounded' },
|
||||||
|
// attrs: {
|
||||||
|
// stroke: {
|
||||||
|
// fill: 'none',
|
||||||
|
// connection: true,
|
||||||
|
// strokeWidth: 4,
|
||||||
|
// strokeLinecap: 'round',
|
||||||
|
// stroke: '#666'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
attrs: {
|
||||||
|
line: {
|
||||||
|
stroke: '#A2B1C3',
|
||||||
|
strokeWidth: 3,
|
||||||
|
targetMarker: {
|
||||||
|
name: 'block',
|
||||||
|
width: 12,
|
||||||
|
height: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
zIndex: 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
validateConnection({ targetMagnet }) {
|
||||||
|
return !!targetMagnet
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 连线高亮
|
||||||
|
highlighting: {
|
||||||
|
// 连线过程中,自动吸附到链接桩时被使用。
|
||||||
|
magnetAdsorbed: {
|
||||||
|
name: 'stroke',
|
||||||
|
args: {
|
||||||
|
attrs: {
|
||||||
|
width: 12,
|
||||||
|
r: 6,
|
||||||
|
magnet: true,
|
||||||
|
stroke: '#008CFF',
|
||||||
|
strokeWidth: 2,
|
||||||
|
fill: '#0F67FF'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rotating: false, // 不能旋转
|
||||||
|
keyboard: !check, // 按键操作
|
||||||
|
clipboard: true, // 剪切板
|
||||||
|
autoResize: true,
|
||||||
|
onToolItemCreated({ tool }) {
|
||||||
|
const options = tool.options
|
||||||
|
if (options && options.index % 2 === 1) {
|
||||||
|
tool.setAttrs({ fill: 'red' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 链接桩样式
|
||||||
|
export const portStyle = {
|
||||||
|
// width: 12,
|
||||||
|
// r: 6, // 半径
|
||||||
|
// // 当 magnet 属性为 true 时,表示该元素可以被链接,即在连线过程中可以被当做连线的起点或终点,与链接桩类似。
|
||||||
|
// magnet: true,
|
||||||
|
// stroke: '#008CFF',
|
||||||
|
// strokeWidth: 2,
|
||||||
|
// fill: '#fff',
|
||||||
|
// zIndex: 1,
|
||||||
|
// style: {
|
||||||
|
// visibility: 'hidden',
|
||||||
|
// },
|
||||||
|
r: 6,
|
||||||
|
magnet: true,
|
||||||
|
stroke: '#5F95FF',
|
||||||
|
strokeWidth: 2,
|
||||||
|
fill: '#fff',
|
||||||
|
style: {
|
||||||
|
visibility: 'hidden',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 链接桩配置
|
||||||
|
export const ports = {
|
||||||
|
// 设置链接桩分组
|
||||||
|
groups: {
|
||||||
|
top: {
|
||||||
|
// 定义连接柱的位置,如果不配置,将显示为默认样式
|
||||||
|
position: 'top',
|
||||||
|
// 定义连接柱的样式
|
||||||
|
attrs: {
|
||||||
|
circle: {
|
||||||
|
...portStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
position: 'right',
|
||||||
|
attrs: {
|
||||||
|
circle: {
|
||||||
|
...portStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
position: 'bottom',
|
||||||
|
attrs: {
|
||||||
|
circle: {
|
||||||
|
...portStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
position: 'left',
|
||||||
|
attrs: {
|
||||||
|
circle: {
|
||||||
|
...portStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
absolute: {
|
||||||
|
position: 'absolute',
|
||||||
|
attrs: {
|
||||||
|
circle: {
|
||||||
|
r: 6,
|
||||||
|
magnet: true,
|
||||||
|
stroke: '#008CFF',
|
||||||
|
strokeWidth: 2,
|
||||||
|
fill: '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 链接桩
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
group: 'top'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'right'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'bottom'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'left'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态计算宽高比
|
||||||
|
export const transformToPercent = (target, sum, font) => {
|
||||||
|
// https://x6.antv.vision/zh/docs/tutorial/intermediate/attrs
|
||||||
|
// 相对节点的大小
|
||||||
|
const percent = (target / sum).toFixed(2) * 100
|
||||||
|
return `${percent}${font ? 'px' : '%'}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册节点配置信息 注册以后就可以像使用内置节点那样使用该节点
|
||||||
|
export const registerNodeOpeions = {
|
||||||
|
'custom-rect': {
|
||||||
|
inherit: 'rect',
|
||||||
|
width: 70,
|
||||||
|
height: 40,
|
||||||
|
attrs: {
|
||||||
|
body: {
|
||||||
|
strokeWidth: 1,
|
||||||
|
stroke: '#5F95FF',
|
||||||
|
fill: '#EFF4FF',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 12,
|
||||||
|
fill: '#262626',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ports: { ...ports },
|
||||||
|
},
|
||||||
|
'custom-polygon' : {
|
||||||
|
inherit: 'polygon',
|
||||||
|
width: 70,
|
||||||
|
height: 40,
|
||||||
|
attrs: {
|
||||||
|
body: {
|
||||||
|
strokeWidth: 1,
|
||||||
|
stroke: '#5F95FF',
|
||||||
|
fill: '#EFF4FF',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 12,
|
||||||
|
fill: '#262626',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ports: {
|
||||||
|
...ports,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
group: 'top',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'bottom',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'custom-circle' : {
|
||||||
|
inherit: 'circle',
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
attrs: {
|
||||||
|
body: {
|
||||||
|
strokeWidth: 1,
|
||||||
|
stroke: '#5F95FF',
|
||||||
|
fill: '#EFF4FF',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 12,
|
||||||
|
fill: '#262626',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ports: { ...ports },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图形变换配置
|
||||||
|
export const transFormOptions = {
|
||||||
|
// 调整尺寸
|
||||||
|
resizing: {
|
||||||
|
enabled: true,
|
||||||
|
minWidth: 1,
|
||||||
|
maxWidth: 200,
|
||||||
|
minHeight: 1,
|
||||||
|
maxHeight: 150,
|
||||||
|
restrict: false,
|
||||||
|
preserveAspectRatio: false,
|
||||||
|
},
|
||||||
|
// 调整角度---旋转
|
||||||
|
rotating: {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拖动添加节点样式配置
|
||||||
|
export const addNodeAttrStyle = {
|
||||||
|
'可选过程': {
|
||||||
|
rx: 6,
|
||||||
|
ry: 6,
|
||||||
|
},
|
||||||
|
'开始': {
|
||||||
|
rx: 20,
|
||||||
|
ry: 26,
|
||||||
|
},
|
||||||
|
'决策': {
|
||||||
|
refPoints: '0,10 10,0 20,10 10,20',
|
||||||
|
},
|
||||||
|
'数据': {
|
||||||
|
refPoints: '10,0 40,0 30,20 0,20',
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,391 @@
|
||||||
|
<template>
|
||||||
|
<div v-loading="flowLoading" class="ant-flow" :style="{ height: 70 + 'vh' }">
|
||||||
|
<!-- 左侧节点库 -->
|
||||||
|
<flow-library @onAddNode="onAddNode" />
|
||||||
|
<!--画布-->
|
||||||
|
<div id="flow-container"></div>
|
||||||
|
<!--右侧抽屉-->
|
||||||
|
<FlowDrawer :drawer="drawer" :form="form" @closeDrawer="closeDrawer" @updateNode="updateNode" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Graph } from '@antv/x6'
|
||||||
|
// 快捷键
|
||||||
|
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||||
|
// 通过拖拽交互往画布中添加节点
|
||||||
|
import { Dnd } from '@antv/x6-plugin-dnd'
|
||||||
|
// 框选
|
||||||
|
import { Selection } from '@antv/x6-plugin-selection'
|
||||||
|
// 图形变换
|
||||||
|
import { Transform } from '@antv/x6-plugin-transform'
|
||||||
|
// 对齐线
|
||||||
|
import { Snapline } from '@antv/x6-plugin-snapline'
|
||||||
|
// 剪切板
|
||||||
|
import { Clipboard } from '@antv/x6-plugin-clipboard'
|
||||||
|
// 导出
|
||||||
|
import { Export } from '@antv/x6-plugin-export'
|
||||||
|
|
||||||
|
import FlowLibrary from '@/components/Flowchart/FlowLibrary.vue'
|
||||||
|
import FlowContentMenu from '@/components/Flowchart/FlowContentMenu.vue'
|
||||||
|
import FlowDrawer from '@/components/Flowchart/FlowDrawer.vue'
|
||||||
|
import { graphOptions, ports, registerNodeOpeions, transFormOptions, addNodeAttrStyle } from '@/components/Flowchart/config'
|
||||||
|
|
||||||
|
let graph = null
|
||||||
|
let dnd = null
|
||||||
|
let selector = null
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'X6',
|
||||||
|
components: { FlowContentMenu, FlowLibrary, FlowDrawer },
|
||||||
|
title: 'Antv/X6流程图',
|
||||||
|
props: {
|
||||||
|
flowHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 800
|
||||||
|
},
|
||||||
|
dataSource: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
form: {
|
||||||
|
label: '',
|
||||||
|
bgcolor: '',
|
||||||
|
borderColor: '',
|
||||||
|
textColor: ''
|
||||||
|
},
|
||||||
|
currentNode: null,
|
||||||
|
flowLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dataSource(newVal){
|
||||||
|
this.flowLoading = true
|
||||||
|
this.updateConfigure(newVal)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.flowLoading = true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
if(graph){
|
||||||
|
graph.clearCells()
|
||||||
|
|
||||||
|
}
|
||||||
|
this.init()
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destoryFlow()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 初始化画布
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
// 实例化
|
||||||
|
graph = new Graph(graphOptions(false))
|
||||||
|
|
||||||
|
// 使用插件
|
||||||
|
this.initPlugin()
|
||||||
|
|
||||||
|
// 注册自定义节点
|
||||||
|
this.registerNode()
|
||||||
|
|
||||||
|
// 读取配置
|
||||||
|
graph.fromJSON(this.dataSource)
|
||||||
|
|
||||||
|
// 居中展示
|
||||||
|
graph.centerContent()
|
||||||
|
|
||||||
|
// 快捷键
|
||||||
|
this.initEvent()
|
||||||
|
|
||||||
|
// 实例化拖动添加节点
|
||||||
|
dnd = new Dnd({
|
||||||
|
target: graph,
|
||||||
|
scaled: false,
|
||||||
|
})
|
||||||
|
this.flowLoading = false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 注册自定义节点
|
||||||
|
*/
|
||||||
|
registerNode() {
|
||||||
|
Graph.registerNode('custom-rect',registerNodeOpeions['custom-rect'], true)
|
||||||
|
Graph.registerNode('custom-polygon',registerNodeOpeions['custom-polygon'], true)
|
||||||
|
Graph.registerNode('custom-circle',registerNodeOpeions['custom-circle'], true)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 快捷键与事件
|
||||||
|
*/
|
||||||
|
initEvent() {
|
||||||
|
// 点击...
|
||||||
|
graph.on('cell:click', e => {
|
||||||
|
this.showPorts(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 双击动态添加链接桩
|
||||||
|
graph.on('node:dblclick', e => {
|
||||||
|
const { node } = e
|
||||||
|
|
||||||
|
this.currentNode = node
|
||||||
|
this.form.label = node.attr('text/text')
|
||||||
|
this.form.bgcolor = node.attr('body/fill')
|
||||||
|
this.form.borderColor = node.attr('body/stroke')
|
||||||
|
this.form.textColor = node.attr('text/fill')
|
||||||
|
this.drawer = true
|
||||||
|
})
|
||||||
|
|
||||||
|
// Edge工具
|
||||||
|
graph.on('cell:mouseenter', ({ cell }) => {
|
||||||
|
if (cell.isEdge()) {
|
||||||
|
// https://x6.antv.vision/zh/docs/tutorial/intermediate/tools
|
||||||
|
// 1、vertices 路径点工具,在路径点位置渲染一个小圆点,
|
||||||
|
// 2、segments 线段工具。在边的每条线段的中心渲染一个工具条,可以拖动工具条调整线段两端的路径点的位置。
|
||||||
|
cell.addTools([
|
||||||
|
'vertices',
|
||||||
|
'segments',
|
||||||
|
{
|
||||||
|
name: 'button-remove',
|
||||||
|
args: {
|
||||||
|
x: '30%',
|
||||||
|
y: '50%'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
graph.on('cell:mouseleave', ({ cell }) => {
|
||||||
|
if (cell.isEdge()) {
|
||||||
|
cell.removeTool('vertices')
|
||||||
|
cell.removeTool('segments')
|
||||||
|
cell.removeTool('button-remove')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 链接桩控制
|
||||||
|
graph.on('node:mouseenter', () => {
|
||||||
|
this.showPorts(true)
|
||||||
|
})
|
||||||
|
graph.on('node:mouseleave', () => {
|
||||||
|
this.showPorts(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击画布空白区域
|
||||||
|
graph.on('blank:click', () => {
|
||||||
|
graph.cleanSelection && graph.cleanSelection()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础操作S
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
graph.bindKey(['meta+c', 'ctrl+c'], () => {
|
||||||
|
const cells = graph.getSelectedCells()
|
||||||
|
if (cells.length) {
|
||||||
|
graph.copy(cells)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
graph.bindKey(['meta+x', 'ctrl+x'], () => {
|
||||||
|
const cells = graph.getSelectedCells()
|
||||||
|
if (cells.length) {
|
||||||
|
graph.cut(cells)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
graph.bindKey(['meta+v', 'ctrl+v'], () => {
|
||||||
|
if (!graph.isClipboardEmpty()) {
|
||||||
|
const cells = graph.paste({ offset: 32 })
|
||||||
|
graph.cleanSelection()
|
||||||
|
graph.select(cells)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
//undo redo
|
||||||
|
graph.bindKey(['meta+z', 'ctrl+z'], () => {
|
||||||
|
if (graph.history.canUndo()) {
|
||||||
|
graph.history.undo()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
|
||||||
|
if (graph.history.canRedo()) {
|
||||||
|
graph.history.redo()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
// select all
|
||||||
|
graph.bindKey(['meta+shift+a', 'ctrl+shift+a'], () => {
|
||||||
|
const nodes = graph.getNodes()
|
||||||
|
if (nodes) {
|
||||||
|
graph.select(nodes)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// delete
|
||||||
|
graph.bindKey(['backspace', 'delete'], () => {
|
||||||
|
// 删除选中的元素
|
||||||
|
const cells = graph.getSelectedCells()
|
||||||
|
if (cells.length) {
|
||||||
|
graph.removeCells(cells)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// zoom
|
||||||
|
graph.bindKey(['ctrl+1', 'meta+1'], () => {
|
||||||
|
const zoom = graph.zoom()
|
||||||
|
if (zoom < 1.5) {
|
||||||
|
graph.zoom(0.1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
graph.bindKey(['ctrl+2', 'meta+2'], () => {
|
||||||
|
const zoom = graph.zoom()
|
||||||
|
if (zoom > 0.5) {
|
||||||
|
graph.zoom(-0.1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 基础操作E
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
// 连接桩显示/隐藏
|
||||||
|
showPorts(show) {
|
||||||
|
const container = document.getElementById('flow-container')
|
||||||
|
const ports = container.querySelectorAll('.x6-port-body')
|
||||||
|
for (let i = 0, len = ports.length; i < len; i = i + 1) {
|
||||||
|
ports[i].style.visibility = show ? 'visible' : 'hidden'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 使用插件
|
||||||
|
*/
|
||||||
|
initPlugin(){
|
||||||
|
graph.use(
|
||||||
|
new Keyboard({
|
||||||
|
enabled: true,
|
||||||
|
global: true,
|
||||||
|
}),
|
||||||
|
).use(new Selection({
|
||||||
|
multiple: true,
|
||||||
|
showNodeSelectionBox: true,
|
||||||
|
})).use(new Snapline({
|
||||||
|
enabled: true,
|
||||||
|
clean: false,
|
||||||
|
})).use(new Transform(transFormOptions)).use(new Clipboard({
|
||||||
|
enabled: true,
|
||||||
|
})).use(new Export())
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加节点
|
||||||
|
*/
|
||||||
|
onAddNode(e) {
|
||||||
|
const target = e && e.target.closest('.node-item')
|
||||||
|
if (target) {
|
||||||
|
const name = target.getAttribute('data-name')
|
||||||
|
const shape = target.getAttribute('data-shape')
|
||||||
|
|
||||||
|
let nodeOptions = {
|
||||||
|
shape,
|
||||||
|
label: name,
|
||||||
|
ports: { ...ports },
|
||||||
|
}
|
||||||
|
if(addNodeAttrStyle[name]){
|
||||||
|
nodeOptions.attrs = {
|
||||||
|
body: addNodeAttrStyle[name]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const newNode = graph.createNode(nodeOptions)
|
||||||
|
dnd.start(newNode, e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 保存
|
||||||
|
*/
|
||||||
|
handleSave() {
|
||||||
|
const res = graph.toJSON()
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭抽屉
|
||||||
|
*/
|
||||||
|
closeDrawer(data) {
|
||||||
|
this.drawer = data
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 更新节点-节点名称/背景色/边框/节点颜色
|
||||||
|
*/
|
||||||
|
updateNode(form) {
|
||||||
|
this.currentNode.attr('text/text', form.label)
|
||||||
|
this.currentNode.attr('text/fill', form.textColor)
|
||||||
|
this.currentNode.attr(`body/fill`, form.bgcolor)
|
||||||
|
this.currentNode.attr(`body/stroke`, form.borderColor)
|
||||||
|
this.drawer = false
|
||||||
|
},
|
||||||
|
updateConfigure(data) {
|
||||||
|
graph.fromJSON(data)
|
||||||
|
graph.centerContent()
|
||||||
|
this.flowLoading = false
|
||||||
|
},
|
||||||
|
destoryFlow() {
|
||||||
|
// 画布的销毁以及回收
|
||||||
|
graph && graph.dispose()
|
||||||
|
graph = null
|
||||||
|
dnd = null
|
||||||
|
selector = null
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取PNG
|
||||||
|
*/
|
||||||
|
getBase64Png(){
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
graph.toPNG((dataUri)=>{
|
||||||
|
resolve(dataUri)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.ant-flow {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
#flow-container {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#stencil{
|
||||||
|
user-select: none;
|
||||||
|
width: 250px;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-right: 1px solid #dcdfe6;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -19,6 +19,7 @@
|
||||||
<el-row class="middle">
|
<el-row class="middle">
|
||||||
<el-col :span="24" style="height: 100%; overflow: hidden;">
|
<el-col :span="24" style="height: 100%; overflow: hidden;">
|
||||||
<el-form-item label="作业资源:" class="el-form-work-list">
|
<el-form-item label="作业资源:" class="el-form-work-list">
|
||||||
|
<!-- 左侧作业资源 -->
|
||||||
<el-col :span="15" class="work-left">
|
<el-col :span="15" class="work-left">
|
||||||
<!-- 习题训练 -->
|
<!-- 习题训练 -->
|
||||||
<div v-if="classWorkForm.worktype=='习题训练'" style="height: 100%; display: flex; flex-direction: column;">
|
<div v-if="classWorkForm.worktype=='习题训练'" style="height: 100%; display: flex; flex-direction: column;">
|
||||||
|
@ -114,7 +115,8 @@
|
||||||
@pagination="getPaginationList" />
|
@pagination="getPaginationList" />
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<!-- <div v-if="classWorkForm.worktype!='习题训练'">
|
<!-- 非习题训练:常规作业、 -->
|
||||||
|
<div v-if="classWorkForm.worktype!='习题训练'">
|
||||||
<div :style="{ 'overflow': 'auto'}">
|
<div :style="{ 'overflow': 'auto'}">
|
||||||
<template v-if="classWorkForm.worktype!='常规作业'">
|
<template v-if="classWorkForm.worktype!='常规作业'">
|
||||||
<template v-for="(item, index) in workResource.teachResourceList" :key="item">
|
<template v-for="(item, index) in workResource.teachResourceList" :key="item">
|
||||||
|
@ -132,19 +134,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;align-items: center; justify-content: space-around; margin-left: 15px; margin-right: 15px;">
|
<div style="display: flex;align-items: center; justify-content: space-around; margin-left: 15px; margin-right: 15px;">
|
||||||
<el-button @click="prevRead(item)" icon="Search">预览</el-button>
|
<el-button icon="Search" @click="prevRead(item)">预览</el-button>
|
||||||
<el-button @click="handleClassWorkAddOfResource(item)" icon="FolderAdd">添加到作业</el-button>
|
<el-button icon="FolderAdd" @click="handleClassWorkAddOfResource(item)">添加到作业</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="classWorkForm.worktype =='常规作业'">
|
<!-- <template v-if="classWorkForm.worktype =='常规作业'">
|
||||||
<div class="upload-homework" v-loading="fileLoading">
|
<div class="upload-homework" v-loading="fileLoading">
|
||||||
<FileUpload v-model="fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
|
<FileUpload v-model="fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template> -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
|
||||||
<!-- <div v-if="classWorkForm.activeIndex==3">
|
<!-- <div v-if="classWorkForm.activeIndex==3">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="20">
|
<el-col :span="20">
|
||||||
|
@ -196,6 +198,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右侧选中的作业资源 -->
|
||||||
<el-col :span="9" class="work-right">
|
<el-col :span="9" class="work-right">
|
||||||
<div v-if="classWorkForm.worktype=='习题训练'" :style="{height: '100%', 'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
|
<div v-if="classWorkForm.worktype=='习题训练'" :style="{height: '100%', 'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
|
||||||
<template v-for="(item,index) in classWorkForm.quizlist" :key="item.id">
|
<template v-for="(item,index) in classWorkForm.quizlist" :key="item.id">
|
||||||
|
@ -214,18 +218,20 @@
|
||||||
|
|
||||||
<div v-if="classWorkForm.worktype!='习题训练'" :style="{'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
|
<div v-if="classWorkForm.worktype!='习题训练'" :style="{'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
|
||||||
<div style="margin: 5px; background-color: white">
|
<div style="margin: 5px; background-color: white">
|
||||||
<template v-for="(item,index) in chooseWorkLists" :key="item.id">
|
<template v-for="(item) in chooseWorkLists" :key="item.id">
|
||||||
<div v-if="item.worktype==classWorkForm.worktype">
|
<div v-if="item.worktype==classWorkForm.worktype">
|
||||||
<div style="margin-bottom: 5px; padding-left: 15px;display: flex;flex-direction: row;align-items: center;">
|
<div class="choose-work">
|
||||||
<div style="font-size: 1.2em; font-weight: bold;margin-right: 5px">{{ item.worktype }}</div>
|
<div class="choose-work-title">{{ item.worktype }}</div>
|
||||||
<div style="display: flex;align-items: center; justify-content: space-around; margin-left: 15px; margin-right: 15px;flex: 1;">
|
<div class="choose-work-content">
|
||||||
<div style="color: silver; display: flex;align-items: center;flex: 1;">
|
<div style="color: silver; display: flex;align-items: center;flex: 1;">
|
||||||
<el-form-item label="分值">
|
<el-form-item label="分值">
|
||||||
<el-input-number v-model="item.score" :min="1" :max="100" size="small"></el-input-number >
|
<el-input-number v-model="item.score" :min="1" :max="100" size="small"></el-input-number >
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div style="display: flex;align-items: center;flex: 1;justify-content: flex-end;">
|
||||||
|
<el-button @click="prevRead(item)">预览</el-button>
|
||||||
|
<el-button type="danger" @click="deleteClassWorkAddOfResource(item)">删除</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button @click="prevRead(item)" icon="Search">预览</el-button>
|
|
||||||
<el-button @click="deleteClassWorkAddOfResource(item)" type="danger" icon="Delete">删除</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -252,6 +258,26 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 预览框 -->
|
||||||
|
<el-dialog v-if="prevReadMsg.visible" v-model="prevReadMsg.visible" class="prev-read-zy-wrap" width="90%" style="height: 80vh" append-to-body>
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='课标研读'" style="height: 100%;">
|
||||||
|
<standard book-type="课标研读" :show-cata="true" :show-tools="false" :course-obj="courseObj" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
||||||
|
</div>
|
||||||
|
<div v-if="prevReadMsg.type=='目标设定'" style="height: 100%;display: flex;">
|
||||||
|
<degreeevolution :courseObj="courseObj" :show-class="true" :teachResObj="activeTeachResOfStandard" :attainmentList="attainmentList" :courseQualityList="courseQualityList"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="prevReadMsg.type=='教材研读'" style="height: 100%;">
|
||||||
|
<standard book-type="教材研读" :course-obj="courseObj" :show-tools="false" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
||||||
|
</div> -->
|
||||||
|
<div v-if="prevReadMsg.type=='框架梳理'" style="height: 100%;">
|
||||||
|
<FlowChart ref="flowref" :flowHeight="mainHeight" :dataSource="flowData"/>
|
||||||
|
</div>
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='学科定位'" style="height: 100%;">
|
||||||
|
<teachJsMind :course-obj="courseObj" :teachResObj="activeTeachResOfStandard"></teachJsMind>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='习题训练'">习题训练</div> -->
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -259,12 +285,17 @@
|
||||||
import { onMounted, ref, nextTick, watch, reactive, getCurrentInstance } from 'vue'
|
import { onMounted, ref, nextTick, watch, reactive, getCurrentInstance } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useToolState } from '@/store/modules/tool'
|
import { useToolState } from '@/store/modules/tool'
|
||||||
import { getCurrentTime } from '@/utils/date'
|
|
||||||
import { processList } from '@/hooks/useProcessList'
|
|
||||||
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
||||||
import { updateClasswork } from '@/api/classTask'
|
|
||||||
import { useGetHomework } from '@/hooks/useGetHomework'
|
|
||||||
import { addClassworkReturnId } from '@/api/teaching/classwork'
|
import { addClassworkReturnId } from '@/api/teaching/classwork'
|
||||||
|
import { updateClasswork, listEvaluationclue,readFile } from '@/api/classTask'
|
||||||
|
import { listEvaluation } from '@/api/subject'
|
||||||
|
import { listEntpcoursefile } from '@/api/education/entpcoursefile'
|
||||||
|
|
||||||
|
import { useGetHomework } from '@/hooks/useGetHomework'
|
||||||
|
import { processList } from '@/hooks/useProcessList'
|
||||||
|
import { getCurrentTime } from '@/utils/date'
|
||||||
|
import FlowChart from "@/components/Flowchart/index.vue";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
|
@ -364,9 +395,16 @@ let classWorkForm = reactive({
|
||||||
title: '',// 作业说明
|
title: '',// 作业说明
|
||||||
quizlist: [], // 作业习题列表内容
|
quizlist: [], // 作业习题列表内容
|
||||||
}); // 提交的作业内容
|
}); // 提交的作业内容
|
||||||
const chooseWorkLists = ref([]); // 选择作业资源列表? 非习题训练的list
|
const chooseWorkLists = ref([]); // 框架梳理、?课堂展示
|
||||||
const whiteboardObj = ref(''); // 作业资源 - 课堂展示 白板
|
const whiteboardObj = ref(''); // 作业资源 - 课堂展示 白板
|
||||||
|
// 课堂展示
|
||||||
|
const boardLoading = ref(false);
|
||||||
|
const question = ref(''); // 课堂展示
|
||||||
|
const prevReadMsg = reactive({
|
||||||
|
visible: false,
|
||||||
|
type: ""
|
||||||
|
});// 预览msg
|
||||||
|
const flowData = ref({})// 框架梳理
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* 作业类型切换
|
* 作业类型切换
|
||||||
|
@ -403,7 +441,7 @@ const queryForm = reactive({
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @desc: 新查询试题
|
* @desc: 1、习题训练 - 新查询试题
|
||||||
* @return: {*}
|
* @return: {*}
|
||||||
* @param {*} queryType
|
* @param {*} queryType
|
||||||
* 0 - 标准查询
|
* 0 - 标准查询
|
||||||
|
@ -451,6 +489,41 @@ const handleQueryFromEntpCourseWork= (queryType) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 教学资源,从课标分析、教材分析里来
|
||||||
|
/**
|
||||||
|
* 2、框架设计、教学资源,从课标分析、教材分析里来
|
||||||
|
*/
|
||||||
|
const getQueryFromEvaluationclue = () => {
|
||||||
|
// props.bookobj.levelSecondId, //userStore.evalid, // // 单元下的课ID
|
||||||
|
listEvaluationclue({ cluegroup: 'teachresource', evalid: props.bookobj.levelSecondId, pageSize: 1000 }).then((clueres) => {
|
||||||
|
for (var i=0; i<clueres.rows.length; i++) {
|
||||||
|
|
||||||
|
if (clueres.rows[i].cluetag == 'standardview') {
|
||||||
|
clueres.rows[i].worktype = '课标研读';
|
||||||
|
} else if (clueres.rows[i].cluetag == 'targetview') {
|
||||||
|
clueres.rows[i].worktype = '目标设定';
|
||||||
|
} else if (clueres.rows[i].cluetag == 'contentview') {
|
||||||
|
clueres.rows[i].worktype = '教材研读';
|
||||||
|
} else if (clueres.rows[i].cluetag == 'frameview') {
|
||||||
|
clueres.rows[i].worktype = '框架梳理';
|
||||||
|
} else if (clueres.rows[i].cluetag == 'mapview') {
|
||||||
|
clueres.rows[i].worktype = '学科定位';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clueres.rows[i].childlist != '') {
|
||||||
|
clueres.rows[i].childArray = JSON.parse('['+clueres.rows[i].childlist+']');
|
||||||
|
for (var j=0; j<clueres.rows[i].childArray.length; j++) {
|
||||||
|
clueres.rows[i].childArray[j].title = clueres.rows[i].childArray[j].title.replace(/(<([^>]+)>)/ig, '');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clueres.rows[i].childArray = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("框架梳理、课标研读、目标设定、教材研读、学科定位的资源",clueres.rows);
|
||||||
|
workResource.teachResourceList = clueres.rows;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加资源
|
* 添加资源
|
||||||
* @param fromsrc - 试题来源
|
* @param fromsrc - 试题来源
|
||||||
|
@ -481,6 +554,103 @@ const handleClassWorkQuizAdd = (fromsrc, entpcourseworkid) => {
|
||||||
ElMessage('试题已经存在')
|
ElMessage('试题已经存在')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 预览资源
|
||||||
|
*/
|
||||||
|
const prevRead = async (item) => {
|
||||||
|
prevReadMsg.visible = true;
|
||||||
|
prevReadMsg.type = item.worktype;
|
||||||
|
if (item.worktype==='课标研读'){
|
||||||
|
//获取教材文件和批注信息
|
||||||
|
listEvaluation({itemkey: 'subject', edusubject: userStore.edusubject, edustage: userStore.edustage}).then(res => {
|
||||||
|
// TODO 课标研读-还未接入
|
||||||
|
console.log("课标研读-还未接入",res);
|
||||||
|
// this.versionObj = res.rows[0];
|
||||||
|
// // 读取出课标文件的每一行
|
||||||
|
// if (this.versionObj.fileurl.length > 0) {
|
||||||
|
// readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
||||||
|
// this.versionObj.bookdata = fileres;
|
||||||
|
// this.activeTeachResOfStandard = item;
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.worktype==='目标设定'){
|
||||||
|
// TODO 目标设定-还未接入
|
||||||
|
// this.activeTeachResOfStandard = item;
|
||||||
|
}
|
||||||
|
if (item.worktype==='教材研读'){
|
||||||
|
// TODO 教材研读-还未接入
|
||||||
|
// getEvaluation(this.courseObj.evalrootid).then(bookres => {
|
||||||
|
// this.versionObj = bookres.data;
|
||||||
|
// if (this.versionObj.fileurl.length > 0) {
|
||||||
|
// readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
||||||
|
// this.versionObj.bookdata = fileres;
|
||||||
|
// this.activeTeachResOfStandard = item;
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
if (item.worktype==='框架梳理'){
|
||||||
|
flowData.value = {};
|
||||||
|
const { chapterId } = await useGetHomework(props.bookobj.node)
|
||||||
|
// this.entpcourseid = chapterId
|
||||||
|
let queryParams = {
|
||||||
|
entpcourseid: chapterId,
|
||||||
|
ppttype: '教材分析',
|
||||||
|
parentid: item.id,
|
||||||
|
title: '逻辑框架建构',
|
||||||
|
filetype: 'draw'
|
||||||
|
}
|
||||||
|
listEntpcoursefile(queryParams).then(response=>{
|
||||||
|
if (response.rows.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flowData.value = JSON.parse(response.rows[0].datacontent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.worktype==='学科定位'){
|
||||||
|
// TODO 学科定位-还未接入
|
||||||
|
// this.activeTeachResOfStandard = item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 添加到作业
|
||||||
|
*/
|
||||||
|
// 把教学资源添加为作业
|
||||||
|
const handleClassWorkAddOfResource = (work) => {
|
||||||
|
// 当前资源下是否已存在
|
||||||
|
let arrSole = chooseWorkLists.value.filter((item) => {
|
||||||
|
return item.worktype === classWorkForm.worktype
|
||||||
|
})
|
||||||
|
// 仅能添加一个
|
||||||
|
if(arrSole.length > 0) {
|
||||||
|
ElMessage('该资源已存在,请勿重复添加')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//存入集合
|
||||||
|
let arr = chooseWorkLists.value.filter((item) => {
|
||||||
|
return item.id === work.id
|
||||||
|
})
|
||||||
|
if (arr.length===0) {
|
||||||
|
work.score = 1;
|
||||||
|
chooseWorkLists.value.push(work);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 删除作业
|
||||||
|
*/
|
||||||
|
const deleteClassWorkAddOfResource = (work) => {
|
||||||
|
chooseWorkLists.value.filter((item, index) => {
|
||||||
|
if (item.id === work.id) {
|
||||||
|
chooseWorkLists.value.splice(index, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 作业设计-提交
|
* 作业设计-提交
|
||||||
|
@ -656,47 +826,66 @@ const handleClassWorkSave = async () => {
|
||||||
const { chapterId } = await useGetHomework(props.bookobj.node)
|
const { chapterId } = await useGetHomework(props.bookobj.node)
|
||||||
// this.entpcourseid = chapterId
|
// this.entpcourseid = chapterId
|
||||||
|
|
||||||
|
const cform = {
|
||||||
|
id: 0,
|
||||||
|
workdate: classWorkForm.workdate, // //作业类型?web端这里貌似没有这个时间
|
||||||
|
deaddate: '', // 截止时间
|
||||||
|
entpid: userStore.deptId, //
|
||||||
|
level: 1,
|
||||||
|
parentid: 0,
|
||||||
|
worktype: classWorkForm.worktype, // 作业类型
|
||||||
|
workkey: '',
|
||||||
|
worktag: '',
|
||||||
|
uniquekey: classWorkForm.uniquekey,// 作业名称、编码
|
||||||
|
classid: 0,
|
||||||
|
classcourseid: 0,
|
||||||
|
entpcourseid: chapterId, // 这个字段很特别
|
||||||
|
slideid: 0,
|
||||||
|
title: classWorkForm.title, // 作业说明?
|
||||||
|
workcodes: JSON.stringify(classWorkForm.workcodes), // 作业内容?
|
||||||
|
edusubject: userStore.edusubject, // 学科 语文 数学
|
||||||
|
evalid: props.bookobj.levelSecondId, //userStore.evalid, // // 单元下的课ID
|
||||||
|
edustage: userStore.edustage, // 学段 年纪 高中,初中,小学
|
||||||
|
status: '10', //2024-09-11 作业布置分离后的 新模版数据; 之前老版本为空
|
||||||
|
edituserid: userStore.userId, // 当前用户id
|
||||||
|
entpcourseworklist: '', // 选择的 习题训练 list 需要转字符串
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
if (classWorkForm.worktype === "课堂展示") {
|
if (classWorkForm.worktype === "课堂展示") {
|
||||||
this.boardLoading = true
|
boardLoading.value = true
|
||||||
let canvasJson = this.$refs.boardref.getCanvasJson()
|
let canvasJson = this.$refs.boardref.getCanvasJson()
|
||||||
let canvasBase64 = await this.$refs.boardref.getCanvasBase64()
|
let canvasBase64 = await this.$refs.boardref.getCanvasBase64()
|
||||||
var formObj = {};
|
// 课堂展示提交内容
|
||||||
formObj.id = 0;
|
formObj.worktag = question.value;
|
||||||
formObj.workdate = this.classWorkForm.workdate;
|
|
||||||
formObj.deaddate = '';
|
|
||||||
formObj.entpid = this.userStore.deptId;
|
|
||||||
formObj.level = 1;
|
|
||||||
formObj.parentid = 0;
|
|
||||||
formObj.worktype = this.classWorkForm.worktype;
|
|
||||||
formObj.workkey = '';
|
|
||||||
formObj.worktag = this.question;
|
|
||||||
formObj.uniquekey = this.classWorkForm.uniquekey;
|
|
||||||
formObj.classid = 0;
|
|
||||||
formObj.classcourseid = 0;
|
|
||||||
formObj.entpcourseid = chapterId;// 这个字段很特别
|
|
||||||
formObj.slideid = 0;
|
|
||||||
formObj.title = this.classWorkForm.title;
|
|
||||||
formObj.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
|
formObj.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
|
||||||
formObj.edusubject = this.courseObj.edusubject;
|
|
||||||
formObj.evalid = this.courseObj.evalid;
|
|
||||||
formObj.edustage = this.userStore.edustage;
|
|
||||||
formObj.status = '10'; //2024-09-11 作业布置分离后的 新模版数据; 之前老版本为空
|
|
||||||
formObj.edituserid = this.userStore.id;
|
|
||||||
formObj.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
|
formObj.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
|
||||||
try {
|
try {
|
||||||
addClassworkReturnId(formObj).then(() => {
|
addClassworkReturnId(formObj).then(() => {
|
||||||
this.classWorkForm.worktype = "习题训练";
|
ElMessage({ type: 'success', message: '作业设计成功!'});
|
||||||
this.chooseWorkLists = [];
|
// 重置提交表单
|
||||||
this.whiteboardObj = '';
|
classWorkForm.worktype = "习题训练";
|
||||||
|
classWorkForm.uniquekey = props.uniquekey, // 作业唯一标识 作业名称
|
||||||
|
classWorkForm.title = "";
|
||||||
|
classWorkForm.quizlist = [], // 作业习题列表内容
|
||||||
|
|
||||||
|
// 情况选择的资源缓存
|
||||||
|
chooseWorkLists.value = [];
|
||||||
|
whiteboardObj.value = ''; // ? // 清空白板
|
||||||
// refresh the list
|
// refresh the list
|
||||||
//这里分离了,所以不需要更新表单数据了
|
//这里分离了,所以不需要更新表单数据了
|
||||||
// this.getClassWorkAllList();
|
// this.getClassWorkAllList();
|
||||||
this.newWorkSpace = false;
|
|
||||||
this.newWorkSpaceEdit = false;
|
// TODO 后续看是否跳转到 作业布置页面
|
||||||
this.workEdit = false;
|
|
||||||
|
//TODO 下面3个后续看是啥
|
||||||
|
// this.newWorkSpace = false;
|
||||||
|
// this.newWorkSpaceEdit = false;
|
||||||
|
// this.workEdit = false;
|
||||||
|
boardLoading.value = false
|
||||||
})
|
})
|
||||||
} finally {
|
} finally {
|
||||||
this.boardLoading = false
|
boardLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(classWorkForm.worktype === "常规作业"){
|
else if(classWorkForm.worktype === "常规作业"){
|
||||||
|
@ -750,47 +939,22 @@ const handleClassWorkSave = async () => {
|
||||||
// 更新 题目分值
|
// 更新 题目分值
|
||||||
ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score});
|
ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score});
|
||||||
}
|
}
|
||||||
}else {
|
}else if( classWorkForm.worktype === "框架梳理") {
|
||||||
// TODO 待定 非习题训练------------
|
chooseWorkLists.value.filter((item) => {
|
||||||
// this.chooseWorkLists.filter((item, index) => {
|
if (item.worktype === classWorkForm.worktype) {
|
||||||
// if (item.worktype === this.classWorkForm.worktype) {
|
ll.push({'id':item.id, 'score': item.score});
|
||||||
// ll.push({'id':item.id, 'score': item.score});
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
console.log(userStore,'userStoreuserStoreuserStore')
|
})
|
||||||
const cform = {
|
}
|
||||||
id: 0,
|
// 习题训练 右侧选择的资源list
|
||||||
workdate: classWorkForm.workdate, // //作业类型?web端这里貌似没有这个时间
|
|
||||||
deaddate: '', // 截止时间
|
|
||||||
entpid: userStore.deptId, //
|
|
||||||
level: 1,
|
|
||||||
parentid: 0,
|
|
||||||
worktype: classWorkForm.worktype, // 作业类型
|
|
||||||
workkey: '',
|
|
||||||
worktag: '',
|
|
||||||
uniquekey: classWorkForm.uniquekey,// 作业名称、编码
|
|
||||||
classid: 0,
|
|
||||||
classcourseid: 0,
|
|
||||||
entpcourseid: chapterId, // 这个字段很特别
|
|
||||||
slideid: 0,
|
|
||||||
title: classWorkForm.title, // 作业说明?
|
|
||||||
workcodes: JSON.stringify(classWorkForm.workcodes), // 作业内容?
|
|
||||||
edusubject: userStore.edusubject, // 学科 语文 数学
|
|
||||||
evalid: props.bookobj.levelSecondId, //userStore.evalid, // // 单元下的课ID
|
|
||||||
edustage: userStore.edustage, // 学段 年纪 高中,初中,小学
|
|
||||||
status: '10', //2024-09-11 作业布置分离后的 新模版数据; 之前老版本为空
|
|
||||||
edituserid: userStore.userId, // 当前用户id
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ll.length > 0) {
|
if (ll.length > 0) {
|
||||||
cform.entpcourseworklist = JSON.stringify(ll);
|
cform.entpcourseworklist = JSON.stringify(ll);
|
||||||
} else {
|
} else {
|
||||||
cform.entpcourseworklist = '';
|
cform.entpcourseworklist = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cform.entpcourseworklist == '') return ElMessage({ type: 'warning', message: '请先添加作业资源!'});
|
|
||||||
console.log(cform,'提交的数据');
|
console.log(cform,'提交的数据');
|
||||||
|
if(cform.entpcourseworklist == '') return ElMessage({ type: 'warning', message: '请先添加作业资源!'});
|
||||||
|
|
||||||
addClassworkReturnId(cform).then(workres => {
|
addClassworkReturnId(cform).then(workres => {
|
||||||
ElMessage({ type: 'success', message: '作业设计成功!'});
|
ElMessage({ type: 'success', message: '作业设计成功!'});
|
||||||
// 重置提交表单
|
// 重置提交表单
|
||||||
|
@ -827,7 +991,10 @@ watch(() => props.bookobj.levelSecondId, (newVal) => {
|
||||||
console.log(props.bookobj,'课程选择')
|
console.log(props.bookobj,'课程选择')
|
||||||
queryForm.eid = props.bookobj.levelSecondId,
|
queryForm.eid = props.bookobj.levelSecondId,
|
||||||
queryForm.sectionName = props.bookobj.coursetitle,
|
queryForm.sectionName = props.bookobj.coursetitle,
|
||||||
|
// 习题资源
|
||||||
handleQueryFromEntpCourseWork(0);
|
handleQueryFromEntpCourseWork(0);
|
||||||
|
// 框架梳理
|
||||||
|
getQueryFromEvaluationclue();
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -879,7 +1046,31 @@ watch(() => props.bookobj.levelSecondId, (newVal) => {
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-work{
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
.choose-work-title{
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-work-content{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
:deep(.el-form-item__label){
|
||||||
|
width: 50px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue