whj hace 1 semana
padre
commit
792d3582fb

+ 49 - 0
api/subject/catalog.ts

@@ -0,0 +1,49 @@
+import { usePost, stringify, useGet } from "@/.cool";
+import type { SubjectCourseResult } from './course'
+import type { FileList } from '../types/index'
+
+export interface SubjectCatalogResult {
+    id?: string
+    subjectId?: string
+    name?: string
+    iconPath?: string
+    sortNum?: string
+    courseStartNum?: string
+    remark?: string
+    updateUserId?: string
+    updateUserName?: string
+    createdUserId?: string
+    createdUserName?: string
+    createdTime?: string
+    updateTime?: string
+    fileList?: FileList[]
+    courseList?: SubjectCourseResult[]
+}
+
+// export function getSubjectCatalogPage(parameter: any) {
+//     return useGet<GetPage<any>>(`/subject/catalog/page`, parameter)
+// }
+// export function addSubjectCatalog(parameter: SubjectCatalogResult) {
+//     return usePost<any>(`/subject/catalog`, parameter)
+// }
+// export function updateSubjectCatalog(parameter: SubjectCatalogResult) {
+//     return usePut<any>(`/subject/catalog/${parameter.id}`, parameter)
+// }
+// export function fetchSubjectCatalog(parameter: any) {
+//     return useGet<SubjectCatalogResult>(`/subject/catalog/${parameter.id}`, {}, {
+//         loading: true,
+//     })
+// }
+
+// export function deleteSubjectCatalogs(parameter: string[]) {
+//     return useDelete<any>(`/subject/catalog`, parameter)
+// }
+
+// export function exportSubjectCatalog(parameter: any) {
+//     return useGet<any>(`/subject/catalog/export`, parameter, {
+//         responseType: 'blob',
+//         headers: {
+//             'Content-Type': 'application/json;charset=UTF-8',
+//         },
+//     })
+// }

+ 59 - 0
api/subject/course.ts

@@ -0,0 +1,59 @@
+import { usePost, stringify, useGet } from "@/.cool";
+import type { FileList } from '../types/index'
+
+
+export interface SubjectCourseResult {
+    id?: string
+    subjectId?: string
+    catalogId?: string
+    mainTitle?: string
+    assistantTitle?: string
+    iconPath?: string
+    sortNum?: string
+    remark?: string
+    updateUserId?: string
+    updateUserName?: string
+    createdUserId?: string
+    createdUserName?: string
+    createdTime?: string
+    updateTime?: string
+    delFlag?: boolean
+    trialPlay?: boolean
+    feeType?: number
+    gameHtmlPath?: string
+    videoPath?: string
+    detailItem?: any
+    practiceList?: any[]
+    testItem?: any
+    diaryItem?: any
+    courseUserProgress?: any
+    fileList?: FileList[]
+}
+
+// export function getSubjectCoursePage(parameter: any) {
+//     return useGet<GetPage<any>>(`/subject/course/page`, parameter)
+// }
+// export function addSubjectCourse(parameter: SubjectCourseResult) {
+//     return usePost<any>(`/subject/course`, parameter)
+// }
+// export function updateSubjectCourse(parameter: SubjectCourseResult) {
+//     return usePut<any>(`/subject/course/${parameter.id}`, parameter)
+// }
+// export function fetchSubjectCourse(parameter: any) {
+//     return useGet<SubjectCourseResult>(`/subject/course/${parameter.id}`)
+// }
+// export function fetchSubjectCourseApp(parameter: any) {
+//     return useGet<any>(`/subject/course/app/query/${parameter.id}`)
+// }
+// export function deleteSubjectCourses(parameter: string[]) {
+//     return useDelete<any>(`/subject/course`, parameter)
+// }
+
+// export function exportSubjectCourse(parameter: any) {
+//     return useGet<any>(`/subject/course/export`, parameter, {
+//         responseType: 'blob',
+//         headers: {
+//             'Content-Type': 'application/json;charset=UTF-8',
+//         },
+//     })
+// }

