Merge pull request 'lyc-dev' (#27) from lyc-dev into main

This commit is contained in:
lyc 2024-07-17 11:34:27 +08:00
commit e1f0c1a052
16 changed files with 466 additions and 29 deletions

View File

@ -22,8 +22,8 @@ export default defineConfig({
server: {
proxy: {
'/dev-api': {
// target: 'http://27.128.240.72:7865',
target: 'http://192.168.2.52:7863',
target: 'http://27.128.240.72:7865',
// target: 'http://192.168.2.52:7863',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
},

View File

@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont"; /* Project id 2794390 */
src: url('iconfont.woff2?t=1720953486579') format('woff2'),
url('iconfont.woff?t=1720953486579') format('woff'),
url('iconfont.ttf?t=1720953486579') format('truetype'),
url('iconfont.svg?t=1720953486579#iconfont') format('svg');
src: url('iconfont.woff2?t=1721179711733') format('woff2'),
url('iconfont.woff?t=1721179711733') format('woff'),
url('iconfont.ttf?t=1721179711733') format('truetype'),
url('iconfont.svg?t=1721179711733#iconfont') format('svg');
}
.iconfont {
@ -14,6 +14,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-yidongdaozu:before {
content: "\e67d";
}
.icon-shanchu:before {
content: "\e852";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "1207918",
"name": "移动到组",
"font_class": "yidongdaozu",
"unicode": "e67d",
"unicode_decimal": 59005
},
{
"icon_id": "8288874",
"name": "删除",

View File

@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="yidongdaozu" unicode="&#59005;" d="M904.448 270.272 119.616 270.272c-23.68 0-44.736-14.656-52.48-36.48C65.024 227.968 64 221.952 64 216c0-16.32 7.616-32.192 21.184-42.688l293.248-225.728c24.128-18.56 59.008-14.464 78.016 9.088 18.944 23.552 14.848 57.664-9.28 76.224L288 156.544l616 0c30.72 0 56 29.44 56 59.456C960 246.016 935.168 270.272 904.448 270.272zM119.552 497.728l784.832 0c23.68 0 44.736 14.656 52.48 36.48C958.976 540.032 960 546.048 960 552c0 16.32-7.616 32.192-21.184 42.688l-293.248 225.728c-24.128 18.56-59.008 14.464-78.016-9.088C548.608 787.776 552.64 753.6 576.832 735.04L736 611.456 120 611.456C89.28 611.456 64 582.016 64 552 64 521.984 88.832 497.728 119.552 497.728z" horiz-adv-x="1024" />
<glyph glyph-name="shanchu" unicode="&#59474;" d="M736.653061-33.959184H287.346939c-45.97551 0-83.591837 37.616327-83.591837 83.591837V540.734694h616.489796v-491.102041c0-45.97551-37.616327-83.591837-83.591837-83.591837zM245.55102 498.938776v-449.306123c0-22.987755 18.808163-41.795918 41.795919-41.795918h449.306122c22.987755 0 41.795918 18.808163 41.795919 41.795918V498.938776H245.55102zM407.510204 101.877551c-11.493878 0-20.897959 9.404082-20.897959 20.897959V384c0 11.493878 9.404082 20.897959 20.897959 20.897959s20.897959-9.404082 20.897959-20.897959v-261.22449c0-11.493878-9.404082-20.897959-20.897959-20.897959zM616.489796 101.877551c-11.493878 0-20.897959 9.404082-20.897959 20.897959V384c0 11.493878 9.404082 20.897959 20.897959 20.897959s20.897959-9.404082 20.897959-20.897959v-261.22449c0-11.493878-9.404082-20.897959-20.897959-20.897959zM846.367347 498.938776H177.632653c-45.97551 0-83.591837 37.616327-83.591837 83.591836v31.346939c0 45.97551 37.616327 83.591837 83.591837 83.591837h668.734694c45.97551 0 83.591837-37.616327 83.591837-83.591837v-31.346939c0-45.97551-37.616327-83.591837-83.591837-83.591836zM177.632653 655.673469c-22.987755 0-41.795918-18.808163-41.795918-41.795918v-31.346939c0-22.987755 18.808163-41.795918 41.795918-41.795918h668.734694c22.987755 0 41.795918 18.808163 41.795918 41.795918v31.346939c0 22.987755-18.808163 41.795918-41.795918 41.795918H177.632653zM650.44898 655.673469h-276.89796c-28.734694 0-52.244898 23.510204-52.244898 52.244898v41.795919c0 28.734694 23.510204 52.244898 52.244898 52.244898h276.89796c28.734694 0 52.244898-23.510204 52.244898-52.244898v-41.795919c0-28.734694-23.510204-52.244898-52.244898-52.244898z m-276.89796 104.489796c-5.746939 0-10.44898-4.702041-10.448979-10.448979v-41.795919c0-5.746939 4.702041-10.44898 10.448979-10.448979h276.89796c5.746939 0 10.44898 4.702041 10.448979 10.448979v41.795919c0 5.746939-4.702041 10.44898-10.448979 10.448979h-276.89796z" horiz-adv-x="1024" />
<glyph glyph-name="xiazai" unicode="&#58973;" d="M795.694545 500.363636a289.047273 289.047273 0 0 1-567.38909 0 197.585455 197.585455 0 0 1 18.385454-395.636363h30.952727a23.272727 23.272727 0 0 1 0 46.545454H246.690909a151.272727 151.272727 0 1 0-2.327273 302.545455l23.272728-5.352727 3.025454 25.6a242.269091 242.269091 0 0 0 480.814546 0l4.654545-25.134546 23.272727 4.887273a151.272727 151.272727 0 1 0-2.327272-302.545455h-34.909091a23.272727 23.272727 0 0 1 0-46.545454h35.141818a197.585455 197.585455 0 0 1 18.385454 395.636363zM628.363636 206.196364l-91.927272-93.090909v286.254545a23.272727 23.272727 0 0 1-46.545455 0v-285.090909l-91.927273 93.090909A23.272727 23.272727 0 1 1 365.149091 174.545455l131.490909-131.723637a23.272727 23.272727 0 0 1 33.047273 0L661.178182 174.545455A23.272727 23.272727 0 1 1 628.363636 206.196364z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -6,7 +6,6 @@
<i class="iconfont icon-xiangyou"></i>
</div>
<div class="book-list">
<el-tree ref="refTree" :data="treeData" :props="defaultProps" node-key="id"
:default-expanded-keys="defaultExpandedKeys" :current-node-key="currentNode" highlight-current
@node-click="handleNodeClick">
@ -14,7 +13,6 @@
<span :title="node.label" class="tree-label">{{ node.label }}</span>
</template>
</el-tree>
</div>
</el-scrollbar>
</div>
@ -87,14 +85,25 @@ const getSubjectContent = async () => {
entpcourseedituserid: userId,
pageSize: 500
}
const { rows } = await listEvaluation(params)
evaluationList.value = rows
let data;
if (localStorage.getItem('evaluationList')) {
evaluationList.value = JSON.parse(localStorage.getItem('evaluationList'))
data = evaluationList.value
}
else {
const { rows } = await listEvaluation(params)
localStorage.setItem('evaluationList', JSON.stringify(rows))
evaluationList.value = rows
data = rows
}
//
await getSubject()
//
volumeOne.value = rows.filter(item => item.level == 1 && item.semester == '上册')
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
//
volumeTwo.value = rows.filter(item => item.level == 1 && item.semester == '下册')
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
getTreeData()
}
@ -175,7 +184,7 @@ const findParentByChildId = (treeData, targetNodeId) => {
}
//
if (node.children) {
let parentNode = findParentNode(node.children, targetNodeId);
let parentNode = findParentByChildId(node.children, targetNodeId);
if (parentNode) {
return parentNode;
}
@ -214,8 +223,15 @@ const transData = (data) => {
//
const getSubject = async () => {
const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 })
subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject && isHaveUnit(item.id))
if (localStorage.getItem('subjectList')) {
subjectList.value = JSON.parse(localStorage.getItem('subjectList'))
}
else {
const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 })
subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject && isHaveUnit(item.id))
localStorage.setItem('subjectList', JSON.stringify(subjectList.value))
}
//
curBookName.value = subjectList.value[0].itemtitle
curBookId.value = subjectList.value[0].id
@ -292,8 +308,7 @@ onMounted(() => {
}
.book-list {
padding-top: 45px;
padding-left: 10px;
padding: 45px 10px 0 10px;
flex: 1;
}
}
@ -349,12 +364,12 @@ onMounted(() => {
:deep(.el-tree-node) {
.el-tree-node__content {
height: 40px;
border-radius: 10px;
&:hover {
background-color: #eaf3ff;
}
}
}
.tree-label {
@ -364,7 +379,7 @@ onMounted(() => {
}
:deep(.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content) {
background-color: #d9e8fe !important;
background-color: #eaf3ff !important;
color: #409EFF
}
</style>

View File

@ -0,0 +1,384 @@
<template>
<el-dialog v-model="dialogVisible" append-to-body :show-close="false" width="630" :before-close="beforeClose"
style="border-radius: 5px;padding-top: 0">
<div class="dialog-title flex">
<span>{{ title }}</span>
<i class="iconfont icon-close" @click="closeDialog"></i>
</div>
<div class="dialog-content">
<div class="book-name flex" @click="bookVisible = true">
<span>{{ curBookName }}</span>
<i class="iconfont icon-yidongdaozu"></i>
</div>
<el-scrollbar height="400px">
<div class="book-data">
<el-tree ref="refTree" :data="treeData" :props="defaultProps" node-key="id"
:default-expanded-keys="defaultExpandedKeys" :current-node-key="currentNodeId" highlight-current
@node-click="handleNodeClick">
<template #default="{ node }">
<span :title="node.label" class="tree-label">{{ node.label }}</span>
</template>
</el-tree>
</div>
</el-scrollbar>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="onSubmit">
确定
</el-button>
</div>
</template>
</el-dialog>
<!--选择教材弹窗-->
<el-dialog v-model="bookVisible" append-to-body :show-close="false" width="550"
style="border-radius: 10px; padding: 10px 15px;">
<template #header>
<div class="choose-book-header flex">
<span>切换教材</span>
<i class="iconfont icon-guanbi" @click="bookVisible = false"></i>
</div>
</template>
<div class="textbook-container">
<el-scrollbar height="450px">
<div class="textbook-item flex" v-for="item in subjectList" :class="curBookId == item.id ? 'active-item' : ''"
:key="item.id" @click="changeBook(item)">
<img :src="item.avartar" class="textbook-img" alt="">
<span class="book-name">{{ item.itemtitle }}</span>
</div>
</el-scrollbar>
</div>
</el-dialog>
</template>
<script setup>
import { ref, reactive, toRaw, onMounted, nextTick, watch, defineProps, defineEmits } from 'vue'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: '移动至'
}
})
const dialogVisible = ref(false)
const bookVisible = ref(false)
//
const subjectList = ref([])
const evaluationList = ref([])
const treeData = ref([])
const defaultProps = {
children: 'children',
label: 'label',
class: 'textbook-tree'
}
//ID
const curBookId = ref(-1)
//
const curBookName = ref('')
//
const volumeOne = ref([])
//
const volumeTwo = ref([])
//
const currentNode = reactive({
data: {}
})
// ID
const currentNodeId = ref(0)
//
const currentNodeName = ref('')
//
const defaultExpandedKeys = ref([])
// tree
const refTree = ref(null)
// emit
const emit = defineEmits(['update:modelValue', 'onSubmit'])
watch(() => props.modelValue, (newVal) => {
dialogVisible.value = newVal
})
const getSubjectContent = () => {
evaluationList.value = JSON.parse(localStorage.getItem('evaluationList'))
let data = evaluationList.value
//
getSubject()
//
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
//
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
getTreeData()
}
const getSubject = () => {
subjectList.value = JSON.parse(localStorage.getItem('subjectList'))
//
curBookName.value = subjectList.value[0].itemtitle
curBookId.value = subjectList.value[0].id
}
const getTreeData = () => {
//
let upData = transData(volumeOne.value)
let downData = transData(volumeTwo.value)
treeData.value = upData.length ? upData : downData
defaultExpandedKeys.value = [treeData.value[0].id]
nextTick(() => {
currentNodeId.value = getLastLevelData(treeData.value)[0].id
currentNodeName.value = getLastLevelData(treeData.value)[0].label
emitChangeBook()
})
}
const emitChangeBook = () => {
let curNode = {
id: currentNodeId.value,
label: currentNodeName.value
}
let parentNode = findParentByChildId(treeData.value, currentNodeId.value)
curNode.parentNode = toRaw(parentNode)
const data = {
textBook: {
curBookId: curBookId.value,
curBookName: curBookName.value
},
node: curNode
}
currentNode.data = data
}
// id
const findParentByChildId = (treeData, targetNodeId) => {
//
//
for (let node of treeData) {
// ID
if (node.children && node.children.some(child => child.id === targetNodeId)) {
// ID ID
return node;
}
//
if (node.children) {
let parentNode = findParentByChildId(node.children, targetNodeId);
if (parentNode) {
return parentNode;
}
}
}
// null
return null;
}
const handleNodeClick = (data, node) => {
/**
* data : 当前节点数据
* node : 当前节点对象 包含当前节点所有数据 parent属性 指向父节点Node对象
*/
const nodeData = data;
const parentNode = node.parent.data;
if (Array.isArray(parentNode)) {
nodeData.parentNode = null
}
else {
nodeData.parentNode = parentNode
}
let curData = {
textBook: {
curBookId: curBookId.value,
curBookName: curBookName.value
},
node: toRaw(nodeData)
}
currentNode.data = curData
// emit('nodeClick', curData)
}
const transData = (data) => {
let ary = []
data.forEach(item => {
let obj = {}
if (item.rootid == curBookId.value) {
obj.label = item.itemtitle
obj.id = item.id
let ary2 = []
evaluationList.value.forEach(el => {
let obj2 = {}
if (item.id == el.parentid) {
obj2 = {
label: el.itemtitle,
id: el.id
}
ary2.push(obj2)
}
obj.children = ary2
})
ary.push(obj)
}
})
return ary
}
//
const getLastLevelData = (tree) => {
let lastLevelData = [];
//
function traverseTree(nodes) {
nodes.forEach((node) => {
//
if (node.children && node.children.length > 0) {
traverseTree(node.children);
} else {
//
lastLevelData.push(node);
}
});
}
//
traverseTree(tree);
//
return lastLevelData;
}
//
const changeBook = ({ id, itemtitle }) => {
curBookId.value = id
curBookName.value = itemtitle
getTreeData()
setTimeout(() => {
bookVisible.value = false
}, 0);
}
const onSubmit = () => {
emit('onSubmit', toRaw(currentNode.data))
closeDialog()
}
const closeDialog = () => {
emit('update:modelValue', false)
}
//
const beforeClose = (done) => {
emit('update:modelValue', false)
done()
}
onMounted(() => {
getSubjectContent()
})
</script>
<style lang="scss" scoped>
.dialog-title {
justify-content: space-between;
font-size: 16px;
font-weight: 600;
color: #000;
.icon-close{
cursor: pointer;
}
}
.dialog-content {
padding: 10px 20px;
.book-name {
justify-content: space-between;
font-size: 14px;
font-weight: 600;
color: #0f0f0f;
margin: 15px 0;
cursor: pointer;
.icon-yidongdaozu {
color: #3a3a3a;
}
}
}
.choose-book-header {
justify-content: space-between;
font-size: 15px;
font-weight: bold;
.icon-guanbi {
font-size: 20px;
cursor: pointer;
}
}
.textbook-container {
.textbook-item {
padding: 10px 20px;
align-items: center;
border-radius: 5px;
cursor: pointer;
.book-name {
margin-left: 20px;
color: #3b3b3b;
font-size: 13px;
}
&:hover {
background: #f4f7f9;
}
}
.active-item {
background-color: #f4f7f9;
.book-name {
color: #368fff;
font-weight: bold
}
}
.textbook-img {
width: 55px;
height: 70px;
}
}
:deep(.el-tree-node) {
.el-tree-node__content {
height: 40px;
border-radius: 10px;
&:hover {
background-color: #eaf3ff;
}
}
}
:deep(.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content) {
background-color: #eaf3ff !important;
color: #409EFF;
font-weight: bold
}
</style>

View File

@ -90,7 +90,7 @@ const hanleFileChange = (file) => {
const fileType = file.raw.type
if (!(audioTypes.includes(fileType) || videoTypes.includes(fileType) || wordTypes.includes(fileType) || pptTypes.includes(fileType) || pdfTypes.includes(fileType) || zipTypes.includes(fileType) || imgTypes.includes(fileType) || textTypes.includes(fileType))) {
ElMessage.error('文件格式错误! 请上传图片、音频、视频、word、ppt、pdf、text、zip文件!')
ElMessage.error('文件格式错误! 请上传图片、音频、视频、word、ppt、pdf、txt、zip文件!')
return false
}
//
@ -100,7 +100,7 @@ const hanleFileChange = (file) => {
return false
}
if (file.status === 'ready') {
// fileData
file.fileData = {
fileFlag: '课件',
@ -110,7 +110,6 @@ const hanleFileChange = (file) => {
}
}
//
const delFile = (index) => {
fileList.value.splice(index, 1)

View File

@ -179,6 +179,10 @@ export default {
}
.prepare-body-main-item {
position: relative;
display: flex;
align-items: center;
border-bottom: 1px solid rgba(131, 131, 127, 0.17);
padding: 10px 0;
.prepare-uploader-progress {
height: 100%;
position: absolute;
@ -189,10 +193,7 @@ export default {
&:hover {
background-color: rgba(144, 147, 153, 0.2);
}
display: flex;
align-items: center;
border-bottom: 1px solid rgba(131, 131, 127, 0.17);
padding: 10px 0;
.prepare-body-main-item-icon {
width: 80px;
}

View File

@ -84,6 +84,7 @@ const useUserStore = defineStore(
this.token = ''
this.roles = []
this.permissions = []
localStorage.clear()
removeToken()
resolve()
}).catch(error => {

View File

@ -37,6 +37,10 @@
<i class="iconfont icon-xiazai"></i>
<span>下载</span>
</div>
<div class="item-popover-item" @click="moveFile(item)">
<i class="iconfont icon-xiazai"></i>
<span>移动至</span>
</div>
</div>
</template>
</el-popover>
@ -54,10 +58,12 @@
:page-sizes="[10, 20, 30, 50]" background layout="total, sizes, prev, pager, next, jumper"
:total="sourceStore.result.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import FileImage from '@/components/file-image/index.vue'
import { deleteSmarttalk, updateSmarttalk } from '@/api/file'
@ -66,7 +72,6 @@ import useResoureStore from '../store'
const { ipcRenderer } = window.electron || {}
const sourceStore = useResoureStore()
const handleSizeChange = () => { }
const handleCurrentChange = () => { }
@ -109,6 +114,11 @@ const delRow = (item) => {
}
}
//
const moveFile = (item) => {
moveDialogVisible.value = true
}
</script>
<style>

View File

@ -16,6 +16,7 @@
</div>
<!-- 上传弹窗 -->
<uploadDialog v-model="isDialogOpen" @submitFile="submitFile" />
<!-- <MoveFile v-model="isDialogOpen" @onSubmit="onSubmit" /> -->
</template>
<script setup>
@ -25,6 +26,7 @@ import ChooseTextbook from '@/components/choose-textbook/index.vue'
import ResoureSearch from './container/resoure-search.vue'
import ResoureList from './container/resoure-list.vue'
import uploadDialog from '@/components/upload-dialog/index.vue'
import MoveFile from '@/components/move-file/index.vue'
import uploaderState from '@/store/modules/uploader'
const sourceStore = useResoureStore()
@ -37,6 +39,10 @@ const openDialog = () => {
isDialogOpen.value = true
}
const onSubmit = (data)=>{
console.log(data)
}
//
const changeBook = (data) => {
getData(data)

View File

@ -1,6 +1,9 @@
import { defineStore } from 'pinia'
import { getSmarttalkPage } from '@/api/file/index'
import { tabs, resourceType, resourceFormat } from '@/utils/resourceDict'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const resourceTypeList = [
{
@ -17,7 +20,12 @@ const resourceFormatList = [
...resourceFormat
]
// 校本资源为学校ID
tabs.forEach(item =>{
if( item.label == "校本资源"){
item.value = userStore.user.deptId
}
})
const structQuery = {
pageNum: 1,