Merge branch 'main' into zouyf_dev
This commit is contained in:
commit
728ce16c8b
|
@ -0,0 +1,5 @@
|
||||||
|
declare module '*.vue' {
|
||||||
|
import { ComponentOptions } from 'vue'
|
||||||
|
const componentOptions: ComponentOptions
|
||||||
|
export default componentOptions
|
||||||
|
}
|
|
@ -81,5 +81,8 @@ const initLoad: Function = () => {
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#app {
|
#app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
svg, canvas, img, audio, video, iframe {
|
||||||
|
display: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -125,6 +125,8 @@ import {
|
||||||
User,
|
User,
|
||||||
Switch,
|
Switch,
|
||||||
More,
|
More,
|
||||||
|
Material,
|
||||||
|
AddPicture
|
||||||
} from '@icon-park/vue-next'
|
} from '@icon-park/vue-next'
|
||||||
|
|
||||||
export interface Icons {
|
export interface Icons {
|
||||||
|
@ -255,6 +257,8 @@ export const icons: Icons = {
|
||||||
IconUser: User,
|
IconUser: User,
|
||||||
IconSwitch: Switch,
|
IconSwitch: Switch,
|
||||||
IconMore: More,
|
IconMore: More,
|
||||||
|
IconMaterial: Material,
|
||||||
|
IconAddPicture: AddPicture
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
<template>
|
||||||
|
<header class="flex material-header">
|
||||||
|
<span>选择素材</span>
|
||||||
|
<i class="iconfont icon-guanbi" @click="onClose"></i>
|
||||||
|
</header>
|
||||||
|
<div class="flex material-list" v-loading="loading">
|
||||||
|
<div class="flex material-item" v-for="item in list" :key="item.id" >
|
||||||
|
<div class="flex">
|
||||||
|
<el-image :src="fileUrl(item)" class="img" />
|
||||||
|
<el-text truncated>{{ item.fileShowName }}</el-text>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="onInsert(item)">插入</el-button>
|
||||||
|
</div>
|
||||||
|
<el-empty description="暂无素材" v-if="!list.length" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue';
|
||||||
|
import { sessionStore } from '@/utils/store'
|
||||||
|
import { getSmarttalkPage } from '@/api/file'
|
||||||
|
import { getFileSuffix, urlToBase64 } from '@/utils/ruoyi.js'
|
||||||
|
|
||||||
|
const emit = defineEmits(['insertMaterial', 'close'])
|
||||||
|
|
||||||
|
const curNode = reactive({})
|
||||||
|
let params = {
|
||||||
|
textbookId: '',
|
||||||
|
levelFirstId: '',
|
||||||
|
levelSecondId: null,
|
||||||
|
fileSource: '个人',
|
||||||
|
fileRoot: '备课',
|
||||||
|
orderByColumn: 'uploadTime',
|
||||||
|
isAsc: 'desc',
|
||||||
|
pageSize: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
const suffixAry = [ 'jpeg','jpg','png','gif','mp3','mp4','avi','mov']
|
||||||
|
const videoSuffix = ['mp3','mp4','avi','mov']
|
||||||
|
const list = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const init = () => {
|
||||||
|
loading.value = true
|
||||||
|
getSmarttalkPage(params).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if(res.rows && res.rows.length){
|
||||||
|
// 过滤出图片和视频
|
||||||
|
list.value = res.rows.filter( item => suffixAry.indexOf(getFileSuffix(item.fileShowName)) != -1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileUrl = computed(() => (item) =>{
|
||||||
|
if(videoSuffix.indexOf(getFileSuffix(item.fileShowName)) != -1){
|
||||||
|
return item.coverPic
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return item.fileFullPath
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 插入
|
||||||
|
const onInsert = async (item) =>{
|
||||||
|
if(videoSuffix.indexOf(getFileSuffix(item.fileShowName)) != -1){
|
||||||
|
emit('insertMaterial',{ type: 'video', data: item.fileFullPath })
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const base64 = await urlToBase64(item.fileFullPath)
|
||||||
|
emit('insertMaterial',{ type: 'img', data: base64 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const GetUrlParameters = (parameters) => {
|
||||||
|
let resData = "";
|
||||||
|
|
||||||
|
let url = document.location.toString();
|
||||||
|
let arrUrl = url.split("?");
|
||||||
|
// 判断是否有参数
|
||||||
|
if (arrUrl.length > 1) {
|
||||||
|
// 拆分参数字符串
|
||||||
|
let parametersArr = arrUrl[1].split("&");
|
||||||
|
// 循环查找参数
|
||||||
|
for (let i = 0; i <= parametersArr.length; i++) {
|
||||||
|
if (parametersArr[i]) {
|
||||||
|
// 拆分参数的键和值
|
||||||
|
let parameterStr = parametersArr[i].split("=");
|
||||||
|
if (parameters == parameterStr[0]) {
|
||||||
|
resData = parameterStr[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyToBase64 = (url)=> {
|
||||||
|
const dourl = GetUrlParameters(url)
|
||||||
|
console.log(dourl,'dourl')
|
||||||
|
return
|
||||||
|
axios({
|
||||||
|
url: "/api/logo.png",
|
||||||
|
method: "get",
|
||||||
|
responseType: "blob",
|
||||||
|
}).then((res) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(res.data);
|
||||||
|
reader.onload = () => {
|
||||||
|
console.log(reader.result);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
const onClose = () =>{
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
Object.assign(curNode, data);
|
||||||
|
params.textbookId = curNode.rootid
|
||||||
|
if (curNode.parentNode) {
|
||||||
|
params.levelFirstId = curNode.parentNode.id
|
||||||
|
params.levelSecondId = curNode.id
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
params.levelFirstId = curNode.id
|
||||||
|
}
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.material-header {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
.icon-guanbi{
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.material-list{
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 150px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-item {
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
justify-content: space-between;
|
||||||
|
.img{
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -82,6 +82,8 @@
|
||||||
<IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" />
|
<IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" />
|
||||||
</Popover>
|
</Popover>
|
||||||
<IconPreviewOpen class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" />
|
<IconPreviewOpen class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" />
|
||||||
|
<IconMaterial class="handler-item" v-tooltip="'插入素材'" @click="materiaVisible = true"/>
|
||||||
|
<IconAddPicture class="handler-item" v-tooltip="'文生图'" @click="imgVisible = true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-handler">
|
<div class="right-handler">
|
||||||
|
@ -120,7 +122,18 @@
|
||||||
@update="data => { onhtml2canvas(data); classWorkTaskVisible = false }"
|
@update="data => { onhtml2canvas(data); classWorkTaskVisible = false }"
|
||||||
/>
|
/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!--插入素材-->
|
||||||
|
<Modal
|
||||||
|
v-model:visible="materiaVisible"
|
||||||
|
:width="880">
|
||||||
|
<MaterialDialog @close="materiaVisible = false" @insertMaterial="insertMaterial"/>
|
||||||
|
</Modal>
|
||||||
|
<!--文生图-->
|
||||||
|
<Modal
|
||||||
|
v-model:visible="imgVisible"
|
||||||
|
:width="1300">
|
||||||
|
<TextCreateImg hasPPt @insertImg="(url: string) => { createImageElement(url); imgVisible = false }" />
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -147,6 +160,8 @@ import Divider from '../../../components/Divider.vue'
|
||||||
import Popover from '../../../components/Popover.vue'
|
import Popover from '../../../components/Popover.vue'
|
||||||
import PopoverMenuItem from '../../../components/PopoverMenuItem.vue'
|
import PopoverMenuItem from '../../../components/PopoverMenuItem.vue'
|
||||||
import QuestToPPTist from '@/views/classTask/newClassTaskAssign/questToPPTist/index.vue'
|
import QuestToPPTist from '@/views/classTask/newClassTaskAssign/questToPPTist/index.vue'
|
||||||
|
import MaterialDialog from './MaterialDialog.vue'
|
||||||
|
import TextCreateImg from '@/components/ai-kolors/index.vue'
|
||||||
|
|
||||||
const mainStore = useMainStore()
|
const mainStore = useMainStore()
|
||||||
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore)
|
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore)
|
||||||
|
@ -198,6 +213,7 @@ const classWorkTaskVisible = ref(false)
|
||||||
const textTypeSelectVisible = ref(false)
|
const textTypeSelectVisible = ref(false)
|
||||||
const shapeMenuVisible = ref(false)
|
const shapeMenuVisible = ref(false)
|
||||||
const moreVisible = ref(false)
|
const moreVisible = ref(false)
|
||||||
|
const materiaVisible = ref(false)
|
||||||
|
|
||||||
// 绘制文字范围
|
// 绘制文字范围
|
||||||
const drawText = (vertical = false) => {
|
const drawText = (vertical = false) => {
|
||||||
|
@ -244,6 +260,25 @@ const toggleSraechPanel = () => {
|
||||||
const toggleNotesPanel = () => {
|
const toggleNotesPanel = () => {
|
||||||
mainStore.setNotesPanelState(!showNotesPanel.value)
|
mainStore.setNotesPanelState(!showNotesPanel.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 插入素材
|
||||||
|
interface MaterialParams {
|
||||||
|
type: string,
|
||||||
|
data: string
|
||||||
|
}
|
||||||
|
const insertMaterial = (item: MaterialParams) =>{
|
||||||
|
const { type, data } = item
|
||||||
|
if(type == 'video'){
|
||||||
|
createVideoElement(data)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
createImageElement(data)
|
||||||
|
}
|
||||||
|
materiaVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文生图
|
||||||
|
const imgVisible = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -154,15 +154,13 @@ const topImgWrapperPositionStyle = computed(() => {
|
||||||
const topImgPositionStyle = computed(() => {
|
const topImgPositionStyle = computed(() => {
|
||||||
const bottomWidth = imgPosition.value.width
|
const bottomWidth = imgPosition.value.width
|
||||||
const bottomHeight = imgPosition.value.height
|
const bottomHeight = imgPosition.value.height
|
||||||
console.log("底层图片位置大小(遮罩区域图片)", imgPosition.value)
|
|
||||||
|
|
||||||
const { top, left, width, height } = topImgWrapperPosition.value
|
const { top, left, width, height } = topImgWrapperPosition.value
|
||||||
console.log("width", ((bottomWidth / width * 100) - (left * (100 / width))) + '%')
|
|
||||||
console.log("height", bottomHeight / height * 100 + '%')
|
|
||||||
return {
|
return {
|
||||||
left: -left * (100 / width) + '%',
|
left: -left * (100 / width) + '%',
|
||||||
top: -top * (100 / height) + '%',
|
top: -top * (100 / height) + '%',
|
||||||
width: ((bottomWidth / width * 100) - (left * (100 / width))) + '%' ,
|
width: bottomWidth / width * 100 + '%' ,
|
||||||
height: bottomHeight / height * 100 + '%',
|
height: bottomHeight / height * 100 + '%',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -540,6 +538,7 @@ const edgePoints = [
|
||||||
|
|
||||||
img {
|
img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
max-width: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ const handleClip = (data: ImageClipedEmitData | null) => {
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
max-width: none !important; // 防止图片被压缩
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.color-mask {
|
.color-mask {
|
||||||
|
|
|
@ -144,8 +144,14 @@ import { convertTextToPicture, getQueue, getPromptId, getPicture, chattoprompt,
|
||||||
import CryptoJS from 'crypto-js'
|
import CryptoJS from 'crypto-js'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
hasPPt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
ratio: "512",
|
ratio: "512",
|
||||||
|
@ -384,7 +390,7 @@ export default {
|
||||||
urls.push(url0)
|
urls.push(url0)
|
||||||
buttonState.push({
|
buttonState.push({
|
||||||
disabled: false,
|
disabled: false,
|
||||||
text: "插入本课素材资源库",
|
text: this.hasPPt ? '插入' : "插入本课素材资源库",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.skeletonNumber = 0
|
this.skeletonNumber = 0
|
||||||
|
@ -476,6 +482,10 @@ export default {
|
||||||
|
|
||||||
//保存图片到素材库
|
//保存图片到素材库
|
||||||
async saveImage(resultIndex, index, url, resultItem) {
|
async saveImage(resultIndex, index, url, resultItem) {
|
||||||
|
if(this.hasPPt){
|
||||||
|
this.$emit('insertImg', url)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.buttonStates[resultIndex][index].disabled = true;
|
this.buttonStates[resultIndex][index].disabled = true;
|
||||||
this.buttonStates[resultIndex][index].text = "正在保存...";
|
this.buttonStates[resultIndex][index].text = "正在保存...";
|
||||||
const numberIndex = url.indexOf('filename=');
|
const numberIndex = url.indexOf('filename=');
|
||||||
|
|
|
@ -35,7 +35,7 @@ const getFileTypeIcon = () => {
|
||||||
txt: 'icon-txt',
|
txt: 'icon-txt',
|
||||||
rar: 'icon-rar',
|
rar: 'icon-rar',
|
||||||
apt: 'icon-A',
|
apt: 'icon-A',
|
||||||
aptist: 'icon-A',
|
aippt: 'icon-A',
|
||||||
}
|
}
|
||||||
if (iconObj[name]) {
|
if (iconObj[name]) {
|
||||||
return '#' + iconObj[name]
|
return '#' + iconObj[name]
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="verson">V{{ version }}</div>
|
<div class="verson">V{{ version }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -87,6 +87,12 @@ const headerMenus = [
|
||||||
icon: 'icon-gongzuotai',
|
icon: 'icon-gongzuotai',
|
||||||
path: '/desktop'
|
path: '/desktop'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '教学实践',
|
||||||
|
id: 4,
|
||||||
|
icon: 'icon-jiaoxueshijian',
|
||||||
|
path: '/prepare'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: '资源中心',
|
name: '资源中心',
|
||||||
id: 3,
|
id: 3,
|
||||||
|
@ -126,12 +132,12 @@ const computedregistertype = computed(() => {
|
||||||
if(type==3 && userStore.DeptInfo.register.auditStatus==0){
|
if(type==3 && userStore.DeptInfo.register.auditStatus==0){
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建学校 待审核
|
// 创建学校 待审核
|
||||||
if(type==4 && userStore.DeptInfo.register.auditStatus==0){
|
if(type==4 && userStore.DeptInfo.register.auditStatus==0){
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
const clickMenu = ({ id, disabled, path }) => {
|
const clickMenu = ({ id, disabled, path }) => {
|
||||||
if (disabled) return
|
if (disabled) return
|
||||||
|
@ -193,7 +199,7 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
.popoverStyle .head-aside{
|
.popoverStyle .head-aside{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -246,7 +252,7 @@ onMounted(() => {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
.user-img{
|
.user-img{
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -312,4 +318,4 @@ onMounted(() => {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -258,16 +258,45 @@ export const getFileName = (filename) => {
|
||||||
return filename.replace(/\.[^/.]+$/, "");
|
return filename.replace(/\.[^/.]+$/, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除当前选中的教材 章节 相关信息
|
|
||||||
export const clearBookInfo = () =>{
|
/**
|
||||||
//当前选中的教材
|
* 根据图片的url转换对应的base64值
|
||||||
localStorage.removeItem('curBook')
|
* @param { String } url 如:http://xxxx/xxx.png
|
||||||
// 当前选中的节点
|
* @returns base64取值
|
||||||
localStorage.removeItem('curNode')
|
*/
|
||||||
// 所有章节单元数据
|
export const urlToBase64 = (url) => {
|
||||||
localStorage.removeItem('unitList')
|
|
||||||
// 所有教材数据
|
return new Promise((resolve, reject) => {
|
||||||
localStorage.removeItem('subjectList')
|
if (!url) {
|
||||||
// 展开的节点
|
reject('请传入url内容')
|
||||||
localStorage.removeItem('defaultExpandedKeys')
|
}
|
||||||
|
if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(url)) {
|
||||||
|
// 图片地址
|
||||||
|
let image = new Image()
|
||||||
|
// 设置跨域问题
|
||||||
|
image.setAttribute('crossOrigin', 'anonymous')
|
||||||
|
// 图片地址
|
||||||
|
image.src = url +"?v=" + Math.random(); // 处理缓存,fix缓存bug,有缓存,浏览器会报错;
|
||||||
|
image.onload = () => {
|
||||||
|
let canvas = document.createElement('canvas')
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
canvas.width = image.width
|
||||||
|
canvas.height = image.height
|
||||||
|
ctx.drawImage(image, 0, 0, image.width, image.height)
|
||||||
|
|
||||||
|
// 获取图片后缀
|
||||||
|
const ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase()
|
||||||
|
// 转base64
|
||||||
|
const dataUrl = canvas.toDataURL(`image/${ext}`)
|
||||||
|
resolve(dataUrl || '')
|
||||||
|
canvas = null // 清除canvas元素
|
||||||
|
image = null // 清除img元素
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非图片地址
|
||||||
|
reject('非(png/jpe?g/gif/svg等)图片地址');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
<el-button type="primary" @click="onchange('/model/newClassTaskAssign')">作业管理</el-button>
|
<el-button type="primary" @click="onchange('/model/newClassTaskAssign')">作业管理</el-button>
|
||||||
<el-button type="success" @click="onchange('/model/teaching')">教材研读</el-button>
|
<el-button type="success" @click="onchange('/model/teaching')">教材研读</el-button>
|
||||||
<el-button type="info" @click="onchange('/model/design')">教学框架设计</el-button>
|
<el-button type="info" @click="onchange('/model/design')">教学框架设计</el-button>
|
||||||
<el-button type="success" @click="openPPTist">打开PPTist</el-button>
|
<!-- <el-button type="success" @click="openPPTist">打开PPTist</el-button>-->
|
||||||
<el-button type="info" @click="onchange('/model/examination')">考试分析</el-button>
|
<el-button type="info" @click="onchange('/model/examination')">考试分析</el-button>
|
||||||
<el-button type="primary" v-menus="dt.menus">测试</el-button>
|
<el-button type="primary" v-menus="dt.menus">测试</el-button>
|
||||||
<el-button type="success" @click="onchange('/model/aiKolors')">文生图片</el-button>
|
<el-button type="success" @click="onchange('/model/aiKolors')">文生图片</el-button>
|
||||||
|
@ -230,7 +230,7 @@ const HTTP_SERVER_API = (type, params = {}) => {
|
||||||
ppttype: 'file',
|
ppttype: 'file',
|
||||||
title: enpt.coursetitle,
|
title: enpt.coursetitle,
|
||||||
fileurl: '',
|
fileurl: '',
|
||||||
filetype: 'aptist',
|
filetype: 'aippt',
|
||||||
datacontent: '',
|
datacontent: '',
|
||||||
filekey: '',
|
filekey: '',
|
||||||
filetag: '',
|
filetag: '',
|
||||||
|
@ -287,7 +287,7 @@ const handleAll = async(type, row) =>{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'open': { // 打开资源-pptist
|
case 'open': { // 打开资源-pptist
|
||||||
if (row.filetype != 'aptist') return msgUtils.msgWarning('暂不支持该类型文件操作!')
|
if (row.filetype != 'aippt') return msgUtils.msgWarning('暂不支持该类型文件操作!')
|
||||||
sessionStore.set('curr.resource', row) // 缓存当前资源信息
|
sessionStore.set('curr.resource', row) // 缓存当前资源信息
|
||||||
createWindow('open-win', {
|
createWindow('open-win', {
|
||||||
url: '/pptist', // 窗口关闭时,清除缓存
|
url: '/pptist', // 窗口关闭时,清除缓存
|
||||||
|
@ -312,7 +312,7 @@ const handleAll = async(type, row) =>{
|
||||||
// icons 处理 type 代表传递svg
|
// icons 处理 type 代表传递svg
|
||||||
const getIcon = (o, type) => {
|
const getIcon = (o, type) => {
|
||||||
let icon = typeof o == 'string' ? o : o?.filetype
|
let icon = typeof o == 'string' ? o : o?.filetype
|
||||||
if (['aptist'].includes(o?.filetype)) icon = 'pptx'
|
if (['aippt'].includes(o?.filetype)) icon = 'pptx'
|
||||||
if (!!type) { // 其他格式icon
|
if (!!type) { // 其他格式icon
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 'svg': // 返回svg格式
|
case 'svg': // 返回svg格式
|
||||||
|
|
|
@ -158,7 +158,7 @@ const outlineCreatePPT = () => {
|
||||||
|
|
||||||
const checkProgress = () => {
|
const checkProgress = () => {
|
||||||
getProgressV2(res.sid).then(response => {
|
getProgressV2(res.sid).then(response => {
|
||||||
percentage.value = Math.round(response?.donePages/response?.totalPages)*100;
|
percentage.value = Math.round(response?.donePages*100/response?.totalPages);
|
||||||
if (response.pptStatus === "done") {
|
if (response.pptStatus === "done") {
|
||||||
emit('addSuccess',{...res,url:response.pptUrl})
|
emit('addSuccess',{...res,url:response.pptUrl})
|
||||||
ElMessage.success("生成成功");
|
ElMessage.success("生成成功");
|
||||||
|
@ -267,7 +267,6 @@ function webSocketSend(ws, data) {
|
||||||
|
|
||||||
function result1(resultData) {
|
function result1(resultData) {
|
||||||
let jsonData = JSON.parse(resultData);
|
let jsonData = JSON.parse(resultData);
|
||||||
console.log(jsonData)
|
|
||||||
outputText.value += jsonData.payload.choices.text[0].content;
|
outputText.value += jsonData.payload.choices.text[0].content;
|
||||||
const div = document.querySelector('.paragraphs');
|
const div = document.querySelector('.paragraphs');
|
||||||
if (div) {
|
if (div) {
|
||||||
|
|
|
@ -262,7 +262,7 @@ const createClasscourse = async () => {
|
||||||
// getClasscourseList('update') // 更新列表
|
// getClasscourseList('update') // 更新列表
|
||||||
ElMessage.success('创建课程-成功')
|
ElMessage.success('创建课程-成功')
|
||||||
// 新版-pptList 打开公屏
|
// 新版-pptList 打开公屏
|
||||||
if (myClassActive.value.filetype == 'aptist') {
|
if (myClassActive.value.filetype == 'aippt') {
|
||||||
const msgEl = ElMessage.warning({message:'正在打开公屏,请稍后...',duration: 0})
|
const msgEl = ElMessage.warning({message:'正在打开公屏,请稍后...',duration: 0})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
msgEl.close()
|
msgEl.close()
|
||||||
|
|
|
@ -341,7 +341,7 @@ export default {
|
||||||
cookieData: { ...configObj.data }
|
cookieData: { ...configObj.data }
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
} else if(items.fileFlag === 'aptist') { // aptist 被点击 打开PPT-List 课件
|
} else if(items.fileFlag === 'aippt') { // aippt 被点击 打开PPT-List 课件
|
||||||
return this.$emit('change', 'click', items)
|
return this.$emit('change', 'click', items)
|
||||||
}
|
}
|
||||||
if (!items||!items.fileSuffix) return;
|
if (!items||!items.fileSuffix) return;
|
||||||
|
|
|
@ -2,8 +2,20 @@
|
||||||
<div v-loading="isLoading" class="page-resource flex">
|
<div v-loading="isLoading" class="page-resource flex">
|
||||||
<ChooseTextbook @node-click="nodeClick" />
|
<ChooseTextbook @node-click="nodeClick" />
|
||||||
<div class="page-center-wrap">
|
<div class="page-center-wrap">
|
||||||
|
<el-dropdown class="prepare-center-dropdown">
|
||||||
|
<el-button type="primary">
|
||||||
|
新建<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="createAptFile">新建文枢课件</el-dropdown-item>
|
||||||
|
<el-dropdown-item>AI一键生成</el-dropdown-item>
|
||||||
|
<el-dropdown-item>导入PPT</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
<el-tabs v-model="activeAptTab" style="height: 100%;">
|
<el-tabs v-model="activeAptTab" style="height: 100%;">
|
||||||
<el-tab-pane label="教学课件" name="教学课件" class="prepare-center-jxkj">
|
<el-tab-pane label="文枢课件" name="教学课件" class="prepare-center-jxkj">
|
||||||
<div class="prepare-center-header">
|
<div class="prepare-center-header">
|
||||||
<div class="center-create-btn" style="background-color: rgb(64,158,255)" @click="createAptFile">
|
<div class="center-create-btn" style="background-color: rgb(64,158,255)" @click="createAptFile">
|
||||||
<div class="create-btn-title"><el-icon><Plus /></el-icon><label>创建APT</label></div>
|
<div class="create-btn-title"><el-icon><Plus /></el-icon><label>创建APT</label></div>
|
||||||
|
@ -145,7 +157,7 @@
|
||||||
<!-- <button @click="test">test</button> -->
|
<!-- <button @click="test">test</button> -->
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Check,Plus } from '@element-plus/icons-vue'
|
import {Check, Plus, Position} from '@element-plus/icons-vue'
|
||||||
import Reserv from '@/views/prepare/container/reserv.vue'
|
import Reserv from '@/views/prepare/container/reserv.vue'
|
||||||
import { ArrowDown } from '@element-plus/icons-vue'
|
import { ArrowDown } from '@element-plus/icons-vue'
|
||||||
import PptDialog from '@/views/prepare/container/ppt-dialog.vue'
|
import PptDialog from '@/views/prepare/container/ppt-dialog.vue'
|
||||||
|
@ -253,11 +265,11 @@ export default {
|
||||||
},
|
},
|
||||||
currentKJFileList() {
|
currentKJFileList() {
|
||||||
// return this.currentFileList.filter((item) => item.fileFlag === 'apt' || item.fileFlag === '课件')
|
// return this.currentFileList.filter((item) => item.fileFlag === 'apt' || item.fileFlag === '课件')
|
||||||
return this.currentFileList.filter((item) => ['apt','aptist','课件'].includes(item.fileFlag))
|
return this.currentFileList.filter((item) => ['apt','aippt','课件'].includes(item.fileFlag))
|
||||||
},
|
},
|
||||||
currentSCFileList() {
|
currentSCFileList() {
|
||||||
// return this.currentFileList.filter((item) => item.fileFlag !== 'apt' && item.fileFlag !== '课件')
|
// return this.currentFileList.filter((item) => item.fileFlag !== 'apt' && item.fileFlag !== '课件')
|
||||||
return this.currentFileList.filter((item) => !['apt','aptist','课件'].includes(item.fileFlag))
|
return this.currentFileList.filter((item) => !['apt','aippt','课件'].includes(item.fileFlag))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -321,7 +333,7 @@ export default {
|
||||||
if(item.fileFlag === 'apt') {
|
if(item.fileFlag === 'apt') {
|
||||||
this.$refs.calssRef.open(item.fileId, classObj)
|
this.$refs.calssRef.open(item.fileId, classObj)
|
||||||
}
|
}
|
||||||
if(item.fileFlag === 'aptist') {
|
if(item.fileFlag === 'aippt') {
|
||||||
this.$refs.calssRef.open(item.fileId, classObj)
|
this.$refs.calssRef.open(item.fileId, classObj)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -378,8 +390,8 @@ export default {
|
||||||
}, 1000)
|
}, 1000)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'click': { // 点击-打开课件-aptist
|
case 'click': { // 点击-打开课件-aippt
|
||||||
if (row.fileFlag === 'aptist' && !!row.fileId) {
|
if (row.fileFlag === 'aippt' && !!row.fileId) {
|
||||||
const res = await getEntpcoursefile(row.fileId)
|
const res = await getEntpcoursefile(row.fileId)
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
sessionStore.set('curr.resource', res.data) // 缓存当前资源信息
|
sessionStore.set('curr.resource', res.data) // 缓存当前资源信息
|
||||||
|
@ -461,6 +473,93 @@ export default {
|
||||||
},500)
|
},500)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
createAIPPT() {
|
||||||
|
listEntpcourse({
|
||||||
|
evalid: this.currentNode.id,
|
||||||
|
edituserid: this.userStore.userId,
|
||||||
|
pageSize: 500
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.rows.length <= 0) return
|
||||||
|
let resCourse = response.rows[0]
|
||||||
|
// 添加
|
||||||
|
let form = {
|
||||||
|
parentid: 0,
|
||||||
|
entpid: this.userStore.deptId,
|
||||||
|
entpcourseid: resCourse.id,
|
||||||
|
ppttype: 'file',
|
||||||
|
title: resCourse.coursetitle,
|
||||||
|
fileurl: '',
|
||||||
|
filetype: 'aippt',
|
||||||
|
datacontent: '',
|
||||||
|
filekey: '',
|
||||||
|
filetag: '',
|
||||||
|
fileidx: 0,
|
||||||
|
dflag: 0,
|
||||||
|
status: '',
|
||||||
|
edituserid: this.userStore.userId
|
||||||
|
}
|
||||||
|
addEntpcoursefileReturnId(form).then((slideid) => {
|
||||||
|
let pagearray = []
|
||||||
|
// 公屏
|
||||||
|
pagearray.push({
|
||||||
|
key: '公屏',
|
||||||
|
title: '公屏页',
|
||||||
|
slidedata: {
|
||||||
|
attrs: { width: 1333, height: 749.8125 },
|
||||||
|
className: 'Stage',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
attrs: {},
|
||||||
|
className: 'Layer',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
attrs: {
|
||||||
|
width: 1333,
|
||||||
|
height: 749.8125,
|
||||||
|
fill: 'white',
|
||||||
|
name: 'fixedbackground',
|
||||||
|
listening: true
|
||||||
|
},
|
||||||
|
className: 'Rect'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加
|
||||||
|
var form = {
|
||||||
|
parentid: slideid,
|
||||||
|
entpid: resCourse.entpid,
|
||||||
|
entpcourseid: resCourse.id,
|
||||||
|
ppttype: 'file',
|
||||||
|
title: '第一页',
|
||||||
|
fileurl: '',
|
||||||
|
filetype: 'slide',
|
||||||
|
datacontent: JSON.stringify(pagearray),
|
||||||
|
filekey: '',
|
||||||
|
filetag: '',
|
||||||
|
fileidx: 0,
|
||||||
|
dflag: 0,
|
||||||
|
status: '',
|
||||||
|
edituserid: this.userStore.userId
|
||||||
|
}
|
||||||
|
addEntpcoursefileReturnId(form).then((res) => {
|
||||||
|
creatAPT({
|
||||||
|
...this.uploadData,
|
||||||
|
fileId: slideid,
|
||||||
|
fileShowName: this.currentNode.itemtitle + '.apt'
|
||||||
|
}).then((res) => {
|
||||||
|
this.currentFileList.unshift(res.resData)
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.$refs['kjItemRef'+res.resData.id][0].openFileWin(res.resData);
|
||||||
|
},500)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
createAptFile() {
|
createAptFile() {
|
||||||
listEntpcourse({
|
listEntpcourse({
|
||||||
evalid: this.currentNode.id,
|
evalid: this.currentNode.id,
|
||||||
|
@ -653,7 +752,7 @@ export default {
|
||||||
for (let i = 0; i < this.currentFileList.length; i++) {
|
for (let i = 0; i < this.currentFileList.length; i++) {
|
||||||
let item = this.currentFileList[i]
|
let item = this.currentFileList[i]
|
||||||
if (item.fileFlag === 'apt') continue;
|
if (item.fileFlag === 'apt') continue;
|
||||||
if (item.fileFlag === 'aptist') continue;
|
if (item.fileFlag === 'aippt') continue;
|
||||||
await asyncLocalFile(item)
|
await asyncLocalFile(item)
|
||||||
}
|
}
|
||||||
this.asyncAllFileVisiable = false
|
this.asyncAllFileVisiable = false
|
||||||
|
@ -872,6 +971,13 @@ export default {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
position: relative;
|
||||||
|
.prepare-center-dropdown{
|
||||||
|
z-index: 9999;
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
.prepare-center-jxkj{
|
.prepare-center-jxkj{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -131,6 +131,7 @@ const params = reactive(
|
||||||
|
|
||||||
const addAiPPT = async(res) => {
|
const addAiPPT = async(res) => {
|
||||||
let node = courseObj.node
|
let node = courseObj.node
|
||||||
|
pptDialog.value = false;
|
||||||
if (!node) return msgUtils.msgWarning('请选择章节?')
|
if (!node) return msgUtils.msgWarning('请选择章节?')
|
||||||
pgDialog.visible = true
|
pgDialog.visible = true
|
||||||
pgDialog.pg.percentage = 0
|
pgDialog.pg.percentage = 0
|
||||||
|
@ -238,8 +239,8 @@ const HTTP_SERVER_API = (type, params = {}) => {
|
||||||
const node = courseObj.node || {}
|
const node = courseObj.node || {}
|
||||||
const def = {
|
const def = {
|
||||||
fileId: '', // 文件id - Entpcoursefile 对应id
|
fileId: '', // 文件id - Entpcoursefile 对应id
|
||||||
fileFlag: 'aptist',
|
fileFlag: 'aippt',
|
||||||
fileShowName: node.itemtitle + '.aptist',
|
fileShowName: node.itemtitle + '.aippt',
|
||||||
textbookId: node.rootid,
|
textbookId: node.rootid,
|
||||||
levelFirstId: node.parentid||node.id,
|
levelFirstId: node.parentid||node.id,
|
||||||
levelSecondId: node.parentid && node.id,
|
levelSecondId: node.parentid && node.id,
|
||||||
|
@ -298,7 +299,7 @@ const getDefParams = (params) => {
|
||||||
ppttype: 'file',
|
ppttype: 'file',
|
||||||
title: enpt.coursetitle,
|
title: enpt.coursetitle,
|
||||||
fileurl: '',
|
fileurl: '',
|
||||||
filetype: 'aptist',
|
filetype: 'aippt',
|
||||||
datacontent: '',
|
datacontent: '',
|
||||||
filekey: '',
|
filekey: '',
|
||||||
filetag: '',
|
filetag: '',
|
||||||
|
|
Loading…
Reference in New Issue