+ 50 - 0
api/subject/info.ts

@@ -0,0 +1,50 @@
+import { usePost, stringify, useGet } from "@/.cool";
+import type { SubjectCatalogResult } from './catalog'
+
+export interface SubjectInfoResult {
+    id?: string
+    mainTitle?: string
+    assistantTitle?: string
+    content?: string
+    subjectType?: string
+    price?: string
+    salePrice?: string
+    dealNum?: string
+    remark?: string
+    updateUserId?: string
+    updateUserName?: string
+    createdUserId?: string
+    createdUserName?: string
+    createdTime?: string
+    updateTime?: string
+    interactionFlag?: boolean
+    catalogList?: SubjectCatalogResult[]
+}
+
+// export function getSubjectInfoPage(parameter: any) {
+//     return useGet<GetPage<any>>(`/subject/info/page`, parameter)
+// }
+// export function addSubjectInfo(parameter: SubjectInfoResult) {
+//     return usePost<any>(`/subject/info`, parameter)
+// }
+// export function updateSubjectInfo(parameter: SubjectInfoResult) {
+//     return usePut<any>(`/subject/info/${parameter.id}`, parameter)
+// }
+export function fetchSubjectConfigInfo(parameter: any) {
+    return useGet(`/subject/info/config/info/${parameter.id}`) as Promise<SubjectInfoResult>
+}
+export function fetchSubjectInfo(parameter: any) {
+    return useGet(`/subject/info/${parameter.id}`) as Promise<SubjectInfoResult>
+}
+// export function deleteSubjectInfos(parameter: string[]) {
+//     return useDelete<any>(`/subject/info`, parameter)
+// }
+
+// export function exportSubjectInfo(parameter: any) {
+//     return useGet<any>(`/subject/info/export`, parameter, {
+//         responseType: 'blob',
+//         headers: {
+//             'Content-Type': 'application/json;charset=UTF-8',
+//         },
+//     })
+// }

+ 12 - 0
api/types/index.ts

@@ -0,0 +1,12 @@
+export interface GetPage<T> {
+  total: number
+  rows: T[]
+  pageNum: number
+  pageSize: number
+  pages: number
+}
+export interface FileList {
+  id: string
+  url: string
+  name: string
+}

+ 12 - 1
config/proxy.ts

@@ -6,12 +6,23 @@ export const proxy = {
 		changeOrigin: true,
 		rewrite: (path: string) => path.replace("/dev", "")
 	},
+	file: {
+		// 本地地址
+		target: "http://192.168.110.161:5001",
+		changeOrigin: true,
+	},
+	api: {
+		// 本地地址
+		target: "http://192.168.110.161:5001",
+		changeOrigin: true,
+		rewrite: (path: string) => path.replace("/api", "")
+	},
 	// 生产环境配置
 	prod: {
 		// 官方测试地址
 		target: "http://127.0.0.1:5000",
 		changeOrigin: true,
-		rewrite: (path: string) => path.replace("/prod", "/api")
+		rewrite: (path: string) => path.replace("/prod", "")
 	}
 };
 

+ 60 - 0
pages/index/components/progress.uvue

