Compare commits
13 Commits
e5b6473de4
...
53308a09d1
Author | SHA1 | Date |
---|---|---|
zhangxuelin | 53308a09d1 | |
lyc | 244a4b2b43 | |
lyc | 7dc10cb986 | |
baigl | 4fdb9a3ecc | |
白了个白 | be138b8c58 | |
朱浩 | fb6e0da6ff | |
朱浩 | 34fec10fc1 | |
baigl | c150564797 | |
白了个白 | b5176e41b3 | |
白了个白 | 36b6d1cc05 | |
yangws | c6b65102bd | |
小杨 | 2513215a52 | |
zhangxuelin | 488ad420d7 |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "aix-win",
|
||||
"version": "2.5.1",
|
||||
"name": "aix-win-ws",
|
||||
"version": "2.5.3",
|
||||
"description": "",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "上海交大重庆人工智能研究院",
|
||||
|
|
|
@ -53,3 +53,14 @@ export const moveSmarttalk = (params) => {
|
|||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const addFileToPrepareThird = (data) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/addFileToPrepareThird',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ export function conversation(data) {
|
|||
url: '/v1/api/new_conversation',
|
||||
method: 'get',
|
||||
headers: {
|
||||
isToken: true,
|
||||
'Authorization':'Bearer ragflow-IwNzMxMTIyOGY0ZTExZWZiOGE2MDI0Mm',
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': '*/*'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4723712 */
|
||||
src: url('iconfont.woff2?t=1731315402630') format('woff2'),
|
||||
url('iconfont.woff?t=1731315402630') format('woff'),
|
||||
url('iconfont.ttf?t=1731315402630') format('truetype');
|
||||
src: url('iconfont.woff2?t=1731393731097') format('woff2'),
|
||||
url('iconfont.woff?t=1731393731097') format('woff'),
|
||||
url('iconfont.ttf?t=1731393731097') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,14 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-tihuan:before {
|
||||
content: "\e7ab";
|
||||
}
|
||||
|
||||
.icon-fasong:before {
|
||||
content: "\e692";
|
||||
}
|
||||
|
||||
.icon-ai1:before {
|
||||
content: "\e70a";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,20 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "12730938",
|
||||
"name": "替换",
|
||||
"font_class": "tihuan",
|
||||
"unicode": "e7ab",
|
||||
"unicode_decimal": 59307
|
||||
},
|
||||
{
|
||||
"icon_id": "34833984",
|
||||
"name": "发送",
|
||||
"font_class": "fasong",
|
||||
"unicode": "e692",
|
||||
"unicode_decimal": 59026
|
||||
},
|
||||
{
|
||||
"icon_id": "41844021",
|
||||
"name": "ai",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,260 @@
|
|||
<template>
|
||||
<el-dialog v-model="isDialog" :show-close="false" width="800" destroy-on-close>
|
||||
<template #header>
|
||||
<div class="custom-header flex">
|
||||
<span>{{ item.name }}</span>
|
||||
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dialog-content">
|
||||
<el-scrollbar height="400px">
|
||||
<div class="chart-con flex">
|
||||
<template v-for="item in msgList">
|
||||
<div class="flex-end flex" v-if="item.type == 'user'">
|
||||
<div class="chart-item user">{{ item.msg }}</div>
|
||||
</div>
|
||||
<div class="flex-start flex" v-else>
|
||||
<div class="flex" v-loading="!item.msg">
|
||||
<div class="chart-item robot">{{ item.msg }}</div>
|
||||
</div>
|
||||
<div class="flex flex-end replace-item">
|
||||
<span @click="saveAdjust(item)"><i class="iconfont icon-tihuan"></i>替换分析结果</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="loaded" class="chart-loading">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<div class="input-box flex">
|
||||
<el-input v-model="textarea" :disabled="loaded"/>
|
||||
<div class="ipt-icon" @click="send">
|
||||
<i class="iconfont icon-fasong"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { conversation, completion } from '@/api/mode/index'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const textarea = ref('')
|
||||
|
||||
const isDialog = defineModel()
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return { name: '11' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['saveEdit'])
|
||||
|
||||
const loaded = ref(false)
|
||||
|
||||
const msgList = ref([])
|
||||
|
||||
const send = () =>{
|
||||
if(loaded.value) return
|
||||
msgList.value.push({
|
||||
type: 'user',
|
||||
msg: textarea.value
|
||||
})
|
||||
loaded.value = true
|
||||
getConversation(textarea.value)
|
||||
textarea.value = ''
|
||||
}
|
||||
const curNode = reactive({})
|
||||
const params = reactive(
|
||||
{
|
||||
"conversation_id": "",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": ""
|
||||
}
|
||||
],
|
||||
"quote": false,
|
||||
"stream": false
|
||||
}
|
||||
)
|
||||
// 获取会话ID
|
||||
const getConversation = async (val) => {
|
||||
const result = await conversation()
|
||||
params.conversation_id = result.data.data.id
|
||||
getCompletion(val)
|
||||
}
|
||||
// 大模型对话
|
||||
const getCompletion = async (val) => {
|
||||
try {
|
||||
|
||||
params.messages[0].content = `根据${curNode.edustage}语文课标${props.item.name},${val}`
|
||||
const res = await completion(params)
|
||||
console.log('对话结果===》', res)
|
||||
let answer = res.data.data.answer
|
||||
msgList.value.push({
|
||||
type: 'robot',
|
||||
msg: answer,
|
||||
})
|
||||
|
||||
} finally {
|
||||
loaded.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const saveAdjust = (item) =>{
|
||||
emit('saveAdjust', item.msg)
|
||||
isDialog.value = false
|
||||
ElMessage.success('操作成功')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
let data = sessionStore.get('subject.curNode')
|
||||
Object.assign(curNode, data);
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom-header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.icon-guanbi {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 20px;
|
||||
|
||||
.chart-con {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
.flex-end{
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.flex-start{
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
.chart-item {
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.user {
|
||||
background: #F2F2F2;
|
||||
margin-bottom: 10px;
|
||||
|
||||
}
|
||||
|
||||
.robot {
|
||||
background: #409EFF;
|
||||
color: #FFF;
|
||||
}
|
||||
.replace-item{
|
||||
font-size: 12px;
|
||||
color: #409EFF;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.input-box {
|
||||
position: relative;
|
||||
|
||||
.ipt-icon {
|
||||
cursor: pointer;
|
||||
padding: 0 5px;
|
||||
.icon-fasong {
|
||||
font-size: 26px;
|
||||
color: #409EFF;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.chart-loading,
|
||||
.chart-loading>div {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.chart-loading {
|
||||
display: block;
|
||||
font-size: 0;
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
.chart-loading.la-dark {
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
.chart-loading>div {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
background-color: currentColor;
|
||||
border: 0 solid currentColor;
|
||||
}
|
||||
|
||||
.chart-loading {
|
||||
width: 54px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.chart-loading>div:nth-child(1) {
|
||||
animation-delay: -200ms;
|
||||
}
|
||||
|
||||
.chart-loading>div:nth-child(2) {
|
||||
animation-delay: -100ms;
|
||||
}
|
||||
|
||||
.chart-loading>div:nth-child(3) {
|
||||
animation-delay: 0ms;
|
||||
}
|
||||
|
||||
.chart-loading>div {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 100%;
|
||||
margin-right: 4px;
|
||||
animation: ball-pulse 1s ease infinite;
|
||||
}
|
||||
@keyframes ball-pulse {
|
||||
|
||||
0%,
|
||||
60%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
30% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0.01);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<el-dialog v-model="isDialog" :show-close="false" width="900">
|
||||
<template #header>
|
||||
<div class="custom-header flex">
|
||||
<span>{{ item.name }}</span>
|
||||
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dialog-content">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-input v-model="textarea" :autosize="{ minRows: 5, maxRows: 15 }" type="textarea" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="isDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSave">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch} from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const textarea = ref('')
|
||||
|
||||
const isDialog = defineModel()
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return { name: '11' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.item.oldAnswer, (newVal) => {
|
||||
if (newVal) {
|
||||
textarea.value = newVal
|
||||
}
|
||||
},{ deep: true })
|
||||
|
||||
const emit = defineEmits(['saveEdit'])
|
||||
const onSave = () =>{
|
||||
emit('saveEdit', textarea.value)
|
||||
isDialog.value = false
|
||||
ElMessage.success('操作成功')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom-header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.icon-guanbi {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
padding-top: 10px;
|
||||
|
||||
}
|
||||
</style>
|
|
@ -20,7 +20,7 @@
|
|||
</template>
|
||||
</el-dropdown>
|
||||
<div>
|
||||
<el-button type="primary" link>
|
||||
<el-button type="primary" link @click="keywordDialog = true">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
|
@ -31,6 +31,35 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="keywordDialog" :show-close="false" width="600">
|
||||
<template #header>
|
||||
<div class="custom-header flex">
|
||||
<span>添加提示词</span>
|
||||
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dialog-content">
|
||||
<el-form :model="form" label-width="auto">
|
||||
<el-form-item label="名称">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="提示词">
|
||||
<el-input v-model="form.desc" type="textarea" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="keywordDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="keywordDialog = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<Dialog v-model="showDialog" :model="model" />
|
||||
</template>
|
||||
|
||||
|
@ -41,6 +70,7 @@ import { ElMessageBox } from 'element-plus'
|
|||
import { modelList } from '@/api/mode/index'
|
||||
import Dialog from './dialog.vue'
|
||||
|
||||
const keywordDialog = ref(false)
|
||||
const props = defineProps({
|
||||
model: {
|
||||
type: [String, Number],
|
||||
|
@ -52,7 +82,7 @@ const emit = defineEmits(['changeTemp', 'onRead'])
|
|||
const showDialog = ref(false)
|
||||
|
||||
const aiRead = () => {
|
||||
emit('onRead')
|
||||
emit('onRead')
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,6 +118,11 @@ const changeTemplate = (val) => {
|
|||
}
|
||||
|
||||
|
||||
const form = reactive({
|
||||
name: '',
|
||||
desc: '',
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getTemplateList()
|
||||
|
@ -121,4 +156,14 @@ onMounted(() => {
|
|||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.icon-guanbi {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<el-scrollbar height="100%">
|
||||
<div class="template-list">
|
||||
<el-row v-for="item in childTempList">
|
||||
<el-row v-for="(item,index) in childTempList">
|
||||
<el-col :span="24">
|
||||
<div class="template-item" v-loading="item.loading">
|
||||
<div class="item-header"><span class="blue">#</span>{{ item.name }}</div>
|
||||
|
@ -17,15 +17,15 @@
|
|||
<div class="item-answer" v-html="item.answer"></div>
|
||||
</div>
|
||||
<div class="ai-btn" v-if="item.answer">
|
||||
<el-button type="primary" link>
|
||||
<el-button type="primary" link @click="againResult(index, item)">
|
||||
<i class="iconfont icon-ai1"></i>
|
||||
重新研读
|
||||
</el-button>
|
||||
<el-button type="primary" link>
|
||||
<el-button type="primary" link @click="onAdjust(index, item)">
|
||||
<i class="iconfont icon-duihua"></i>
|
||||
AI对话调整
|
||||
</el-button>
|
||||
<el-button type="primary" link>
|
||||
<el-button type="primary" link @click="onEdit(index, item)">
|
||||
<i class="iconfont icon-bianji1"></i>
|
||||
手动编辑结果
|
||||
</el-button>
|
||||
|
@ -36,16 +36,21 @@
|
|||
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<!--编辑结果-->
|
||||
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit"/>
|
||||
<!--AI 对话调整-->
|
||||
<AdjustDialog v-model="isAdjust" :item="editItem" @saveAdjust="saveAdjust"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, watch } from 'vue';
|
||||
import EditDialog from './edit-dialog.vue'
|
||||
import AdjustDialog from './adjust-dialog.vue'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { conversation, completion } from '@/api/mode/index'
|
||||
import { modelList } from '@/api/mode/index'
|
||||
import { conversation, completion, modelList } from '@/api/mode/index'
|
||||
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
|
@ -79,17 +84,15 @@ const getChildTemplate = () => {
|
|||
tempLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const isEdit = ref(false)
|
||||
watch(() => props.tempId, (newVal) => {
|
||||
if (newVal) {
|
||||
// isEdit.value = true
|
||||
getChildTemplate()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
// 获取会话ID
|
||||
const params = reactive(
|
||||
{
|
||||
|
@ -104,22 +107,17 @@ const params = reactive(
|
|||
"stream": false
|
||||
}
|
||||
)
|
||||
const isAiDeal = ref(false)
|
||||
const curNode = reactive({})
|
||||
const getConversation = async () => {
|
||||
|
||||
const { user: { userId } } = userStore
|
||||
const result = await conversation({ user_id: String(userId) })
|
||||
console.log('result',result)
|
||||
params.conversation_id = result.data.data.id
|
||||
|
||||
|
||||
getCompletion()
|
||||
}
|
||||
// 大模型对话
|
||||
const resultList = ref([])
|
||||
const getCompletion = async () => {
|
||||
console.log('params=====>', params)
|
||||
|
||||
for (let item of childTempList.value) {
|
||||
try {
|
||||
item.loading = true
|
||||
|
@ -127,6 +125,7 @@ const getCompletion = async () => {
|
|||
const res = await completion(params)
|
||||
console.log('对话结果===》', res)
|
||||
let answer = res.data.data.answer
|
||||
item.oldAnswer = answer
|
||||
item.answer = getResult(answer);
|
||||
|
||||
} finally {
|
||||
|
@ -136,6 +135,20 @@ const getCompletion = async () => {
|
|||
}
|
||||
|
||||
|
||||
// 重新研读
|
||||
const againResult = async (index,item) =>{
|
||||
try{
|
||||
childTempList.value[index].loading = true
|
||||
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
||||
const res = await completion(params)
|
||||
let answer = res.data.data.answer
|
||||
item.oldAnswer = answer
|
||||
item.answer = getResult(answer);
|
||||
}finally {
|
||||
childTempList.value[index].loading = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 分析获取课标对话结果
|
||||
let getResult = (text) => {
|
||||
|
@ -144,7 +157,34 @@ let getResult = (text) => {
|
|||
text = text.replace(/\*\*(.*?)\*\*/g, "<div class='text-tit'>$1</div>");
|
||||
text = text.replace(/(\d+\..*?)\n/g, "<div class='text-num'>$1</div>\n");
|
||||
return text
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const curIndex = ref(-1)
|
||||
const editItem = reactive({})
|
||||
const onEdit = (index,item) =>{
|
||||
curIndex.value = index
|
||||
Object.assign(editItem, item)
|
||||
isEdit.value = true
|
||||
}
|
||||
|
||||
// 保存编辑
|
||||
const saveEdit = (data) =>{
|
||||
childTempList.value[curIndex.value].oldAnswer = data
|
||||
let answer = getResult(data);
|
||||
childTempList.value[curIndex.value].answer = answer
|
||||
}
|
||||
|
||||
const isAdjust = ref(false)
|
||||
const onAdjust = (index, item) =>{
|
||||
curIndex.value = index
|
||||
Object.assign(editItem, item)
|
||||
isAdjust.value = true
|
||||
}
|
||||
const saveAdjust = (item) =>{
|
||||
childTempList.value[curIndex.value].oldAnswer = item
|
||||
let answer = getResult(item);
|
||||
childTempList.value[curIndex.value].answer = answer
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -895,7 +895,7 @@ ol {
|
|||
font-size: 14px;
|
||||
color: #000;
|
||||
|
||||
/deep/ .jsontree_tree {
|
||||
:deep(.jsontree_tree) {
|
||||
font-family: 'Trebuchet MS', Arial, sans-serif !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,11 @@
|
|||
</el-row>
|
||||
<!-- 习题表格 -->
|
||||
<div class="infinite-list-wrapper" >
|
||||
<!-- <el-table :data="workResource.entpCourseWorkList" style="width: 100%; height: 100%;">
|
||||
<el-table
|
||||
:data="workResource.entpCourseWorkList"
|
||||
style="width: 100%; height: 100%;"
|
||||
v-loading="pageParams.loading"
|
||||
>
|
||||
<el-table-column type="index" width="60" />
|
||||
<el-table-column align="left" >
|
||||
<template #header>
|
||||
|
@ -114,22 +118,18 @@
|
|||
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table> -->
|
||||
<ul
|
||||
</el-table>
|
||||
|
||||
<!-- <ul
|
||||
v-infinite-scroll="pageLoad"
|
||||
class="infinite-list"
|
||||
infinite-scroll-immediate="false"
|
||||
infinite-scroll-distance='1'
|
||||
infinite-scroll-distance='100'
|
||||
infinite-scroll-delay="1000"
|
||||
:infinite-scroll-disabled="pageDisabled"
|
||||
>
|
||||
<li v-for="(item,index) in workResource.entpCourseWorkList" :key="item" class="infinite-list-item">
|
||||
<div align="left" style="width: 100%;" >
|
||||
<!-- <template #header>
|
||||
<div style="display: flex">
|
||||
<div style="align-items: center;">题目内容</div>
|
||||
</div>
|
||||
</template> -->
|
||||
<div @click="showExamAnalyseDrawer(item)">
|
||||
<div>
|
||||
<span style="width: 20px;">{{ index +1 }}. </span>
|
||||
|
@ -155,18 +155,18 @@
|
|||
description="未找到相关试题"
|
||||
style="width: 100%; height: 200px; margin-top: 20px;"
|
||||
></el-empty>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- 分页 这里不用-->
|
||||
<!-- <div style="height: 55px;">
|
||||
<pagination
|
||||
v-show="entpCourseWorkTotal > 0"
|
||||
<div style="height: 55px;">
|
||||
<el-pagination
|
||||
v-show="pageParams.total > 0"
|
||||
v-model:page="paginationParams.pageNum"
|
||||
v-model:limit="paginationParams.pageSize"
|
||||
:total="entpCourseWorkTotal"
|
||||
:total="pageParams.total"
|
||||
:style="{ position: 'relative', 'margin-top': '5px' }"
|
||||
@pagination="getPaginationList" />
|
||||
</div> -->
|
||||
@change="getPaginationList" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 非习题训练:常规作业、 -->
|
||||
<div v-if="classWorkForm.worktype!='习题训练'">
|
||||
|
@ -276,6 +276,7 @@ import { onMounted, ref, nextTick, watch, reactive, getCurrentInstance, computed
|
|||
import { ElMessage } from 'element-plus'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
|
||||
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
||||
import { addClassworkReturnId } from '@/api/teaching/classwork'
|
||||
|
@ -284,6 +285,7 @@ import { listEvaluation } from '@/api/subject'
|
|||
import { listEntpcoursefile } from '@/api/education/entpcoursefile'
|
||||
import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
|
||||
|
||||
|
||||
import { useGetHomework } from '@/hooks/useGetHomework'
|
||||
import { processList } from '@/hooks/useProcessList'
|
||||
import { getCurrentTime } from '@/utils/date'
|
||||
|
@ -409,15 +411,15 @@ const fileLoading = ref(false); // 常规作业loading
|
|||
|
||||
// 下拉滚动参数
|
||||
|
||||
const BASE_LIMIT_COUT = 50; // 总加载额外试题数
|
||||
const pageNoMore = computed( () => {
|
||||
if (pageParams.value.total < 1) {
|
||||
return false;
|
||||
}
|
||||
let count = BASE_LIMIT_COUT >= pageParams.value.total ? pageParams.value.total : pageParams.value.originCount+BASE_LIMIT_COUT;
|
||||
return workResource.entpCourseWorkList.length >= count;
|
||||
});
|
||||
const pageDisabled = computed(() => pageParams.value.loading || pageNoMore.value);
|
||||
// const BASE_LIMIT_COUT = 50; // 总加载额外试题数
|
||||
// const pageNoMore = computed( () => {
|
||||
// if (pageParams.value.total < 1) {
|
||||
// return false;
|
||||
// }
|
||||
// let count = BASE_LIMIT_COUT >= pageParams.value.total ? pageParams.value.total : pageParams.value.originCount+BASE_LIMIT_COUT;
|
||||
// return workResource.entpCourseWorkList.length >= count;
|
||||
// });
|
||||
// const pageDisabled = computed(() => pageParams.value.loading || pageNoMore.value);
|
||||
const pageParams = ref({
|
||||
loading: false, // 是否正在加载中
|
||||
originCount: 0, // 初始条目数量
|
||||
|
@ -497,7 +499,7 @@ function Apis(key) {
|
|||
// 年份
|
||||
yearStr: entpCourseWorkQueryParams.yearStr !== '-1' ? entpCourseWorkQueryParams.yearStr:'',
|
||||
// 知识点
|
||||
thirdId: entpCourseWorkQueryParams.point.length > 0 ? entpCourseWorkQueryParams.point[0]:'',
|
||||
thirdId: entpCourseWorkQueryParams.point&&entpCourseWorkQueryParams.point.length > 0 ? entpCourseWorkQueryParams.point[0]:'',
|
||||
// 关键字
|
||||
keyword: entpCourseWorkQueryParams.keyWord && entpCourseWorkQueryParams.keyWord !== '' ? entpCourseWorkQueryParams.keyWord:'',
|
||||
|
||||
|
@ -519,16 +521,16 @@ const handleQueryFromEntpCourseWork= async (queryType) => {
|
|||
// }
|
||||
|
||||
client(t('任务1', 1500)).then(res => {
|
||||
console.log("请求返回",res);
|
||||
if(paginationParams.pageNum == 1){
|
||||
workResource.entpCourseWorkList = [];
|
||||
workResource.entpCourseWorkTotal = 0;
|
||||
//console.log("请求返回",res);
|
||||
// if(paginationParams.pageNum == 1){
|
||||
// workResource.entpCourseWorkList = [];
|
||||
// workResource.entpCourseWorkTotal = 0;
|
||||
|
||||
// 初始化下拉滚动条参数
|
||||
// pageParams.value.loading = false;
|
||||
// pageParams.value.isFirst = true;
|
||||
// pageParams.value.originCount = 0;
|
||||
}
|
||||
// // 初始化下拉滚动条参数
|
||||
// // pageParams.value.loading = false;
|
||||
// // pageParams.value.isFirst = true;
|
||||
// // pageParams.value.originCount = 0;
|
||||
// }
|
||||
const data = res.data || [];
|
||||
if(data && data.length>0){
|
||||
// workResource.entpCourseWorkList = entpcourseworkres.data;
|
||||
|
@ -542,17 +544,20 @@ const handleQueryFromEntpCourseWork= async (queryType) => {
|
|||
|
||||
// 格式化试题信息
|
||||
processList(data);
|
||||
workResource.entpCourseWorkList.push(...data);
|
||||
//workResource.entpCourseWorkList.push(...data);
|
||||
workResource.entpCourseWorkList = data;
|
||||
|
||||
// 初次加载时更新当前试题数量
|
||||
if (pageParams.value.isFirst) {
|
||||
pageParams.value.isFirst = false;
|
||||
pageParams.value.originCount = workResource.entpCourseWorkList.length;
|
||||
pageParams.value.total = parseInt(res.msg);
|
||||
paginationParams.pageNum = Math.ceil(parseInt(res.msg)/paginationParams.pageSize);
|
||||
console.log('first->', pageParams.value, paginationParams);
|
||||
}
|
||||
}
|
||||
pageParams.value.loading = false;
|
||||
});
|
||||
});
|
||||
|
||||
//const entpcourseworkres = await listEntpcourseworkNew(queryForm);
|
||||
|
||||
|
@ -977,6 +982,12 @@ const showExamAnalyseDrawer = (row) => {
|
|||
})
|
||||
}
|
||||
|
||||
const getPaginationList = ( page, limit ) => {
|
||||
paginationParams.pageNum = page;
|
||||
paginationParams.pageSize = limit;
|
||||
console.log(page, limit)
|
||||
handleQueryFromEntpCourseWork(0);
|
||||
}
|
||||
|
||||
const pageLoad = async() => {
|
||||
console.log("加载中...")
|
||||
|
|
|
@ -179,7 +179,7 @@ const classWorkAnalysis = reactive({
|
|||
entpcourseworklistarray: [], // 当前学习任务所包含的试题ID
|
||||
})
|
||||
const tableRadio = reactive({
|
||||
value: '1', // 已交
|
||||
value: 1, // 已交
|
||||
list: [], // 已交list
|
||||
num1: 0, // 已交人数
|
||||
num0: 0 // 未交人数
|
||||
|
@ -219,7 +219,7 @@ const openDialog = (data, isInit=true) => {
|
|||
classWorkAnalysis.workclass = data.workclass
|
||||
// 重置学生列表
|
||||
tableRadio.list = []
|
||||
tableRadio.value = '1'
|
||||
tableRadio.value = 1
|
||||
tableRadio.num0 = 0
|
||||
tableRadio.num1 = 0
|
||||
|
||||
|
@ -399,7 +399,7 @@ const getClassWorkStudentList = (rowId) => {
|
|||
tableRadio.list =
|
||||
classWorkAnalysis.classworkdata &&
|
||||
classWorkAnalysis.classworkdata.filter((item) => item.finishtimelength != '0')
|
||||
tableRadio.value = '1'
|
||||
tableRadio.value = 1
|
||||
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length
|
||||
tableRadio.num1 = tableRadio.list.length
|
||||
// 自动批阅判断
|
||||
|
@ -415,7 +415,7 @@ const getClassWorkStudentList = (rowId) => {
|
|||
*/
|
||||
const teacherCriticism = ()=>{
|
||||
// 已交的list才自动批阅判断
|
||||
if(tableRadio.value == '1'&& classWorkAnalysis.worktype == '习题训练'){
|
||||
if(tableRadio.value == 1 && classWorkAnalysis.worktype == '习题训练'){
|
||||
// 只有习题训练才会自动批阅
|
||||
tableRadio.list = tableRadio.list.map((item) => {
|
||||
return {
|
||||
|
@ -570,16 +570,16 @@ const tableRadioChange = (e) => {
|
|||
isopen_dtwk_table.value = false;
|
||||
console.log(e,'??????')
|
||||
console.log("学生列表:", classWorkAnalysis.classworkdata)
|
||||
if(e=='1'){
|
||||
if(e==1){
|
||||
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength != '0')
|
||||
tableRadio.value = '1';
|
||||
tableRadio.value = 1;
|
||||
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
|
||||
tableRadio.num1 = tableRadio.list.length;
|
||||
// 自动批阅判断
|
||||
teacherCriticism();
|
||||
}else if(e=='0'){
|
||||
}else if(e==0){
|
||||
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength == '0')
|
||||
tableRadio.value = '0';
|
||||
tableRadio.value = 0;
|
||||
tableRadio.num0 = tableRadio.list.length;
|
||||
tableRadio.num1 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ const getHomework = async () => {
|
|||
} else if (item.worktype == '习题训练') {
|
||||
item.workclass = 'danger'
|
||||
} else {
|
||||
item.workclass = ''
|
||||
item.workclass = 'info'
|
||||
}
|
||||
|
||||
item.workdatacount = JSON.parse('[' + item.classworkdatastudentids + ']').length
|
||||
|
|
|
@ -17,24 +17,25 @@
|
|||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { ref, defineExpose } from 'vue'
|
||||
import { ref, defineExpose,defineEmits } from 'vue'
|
||||
import ChooseTextbook from './chooseTextbook.vue'
|
||||
|
||||
const emit = defineEmits(['onsuccess'])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const getNodeInfo = ref([])
|
||||
|
||||
const getNodeInfo = ref({})
|
||||
|
||||
const openDialog = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
||||
const getFullObj = (node) => {
|
||||
const obj = []
|
||||
const recursive = (currentNode) => {
|
||||
// 这里添加节点参数
|
||||
if (currentNode.parentNode) {
|
||||
obj.unshift(Object.assign({curentId: currentNode.id,title:currentNode.itemtitle}, currentNode.parentNode))
|
||||
obj.unshift({id: currentNode.id,title:currentNode.itemtitle})
|
||||
recursive(currentNode.parentNode)
|
||||
} else {
|
||||
obj.unshift({id: currentNode.id,title:currentNode.itemtitle})
|
||||
|
@ -43,19 +44,21 @@
|
|||
recursive(node)
|
||||
return obj
|
||||
}
|
||||
|
||||
|
||||
const nodeClick = (data) => {
|
||||
getNodeInfo.value = {
|
||||
textbookId:data.node.rootid,
|
||||
bookList:getFullObj(data.node)
|
||||
cataList:getFullObj(data.node)
|
||||
}
|
||||
console.log(getNodeInfo.value,'log')
|
||||
}
|
||||
|
||||
|
||||
const save = () => {
|
||||
dialogVisible.value = false
|
||||
emit('onsuccess', getNodeInfo.value)
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-button v-loading="item.loading" size="small" plain round type="primary" @click.stop="openChapter(item)">
|
||||
<i class="iconfont icon-jiahao"></i>
|
||||
备课</el-button
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</el-scrollbar>
|
||||
|
@ -66,17 +70,20 @@
|
|||
/>
|
||||
</div>
|
||||
<FilePreview ref="thirdPreview" v-model="isViewImg"></FilePreview>
|
||||
<TreeLog ref="treelogRef" @onsuccess="addToPrepare"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
// import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Clock,View,Folder,Search } from '@element-plus/icons-vue'
|
||||
import FileImage from '@/components/file-image/index.vue'
|
||||
import FilePreview from '@/components/thirdFile-preview/index.vue'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useResoureStore from '../store'
|
||||
import { addFileToPrepareThird } from '@/api/file'
|
||||
import TreeLog from '@/views/prepare/components/treeLog.vue'
|
||||
|
||||
const userstore = useUserStore()
|
||||
const sourceStore = useResoureStore()
|
||||
|
@ -85,6 +92,9 @@ const sourceStore = useResoureStore()
|
|||
//判断是否预览图片
|
||||
const isViewImg = ref(false)
|
||||
const thirdPreview = ref()
|
||||
const treelogRef = ref()
|
||||
const currentItem = ref()
|
||||
const loading = ref(false)
|
||||
|
||||
// 分页change
|
||||
const handleSizeChange = (limit) => {
|
||||
|
@ -114,6 +124,31 @@ const handleRow = (item) => {
|
|||
isViewImg.value = true
|
||||
thirdPreview.value.init(item.itemId)
|
||||
}
|
||||
const openChapter = (item)=>{
|
||||
currentItem.value = item
|
||||
// 打开弹窗
|
||||
treelogRef.value.openDialog()
|
||||
}
|
||||
const addToPrepare = (data) => {
|
||||
console.log(data)
|
||||
let chapterArr = []
|
||||
for (let i = 0; i < data.cataList.length; i++) {
|
||||
chapterArr.push({id: data.cataList[i].id,name: data.cataList[i].title})
|
||||
}
|
||||
let postData = {
|
||||
itemId: currentItem.value.itemId,
|
||||
textBookId: data.textbookId,
|
||||
chapter: JSON.stringify(chapterArr)
|
||||
}
|
||||
currentItem.value.loading = true
|
||||
addFileToPrepareThird(postData).then((res) => {
|
||||
currentItem.value.loading = false
|
||||
console.log(res)
|
||||
if (res.code === 200) {
|
||||
ElMessage.success("加入备课成功")
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
Loading…
Reference in New Issue