于添 5 месяцев назад
Родитель
Сommit
6c5a3e6621

+ 113 - 0
src/components/SelectorList/index.vue

@@ -0,0 +1,113 @@
+<template>
+	<a-select
+		:value="modelValue"
+		placeholder="请选择"
+		:mode="props.mode"
+		style="width: 100%"
+		:options="props.options"
+		@change="handleChange"
+	>
+		<template #dropdownRender="{ menuNode: menu }">
+			<v-nodes :vnodes="menu" />
+			<div style="display: flex; width: 100%;   justify-content: center"    @mousedown.prevent>
+				<a-pagination
+
+					v-model:current="currentPage.current"
+					v-model:pageSize="currentPage.size"
+					size="small"
+					:total="props.total"
+					:show-size-changer="false"
+					:show-less-items="true"
+					@change="onChange"
+				/>
+			</div>
+
+
+		</template>
+
+	</a-select>
+</template>
+
+<script setup>
+
+ import {ref,reactive,defineComponent ,defineProps} from "vue";
+ const emit = defineEmits(['update:modelValue','onChange','onInit'])
+ const props = defineProps({
+	 modelValue: {
+		 type: [String],
+		 default: null
+	 },
+	 options: {
+		 type: Array,
+		 default: []
+	 },
+	 size: {
+		 type: Number,
+		 default: 10
+	 },
+	 total: {
+		 type: Number,
+		 default: 0
+	 },
+	 //'multiple' | 'tags' | 'combobox'
+	 mode: {
+		 type: String,
+		 default: ''
+	 }
+ })
+
+ const VNodes = defineComponent({
+	 props: {
+		 vnodes: {
+			 type: Object,
+			 required: true,
+		 },
+	 },
+	 render() {
+		 return this.vnodes;
+	 },
+ });
+ // 在 form.vue 中监听值的变化
+ watch(() => props.modelValue, (newVal) => {
+	 console.log('等眼看着:', newVal);
+ }, { deep: true });
+ const item = ref(null)
+
+ const currentPage = reactive({
+	 current: 1,
+	 size: props.size,
+
+ })
+ const itemIds = ref(['1935565895337304066'])
+let  options = ref(
+	[
+		// {
+		// 	value : 1,
+		// label : '大佬'},
+		// {
+		// 	value : 2,
+		// label : '小佬'}
+
+]
+
+)
+ const handleChange = (value) => {
+	 emit('update:modelValue', value);
+ };
+ const onChange = (page, pageSize) => {
+
+	 emit('onChange', page, pageSize)
+	 // getList()
+	 // setTimeout(() => {
+		//  paginationRef.value?.focus();
+	 // }, 0);
+ }
+ onMounted(()=>{
+
+	 console.log('什么参水呢',props.modelValue)
+	 emit('onInit')
+ })
+</script>
+<style scoped >
+
+</style>

+ 2 - 2
src/views/announcementManagement/components/DialogView.vue

@@ -9,10 +9,10 @@
 			:wrapper-col="{ span: 12 }"
 		>
 			<a-form-item label="公告标题" name="title">
-				<a-input v-model:value="formState.title" placeholder="输入公告标题"/>
+				<a-input v-model:value="formState.title" placeholder="输入公告标题" maxlength="50" show-count/>
 			</a-form-item>
 			<a-form-item label="公告内容" name="content">
-				<a-textarea v-model:value="formState.content" placeholder="输入公告内容"
+				<a-textarea v-model:value="formState.content" placeholder="输入公告内容" maxlength="100" show-count
 							:auto-size="{ minRows: 5, maxRows: 8 }"/>
 			</a-form-item>
 

+ 1 - 1
src/views/announcementManagement/components/QueryView.vue

@@ -3,7 +3,7 @@
 		<div>
 			<a-form layout="inline" :model="formState">
 				<a-form-item label="标题名称" style="width: 100%">
-					<a-input v-model:value="formState.title" placeholder="请输入标题名称" allowClear />
+					<a-input v-model:value="formState.title" placeholder="请输入标题名称" allowClear  show-count maxlength="50"/>
 				</a-form-item>
 <!--				<a-form-item label="" style="width: 50%">-->
 <!--					<a-range-picker 	v-model:value="formState.time" allowClear />-->

+ 31 - 30
src/views/courseAdd/components/courseInfo.vue

@@ -7,7 +7,7 @@
 		:wrapper-col="{ span: 12 }"
 	>
 		<a-form-item label="教室名称" name="courseName">
