فهرست منبع

上传部分组件

于添 8 ماه پیش
والد
کامیت
0e4efc6f1e

+ 1 - 1
.env.development

@@ -5,7 +5,7 @@ NODE_ENV = development
 VITE_TITLE = Snowy
 
 # 接口地址
-VITE_API_BASEURL = http://192.168.31.14:9003
+VITE_API_BASEURL = http://192.168.31.80:9003
 # VITE_API_BASEURL = http://192.168.31.80:9003
 # VITE_API_BASEURL = http://192.168.31.6:9003
 

+ 223 - 0
src/views/resourceDetails/components/ListGeneralView.vue

@@ -0,0 +1,223 @@
+<template>
+	<div>
+		<!-- 列表 -->
+		<a-table
+			:columns="columns"
+			:data-source="tableData"
+			:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+			:pagination="false"
+			@change="handleTableChange"
+			:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
+		>
+			<template #operation="text, record">
+				<a-space size="small">
+					<a @click="handlePublish(record)">发布</a>
+					<a-dropdown>
+						<a class="ant-dropdown-link"> 更多 <DownOutlined /> </a>
+						<template #overlay>
+							<a-menu>
+								<a-menu-item key="1" @click="handleEdit(record)">编辑</a-menu-item>
+								<a-menu-item key="2" @click="handleDelete(record)">删除</a-menu-item>
+							</a-menu>
+						</template>
+					</a-dropdown>
+				</a-space>
+			</template>
+		</a-table>
+		<div style="display: flex; justify-content: space-between; align-items: center; height: 70px">
+			<div style="display: flex">
+				<a-button @click="handleSelectAll">选择全部</a-button>
+				<div style="width: 10px"></div>
+				<a-button @click="toggleSelection">反向选择</a-button>
+				<!-- 全选/反选按钮 -->
+			</div>
+			<!-- 分页组件 -->
+			<a-pagination
+				v-model:current="pagination.current"
+				v-model:pageSize="pagination.pageSize"
+				:total="pagination.total"
+				show-size-changer
+				@change="handlePageChange"
+				@showSizeChange="handlePageSizeChange"
+			/>
+		</div>
+	</div>
+</template>
+
+<script setup>
+	import { ref, computed, h } from 'vue'
+	import { DownOutlined } from '@ant-design/icons-vue'
+	import color from '@/utils/color'
+	import { green } from '@ant-design/colors'
+	const emit = defineEmits(['selectTab'])
+	const selectedTab = ref('latest')
+
+	const selectTab = (tab) => {
+		if (selectedTab.value != tab) {
+			selectedTab.value = tab
+			emit('selectTab', tab)
+		}
+	}
+
+	// 表格列配置
+	const columns = [
+		{
+			title: '编号',
+			dataIndex: 'id',
+			key: 'id'
+		},
+		{
+			title: '资源名称',
+			dataIndex: 'name',
+			key: 'name',
+			sorter: (a, b) => a.name.localeCompare(b.name)
+		},
+		{
+			title: '课件格式',
+			dataIndex: 'format',
+			key: 'format',
+			sorter: (a, b) => a.format.localeCompare(b.format)
+		},
+		{
+			title: '上传时间',
+			dataIndex: 'uploadTime',
+			key: 'uploadTime',
+			sorter: (a, b) => new Date(a.uploadTime).getTime() - new Date(b.uploadTime).getTime()
+		},
+		{
+			title: '状态',
+			dataIndex: 'status',
+			key: 'status',
+			customRender: ({ text, record }) => {
+				const textStyle = { color: text === '处理中' ? 'orange' : 'green' }
+				return h('span', { style: textStyle }, [text])
+			},
+			sorter: (a, b) => a.status.localeCompare(b.status)
+		},
+		{
+			title: '操作',
+			key: 'operation',
+			slots: { customRender: 'operation' }
+		}
+	]
+
+	// 表格数据
+	const tableData = ref([
+		// 示例数据
+		{ key: '1', id: 1, name: '资源名称资源名称1', format: 'mp4', uploadTime: '2020-11-25 23:26:08', status: '处理中' },
+		{ key: '2', id: 2, name: '资源名称资源名称2', format: 'mp3', uploadTime: '2020-11-26 23:26:08', status: '已上传' },
+		{ key: '3', id: 3, name: '资源名称资源名称3', format: 'avi', uploadTime: '2020-11-27 23:26:08', status: '已上传' },
+		{
+			key: '4',
+			id: 4,
+			name: '资源名称资源名称4',
+			format: 'u3mb4',
+			uploadTime: '2020-11-28 23:26:08',
+			status: '已上传'
+		},
+		{ key: '5', id: 5, name: '资源名称资源名称5', format: 'mp4', uploadTime: '2020-11-29 23:26:08', status: '已上传' },
+		{ key: '6', id: 6, name: '资源名称资源名称6', format: 'mp4', uploadTime: '2020-11-30 23:26:08', status: '已上传' },
+		{ key: '7', id: 7, name: '资源名称资源名称7', format: 'mp4', uploadTime: '2020-11-31 23:26:08', status: '已上传' }
+		// 更多数据...
+	])
+
+	// 选中的行键值
+	const selectedRowKeys = ref([])
+
+	// 全选状态
+	const selectAll = computed(() => {
+		return selectedRowKeys.value.length === tableData.value.length && tableData.value.length > 0
+	})
+
+	// 处理全选
+	const handleSelectAll = (e) => {
+		if (selectedRowKeys.value.length === tableData.value.length) {
+			selectedRowKeys.value = []
+		} else {
+			selectedRowKeys.value = tableData.value.map((item) => item.key)
+		}
+	}
+
+	// 处理反选
+	// 处理反选
+	const toggleSelection = () => {
+		const allKeys = tableData.value.map((item) => item.key)
+		const newSelectedKeys = allKeys.filter((key) => !selectedRowKeys.value.includes(key))
+		selectedRowKeys.value = newSelectedKeys
+	}
+
+	// 处理行选择变化
+	const onSelectChange = (selectedKeys) => {
+		selectedRowKeys.value = selectedKeys
+	}
+
+	// 分页配置
+	const pagination = ref({
+		current: 1,
+		pageSize: 10,
+		total: tableData.value.length
+	})
+
+	// 处理表格变化(分页、排序、筛选等)
+	const handleTableChange = (pagination, filters, sorter) => {
+		console.log('params', pagination, filters, sorter)
+		// 根据需要更新数据
+	}
+
+	// 处理页码变化
+	const handlePageChange = (current) => {
+		pagination.value.current = current
+		// 加载对应页码的数据
+	}
+
+	// 处理每页条数变化
+	const handlePageSizeChange = (current, size) => {
+		pagination.value.current = current
+		pagination.value.pageSize = size
+		// 加载对应页码和条数的数据
+	}
+
+	// 操作方法
+	const handlePublish = (record) => {
+		console.log('发布', record)
+	}
+
+	const handleEdit = (record) => {
+		console.log('编辑', record)
+	}
+
+	const handleDelete = (record) => {
+		console.log('删除', record)
+	}
+</script>
+
+<style scoped>
+	.tab-switcher {
+		display: flex;
+		border-radius: 20px;
+		border: 1px solid #1e90ff;
+		overflow: hidden;
+	}
+
+	.tab-switcher div {
+		padding: 2px 20px;
+		background-color: #f5f5f5;
+
+		cursor: pointer;
+	}
+
+	.tab-switcher div.active {
+		background-color: #1e90ff;
+		color: white;
+	}
+
+	.tab-switcher div:not(:last-child) {
+	}
+	.processing {
+		color: orange;
+	}
+
+	.uploaded {
+		color: green;
+	}
+</style>

