shmily1213 1 місяць тому
батько
коміт
40cf16c37f

+ 4 - 4
src/api/modules/study.ts

@@ -1,6 +1,6 @@
 import { ApiResponse } from "@/types";
 import flyio from "../flyio";
-import { ApiQuestion, ExamPaper, ExamPaperSubmit, Knowledge, StudyPlan, Subject } from "@/types/study";
+import { ApiQuestion, DirectedSchool, ExamPaper, ExamPaperSubmit, Knowledge, StudyPlan, Subject } from "@/types/study";
 
 /**
  * 获取学习计划
@@ -36,7 +36,7 @@ export function getStudyPlanStats(params: any) {
  * @returns 
  */
 export function getDirectedSchool() {
-  return flyio.get('/front/student/directed/school') as Promise<ApiResponse<any>>;
+  return flyio.get('/front/student/directed/school') as Promise<ApiResponse<DirectedSchool[]>>;
 }
 
 
@@ -45,7 +45,7 @@ export function getDirectedSchool() {
  * @param params 
  * @returns 
  */
-export function saveDirectedSchool(params: any) {
+export function saveDirectedSchool(params: DirectedSchool[]) {
   return flyio.post('/front/student/directed/school', params) as Promise<ApiResponse<any>>;
 }
 
@@ -64,7 +64,7 @@ export function getSubjectList(params: any) {
  * @param params 
  * @returns 
  */
-export function getKnowledgeList(params: { subjectId: number }) {
+export function getKnowledgeList(params: { subjectId: number, directed: boolean }) {
   return flyio.get('/front/paper/knowledge', params) as Promise<ApiResponse<Knowledge[]>>;
 }
 

+ 11 - 1
src/api/modules/university.ts

@@ -8,4 +8,14 @@ import flyio from "../flyio";
  */
 export function getUniversityList() {
   return flyio.get('/front/student/university') as Promise<ApiResponse<any>>;
-}
+}
+
+/**
+ * 获取院校专业列表
+ * @param params 
+ * @returns 
+ */
+export function getUniversityMajorList(params: { universityId: string }) {
+  return flyio.get('/front/student/university/major', params) as Promise<ApiResponse<any>>;
+}
+

+ 1 - 1
src/api/webApi/subject.js

@@ -42,7 +42,7 @@ export function exportList(params) {
 // 列表
 export function list(params) {
   return request({
-    url: '/front/subject/list',
+    url: '/front/student/subject',
     method: 'get', 
     params:params
   })

+ 27 - 0
src/components/ie-popup-toolbar/ie-popup-toolbar.vue

@@ -0,0 +1,27 @@
+<template>
+  <view class="flex items-center justify-between pt-20">
+    <view class="px-46 py-20 text-28 text-fore-light" @click="handleCancel">{{ cancelText }}</view>
+    <text class="text-30 text-fore-title font-bold">{{ title }}</text>
+    <view class="px-46 py-20 text-28 text-fore-title" @click="handleConfirm">{{ confirmText }}</view>
+  </view>
+</template>
+<script lang="ts" setup>
+type ToolbarOption = {
+  title: string;
+  cancelText: string;
+  confirmText: string;
+}
+const props = withDefaults(defineProps<ToolbarOption>(), {
+  title: '',
+  cancelText: '取消',
+  confirmText: '确认',
+});
+const emit = defineEmits(['cancel', 'confirm']);
+const handleCancel = () => {
+  emit('cancel');
+}
+const handleConfirm = () => {
+  emit('confirm');
+}
+</script>
+<style lang="scss" scoped></style>

+ 2 - 2
src/hooks/defineCacheActions.js

@@ -19,8 +19,8 @@ export const cacheActions = {
     getSubjectList: {
         type: Symbol('GET_SUBJECT_LIST'),
         handler: async () => {
-            const {rows} = await getSubjectList()
-            return rows
+            const {data} = await getSubjectList()
+            return data
         }
     },
     getKnowledgeTree: {

+ 1 - 1
src/hooks/useCacheStore.js

@@ -6,7 +6,7 @@ import {getSizeOfObject} from "@/utils";
 import _ from 'lodash';
 
 function CacheResult(data, options) {
-    if (hasOwn(data, 'dataSize')) {
+    if (data && hasOwn(data, 'dataSize')) {
         // 如果对象内部有循环钩子,getSizeOfObject无法计算,则预先缓存大小
         this.data = data.data
         this.dataSize = data.dataSize

+ 1 - 1
src/hooks/useImage.ts

@@ -1,7 +1,7 @@
 export const useImage = () => {
   const resolvePath = (src: string) => {
     // 如果是base64的,直接返回
-    if (src.startsWith('data:image/')) {
+    if (src.startsWith('data:image/') || src.startsWith('http') || src.startsWith('https')) {
       return src;
     }
     // h5的开发环境,补上/h5/src/前缀

+ 5 - 0
src/main.ts

@@ -70,6 +70,11 @@ export function createApp() {
         customClass: {
           default: ''
         }
+      },
+      popup: {
+        theme: {
+          default: 'theme-ie'
+        }
       }
     }
   })

+ 7 - 0
src/pages.json

@@ -614,6 +614,13 @@
             "navigationBarTitleText": ""
           }
         },
+        {
+          "path": "pages/targeted-add/targeted-add",
+          "style": {
+            "navigationBarTitleText": "",
+            "disableScroll": true
+          }
+        },
         {
           "path": "pages/homework/homework",
           "style": {

+ 1 - 1
src/pagesStudy/components/knowledge-tree-node.vue

@@ -6,7 +6,7 @@
           <uv-icon v-if="!nodeData.isLeaf" name="arrow-right" size="14" color="#888"
             :custom-class="['mr-16 transition-transform duration-300', nodeData.isExpanded ? 'rotate-90' : '']" />
           <view>
-            <text class="block text-28 text-fore-title font-bold">{{ nodeData.name }}</text>
+            <text class="block text-28 text-fore-title font-bold ellipsis-1">{{ nodeData.name }}</text>
             <text class="mt-4 block text-24 text-fore-light">共{{ nodeData.questionCount || 0 }}道题</text>
           </view>
         </view>

+ 0 - 1
src/pagesStudy/pages/index/compoentns/index-banner.vue

@@ -36,7 +36,6 @@ const navigateTo = (pageUrl: string) => {
 
 const handleOpenPlan = async () => {
   const { data } = await getStudyPlan()
-  // const directedSchool = await getDirectedSchool()
   // console.log(data, directedSchool)
   if (data) {
     transferTo('/pagesStudy/pages/study-plan/study-plan');

+ 15 - 5
src/pagesStudy/pages/index/compoentns/index-menu.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="menu-container">
-    <view class="menu-item" v-for="menu in menus" :key="menu.label" @click="navigateTo(menu.pageUrl)">
+    <view class="menu-item" v-for="menu in menus" :key="menu.label" @click="navigateTo(menu)">
       <ie-image :is-oss="true" :src="menu.icon" custom-class="w-98 h-110" />
       <view class="text-26 text-fore-title">{{ menu.label }}</view>
     </view>
@@ -9,7 +9,11 @@
 <script lang="ts" setup>
 import { useTransferPage } from '@/hooks/useTransferPage';
 const { transferTo } = useTransferPage();
-
+type MenuItem = {
+  label: string;
+  icon: string;
+  pageUrl: string;
+}
 const menus = [
   {
     label: '课程学习',
@@ -29,7 +33,7 @@ const menus = [
   {
     label: '错题本',
     icon: '/menu/menu-mistake.png',
-    pageUrl: '/pagesStudy/mistake/index'
+    pageUrl: '/pagesOther/pages/topic-center/wrong-book/wrong-book'
   },
   {
     label: '学习记录',
@@ -37,8 +41,14 @@ const menus = [
     pageUrl: '/pagesStudy/pages/study-history/study-history'
   }
 ]
-const navigateTo = (pageUrl: string) => {
-  transferTo(pageUrl);
+const navigateTo = (menu: MenuItem) => {
+  if (menu.label === '错题本') {
+    transferTo('/pagesOther/pages/topic-center/wrong-book/wrong-book', {
+      data: {}
+    });
+  } else {
+    transferTo(menu.pageUrl);
+  }
 }
 </script>
 <style lang="scss" scoped>

+ 35 - 7
src/pagesStudy/pages/index/index.vue

@@ -6,7 +6,9 @@
           <uv-icon name="arrow-left" size="20px" color="#333"></uv-icon>
           <ie-image :is-oss="true" src="/study-title.png" custom-class="ml-8 w-148 h-36" mode="heightFix" />
           <view class="w-6 h-6 rounded-2 bg-black mx-12"></view>
-          <view>单招(应届普高)</view>
+          <view>
+            <ie-dict :dict-name="EnumDictName.EXAM_TYPE" :dict-value="userStore.getExamType || '--'" />
+          </view>
         </view>
       </template>
     </ie-navbar>
@@ -29,7 +31,7 @@
         <view class="bg-[#FFFBEB] border-2 border-[#FEF6DA] flex-1 rounded-15 relative overflow-hidden">
           <view class="mx-30 h-70 z-1 relative flex items-center gap-x-6" @click="handleSetting">
             <view class="w-fit ellipsis-1 text-[#F59E0B]">
-              <text class="text-24 ">长沙民政职业技术学院长沙民政职业技术学院</text>
+              <text class="text-24 ">{{ firstDirectedSchool.universityName || '请选择定向院校' }}</text>
             </view>
             <ie-image src="/pagesStudy/static/image/icon-edit-pen.png" custom-class="w-28 h-28" mode="aspectFill" />
           </view>
@@ -38,7 +40,7 @@
             <view class="mt-8 text-24 text-fore-tip">结合考纲考点精准练习</view>
             <view
               class="mt-32 w-200 h-56 flex items-center justify-center rounded-full text-26 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F]"
-              @click="navigateTo('/pagesStudy/pages/targeted-practice/targeted-practice')">
+              @click="handlePracticeDirected">
               开始练习
             </view>
           </view>
@@ -60,22 +62,48 @@ import IndexMenu from './compoentns/index-menu.vue';
 import IndexBanner from './compoentns/index-banner.vue';
 import IndexTest from './compoentns/index-test.vue';
 import IndexExamRecord from './compoentns/index-exam-record.vue';
+import { EnumDictName } from '@/common/enum';
+import { useUserStore } from '@/store/userStore';
 import { useTransferPage } from '@/hooks/useTransferPage';
+import { getDirectedSchool } from '@/api/modules/study';
+import { DirectedSchool } from '@/types/study';
 const { transferTo } = useTransferPage();
+const userStore = useUserStore();
+
+const directedSchoolData = ref<DirectedSchool[]>([]);
+const firstDirectedSchool = computed(() => directedSchoolData.value[0] || {});
+const hasDirectedSchool = computed(() => directedSchoolData.value.length > 0);
 
-const navigateTo = (pageUrl: string) => {
-  transferTo(pageUrl);
-}
 const handlePracticeAll = () => {
   transferTo('/pagesStudy/pages/knowledge-practice/knowledge-practice', {
     data: {
-      universityId: undefined
+      directed: false
+    }
+  });
+}
+const handlePracticeDirected = () => {
+  if (!hasDirectedSchool.value) {
+    uni.$ie.showToast('请先选择定向院校');
+    return;
+  }
+  transferTo('/pagesStudy/pages/knowledge-practice/knowledge-practice', {
+    data: {
+      directed: true
     }
   });
 }
 const handleSetting = () => {
   transferTo('/pagesStudy/pages/targeted-setting/targeted-setting');
 }
+const loadData = async () => {
+  const res = await getDirectedSchool();
+  if (res.data) {
+    directedSchoolData.value = res.data;
+  }
+}
+onShow(() => {
+  loadData();
+});
 </script>
 
 <style></style>

+ 2 - 1
src/pagesStudy/pages/knowledge-practice/knowledge-practice.vue

@@ -37,7 +37,8 @@ const loadKnowledgeList = async () => {
   }
   try {
     const { data } = await getKnowledgeList({
-      subjectId: currentSubjectId.value
+      subjectId: currentSubjectId.value,
+      directed: prevData.value.directed
     });
     treeData.value = data as Study.KnowledgeNode[];
   } catch (error) {

+ 6 - 4
src/pagesStudy/pages/start-exam/components/question-item.vue

@@ -1,5 +1,6 @@
 <template>
-  <view class="question-item">
+  <scroll-view scroll-y class="question-item">
+    <view class="h-20"></view>
     <view class="question-type">{{ questionTypeDesc[question.typeId as EnumQuestionType] }}</view>
     <view class="question-content">
       <uv-parse :content="question.title"></uv-parse>
@@ -25,7 +26,8 @@
         <question-item :question="subQuestion" v-for="subQuestion in question.subQuestions" :key="subQuestion.id" />
       </view>
     </view>
-  </view>
+    <view class="h-20"></view>
+  </scroll-view>
 </template>
 
 <script lang="ts" setup>
@@ -88,7 +90,7 @@ const isSelected = (option: Study.QuestionOption) => {
 
 <style lang="scss" scoped>
 .question-item {
-  @apply h-full pt-20;
+  @apply h-full box-border;
 
   .question-type {
     @apply px-40 my-20 text-32 text-fore-subtitle font-bold;
@@ -105,7 +107,7 @@ const isSelected = (option: Study.QuestionOption) => {
       @apply flex items-center px-30 py-30 bg-back rounded-10;
 
       .question-option-index {
-        @apply w-40 h-40 rounded-full bg-transparent text-30 text-fore-light font-bold flex items-center justify-center;
+        @apply w-40 h-40 rounded-full bg-transparent text-30 text-fore-light font-bold flex items-center justify-center flex-shrink-0;
       }
 
       .question-option-content {

+ 7 - 7
src/pagesStudy/pages/study-plan-edit/study-plan-edit.vue

@@ -2,27 +2,27 @@
   <ie-page bg-color="#F6F8FA">
     <ie-navbar title="定制学习计划" />
     <view class="mt-16 bg-white py-30">
-      <view class="mx-40 text-30 text-fore-title font-bold">每日学习计划</view>
+      <view class="mx-40 text-32 text-fore-title font-bold">每日学习计划</view>
       <view class="mt-20">
         <uv-cell-group :border="false">
           <uv-cell isLink value="去设置" :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
             @click="handleCourseStudySetting">
             <template #title>
-              <text class="text-26 text-fore-subtitle">课程学习</text>
+              <text class="text-30 text-fore-subtitle">课程学习</text>
             </template>
             <template #value>
-              <text v-if="form.courseTime" class="mr-10 text-26 text-fore-title">{{ form.courseTime }}课时</text>
-              <text v-else class="mr-10 text-26 text-fore-placeholder">去设置</text>
+              <text v-if="form.courseTime" class="mr-10 text-30 text-fore-title">{{ form.courseTime }}课时</text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">去设置</text>
             </template>
           </uv-cell>
           <uv-cell isLink value="去设置" :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
             @click="handleQuestionStudySetting">
             <template #title>
-              <text class="text-26 text-fore-subtitle">题库练习</text>
+              <text class="text-30 text-fore-subtitle">题库练习</text>
             </template>
             <template #value>
-              <text v-if="form.questionTime" class="mr-10 text-26 text-fore-title">{{ form.questionTime }}题</text>
-              <text v-else class="mr-10 text-26 text-fore-placeholder">去设置</text>
+              <text v-if="form.questionTime" class="mr-10 text-30 text-fore-title">{{ form.questionTime }}题</text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">去设置</text>
             </template>
           </uv-cell>
         </uv-cell-group>

+ 154 - 0
src/pagesStudy/pages/targeted-add/targeted-add.vue

@@ -0,0 +1,154 @@
+<template>
+  <ie-page bg-color="#F6F8FA" :fix-height="true">
+    <ie-navbar title="添加定向院校" />
+    <view class="mt-16 bg-white py-10">
+      <view class="">
+        <uv-cell-group :border="false">
+          <uv-cell isLink :border="true" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
+            @click="handleUniversitySelect">
+            <template #title>
+              <text class="text-30 text-fore-subtitle">选择院校</text>
+            </template>
+            <template #value>
+              <text v-if="form.universityName" class="mr-10 text-30 text-fore-title">{{ form.universityName }}</text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
+            </template>
+          </uv-cell>
+          <uv-cell isLink :border="false" :cellStyle="cellStyle" :rightIconStyle="rightIconStyle"
+            @click="handleMajorSelect">
+            <template #title>
+              <text class="text-30 text-fore-subtitle">选择专业</text>
+            </template>
+            <template #value>
+              <text v-if="form.majorName" class="mr-10 text-30 text-fore-title">{{ form.majorName }}</text>
+              <text v-else class="mr-10 text-30 text-fore-placeholder">请选择</text>
+            </template>
+          </uv-cell>
+        </uv-cell-group>
+      </view>
+    </view>
+    <ie-safe-toolbar :height="84" :shadow="false">
+      <view class="px-46 pt-24">
+        <ie-button type="primary" @click="handleAdd">添加</ie-button>
+      </view>
+    </ie-safe-toolbar>
+  </ie-page>
+  <!-- #ifdef H5 -->
+  <teleport to="body">
+    <!-- #endif -->
+    <!-- #ifdef MP-WEIXIN -->
+    <root-portal externalClass="theme-ie">
+      <!-- #endif -->
+      <uv-popup ref="popupRef" mode="bottom" :round="16" popup-class="theme-ie" :close-on-click-overlay="false">
+        <ie-popup-toolbar title="选择专业" @cancel="handleCancel" @confirm="handleConfirm" />
+        <view class="h-[50vh] bg-white px-30 pt-20 flex flex-col">
+          <view>
+            <uv-search v-model="keyword" shape="square" :showAction="false" placeholder="请输入专业名称" />
+          </view>
+          <view class="mt-20 flex-1 min-h-1">
+            <scroll-view scroll-y class="h-full">
+              <view v-for="item in filteredMajorList" :key="item.id"
+                class="px-20 py-16 bg-white sibling-border-top flex items-center" @click="handleSelect(item)">
+                <view class="flex-1 min-w-1 flex-shrink-0">
+                  <view class="text-30 text-fore-title">{{ item.name }}</view>
+                  <view class="mt-6 text-22 text-fore-light">{{ item.ancestors }}</view>
+                </view>
+                <uv-icon v-if="selectedMajor && selectedMajor.id === item.id" name="checkmark" size="20"
+                  color="#31A0FC" />
+              </view>
+            </scroll-view>
+          </view>
+        </view>
+      </uv-popup>
+      <!-- #ifdef MP-WEIXIN -->
+    </root-portal>
+    <!-- #endif -->
+    <!-- #ifdef H5 -->
+  </teleport>
+  <!-- #endif -->
+</template>
+
+<script lang="ts" setup>
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { DirectedSchool, UniversityMajor } from '@/types/study';
+import { getUniversityMajorList } from '@/api/modules/university';
+const { transferTo, transferBack } = useTransferPage();
+const form = ref<Partial<DirectedSchool>>({});
+const keyword = ref('');
+const cellStyle = {
+  padding: '20rpx 40rpx'
+}
+const rightIconStyle = {
+  fontSize: '14px'
+}
+const majorList = ref<UniversityMajor[]>([]);
+const filteredMajorList = computed(() => {
+  return majorList.value.filter(item => item.name.includes(keyword.value));
+});
+const handleUniversitySelect = () => {
+  transferTo('/pagesOther/pages/college-library/picker/picker', {
+    data: {
+      transferType: 'v2'
+    }
+  }).then((res: any) => {
+    if (res) {
+      if (res.code !== form.value.universityId) {
+        selectedMajor.value = null;
+        form.value.majorId = '';
+        form.value.majorName = '';
+      }
+      form.value.universityId = res.code;
+      form.value.universityName = res.name;
+      form.value.universityLogo = res.logo;
+      loadMajorList(res.id);
+    }
+  });
+}
+
+const popupRef = ref();
+const selectedMajor = ref<UniversityMajor | null>(null);
+const handleMajorSelect = () => {
+  if (!form.value.universityId) {
+    uni.$ie.showToast('请选择院校');
+    return;
+  }
+  keyword.value = '';
+  popupRef.value.open();
+}
+const handleCancel = () => {
+  popupRef.value.close();
+}
+const handleConfirm = () => {
+  if (!selectedMajor.value) {
+    uni.$ie.showToast('请选择专业');
+    return;
+  }
+  form.value.ancestors = selectedMajor.value.ancestors;
+  form.value.majorId = selectedMajor.value.id.toString();
+  form.value.majorName = selectedMajor.value.name;
+  popupRef.value.close();
+}
+const handleSelect = (item: any) => {
+  selectedMajor.value = item;
+}
+
+const handleAdd = () => {
+  if (!form.value.universityId) {
+    uni.$ie.showToast('请选择院校');
+    return;
+  }
+  if (!form.value.majorId) {
+    uni.$ie.showToast('请选择专业');
+    return;
+  }
+  transferBack(form.value);
+}
+const loadMajorList = (universityId: string) => {
+  getUniversityMajorList({ universityId }).then(res => {
+    console.log(res);
+    majorList.value = res.data;
+  });
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 75 - 32
src/pagesStudy/pages/targeted-setting/targeted-setting.vue

@@ -4,47 +4,62 @@
     <view class="p-32 bg-white flex items-center justify-between">
       <view class="">
         <text class="text-32 text-fore-title font-bold">添加定向院校</text>
-        <text class="ml-10 text-32 text-fore-light">({{ collegeList.length }}/3)</text>
+        <text class="ml-10 text-32 text-fore-light">({{ directedSchoolList.length }}/3)</text>
       </view>
       <view class="text-24 text-primary">添加后无法更改</view>
     </view>
     <view class="px-48 pt-52 pb-32 flex items-center justify-between">
       <view class="text-32 text-fore-title font-bold">我的定向院校</view>
-      <view v-if="hasSetting" class="flex items-center gap-x-4">
+      <!-- <view v-if="hasDirectedSchool" class="flex items-center gap-x-4">
         <text class="text-28 text-[#F59E0B]">设置</text>
         <ie-image src="/pagesStudy/static/image/icon-edit-pen.png" custom-class="w-24 h-24" mode="aspectFill" />
-      </view>
+      </view> -->
     </view>
-    <view v-if="hasSetting" class="px-30">
-      <view class="bg-white rounded-10 py-28 pl-32 pr-20 relative flex items-center gap-x-20 mb-20"
-        v-for="(item, index) in collegeList" :key="item.code">
-        <view class="w-44 text-64 text-primary font-bold absolute top-6 left-14 italic leading-[1] opacity-30 z-1">
-          {{ index + 1 }}
-        </view>
-        <view class="w-40 h-40 bg-back"></view>
-        <view class="flex-1 min-w-1 flex items-center gap-x-20">
-          <ie-image :src="item.logo" custom-class="w-96 h-96" mode="aspectFill" />
-          <view class="flex-1 min-w-1">
-            <view class="text-28 text-fore-title font-bold">{{ item.name }}</view>
-            <view class="mt-8 w-fit text-20 text-primary border border-solid border-primary rounded-4 px-10 py-4">大数据与会计
+    <view v-if="hasDirectedSchool || loading" class="px-30">
+      <l-drag ref="dragRef" :list="directedSchoolList" :column="1" :gridHeight="104" :touchHandle="touchHandle" ghost handle
+        @change="changeSort">
+        <!-- // 每一项的插槽 grid 的 content 您传入的数据 -->
+        <template #grid="{ active, content, index }">
+          <!-- // grid.active 是否为当前拖拽项目 根据自己需要写样式 -->
+          <view class="bg-white rounded-10 py-28 pl-30 pr-20 relative flex items-center gap-x-16 mb-20"
+            :class="{ 'border border-solid border-primary': active }">
+            <view class="w-44 text-64 text-primary font-bold absolute top-6 left-14 italic leading-[1] opacity-30 z-1">
+              {{ index + 1 }}
+            </view>
+            <view slot="handle" @touchstart="touchHandle = true" @touchend="touchHandle = false">
+              <ie-image src="/pagesStudy/static/image/icon-drag.png" custom-class="w-46 h-46" mode="aspectFill" />
             </view>
-            <view class="flex items-center justify-between text-20">
-              <view class="mt-8  text-fore-light">财经商贸大类>财务会计类</view>
-              <view
-                class="flex items-center gap-x-4 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F] rounded-full px-12 py-4">
-                <ie-image src="/pagesStudy/static/image/icon-check-white.png" custom-class="w-24 h-24" />
-                <text>定向学习中</text>
+            <view class="flex-1 min-w-1 flex items-center gap-x-20">
+              <ie-image :src="content.universityLogo" custom-class="w-96 h-96" mode="aspectFill" />
+              <view class="flex-1 min-w-1">
+                <view class="text-28 text-fore-title font-bold">{{ content.universityName }}</view>
+                <view class="mt-8 w-fit text-20 text-primary border border-solid border-primary rounded-4 px-10 py-4">
+                  {{ content.majorName }}
+                </view>
+                <view class="flex items-center justify-between text-20">
+                  <view class="mt-8  text-fore-light">{{ content.ancestors }}</view>
+                  <view v-if="index === 0"
+                    class="flex items-center gap-x-4 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F] rounded-full px-12 py-4">
+                    <ie-image src="/pagesStudy/static/image/icon-check-white.png" custom-class="w-24 h-24" />
+                    <text>定向学习中</text>
+                  </view>
+                  <view v-else class="flex items-center gap-x-4 text-22 text-primary px-12 py-4"
+                    @click="handleSetDirectedSchool(content, index)">
+                    <text>设置定向</text>
+                  </view>
+                </view>
               </view>
             </view>
           </view>
-        </view>
-      </view>
+        </template>
+        <template #ghots></template>
+      </l-drag>
     </view>
     <view v-else class="flex-1 flex flex-col items-center justify-center gap-y-50">
       <ie-image src="/pagesStudy/static/image/icon-empty.png" custom-class="w-364 h-252 mx-auto" mode="aspectFill" />
       <text class="text-30 text-fore-light text-center">目前暂无定向院校~</text>
     </view>
-    <ie-safe-toolbar v-if="collegeList.length < 3" :height="84" :shadow="false">
+    <ie-safe-toolbar v-if="directedSchoolList.length < 3 && !loading" :height="84" :shadow="false">
       <view class="px-46 pt-24">
         <ie-button type="primary" @click="handleAdd">添加</ie-button>
       </view>
@@ -54,19 +69,47 @@
 
 <script lang="ts" setup>
 import { useTransferPage } from '@/hooks/useTransferPage';
+import { DirectedSchool } from '@/types/study';
+import { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
 const { transferTo } = useTransferPage();
-const hasSetting = ref(false);
-const collegeList = ref<any[]>([]);
+const loading = ref(true);
+const directedSchoolList = ref<DirectedSchool[]>([]);
+const touchHandle = ref(false)
+const hasDirectedSchool = computed(() => directedSchoolList.value.length > 0);
+const handleSetDirectedSchool = async (item: DirectedSchool, index: number) => {
+  // 将该院校设置为第一个
+  directedSchoolList.value.splice(index, 1);
+  directedSchoolList.value.unshift(item);
+  save(directedSchoolList.value);
+}
 const handleAdd = () => {
-  transferTo('/pagesOther/pages/college-library/picker/picker', {
-    data: {
-      transferType: 'v2'
+  transferTo('/pagesStudy/pages/targeted-add/targeted-add', {
+    data: {}
+  }).then(async res => {
+    if (res) {
+      directedSchoolList.value.push(res as DirectedSchool);
+      save(directedSchoolList.value);
     }
-  }).then(res => {
-    collegeList.value.push(res);
-    hasSetting.value = true;
   });
 }
+const dragRef = ref();
+const changeSort = (e: any) => {
+  const list = e.map((item: any) => item.content);
+  save(list);
+}
+const save = async (list: DirectedSchool[]) => {
+  uni.$ie.showLoading();
+  await saveDirectedSchool(list);
+  await loadData();
+  uni.$ie.hideLoading();
+  uni.$ie.showSuccess('设置成功');
+  loading.value = false;
+}
+const loadData = async () => {
+  const { data } = await getDirectedSchool();
+  directedSchoolList.value = data;
+}
+loadData();
 </script>
 
 <style lang="scss" scoped></style>

BIN
src/pagesStudy/static/image/icon-drag.png


+ 22 - 3
src/types/study.ts

@@ -138,6 +138,25 @@ export interface QuestionOption {
   isAnswer: boolean;
 }
 
-export function QuestionOption(arg0: (option: string, index: number) => { name: string; no: string; id: number; isAnswer: false; }, as: any, QuestionOption: any): QuestionOption[] {
-  throw new Error("Function not implemented.");
-}
+/**
+ * 定向学校
+ */
+export interface DirectedSchool {
+  code: string;
+  name: string;
+  type: string;
+  ancestors: string;
+  universityId: string;
+  universityName: string;
+  universityLogo: string;
+  majorId: string;
+  majorName: string;
+}
+
+export interface UniversityMajor {
+  ancestors: string;
+  code: string;
+  id: number;
+  name: string;
+  type: string
+}

+ 1 - 1
src/uni_modules/uv-popup/components/uv-popup/uv-popup.vue

@@ -3,7 +3,7 @@
         v-if="keepIf"
         v-show="keepShow"
         class="uv-popup"
-        :class="[popupClass, isDesktop ? 'fixforpc-z-index' : '']"
+        :class="[popupClass, theme, isDesktop ? 'fixforpc-z-index' : '']"
         :style="[{zIndex: zIndex}]"
     >
         <view @touchstart="touchstart">