-			<a-input v-model:value="formState.courseName" placeholder="输入教室名称" />
+			<a-input v-model:value="formState.courseName" placeholder="输入教室名称" maxlength="50" show-count/>
 		</a-form-item>
 
 		<a-form-item label="授课教师" name="teacherId">
@@ -59,15 +59,16 @@
 <!--		</a-form-item>-->
 
 		<a-form-item label="教室描述" name="courseDesc">
-			<quill-editor
-				ref="quillEditorRef"
-				placeholder="请输入教室描述"
-				v-model:content="formState.courseDesc"
-				style="height: 200px"
-				contentType="html"
-				theme="snow"
-			/>
-			<span>{{MIN_LENGTH}}/{{MAX_LENGTH}}</span>
+<!--			<quill-editor-->
+<!--				ref="quillEditorRef"-->
+<!--				placeholder="请输入教室描述"-->
+<!--				v-model:content="formState.courseDesc"-->
+<!--				style="height: 200px"-->
+<!--				contentType="html"-->
+<!--				theme="snow"-->
+<!--			/>-->
+<!--			<span>{{MIN_LENGTH}}/{{MAX_LENGTH}}</span>-->
+			<a-textarea v-model:value="formState.courseDesc" :maxlength="100" show-count ></a-textarea>
 		</a-form-item>
 
 		<a-form-item :wrapper-col="{ offset: 5, span: 12 }">