@@ -0,0 +1,60 @@
+<template>
+	<view class="progress-container">
+		<view class="progress-bar" v-for="i in num" :key="i" :class="{
+      'progress-select':percentage>=i
+    }">
+			<view class="progress-fill"></view>
+			<view class="progress-thumb" v-if="i!==num"></view>
+		</view>
+	</view>
+</template>
+
+<script lang="ts" setup>
+import { ref, defineProps } from 'vue';
+
+const props = defineProps({
+	percentage: {
+		type: Number,
+		default: 2
+	},
+  num:{
+    type:Number,
+    default:4
+  },
+  size:{
+    type:String,
+    default:'15px'
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.progress-container {
+	width: 100%;
+	padding: 10rpx 0;
+  @apply flex flex-row;
+	.progress-bar {
+  	@apply flex flex-row items-center;
+		.progress-fill {
+     	@apply  rounded-full ;
+			background-color: #E4F0FF;
+      width:v-bind(size);
+      height:v-bind(size);
+		}
+		.progress-thumb {
+  	@apply  rounded-full ;
+       width:v-bind(size);
+      height:calc(v-bind(size) / 5);
+			background-color: #E4F0FF;
+		}
+	}
+  .progress-select{
+    .progress-fill {
+			background-color: #194DCF;
+		}
+		.progress-thumb {
+			background-color: #194DCF;
+		}
+  }
+}
+</style>

+ 0 - 40
pages/index/components/tabbar.uvue

@@ -1,40 +0,0 @@
-<template>
-	<cl-tabbar :model-value="path" :list="list" @select="onSelect"> </cl-tabbar>
-</template>
-
-<script setup lang="ts">
-import { ctx, getConfig, isDark, router, t } from "@/.cool";
-import type { ClTabbarItem } from "@/uni_modules/cool-ui";
-import { computed } from "vue";
-
-defineOptions({
-	name: "custom-tabbar"
-});
-
-// 当前路径
-const path = computed(() => router.path());
-
-// tabbar 列表
-const list = computed<ClTabbarItem[]>(() => {
-	return (ctx.tabBar.list ?? []).map((e) => {
-		return {
-			icon: e.iconPath,
-			selectedIcon: e.selectedIconPath,
-			value: e.pagePath,
-			text: t(e.text?.replaceAll("%", "")!)
-		} as ClTabbarItem;
-	});
-});
-
-// 选择 tabbar 项
-const onSelect = (item: ClTabbarItem) => {
-	router.to(item.value);
-};
-
-// 隐藏原生 tabBar
-// #ifndef MP
-if (ctx.tabBar.list != null) {
-	uni.hideTabBar();
-}
-// #endif
-</script>

+ 99 - 11
pages/index/home.uvue

@@ -1,34 +1,82 @@
 <template>
 	<cl-page>
 		<img src="/static/home/2.png" alt="" class="w-full h-full object-cover">
-		<cl-image src="/static/home/8.png" mode="widthFix" class="!absolute bottom-0 left-0 !w-[20vw] !h-[50vh] z-[1]" />
+		<!-- 精灵图动画 -->
+		<cl-image src="/static/home/3.gif" mode="heightFix" class="!absolute bottom-0 left-0 !w-[44vh] !h-[55vh] z-[1]" />
+		<!-- <view class="sprite-animation"></view> -->
+		<view>
+
+		</view>
 		<cl-button @tap="handleLogin" class="!absolute top-10 left-10  z-[1]">登录</cl-button>
+		<!-- 顶部右侧光标签 -->
+		<view class="light-tag" @tap="visible = true">
+			<image class="light-icon" :src="catalog?.fileList?.[0]?.url"></image>
+			<text class="light-text">{{ catalog?.name }}</text>
+			<cl-icon name="arrow-left-right-line" color="primary"></cl-icon>
+		</view>
 		<view class="boxs">
 			<scroll-view class="scroll-view_H" direction="horizontal" :scroll-left="120" :show-scrollbar="false">
-				<view class="scroll-view-item_H bg-[white]"><text class="text">A</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">B</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">C</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">C</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">C</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">C</text></view>
-				<view class="scroll-view-item_H bg-[white]"><text class="text">C</text></view>
+				<view class="scroll-view-item_H bg-[white]" v-for="course in catalog?.courseList || []" :key="course.id">
+					<cl-image :src="course?.fileList?.[0]?.url" mode="heightFix"
+						class="!w-full !h-[26vh] mb-[2px] rounded-xl"></cl-image>
+					<text class="text-[16px] font-bold">{{
+						course.mainTitle }}</text>
+					<text class="text-[14px] text-[#666]">{{
+						course.assistantTitle }}</text>
+					<view>
+						<Progress :progress="30" />
+					</view>
+				</view>
 			</scroll-view>
 		</view>
+		<cl-popup v-model="visible" :show-header="false" direction="center" :size="500">
+			<view class="p-4">
+				<cl-row :gutter="0">
+					<cl-col :span="6" v-for="item in dataList" :key="item.id" :pt="{
+						className: '!p-2'
+					}" @tap="handleSelect(item)">
+						<view class="select-item" :class="{ selected: item.id === catalog?.id }">
+							<image :src="item?.fileList?.[0]?.url" class="w-[30rpx] h-[30rpx] mb-[2px]"></image>
+							<text>{{ item.name }}</text>
+						</view>
+					</cl-col>
+				</cl-row>
+			</view>
+		</cl-popup>
 	</cl-page>
 </template>
 
 <script lang="ts" setup>
-import { ref } from 'vue'
+import { ref, onMounted } from 'vue'
+import { fetchSubjectConfigInfo } from '@/api/subject/info'
+import type { SubjectCatalogResult } from '@/api/subject/catalog'
+import Progress from './components/progress.uvue'
+
 function handleLogin() {
 	uni.navigateTo({
 		url: '/pages/user/login'
 	})
 }
+const visible = ref<boolean>(false)
+const dataList = ref<SubjectCatalogResult[]>([])
+const catalog = ref<SubjectCatalogResult>()
+async function getDataList() {
+	const res = await fetchSubjectConfigInfo({ id: '69afc7e048070409048c06b6' })
+	dataList.value = res.catalogList || []
+	catalog.value = res?.catalogList?.[0]
+}
+onMounted(() => {
+	getDataList()
+})
+function handleSelect(item: SubjectCatalogResult) {
+	catalog.value = item
+	visible.value = false
+}
 </script>
 
 <style lang="scss" scoped>
 .boxs {
-	@apply w-[70vw] h-[50vh] absolute top-1/2 right-5 z-[1];
+	@apply w-[100vw] h-[50vh] absolute top-1/2 left-[50vh] z-[1];
 	transform: translateY(-50%);
 }
 
@@ -38,6 +86,46 @@ function handleLogin() {
 }
 
 .scroll-view-item_H {
-	@apply w-[40vh] h-[50vh] mr-[20px] rounded-2xl border-[5px] border-[#1D4BD9] border-solid border-b-[10px];
+	@apply w-[40vh] h-[50vh] mr-[20px] rounded-2xl border-[5px] border-[#1D4BD9] border-solid border-b-[10px] p-1 flex items-center;
+}
+
+.light-tag {
+	@apply absolute top-5 right-5 z-[1] flex flex-row items-center bg-white px-3 py-2 font-bold rounded-full shadow-md;
+
+	.light-icon {
+		width: 20px;
+		height: 20px;
+		margin-right: 3px;
+	}
+
+	.light-text {
+		font-size: 16px;
+		width: 70px;
+	}
+}
+
+.select-item {
+	@apply flex items-center justify-center rounded-xl border-[3px] border-[#1D4BD9] border-solid border-b-[5px] px-4 py-2 font-bold;
+}
+
+.selected {
+	@apply border-green-500;
+}
+
+.sprite-animation {
+	@apply absolute bottom-0 left-0 w-[42vh] h-[60vh] z-[1] bg-[url('https://oss.xiaoxiongcode.com/static/home/sprite.png')] bg-no-repeat;
+	background-size: 1460% 1000%;
+	background-position: 0 0;
+	animation: sprite-animation 3s steps(13) infinite;
+}
+
+@keyframes sprite-animation {
+	from {
+		background-position: 0 0;
+	}
+
+	to {
+		background-position: calc(-42vh * 13) 0;
+	}
 }
 </style>

BIN
static/home/3.gif