+ 188 - 4
src/views/resourceDetails/components/ListUnpublishedView.vue

@@ -1,21 +1,198 @@
 <template>
 	<div>
-		<QueryUnpublishedView />
+		<!-- 列表 -->
+		<a-table
+			:columns="columns"
+			:data-source="tableData"
+			:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+			:pagination="false"
+			@change="handleTableChange"
+			:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
+		>
+			<template #operation="text, record">
+				<a-space size="small">
+					<a @click="handlePublish(record)">发布</a>
+					<a-dropdown>
+						<a class="ant-dropdown-link"> 更多 <DownOutlined /> </a>
+						<template #overlay>
+							<a-menu>
+								<a-menu-item key="1" @click="handleEdit(record)">编辑</a-menu-item>
+								<a-menu-item key="2" @click="handleDelete(record)">删除</a-menu-item>
+							</a-menu>
+						</template>
+					</a-dropdown>
+				</a-space>
+			</template>
+		</a-table>
+		<div style="display: flex; justify-content: space-between; align-items: center; height: 70px">
+			<div style="display: flex">
+				<a-button @click="handleSelectAll">选择全部</a-button>
+				<div style="width: 10px"></div>
+				<a-button @click="toggleSelection">反向选择</a-button>
+				<!-- 全选/反选按钮 -->
+			</div>
+			<!-- 分页组件 -->
+			<a-pagination
+				v-model:current="pagination.current"
+				v-model:pageSize="pagination.pageSize"
+				:total="pagination.total"
+				show-size-changer
+				@change="handlePageChange"
+				@showSizeChange="handlePageSizeChange"
+			/>
+		</div>
 	</div>
 </template>
 
 <script setup>