@@ -166,7 +167,7 @@
 	const handleEdit = () => {
 		console.log('表单编辑数据:', formState)
 		// collegeId
-		formState.courseDesc = toRaw(quillEditorRef.value).getHTML()
+		// formState.courseDesc = toRaw(quillEditorRef.value).getHTML()
 		courseCenterApi
 			.edit({ ...formState, courseId: courseInfoId.value })
 			.then((res) => {
@@ -284,7 +285,7 @@
 
 			MIN_LENGTH.value = formState.courseDesc.length || 0
 
-			toRaw(quillEditorRef.value).setHTML(formState.courseDesc)
+			// toRaw(quillEditorRef.value).setHTML(formState.courseDesc)
 			formState.coverImageId = res.data.coverImageId
 			coverImagePath.value = res.data.coverImagePath
 			// formState.majorId = res.data.majorId
@@ -310,24 +311,24 @@
 			getDetail()
 		}
 
-		nextTick(()=>{
-			let quill = quillEditorRef.value.getQuill()
-			console.log('看看',quill)
-			quill.root.addEventListener('paste', handlePaste, false);
-			// 限制最大字符数
-			// const MAX_LENGTH = 100;
-
-			quill.on('text-change', function(delta, oldDelta, source) {
-				const text = quill.getText();
-				console.log('看看记录',text.length)
-				MIN_LENGTH.value = text.length-1
-				if (text.length > MAX_LENGTH.value) {
-
-					// 截断超出部分
-					quill.deleteText(MAX_LENGTH.value, text.length - MAX_LENGTH.value);
-				}
-			});
-		})
+		// nextTick(()=>{
+		// 	let quill = quillEditorRef.value.getQuill()
+		// 	console.log('看看',quill)
+		// 	quill.root.addEventListener('paste', handlePaste, false);
+		// 	// 限制最大字符数
+		// 	// const MAX_LENGTH = 100;
+		//
+		// 	quill.on('text-change', function(delta, oldDelta, source) {
+		// 		const text = quill.getText();
+		// 		console.log('看看记录',text.length)
+		// 		MIN_LENGTH.value = text.length-1
+		// 		if (text.length > MAX_LENGTH.value) {
+		//
+		// 			// 截断超出部分
+		// 			quill.deleteText(MAX_LENGTH.value, text.length - MAX_LENGTH.value);
+		// 		}
+		// 	});
+		// })
 	})
 	const handlePaste = (e) => {
 		const clipboardData = e.clipboardData;

+ 3 - 1
src/views/courseAdd/components/courseProduction/addDialog.vue

@@ -98,7 +98,7 @@ const open = () => {
 	activeKey.value = '1'
 	modeTag.value = 'add'
 	nextTick(() => {
-		addClassHoursRef.value.reset()
+		addClassHoursRef.value.handleReset()
 		addClassHoursRef.value.open()
 		item1.value = item1.value+1
 
@@ -191,6 +191,8 @@ const edit = (item) => {
 	modeTag.value = 'edit'
 	console.log('有没有', addClassHoursRef.value)
 	nextTick(() => {
+		exListRef.value.handleReset()
+		exListsRef.value.handleReset()
 		addClassHoursRef.value.edit(item)
 		item1.value = item1.value+1
 	})

+ 1 - 1
src/views/courseAdd/components/courseProduction/exList.vue

@@ -310,7 +310,7 @@
 	}
 	// 生命周期
 	onMounted(async () => {
-		console.log('打开了  2')
+		console.log('打开了  作业')
 	})
 
 	defineExpose({getItemData,edit,open,editNot,handleReset})

+ 1 - 1
src/views/courseAdd/components/courseProduction/exLists.vue

@@ -305,7 +305,7 @@
 	// 生命周期
 	onMounted(async () => {
 		// examStore.initSubject(search)
-		console.log('打开了  3')
+		console.log('打开了  章节测验')
 	})
 	const open=() =>{
 		examStore.initSubject(search)

+ 1 - 1
src/views/courseOpen/components/DialogView.vue

@@ -9,7 +9,7 @@
 			:wrapper-col="{ span: 12 }"
 		>
 			<a-form-item label="教室名称" name="room">
-				<a-input v-model:value="formState.room" placeholder="输入教室名称"/>
+				<a-input v-model:value="formState.room" placeholder="输入教室名称" show-count maxlength="50"/>
 			</a-form-item>
 
 			<a-form-item label="老师" name="teacherId">

+ 4 - 1
src/views/forum/addForum.vue

@@ -62,6 +62,7 @@
 								:options="usertypeOptions"
 								:filter-option="filterOption"
 							></a-select>
+<!--							<SelectorList></SelectorList>-->
 						</a-form-item>
 					</a-col>
 					<a-col :span="24">
@@ -85,6 +86,7 @@
 	import tool from '@/utils/tool'
 	import forumApi from '@/api/forum/forumApi'
 	import XnEditor from '@/components/Editor/index.vue'
+	import SelectorList from '@/components/SelectorList/index.vue'
 	import Bowser from 'bowser'
 	import { useRoute, useRouter } from 'vue-router'
 	import sysConfig from '@/config/index'
@@ -183,7 +185,7 @@
 
 	// 验证并提交数据
 	const onSubmit = () => {
-		submitLoading.value = true
+
 		formRef.value.validate().then(() => {
 			if (formData.value.appointUserArr && formData.value.appointUserArr.length > 1) {
 				formData.value.appointUser = formData.value.appointUserArr.join(',')
@@ -201,6 +203,7 @@
 					...errorVal.value
 				}
 			}
+			submitLoading.value = true
 			forumApi
 				.submitForm(params)
 				.then(() => {

+ 39 - 13
src/views/forum/form.vue

@@ -36,16 +36,23 @@
 				</a-col>
 				<a-col :span="8">
 					<a-form-item label="指向:" name="appointUserArr">
-						<a-select
-							v-model:value="formData.appointUserArr"
-							mode="multiple"
-							show-search
-							placeholder="请选择"
-							style="width: 100%"
-							:options="usertypeOptions"
-							:filter-option="filterOption"
-						></a-select>
+<!--						<a-select-->
+<!--							v-model:value="formData.appointUserArr"-->
+<!--							mode="multiple"-->
+<!--							show-search-->
+<!--							placeholder="请选择"-->
+<!--							style="width: 100%"-->
+<!--							:options="usertypeOptions"-->
+<!--							:filter-option="filterOption"-->
+<!--						></a-select>-->
 						<!-- @popupScroll="popupScroll" -->
+					<SelectorList  v-model="formData.appointUserArr"
+								   mode="multiple"
+								   :options="usertypeOptions"
+								   :total="userTotal"
+									@onInit="onInit"
+								   @onChange="onChange"
+					></SelectorList>
 					</a-form-item>
 				</a-col>
 				<a-col :span="24">
@@ -68,6 +75,7 @@
 	import tool from '@/utils/tool'
 	import forumApi from '@/api/forum/forumApi'
 	import XnEditor from '@/components/Editor/index.vue'
+	import SelectorList from '@/components/SelectorList/index.vue'
 	const userInfo = tool.data.get('USER_INFO')
 	const typeOptions = ref([])
 	// 默认是关闭状态
@@ -77,8 +85,13 @@
 	const treeData = ref([])
 	// 表单数据,也就是默认给一些数据
 	const formData = ref({
-		postType: 0
+		postType: 0,
+		appointUserArr : []
 	})
+
+	watch(() => formData.value.appointUserArr, (newVal) => {
+		console.log('等眼看着外面:', newVal);
+	}, { deep: true });
 	// 默认展开的节点(顶级)
 	const defaultExpandedKeys = ref([0])
 	const submitLoading = ref(false)
@@ -89,7 +102,7 @@
 		return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
 	}
 	const userPagination = ref({
-		size: 99999999,
+		size: 10,
 		current: 1
 	})
 	const userTotal = ref(0)
@@ -105,6 +118,7 @@
 				}
 			})
 			usertypeOptions.value = add ? [...usertypeOptions.value, ...userList] : userList
+			console.log('是打开我 我是人员列表',usertypeOptions.value)
 		})
 	}
 	const popupScroll = (el) => {
@@ -116,6 +130,15 @@
 			}
 		}
 	}
+	const onInit = () =>{
+
+	}
+	const onChange = ( page, pageSize) =>{
+		userPagination.value.size = pageSize
+		userPagination.value.current = page
+		getUserAllList()
+	}
+
 	// 打开抽屉
 	const onOpen = (record, module) => {
 		moduleId.value = module
@@ -129,12 +152,14 @@
 				}
 			})
 		})
+		console.log('是打开我',record, module)
 		getUserAllList()
 		if (module) {
-			if (record?.appointUser) {
-				record.appointUserArr = record.appointUser.split(',')
+			if (record?.appointUserId) {
+				record.appointUserArr = record.appointUserId.split(',')
 			}
 			formData.value = Object.assign(formData.value, record)
+			console.log('是打开我 要去放进去',formData.value)
 		}
 	}
 	// 关闭抽屉
@@ -164,6 +189,7 @@
 				.submitForm(formData.value, formData.value.postId)
 				.then(() => {
 					onClose()
+					submitLoading.value = false
 					emit('successful')
 				})
 				.finally(() => {

+ 3 - 3
src/views/forum/index.vue

@@ -23,7 +23,7 @@
 				/>
 				<a-select
 					v-model:value="typeVal"
-					placeholder="所有类"
+					placeholder="所有类"
 					style="width: 110px"
 					:options="typeOptionsVal"
 					@change="handleChangeVal"
@@ -32,7 +32,7 @@
 				<a-select
 					v-if="typeVal == 0"
 					v-model:value="typeValue"
-					placeholder="所有类"
+					placeholder="所有类"
 					style="width: 100px"
 					:options="typeOptions"
 					@change="handleChange"
@@ -178,7 +178,7 @@
 			width: 120
 		}
 	]