-	import { ref } from 'vue'
-	import QueryUnpublishedView from './QueryUnpublishedView.vue'
+	import { ref, computed, h } from 'vue'
+	import { DownOutlined } from '@ant-design/icons-vue'
+	import color from '@/utils/color'
+	import { green } from '@ant-design/colors'
 	const emit = defineEmits(['selectTab'])
 	const selectedTab = ref('latest')
 
-	const selectTab = (tab) => {
+	const setData = (tab) => {
 		if (selectedTab.value != tab) {
 			selectedTab.value = tab
 			emit('selectTab', tab)
 		}
 	}
+
+	// 表格列配置
+	const columns = [
+		{
+			title: '编号',
+			dataIndex: 'id',
+			key: 'id'
+		},
+		{
+			title: '资源名称',
+			dataIndex: 'name',
+			key: 'name',
+			sorter: (a, b) => a.name.localeCompare(b.name)
+		},
+		{
+			title: '课件格式',
+			dataIndex: 'format',
+			key: 'format',
+			sorter: (a, b) => a.format.localeCompare(b.format)
+		},
+		{
+			title: '上传时间',
+			dataIndex: 'uploadTime',
+			key: 'uploadTime',
+			sorter: (a, b) => new Date(a.uploadTime).getTime() - new Date(b.uploadTime).getTime()
+		},
+		{
+			title: '状态',
+			dataIndex: 'status',
+			key: 'status',
+			customRender: ({ text, record }) => {
+				const textStyle = { color: text === '处理中' ? 'orange' : 'green' }
+				return h('span', { style: textStyle }, [text])
+			},
+			sorter: (a, b) => a.status.localeCompare(b.status)
+		},
+		{
+			title: '操作',
+			key: 'operation',
+			slots: { customRender: 'operation' }
+		}
+	]
+
+	// 表格数据
+	const tableData = ref([
+		// 示例数据
+		{ key: '1', id: 1, name: '资源名称资源名称1', format: 'mp4', uploadTime: '2020-11-25 23:26:08', status: '处理中' },
+		{ key: '2', id: 2, name: '资源名称资源名称2', format: 'mp3', uploadTime: '2020-11-26 23:26:08', status: '已上传' },
+		{ key: '3', id: 3, name: '资源名称资源名称3', format: 'avi', uploadTime: '2020-11-27 23:26:08', status: '已上传' },
+		{
+			key: '4',
+			id: 4,
+			name: '资源名称资源名称4',
+			format: 'u3mb4',
+			uploadTime: '2020-11-28 23:26:08',
+			status: '已上传'
+		},
+		{ key: '5', id: 5, name: '资源名称资源名称5', format: 'mp4', uploadTime: '2020-11-29 23:26:08', status: '已上传' },
+		{ key: '6', id: 6, name: '资源名称资源名称6', format: 'mp4', uploadTime: '2020-11-30 23:26:08', status: '已上传' },
+		{ key: '7', id: 7, name: '资源名称资源名称7', format: 'mp4', uploadTime: '2020-11-31 23:26:08', status: '已上传' }
+		// 更多数据...
+	])
+
+	// 选中的行键值
+	const selectedRowKeys = ref([])
+
+	// 全选状态
+	const selectAll = computed(() => {
+		return selectedRowKeys.value.length === tableData.value.length && tableData.value.length > 0
+	})
+
+	// 处理全选
+	const handleSelectAll = (e) => {
+		if (selectedRowKeys.value.length === tableData.value.length) {
+			selectedRowKeys.value = []
+		} else {
+			selectedRowKeys.value = tableData.value.map((item) => item.key)
+		}
+	}
+
+	// 处理反选
+	// 处理反选
+	const toggleSelection = () => {
+		const allKeys = tableData.value.map((item) => item.key)
+		const newSelectedKeys = allKeys.filter((key) => !selectedRowKeys.value.includes(key))
+		selectedRowKeys.value = newSelectedKeys
+	}
+
+	// 处理行选择变化
+	const onSelectChange = (selectedKeys) => {
+		selectedRowKeys.value = selectedKeys
+	}
+
+	// 分页配置
+	const pagination = ref({
+		current: 1,
+		pageSize: 10,
+		total: tableData.value.length
+	})
+
+	// 处理表格变化(分页、排序、筛选等)
+	const handleTableChange = (pagination, filters, sorter) => {
+		console.log('params', pagination, filters, sorter)
+		// 根据需要更新数据
+	}
+
+	// 处理页码变化
+	const handlePageChange = (current) => {
+		pagination.value.current = current
+		// 加载对应页码的数据
+	}
+
+	// 处理每页条数变化
+	const handlePageSizeChange = (current, size) => {
+		pagination.value.current = current
+		pagination.value.pageSize = size
+		// 加载对应页码和条数的数据
+	}
+
+	// 操作方法
+	const handlePublish = (record) => {
+		console.log('发布', record)
+	}
+
+	const handleEdit = (record) => {
+		console.log('编辑', record)
+	}
+
+	const handleDelete = (record) => {
+		console.log('删除', record)
+	}
+
+	defineExpose({
+		setData
+	})
 </script>
 
 <style scoped>
@@ -40,4 +217,11 @@
 
 	.tab-switcher div:not(:last-child) {
 	}
+	.processing {
+		color: orange;
+	}
+
+	.uploaded {
+		color: green;
+	}
 </style>

+ 76 - 0
src/views/resourceDetails/components/QueriesGeneralView.vue

@@ -0,0 +1,76 @@
+<template>
+	<div style="display: flex; justify-content: space-between">
+		<a-form :model="formState">
+			<a-form-item>
+				<a-input v-model:value="formState.name" placeholder="请输入资源名称" style="width: 200px; margin-right: 20px" />
+				<a-button type="primary" @click="onSubmit" :loading="iconLoading">
+					<template #icon> <SearchOutlined /> </template>
+					提交
+				</a-button>
+				<a-button style="margin-left: 10px" @click="reset">
+					<template #icon>
+						<RedoOutlined />
+					</template>
+					重置
+				</a-button>
+			</a-form-item>
+		</a-form>
+		<a-button type="primary" style="margin-left: 10px" @click="reset">
+			<template #icon> <PlusOutlined /> </template>
+			上传资源
+		</a-button>
+	</div>
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	import { Form } from 'ant-design-vue'
+	const emit = defineEmits(['selectTab'])
+	const iconLoading = ref(false)
+
+	const useForm = Form.useForm
+	const formState = reactive({
+		name: ''
+	})
+	const rulesRef = reactive({})
+	const { resetFields, validate, validateInfos } = useForm(formState, rulesRef)
+	const onSubmit = () => {
+		iconLoading.value = true
+		validate()
+			.then(() => {
+				iconLoading.value = false
+				console.log(toRaw(formState))
+			})
+			.catch((err) => {
+				console.log('error', err)
+				iconLoading.value = false
+			})
+	}
+	const reset = () => {
+		resetFields()
+	}
+</script>
+
+<style scoped>
+	.tab-switcher {
+		display: flex;
+		border-radius: 20px;
+		border: 1px solid #1e90ff;
+		overflow: hidden;
+	}
+
+	.tab-switcher div {
+		padding: 2px 20px;
+		background-color: #f5f5f5;
+
+		cursor: pointer;
+	}
+
+	.tab-switcher div.active {
+		background-color: #1e90ff;
+		color: white;
+	}
+
+	.tab-switcher div:not(:last-child) {
+	}
+</style>

+ 30 - 21
src/views/resourceDetails/components/QueryUnpublishedView.vue

@@ -1,31 +1,37 @@
 <template>
-	<div style="display: flex; justify-content: space-between">
-		<a-form :model="formState">
-			<a-form-item>
-				<a-input v-model:value="formState.name" placeholder="请输入资源名称" style="width: 200px; margin-right: 20px" />
-				<a-button type="primary" @click="onSubmit" :loading="iconLoading">
-					<template #icon> <SearchOutlined /> </template>
-					提交
-				</a-button>
-				<a-button style="margin-left: 10px" @click="reset">
-					<template #icon>
-						<RedoOutlined />
-					</template>
-					重置
-				</a-button>
-			</a-form-item>
-		</a-form>
-		<a-button type="primary" style="margin-left: 10px" @click="reset">
-			<template #icon> <PlusOutlined /> </template>
-			上传资源
-		</a-button>
+	<div>
+		<div style="display: flex; justify-content: space-between">
+			<a-form :model="formState">
+				<a-form-item>
+					<a-input
+						v-model:value="formState.name"
+						placeholder="请输入资源名称"
+						style="width: 200px; margin-right: 20px"
+					/>
+					<a-button type="primary" @click="onSubmit" :loading="iconLoading">
+						<template #icon> <SearchOutlined /> </template>
+						提交
+					</a-button>
+					<a-button style="margin-left: 10px" @click="reset">
+						<template #icon>
+							<RedoOutlined />
+						</template>
+						重置
+					</a-button>
+				</a-form-item>
+			</a-form>
+			<a-button type="primary" style="margin-left: 10px" @click="reset">
+				<template #icon> <PlusOutlined /> </template>
+				上传资源
+			</a-button>
+		</div>
 	</div>
 </template>
 
 <script setup>
 	import { ref } from 'vue'
 	import { Form } from 'ant-design-vue'
-	const emit = defineEmits(['selectTab'])
+	const emit = defineEmits(['onQuery'])
 	const iconLoading = ref(false)
 
 	const useForm = Form.useForm
@@ -40,6 +46,8 @@
 			.then(() => {
 				iconLoading.value = false
 				console.log(toRaw(formState))
+
+				emit('onQuery', formState)
 			})
 			.catch((err) => {
 				console.log('error', err)
@@ -48,6 +56,7 @@
 	}
 	const reset = () => {
 		resetFields()
+		emit('onQuery', {})
 	}
 </script>
 

+ 75 - 0
src/views/resourceDetails/components/UnpublishedView.vue

@@ -0,0 +1,75 @@
+<template>
+	<div>
+		<QueryUnpublishedView @onQuery="onQuery" />
+		<ListUnpublishedView ref="listUnpublishedView" />
+	</div>
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	import QueryUnpublishedView from './QueryUnpublishedView.vue'
+	import ListUnpublishedView from './ListUnpublishedView.vue'
+	const emit = defineEmits(['selectTab'])
+	const listUnpublishedView = ref(null)
+
+	// 表格数据
+	const tableData = ref([
+		// 示例数据
+		{ key: '1', id: 1, name: '资源名称资源名称1', format: 'mp4', uploadTime: '2020-11-25 23:26:08', status: '处理中' },
+		{ key: '2', id: 2, name: '资源名称资源名称2', format: 'mp3', uploadTime: '2020-11-26 23:26:08', status: '已上传' },
+		{ key: '3', id: 3, name: '资源名称资源名称3', format: 'avi', uploadTime: '2020-11-27 23:26:08', status: '已上传' },
+		{
+			key: '4',
+			id: 4,
+			name: '资源名称资源名称4',
+			format: 'u3mb4',
+			uploadTime: '2020-11-28 23:26:08',
+			status: '已上传'
+		},
+		{ key: '5', id: 5, name: '资源名称资源名称5', format: 'mp4', uploadTime: '2020-11-29 23:26:08', status: '已上传' },
+		{ key: '6', id: 6, name: '资源名称资源名称6', format: 'mp4', uploadTime: '2020-11-30 23:26:08', status: '已上传' },
+		{ key: '7', id: 7, name: '资源名称资源名称7', format: 'mp4', uploadTime: '2020-11-31 23:26:08', status: '已上传' }
+		// 更多数据...
+	])
+
+	const onQuery = (form) => {
+		console.log('查询内容', form)
+		//....
+
+		listUnpublishedView.value.setData(tableData.value)
+	}
+
+	const getList = () => {
+		//....
+
+		listUnpublishedView.value.setData(tableData.value)
+	}
+
+	onMounted(() => {
+		getList()
+	})
+</script>
+
+<style scoped>
+	.tab-switcher {
+		display: flex;
+		border-radius: 20px;
+		border: 1px solid #1e90ff;
+		overflow: hidden;
+	}
+
+	.tab-switcher div {
+		padding: 2px 20px;
+		background-color: #f5f5f5;
+
+		cursor: pointer;
+	}
+
+	.tab-switcher div.active {
+		background-color: #1e90ff;
+		color: white;
+	}
+
+	.tab-switcher div:not(:last-child) {
+	}
+</style>

+ 2 - 2
src/views/resourceDetails/index.vue

@@ -2,7 +2,7 @@
 	<div class="content">
 		<a-tabs v-model:activeKey="activeKey" type="card">
 			<a-tab-pane key="1" tab="未发布">
-				<ListUnpublishedView />
+				<UnpublishedView />
 			</a-tab-pane>
 			<a-tab-pane key="2" tab="待审核">
 				<!-- <ListUnpublishedView /> -->
@@ -18,7 +18,7 @@
 </template>
 
 <script setup>
-	import ListUnpublishedView from './components/ListUnpublishedView.vue'
+	import UnpublishedView from './components/UnpublishedView.vue'
 
 	const handlerItemSidebar = (item) => {
 		// emit('handlerItemSidebar', item)

+ 0 - 1
vite.config.js

@@ -47,7 +47,6 @@ export default defineConfig(({ command, mode }) => {
 		'~': `${resolve(__dirname, './')}`,
 		'@/': `${resolve(__dirname, 'src')}/`
 	}
-
 	return {
 		server: {
 			port: envConfig.VITE_PORT,