-	const typeVal = ref('所有类')
+	const typeVal = ref('所有类')
 	const typeOptionsVal = ref([
 		{
 			label: '普通帖子',

+ 1 - 2
src/views/forum/reportForm.vue

@@ -120,9 +120,8 @@
 	const visibleOptions = tool.dictList('MENU_VISIBLE')
 	// 验证并提交数据
 	const onSubmit = () => {
-
+		submitLoading.value = true
 		formRef.value.validate().then(() => {
-			submitLoading.value = true
 			forumApi
 				.reportinfoAdd({
 					...formData.value,

+ 14 - 7
src/views/myResources/resourceUpload.vue

@@ -59,7 +59,7 @@
 					<a-tag
 						v-for="(keyword, index) in formState.keywordValue"
 						:key="index"
-						closable
+
 						@close="handleRemoveKeyword(keyword, index)"
 					>
 						{{ keyword }}
@@ -300,6 +300,11 @@
 	}
 
 	const handleRemoveKeyword = (keywordName, index) => {
+
+		console.log('删除的东西 01 ', ' keywordName ',keywordName,' index ',index)
+		console.log('删除的东西 02 ', ' formState.keyword ',formState.keyword)
+
+
 		console.log(keywordName, index,myHot.value)
 		// // 1. 从显示列表中删除
 		// formState.keywordValue = formState.keywordValue.filter((name) => name !== keywordName)
@@ -315,12 +320,14 @@
 		let myId = myHot.value[keywordName]
 		// console.log('换算出来',formState.keyword,index)
 
-		for (let i = formState.keyword.length-1; i > 0 ; i--) {
-			// console.log('看看',formState.keyword[i] , i , index)
-			if( i == index){
-				formState.keyword.splice(i,1)
-			}
-		}
+		// for (let i = formState.keyword.length-1; i > 0 ; i--) {
+		// 	// console.log('看看',formState.keyword[i] , i , index)
+		// 	console.log('要删除第几个' ,i, index ,  formState.keyword[i])
+		// 	if( i == index){
+		//
+		// 		// formState.keyword.splice(i,1)
+		// 	}
+		// }
 		// console.log('换算出来  结果',formState.keyword)
 
 		// formState.keyword.filter((item, i) => item != keywordName)

+ 29 - 23
src/views/statisticalAnalysis/analysisLearningBehaviors/index.vue

@@ -24,7 +24,7 @@
 				<div class="filter-controls">
 					<div class="filter-group">
 						<label>选择学院</label>
-						<a-select v-model:value="collegeFilters.collegeId" placeholder="全部学院" @change="updateCollegeData">
+						<a-select v-model:value="collegeFilters.collegeId" placeholder="全部学院" @change="updateCollegeData" allowClear>
 							<a-select-option v-for="college in collegeList" :key="college.id" :value="college.id">
 								{{ college.name }}
 							</a-select-option>
@@ -32,12 +32,13 @@
 					</div>
 					<div class="filter-group">
 						<label>时间范围</label>
-						<a-select v-model:value="collegeFilters.timeRange" @change="updateCollegeData">
-							<a-select-option :value="7">最近7天</a-select-option>
-							<a-select-option :value="30">最近30天</a-select-option>
-							<a-select-option :value="90">最近90天</a-select-option>
-							<a-select-option :value="365">最近一年</a-select-option>
-						</a-select>
+<!--						<a-select v-model:value="collegeFilters.timeRange" @change="updateCollegeData">-->
+<!--							<a-select-option :value="7">最近7天</a-select-option>-->
+<!--							<a-select-option :value="30">最近30天</a-select-option>-->
+<!--							<a-select-option :value="90">最近90天</a-select-option>-->
+<!--							<a-select-option :value="365">最近一年</a-select-option>-->
+<!--						</a-select>-->
+						<a-range-picker class="w-full" v-model:value="times" />
 					</div>
 					<div class="filter-group">
 						<a-button type="primary" @click="updateCollegeData">查询</a-button>
@@ -59,9 +60,9 @@
 
 				<div class="stat-card">
 					<h3>👥 用户登录统计</h3>
-					<div class="stat-number">{{ collegeStats.allLoginCount }}</div>
+					<div class="stat-number">{{ collegeStats.allLoginCount.toLocaleString() }}</div>
 					<div class="stat-label">总登录人次</div>
-					<div class="stat-number">{{ collegeStats.userCount }}</div>
+					<div class="stat-number">{{ collegeStats.userCount.toLocaleString() }}</div>
 					<div class="stat-label">独立用户数</div>
 					<div class="stat-number">{{ collegeStats.avgLoginCount }}</div>
 					<div class="stat-label">人均登录次数</div>
@@ -182,14 +183,17 @@
 		getCollegeCourseDetails,
 		searchStudents
 	} from '@/api/statisticalAnalysis/analysisLearningBehaviors'
+	import dayjs from "dayjs";
 
 	// 当前活动标签
 	const activeTab = ref('college')
+	const times = ref([])
 
 	// 学院维度筛选条件
 	const collegeFilters = reactive({
 		collegeId: '',
-		timeRange: 30
+		startTime: computed(() => (  times.value && times.value[0] ? dayjs(times.value[0]).format('YYYY-MM-DD') :  undefined)),
+		endTime: computed(() => (times.value && times.value[1] ? dayjs(times.value[1]).format('YYYY-MM-DD') :  undefined))
 	})
 
 	// 学院列表
@@ -439,17 +443,17 @@
 			// 获取学院统计数据 船锚
 			const statsResponse = await getCollegeStats({
 				orgId: collegeFilters.collegeId,
-				startTime : formatDateWithDays(0),
-				endTime : formatDateWithDays(collegeFilters.timeRange)
+				startTime : collegeFilters.startTime,
+				endTime : collegeFilters.endTime
 			})
 			console.log("asdasd",statsResponse.data)
 			// Object.assign(collegeStats, statsResponse.data)
-			collegeStats.value = {...collegeStats.value,...statsResponse.data}
+			collegeStats.value = {...collegeStats,...statsResponse.data}
 			// 获取课程详细统计
 			const detailsResponse = await getCollegeCourseDetails({
 				orgId: collegeFilters.collegeId,
-				startTime : formatDateWithDays(0),
-				endTime : formatDateWithDays(collegeFilters.timeRange)
+				startTime : collegeFilters.startTime,
+				endTime : collegeFilters.endTime
 			})
 			collegeTableData.value = detailsResponse.data
 
@@ -506,8 +510,8 @@
 		try {
 			const response = await getLoginTimeDistribution({
 				orgId: collegeFilters.collegeId,
-				startTime : formatDateWithDays(0),
-				endTime : formatDateWithDays(1),
+				startTime : collegeFilters.startTime,
+				endTime : collegeFilters.endTime,
 				current : 1,
 				size : 24
 			})
@@ -617,14 +621,16 @@
 		try {
 			const response = await getCourseHeat({
 				orgId: collegeFilters.collegeId,
-				startTime : formatDateWithDays(0),
-				endTime : formatDateWithDays(1),
+				startTime : collegeFilters.startTime,
+				endTime : collegeFilters.endTime,
 				current : 1,
 				size : 8
 			})
 
 			const { courses, visits } = response
-
+			console.log('热门数组是什么',courses,visits)
+			let list = [...courses].reverse();
+			let lists = [...visits].reverse();
 			const option = {
 				title: {
 					text: '课程访问热度TOP8',
@@ -666,7 +672,7 @@
 				},
 				yAxis: {
 					type: 'category',
-					data: courses,
+					data: list,
 					axisLine: {
 						lineStyle: {
 							color: '#bdc3c7'
@@ -680,7 +686,7 @@
 					{
 						name: '访问量',
 						type: 'bar',
-						data: visits,
+						data: lists,
 						itemStyle: {
 							color: {
 								type: 'linear',
@@ -727,7 +733,7 @@
 			// 获取学院列表
 			const colleges = await getCollegeList()
 			collegeList.value = colleges
-			collegeFilters.collegeId = colleges.length > 0 ? colleges[0].id : undefined
+			// collegeFilters.collegeId = colleges.length > 0 ? colleges[0].id : undefined
 			// 获取初始学员数据
 			// await searchStudent()
 

+ 27 - 19
src/views/statisticalAnalysis/analysisTeachingActivities/index.vue

@@ -26,12 +26,13 @@
 				</div>
 				<div class="filter-group">
 					<label>时间范围</label>
-					<a-select v-model:value="filters.timeRange" @change="updateStats">
-						<a-select-option :value="1">最近30天</a-select-option>
-						<a-select-option :value="2">最近90天</a-select-option>
-						<a-select-option :value="3">最近180天</a-select-option>
-						<a-select-option :value="4">最近一年</a-select-option>
-					</a-select>
+<!--					<a-select v-model:value="filters.timeRange" @change="updateStats">-->
+<!--						<a-select-option :value="1">最近30天</a-select-option>-->
+<!--						<a-select-option :value="2">最近90天</a-select-option>-->
+<!--						<a-select-option :value="3">最近180天</a-select-option>-->
+<!--						<a-select-option :value="4">最近一年</a-select-option>-->
+<!--					</a-select>-->
+					<a-range-picker class="w-full" v-model:value="times" />
 				</div>
 				<div class="filter-group">
 					<a-button type="primary" @click="updateStats" :loading="loading">查询</a-button>
@@ -47,7 +48,7 @@
 				<div class="stat-label">总观看人数</div>
 				<div class="stat-number">{{ stats.alreadyUserCount }}</div>
 				<div class="stat-label">完成观看人数</div>
-				<div class="completion-rate">{{ stats.finishRate }}%</div>
+				<div class="completion-rate">{{tool.formatValue(stats.finishRate) }}</div>
 				<div class="stat-label">完成率</div>
 			</div>
 
@@ -55,7 +56,7 @@
 				<h3>🚪 文档跳出分析</h3>
 				<div class="stat-number">{{ stats.allHourCount }}</div>
 				<div class="stat-label">总跳出次数</div>
-				<div class="stat-number">{{ stats.allHourCount }}%</div>
+				<div class="stat-number">{{tool.formatValue(stats.allHourCount)  }}</div>
 				<div class="stat-label">跳出率</div>
 				<div class="stat-number">{{ stats.jumpAvgTime }}</div>
 				<div class="stat-label">平均跳出时间</div>
@@ -130,7 +131,7 @@
 </template>
 
 <script setup>
-	import { ref, reactive, onMounted, nextTick, h } from 'vue'
+import {ref, reactive, onMounted, nextTick, h, computed} from 'vue'
 	import * as echarts from 'echarts'
 	import {
 		getCourseOptions,
@@ -142,12 +143,16 @@
 		getDocumentStats
 	} from '@/api/statisticalAnalysis/analysisTeachingActivities'
 	import tool from '@/utils/tool'
+import dayjs from "dayjs";
+// 课程选项
+const courseOptions = ref([])
+const times = ref([])
 	const forumType = computed(() => (tool.dictList('FORUM_TYPE')[0].value == 1 ? true : false))
-	console.log('什么呢的',tool.dictList('FORUM_TYPE')[0])
 	// 响应式数据
 	const filters = reactive({
-		courseId: '',
-		timeRange: 1
+		courseId: undefined,
+		startTime: computed(() => (  times.value && times.value[0] ? dayjs(times.value[0]).format('YYYY-MM-DD') :  undefined)),
+		endTime: computed(() => (times.value && times.value[1] ? dayjs(times.value[1]).format('YYYY-MM-DD') :  undefined))
 	})
 
 	const stats = reactive({
@@ -165,8 +170,7 @@
 		teacherAvgPostsPerDay: 0
 	})
 
-	// 课程选项
-	const courseOptions = ref([])
+
 
 	// 图表引用
 	const dailyVisitsChart = ref(null)
@@ -306,7 +310,7 @@
 
 		const option = {
 			title: {
-				text: `最近${days}天访问人数趋势`,
+				text: `最近一个月访问人数趋势`,
 				left: 'center',
 				textStyle: {
 					color: '#2c3e50',
@@ -432,11 +436,13 @@
 		try {
 			const response = await getTeachingStats({
 				courseId: filters.courseId,
-				type: filters.timeRange
+				startTime: filters.startTime,
+				endTime: filters.endTime,
 			})
 			const statistic = await documentJumpStatistic({
 				courseId: filters.courseId,
-				type: filters.timeRange
+				startTime: filters.startTime,
+				endTime: filters.endTime,
 			})
 
 			Object.assign(stats, response, statistic)
@@ -461,7 +467,6 @@
 	const loadDailyVisits = async () => {
 		try {
 			const response = await getDailyVisits({
-				type: filters.timeRange,
 				courseId: filters.courseId
 			})
 			chartData.dates = response.map((r) => r.TIME)
@@ -477,6 +482,8 @@
 		try {
 			const response = await getDiscussionData({
 				courseId: filters.courseId,
+				startTime: filters.startTime,
+				endTime: filters.endTime,
 				page: discussionPagination.current,
 				pageSize: discussionPagination.pageSize
 			})
@@ -494,7 +501,8 @@
 				courseId: filters.courseId,
 				page: documentPagination.current,
 				pageSize: documentPagination.pageSize,
-				type: filters.timeRange
+				startTime: filters.startTime,
+				endTime: filters.endTime,
 			})
 			documentData.value = response
 			documentPagination.total = response.total

+ 4 - 4
src/views/statisticalAnalysis/overviewLearningProgress/index.vue

@@ -181,13 +181,13 @@
 		},
 		{
 			title: '讲义访问量',
-			dataIndex: 'stayTime',
-			key: 'stayTime'
+			dataIndex: 'teachMaterialsNum',
+			key: 'teachMaterialsNum'
 		},
 		{
 			title: '练习提交量',
-			dataIndex: 'teachMaterialsNum',
-			key: 'teachMaterialsNum'
+			dataIndex: 'paperSubmitNum',
+			key: 'paperSubmitNum'
 		}
 	]
 

+ 2 - 2
src/views/statisticalAnalysis/statisticalAnalysisResourceLibrary/index.vue

@@ -113,7 +113,7 @@
 			</div>
 
 			<footer>
-				<p>数据更新时间: {{ updateTime }} | 资源库统计分析系统</p>
+				<p>数据更新 资源库统计分析系统</p>
 			</footer>
 		</div>
 	</div>
@@ -482,7 +482,7 @@
 					},
 					xAxis: {
 						type: 'value',
-						name: '文件数量'
+						name: ''
 					},
 					yAxis: {
 						type: 'category',

+ 27 - 11
src/views/statisticalAnalysis/videoAnalysis/index.vue

@@ -21,14 +21,15 @@
 				</div>
 				<!-- 日期范围选择 -->
 				<div class="flex-1 mr-4">
-					<label class="block text-sm font-medium text-gray-700 mb-1">开始时间</label>
-					<a-date-picker v-model:value="startTime" class="w-full" placeholder="开始时间" />
+					<label class="block text-sm font-medium text-gray-700 mb-1">时间</label>
+<!--					<a-date-picker v-model:value="startTime" class="w-full" placeholder="开始时间" />-->
+					<a-range-picker class="w-full" v-model:value="times" />
 				</div>
 
-				<div class="flex-1 mr-4">
-					<label class="block text-sm font-medium text-gray-700 mb-1">结束时间</label>
-					<a-date-picker v-model:value="endTime" class="w-full" placeholder="结束时间" />
-				</div>
+<!--				<div class="flex-1 mr-4">-->
+<!--					<label class="block text-sm font-medium text-gray-700 mb-1">结束时间</label>-->
+<!--					<a-date-picker v-model:value="endTime" class="w-full" placeholder="结束时间" />-->
+<!--				</div>-->
 
 				<div class="filter-group">
 					<a-button type="primary" @click="updateStats">查询</a-button>
@@ -44,7 +45,7 @@
 				<div class="stat-label">总观看人数</div>
 				<div class="stat-number">{{ stats.countData.completeWatchUserCount }}</div>
 				<div class="stat-label">完成观看人数</div>
-				<div class="completion-rate">{{ stats.countData.completeRate*100 }}%</div>
+				<div class="completion-rate">{{ tool.formatValue(stats.countData.completeRate) }}</div>
 				<div class="stat-label">完成率</div>
 			</div>
 
@@ -52,7 +53,7 @@
 				<h3>📥 讲义下载统计</h3>
 				<div class="stat-number">{{ stats.downData.allDownloadCount }}</div>
 				<div class="stat-label">总下载次数</div>
-				<div class="stat-number">{{ stats.downData.downloadRate*100 }}%</div>
+				<div class="stat-number">{{tool.formatValue(stats.downData.downloadRate)}}</div>
 				<div class="stat-label">下载率</div>
 				<div class="stat-number">{{ stats.downData.avgDownloadCount }}</div>
 				<div class="stat-label">人均下载次数</div>
@@ -62,7 +63,7 @@
 				<h3>⏱️ 跳出时间分析</h3>
 				<div class="stat-number">{{ stats.jumpData.jumpOutCount }}</div>
 				<div class="stat-label">总跳出次数</div>
-				<div class="stat-number">{{ stats.jumpData.jumpOutRate*100 }}%</div>
+				<div class="stat-number">{{tool.formatValue(stats.jumpData.jumpOutRate)}}</div>
 				<div class="stat-label">跳出率</div>
 				<div class="stat-number">{{ stats.jumpData.jumpAvgTime }}</div>
 				<div class="stat-label">平均跳出时间</div>
@@ -167,16 +168,20 @@
 	import { getCourseOptions } from '@/api/statisticalAnalysis/analysisTeachingActivities'
 	import { videoAnalysisApi } from '@/api/statisticalAnalysis/videoAnalysis'
 	import dayjs from 'dayjs'
+	import tool from "@/utils/tool";
 
 	// 筛选条件
+	const times = ref([])
 	const startTime = ref('')
 	const endTime = ref('')
 	const filters = reactive({
 		courseId: '',
-		startTime: computed(() => (startTime.value ? dayjs(startTime.value).format('YYYY-MM-DD') : '')),
-		endTime: computed(() => (endTime.value ? dayjs(endTime.value).format('YYYY-MM-DD') : ''))
+		startTime: computed(() => (  times.value && times.value[0] ? dayjs(times.value[0]).format('YYYY-MM-DD') :  undefined)),
+		endTime: computed(() => (times.value && times.value[1] ? dayjs(times.value[1]).format('YYYY-MM-DD') :  undefined))
 	})
 
+
+
 	// 课程选项
 	const courseOptions = ref([])
 
@@ -595,6 +600,15 @@
 
 	// 更新统计数据
 	const updateStats = async () => {
+		// console.log('时间问题',' startTime.value ',startTime.value,' endTime.value ',endTime.value)
+		// if((startTime.value != '' || startTime.value != null)  && (endTime.value != '' || endTime.value != null)){
+		// 	if(dayjs(endTime.value).valueOf() - dayjs(startTime.value).valueOf() > 0){
+		//
+		// 	}else{
+		// 		message.error('结束时间比开始时间小')
+		// 		return
+		// 	}
+		// }
 		loading.value = true
 		chapterLoading.value = true
 		try {
@@ -606,6 +620,7 @@
 			loading.value = false
 			chapterLoading.value = false
 		}
+
 	}
 
 	// 初始化所有数据
@@ -813,6 +828,7 @@
 	.completion-rate {
 		color: #27ae60;
 		font-weight: bold;
+		font-size: 2.5em;
 	}
 
 	.low-engagement {

+ 4 - 0
src/views/sys/user/userTab/userMessage.vue

@@ -16,6 +16,9 @@
 								{{ record.subject }}
 							</ellipsis>
 						</template>
+						<template v-if="column.dataIndex === 'createTime'">
+							<span>{{dayjs(record.createTime).format('YYYY-MM-DD HH:mm:ss')}}</span>
+						</template>
 						<template v-if="column.dataIndex === 'read'">
 							<span v-if="record.read" style="color: #d9d9d9">已读</span>
 							<span v-else style="color: #ff4d4f">未读</span>
@@ -38,6 +41,7 @@
 	import userCenterApi from '@/api/sys/userCenterApi'
 	import tool from '@/utils/tool'
 	import { nextTick } from 'vue'
+	import dayjs from 'dayjs'
 
 	const messageCategoryList = tool.dictList('MESSAGE_CATEGORY')
 	const selectedKeys = ref(new Array(messageCategoryList[0].value))

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
stats.html


Некоторые файлы не были показаны из-за большого количества измененных файлов