浏览代码

Merge branch 'master' of http://git.dayaedu.com/lex/orchestra-app

lex 2 年之前
父节点
当前提交
73317d2825

+ 7 - 8
package-lock.json

@@ -30,7 +30,7 @@
         "query-string": "^7.1.1",
         "query-string": "^7.1.1",
         "umi-request": "^1.4.0",
         "umi-request": "^1.4.0",
         "vant": "^4.0.0",
         "vant": "^4.0.0",
-        "vconsole": "^3.14.6",
+        "vconsole": "^3.15.0",
         "vue": "^3.2.26",
         "vue": "^3.2.26",
         "vue-cropper": "^1.0.3",
         "vue-cropper": "^1.0.3",
         "vue-echarts": "^6.2.3",
         "vue-echarts": "^6.2.3",
@@ -9080,10 +9080,9 @@
       }
       }
     },
     },
     "node_modules/vconsole": {
     "node_modules/vconsole": {
-      "version": "3.14.6",
-      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.14.6.tgz",
-      "integrity": "sha512-8Ffk2SfNe6EzKqZ0aNnNjpAVBVT7zgJo81lYEJdKySYLVYBeSawdSkWi9fSjDg3WsQhgS1vNPmRqJDTuwdVbnQ==",
-      "license": "MIT",
+      "version": "3.15.0",
+      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.0.tgz",
+      "integrity": "sha512-8hq7wabPcRucSWQyN7/1tthMawP9JPvM95zgtMHpPknMMMCKj+abpoK7P7oKK4B0qw58C24Mdvo9+raUdpHyVQ==",
       "dependencies": {
       "dependencies": {
         "@babel/runtime": "^7.17.2",
         "@babel/runtime": "^7.17.2",
         "copy-text-to-clipboard": "^3.0.1",
         "copy-text-to-clipboard": "^3.0.1",
@@ -16035,9 +16034,9 @@
       }
       }
     },
     },
     "vconsole": {
     "vconsole": {
-      "version": "3.14.6",
-      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.14.6.tgz",
-      "integrity": "sha512-8Ffk2SfNe6EzKqZ0aNnNjpAVBVT7zgJo81lYEJdKySYLVYBeSawdSkWi9fSjDg3WsQhgS1vNPmRqJDTuwdVbnQ==",
+      "version": "3.15.0",
+      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.0.tgz",
+      "integrity": "sha512-8hq7wabPcRucSWQyN7/1tthMawP9JPvM95zgtMHpPknMMMCKj+abpoK7P7oKK4B0qw58C24Mdvo9+raUdpHyVQ==",
       "requires": {
       "requires": {
         "@babel/runtime": "^7.17.2",
         "@babel/runtime": "^7.17.2",
         "copy-text-to-clipboard": "^3.0.1",
         "copy-text-to-clipboard": "^3.0.1",

+ 1 - 1
package.json

@@ -42,7 +42,7 @@
     "query-string": "^7.1.1",
     "query-string": "^7.1.1",
     "umi-request": "^1.4.0",
     "umi-request": "^1.4.0",
     "vant": "^4.0.0",
     "vant": "^4.0.0",
-    "vconsole": "^3.14.6",
+    "vconsole": "^3.15.0",
     "vue": "^3.2.26",
     "vue": "^3.2.26",
     "vue-cropper": "^1.0.3",
     "vue-cropper": "^1.0.3",
     "vue-echarts": "^6.2.3",
     "vue-echarts": "^6.2.3",

+ 7 - 3
src/constant/index.ts

@@ -1,5 +1,3 @@
-
-
 // 管理老师状态
 // 管理老师状态
 export const manageTeacherType = {
 export const manageTeacherType = {
   // CANCEL: '注销',
   // CANCEL: '注销',
@@ -111,4 +109,10 @@ export const trainCourseEmnu = {
 export const orchestraType = {
 export const orchestraType = {
   DELIVERY: '交付团',
   DELIVERY: '交付团',
   PROMOTION: '晋升团'
   PROMOTION: '晋升团'
-}
+}
+
+// 学年制
+export const schoolSystem = {
+  fiveYearSystem: '五年制',
+  sixYearSystem: '六年制'
+}

+ 13 - 0
src/helpers/request.ts

@@ -57,6 +57,19 @@ request.interceptors.request.use(
     ) {
     ) {
       authHeaders.Authorization = Authorization
       authHeaders.Authorization = Authorization
     }
     }
+    if (state?.user?.data?.schoolInfos) {
+      const schoolId = (state.user.data.schoolInfos || [])
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      if (schoolId) {
+        console.log('schoolId', schoolId)
+        options.data ? (options.data.schoolId = schoolId) : null
+        options.params ? (options.params.schoolId = schoolId) : null
+      }
+    }
+
     return {
     return {
       url,
       url,
       options: {
       options: {

+ 18 - 1
src/router/routes-school.ts

@@ -60,7 +60,8 @@ export default [
         meta: {
         meta: {
           title: '新建乐团'
           title: '新建乐团'
         }
         }
-      }, {
+      },
+      {
         path: '/create-orchestra-teacher',
         path: '/create-orchestra-teacher',
         name: 'create-orchestra-teacher',
         name: 'create-orchestra-teacher',
         component: () => import('@/school/orchestra/create-orchestra/select-teacher'),
         component: () => import('@/school/orchestra/create-orchestra/select-teacher'),
@@ -242,6 +243,22 @@ export default [
         meta: {
         meta: {
           title: '课程调整'
           title: '课程调整'
         }
         }
+      },
+      {
+        path: '/school-detail',
+        name: 'school-detail',
+        component: () => import('@/school/school-detail/index'),
+        meta: {
+          title: '学校信息'
+        }
+      },
+      {
+        path: '/school-eidt',
+        name: 'school-eidt',
+        component: () => import('@/school/school-detail/eidt-school'),
+        meta: {
+          title: '修改学校地址'
+        }
       }
       }
       //
       //
     ]
     ]

+ 1 - 1
src/school/approval-manage/components/student-leave.tsx

@@ -67,7 +67,7 @@ export default defineComponent({
       <>
       <>
         <div class={styles.leaveWrap}>
         <div class={styles.leaveWrap}>
           <OSticky>
           <OSticky>
-            <OHeader isBack={true}></OHeader>
+            <OHeader></OHeader>
           </OSticky>
           </OSticky>
           <ApprovalItem item={item.value} type={route.query.type}></ApprovalItem>
           <ApprovalItem item={item.value} type={route.query.type}></ApprovalItem>
           {item.value.leaveCategoryId == 1 ? (
           {item.value.leaveCategoryId == 1 ? (

+ 1 - 1
src/school/approval-manage/course-adjust.tsx

@@ -153,7 +153,7 @@ export default defineComponent({
     return () => (
     return () => (
       <>
       <>
         <div class={styles.courseWrap}>
         <div class={styles.courseWrap}>
-          <OHeader isBack={true} border={false}></OHeader>
+          <OHeader border={false}></OHeader>
           <div class={styles.courseInfo}>
           <div class={styles.courseInfo}>
             <CellGroup inset border={false}>
             <CellGroup inset border={false}>
               <Cell title="乐团名称" value={courseDetail.value.orchestraName} />
               <Cell title="乐团名称" value={courseDetail.value.orchestraName} />

+ 1 - 1
src/school/approval-manage/index.tsx

@@ -16,7 +16,7 @@ export default defineComponent({
     return () => (
     return () => (
       <>
       <>
         <OSticky position="top" background="#F8F8F8">
         <OSticky position="top" background="#F8F8F8">
-          <OHeader isBack={true}></OHeader>
+          <OHeader></OHeader>
           <Tabs v-model:active={activeName.value} class={styles.approvalTab}>
           <Tabs v-model:active={activeName.value} class={styles.approvalTab}>
             <Tab name="wait" title="待审批">
             <Tab name="wait" title="待审批">
               <WaitApproval></WaitApproval>
               <WaitApproval></WaitApproval>

+ 1 - 1
src/school/attendance/index.tsx

@@ -15,7 +15,7 @@ export default defineComponent({
     return () => (
     return () => (
       <>
       <>
         <OSticky position="top" background="#F8F8F8">
         <OSticky position="top" background="#F8F8F8">
-          <OHeader isBack={true}></OHeader>
+          <OHeader></OHeader>
           <Tabs v-model:active={activeName.value}>
           <Tabs v-model:active={activeName.value}>
             <Tab name="student" title="学生考勤"></Tab>
             <Tab name="student" title="学生考勤"></Tab>
             <Tab name="teacher" title="伴学指导考勤"></Tab>
             <Tab name="teacher" title="伴学指导考勤"></Tab>

+ 1 - 1
src/school/attendance/student-att-day.tsx

@@ -102,7 +102,7 @@ export default defineComponent({
     return () => (
     return () => (
       <>
       <>
         {/* </OSticky> */}
         {/* </OSticky> */}
-        <OHeader isBack={true}>
+        <OHeader>
           {{
           {{
             title: () => (
             title: () => (
               <div class={styles.NavTitle} onClick={() => (state.showPopoverTime = true)}>
               <div class={styles.NavTitle} onClick={() => (state.showPopoverTime = true)}>

+ 0 - 1
src/school/exercise-record/exercis-detail.tsx

@@ -133,7 +133,6 @@ export default defineComponent({
         <OSticky position="top" background="#F8F8F8">
         <OSticky position="top" background="#F8F8F8">
           <div class={styles.topWrap}>
           <div class={styles.topWrap}>
             <OHeader
             <OHeader
-              isBack={true}
               // onHeaderBack={onBack}
               // onHeaderBack={onBack}
               border={false}
               border={false}
               background={'transparent'}
               background={'transparent'}

+ 62 - 61
src/school/exercise-record/index.tsx

@@ -55,13 +55,12 @@ export default defineComponent({
       orchestraName: '全部乐团',
       orchestraName: '全部乐团',
       subjectId: '',
       subjectId: '',
       subjectName: '全部声部',
       subjectName: '全部声部',
-      sortType: '',
-      sortTypeName: '',
+      sortType: 'PRACTICE_DAY',
+      sortTypeName: '按天数',
       keyword: '',
       keyword: '',
       page: 1,
       page: 1,
       rows: 20
       rows: 20
     })
     })
-
     const minDate = ref(new Date(dayjs().subtract(10, 'year').format('YYYY-MM-DD')))
     const minDate = ref(new Date(dayjs().subtract(10, 'year').format('YYYY-MM-DD')))
     const maxDate = ref(new Date(dayjs().add(10, 'year').format('YYYY-MM-DD')))
     const maxDate = ref(new Date(dayjs().add(10, 'year').format('YYYY-MM-DD')))
     const columnsType = ref<DatePickerColumnType[]>(['year', 'month'])
     const columnsType = ref<DatePickerColumnType[]>(['year', 'month'])
@@ -197,69 +196,71 @@ export default defineComponent({
     return () => (
     return () => (
       <>
       <>
         <OSticky position="top" background="#F8F8F8">
         <OSticky position="top" background="#F8F8F8">
-          <OHeader isBack={true} onHeaderBack={onBack}></OHeader>
-          <OSearch
-            placeholder="请输入学生姓名"
-            onSearch={(val: any) => {
-              forms.keyword = val
-              refreshing.value = true
-              getList()
-            }}
-          ></OSearch>
-          <div class={styles.chioseWrap}>
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={styles.searchBand}
-                onClick={() => {
-                  state.showPopoverTime = true
-                }}
-              >
-                {forms.practiceMonthName}
-                <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
+          <div>
+            <OHeader onHeaderBack={onBack}></OHeader>
+            <OSearch
+              placeholder="请输入学生姓名"
+              onSearch={(val: any) => {
+                forms.keyword = val
+                refreshing.value = true
+                getList()
+              }}
+            ></OSearch>
+            <div class={styles.chioseWrap}>
+              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
+                <div
+                  class={styles.searchBand}
+                  onClick={() => {
+                    state.showPopoverTime = true
+                  }}
+                >
+                  {forms.practiceMonthName}
+                  <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
+                </div>
               </div>
               </div>
-            </div>
 
 
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={styles.searchBand}
-                onClick={() => {
-                  state.showPopoverOrchestra = true
-                }}
-              >
-                {forms.orchestraName}
-                <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
+              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
+                <div
+                  class={styles.searchBand}
+                  onClick={() => {
+                    state.showPopoverOrchestra = true
+                  }}
+                >
+                  {forms.orchestraName}
+                  <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
+                </div>
               </div>
               </div>
-            </div>
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={styles.searchBand}
-                onClick={() => {
-                  state.showPopoverSubject = true
-                }}
-              >
-                {forms.subjectName}
-                <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
+              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
+                <div
+                  class={styles.searchBand}
+                  onClick={() => {
+                    state.showPopoverSubject = true
+                  }}
+                >
+                  {forms.subjectName}
+                  <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
+                </div>
               </div>
               </div>
-            </div>
 
 
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <Popover
-                v-model:show={state.showPopoverSort}
-                actions={state.actionSorts}
-                showArrow={false}
-                placement="bottom-end"
-                offset={[0, 12]}
-                onSelect={checkSort}
-              >
-                {{
-                  reference: () => (
-                    <div class={styles.searchBand}>
-                      按天数
-                      <Icon name={state.showPopoverSort ? 'arrow-up' : 'arrow-down'} />
-                    </div>
-                  )
-                }}
-              </Popover>
+              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
+                <Popover
+                  v-model:show={state.showPopoverSort}
+                  actions={state.actionSorts}
+                  showArrow={false}
+                  placement="bottom-end"
+                  offset={[0, 12]}
+                  onSelect={checkSort}
+                >
+                  {{
+                    reference: () => (
+                      <div class={styles.searchBand}>
+                        按天数
+                        <Icon name={state.showPopoverSort ? 'arrow-up' : 'arrow-down'} />
+                      </div>
+                    )
+                  }}
+                </Popover>
+              </div>
             </div>
             </div>
           </div>
           </div>
         </OSticky>
         </OSticky>

+ 3 - 1
src/school/main.ts

@@ -10,8 +10,10 @@ import '../styles/index.less'
 import { state } from '@/state'
 import { state } from '@/state'
 import { browser } from '@/helpers/utils'
 import { browser } from '@/helpers/utils'
 
 
-const app = createApp(App)
+import vConsole from 'vconsole'
+new vConsole()
 
 
+const app = createApp(App)
 
 
 postMessage(
 postMessage(
   {
   {

+ 152 - 0
src/school/school-detail/eidt-school.tsx

@@ -0,0 +1,152 @@
+import OHeader from '@/components/o-header'
+import OSticky from '@/components/o-sticky'
+import { Form, Field, CellGroup, showToast, Icon, Popup, Picker, Button } from 'vant'
+import { defineComponent, reactive, ref, onMounted } from 'vue'
+import styles from './index.module.less'
+import { useRouter } from 'vue-router'
+import { state as globalState } from '@/state'
+import request from '@/helpers/request'
+import { areas } from '@/helpers/area'
+
+export default defineComponent({
+  name: 'school-detail',
+  setup() {
+    const router = useRouter()
+    const state = reactive({
+      list: [],
+      info: {} as any,
+      showArea: false,
+      columns: [] as any,
+      showProvince: ''
+    })
+    const forms = reactive({
+      provinceCode: '',
+      cityCode: '',
+      address: ''
+    })
+    const getSchoolDetail = async () => {
+      const schoolId = (globalState.user.data.schoolInfos || [])
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      try {
+        const { data } = await request.get(`/api-school/school/detail/${schoolId}`, {})
+        state.info = data
+        state.showProvince = data.provinceName + data.cityName
+        forms.provinceCode = data.provinceCode
+        forms.cityCode = data.cityCode
+        forms.address = data.address
+      } catch (e: any) {
+        showToast(e.message)
+      }
+    }
+
+    const submitInfo = async () => {
+      const schoolId = (globalState.user.data.schoolInfos || [])
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      if (!forms.cityCode || !forms.provinceCode) {
+        showToast('请选择省市')
+        return
+      }
+      if (!forms.address) {
+        showToast('请输入详细地址')
+        return
+      }
+      try {
+        const { data } = await request.post('/api-school/school/update', {
+          data: {
+            ...forms,
+            schoolId
+          }
+        })
+        showToast('修改成功')
+        setTimeout(() => {
+          router.push('/school-detail')
+        }, 500)
+      } catch (e: any) {
+        showToast(e.message)
+      }
+      console.log('submitInfo')
+    }
+    onMounted(() => {
+      getSchoolDetail()
+    })
+
+    const onConfirmArea = (val) => {
+      console.log(val)
+      state.showProvince = val.selectedOptions[0].name + val.selectedOptions[1].name
+      forms.provinceCode = val.selectedOptions[0].code
+      forms.cityCode = val.selectedOptions[1].code
+      state.showArea = false
+    }
+
+    onMounted(() => {
+      // console.log(areas)
+      const tempareas: any = []
+      areas.forEach((item) => {
+        const temp = {
+          name: item.name,
+          code: item.code,
+          areas: [] as any
+        }
+        if (item.areas && item.areas.length > 0) {
+          item.areas.forEach((child) => {
+            temp.areas.push({
+              name: child.name,
+              code: child.code
+            })
+          })
+        }
+        tempareas.push(temp)
+      })
+      state.columns = tempareas || []
+    })
+    return () => (
+      <>
+        <div class={styles.schoolEidtWrap}>
+          <OHeader></OHeader>
+          <div class={styles.eidtWrap}>
+            <CellGroup inset>
+              <Field
+                is-link
+                readonly
+                v-model={state.showProvince}
+                name="area"
+                label="地区选择"
+                placeholder="点击选择省市"
+                onClick={() => (state.showArea = true)}
+              ></Field>
+              <Field
+                type="textarea"
+                rows={3}
+                v-model={forms.address}
+                label="详细地址"
+                maxlength={50}
+                placeholder="小区楼栋/乡村名称"
+              ></Field>
+            </CellGroup>
+          </div>
+          <div class={styles.wall}></div>
+          <div class={styles.bottomWrap}>
+            <Button type="primary" size="large" onClick={submitInfo}>
+              确 认
+            </Button>
+          </div>
+          <Popup v-model:show={state.showArea} position="bottom">
+            <Picker
+              showToolbar
+              columnsFieldNames={{ text: 'name', value: 'code', children: 'areas' }}
+              onConfirm={onConfirmArea}
+              columns={state.columns}
+              onCancel={() => (state.showArea = false)}
+            ></Picker>
+          </Popup>
+        </div>
+      </>
+    )
+  }
+})

二进制
src/school/school-detail/images/logo.png


二进制
src/school/school-detail/images/school-bg.png


+ 106 - 0
src/school/school-detail/index.module.less

@@ -0,0 +1,106 @@
+.schoolWrap {
+  position: relative;
+  .schoolBg {
+    width: 100%;
+  }
+  .absWrap {
+    position: absolute;
+    width: calc(100% - 26px);
+    left: 13px;
+    top: 78px;
+    .schoolMainTitle {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      margin-bottom: 20px;
+      .schoolMainLeft {
+        width: 54px;
+        height: 54px;
+        overflow: hidden;
+        border-radius: 50%;
+        margin-right: 12px;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .schoolMainRight {
+        flex: 1;
+        .schoolMainTitle {
+          margin-bottom: 5px;
+          height: 25px;
+          font-size: 18px;
+          font-weight: 600;
+          color: #000000;
+          line-height: 25px;
+        }
+        .schoolMainSub {
+          font-size: 14px;
+          font-weight: 400;
+          color: #333333;
+          line-height: 20px;
+        }
+      }
+    }
+    .detailInfo {
+      padding: 15px;
+      background-color: #fff;
+      border-radius: 10px;
+      p {
+        margin-bottom: 15px;
+        font-size: 15px;
+        font-weight: 500;
+        color: #333333;
+        line-height: 21px;
+      }
+      // .eidtIcon {
+      // }
+    }
+  }
+  .teacherList {
+    margin: 0 13px 54px;
+    .teacherTitle {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      margin-bottom: 12px;
+      .dot {
+        width: 4px;
+        height: 12px;
+        background: #ff8057;
+        border-radius: 2px;
+        margin-right: 6px;
+      }
+      p {
+        font-size: 16px;
+        font-weight: 500;
+        color: #333333;
+        line-height: 22px;
+      }
+    }
+  }
+}
+.schoolEidtWrap {
+  .eidtWrap {
+    margin: 12px 0 12px;
+  }
+}
+.wall {
+  height: 44px;
+}
+.bottomWrap {
+  position: fixed;
+  width: 100%;
+  left: 0;
+  bottom: 60px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  :global {
+    .van-button {
+      line-height: 44px;
+      border-radius: 39px;
+      width: 325px;
+    }
+  }
+}

+ 105 - 0
src/school/school-detail/index.tsx

@@ -0,0 +1,105 @@
+import OHeader from '@/components/o-header'
+import OSticky from '@/components/o-sticky'
+import { Tabs, Tab, showToast, Icon } from 'vant'
+import { defineComponent, reactive, ref, onMounted } from 'vue'
+import styles from './index.module.less'
+import schoolBg from './images/school-bg.png'
+import logoIcon from './images/logo.png'
+import { useRouter } from 'vue-router'
+import { state as globalState } from '@/state'
+import TeacherItem from './modals/teacher-item'
+import { schoolSystem } from '@/constant/index'
+import request from '@/helpers/request'
+
+export default defineComponent({
+  name: 'school-detail',
+  setup() {
+    const router = useRouter()
+    const state = reactive({
+      list: [],
+      info: {} as any
+    })
+    const getSchoolDetail = async () => {
+      const schoolId = (globalState.user.data.schoolInfos || [])
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      try {
+        const { data } = await request.get(`/api-school/school/detail/${schoolId}`, {})
+        state.info = data
+      } catch (e: any) {
+        showToast(e.message)
+      }
+    }
+    const gotoEidt = () => {
+      // /school-eidt
+      router.push({ path: '/school-eidt' })
+    }
+    const getTeacherList = async () => {
+      const schoolId = (globalState.user.data.schoolInfos || [])
+        .map((item) => {
+          return item.id
+        })
+        .join(',')
+      try {
+        const { data } = await request.post(`/api-school/teacher/page`, {
+          data: {
+            schoolId,
+            page: 1,
+            rows: 9999
+          }
+        })
+        state.list = data.rows
+      } catch (e: any) {
+        showToast(e.message)
+      }
+    }
+    onMounted(() => {
+      getSchoolDetail()
+      getTeacherList()
+    })
+    return () => (
+      <>
+        <div class={styles.schoolWrap}>
+          <img src={schoolBg} class={styles.schoolBg} alt="" />
+          <OHeader border={false} background={'transparent'}></OHeader>
+          <div class={styles.absWrap}>
+            <div class={styles.schoolMainTitle}>
+              <div class={styles.schoolMainLeft}>
+                <img src={state.info.logo ? state.info.logo : logoIcon} alt="" />
+              </div>
+              <div class={styles.schoolMainRight}>
+                <p class={styles.schoolMainTitle}>{state.info.name}</p>
+                <p class={styles.schoolMainSub}>
+                  {state.info.provinceName}
+                  {state.info.cityName}
+                </p>
+              </div>
+            </div>
+            <div class={styles.detailInfo}>
+              <p onClick={gotoEidt}>
+                地址:{state.info.address} <Icon class={styles.eidtIcon} name="edit"></Icon>
+              </p>
+              <p>学年制:{schoolSystem[state.info.schoolSystem]} </p>
+              <p>邮箱:{state.info.email}</p>
+              <p>管理老师:{state.info.educationalAdministrationUsername}</p>
+              <p>负责人:{state.info.emergencyContactPosition}</p>
+            </div>
+          </div>
+          <div class={styles.teacherList}>
+            <h2 class={styles.teacherTitle}>
+              <div class={styles.dot}></div>
+              <p>伴学指导</p>
+            </h2>
+            <div>
+              {state.list.map((item) => (
+                <TeacherItem item={item}></TeacherItem>
+              ))}
+            </div>
+          </div>
+        </div>
+      </>
+    )
+  }
+})

+ 72 - 0
src/school/school-detail/modals/teacher-item.module.less

@@ -0,0 +1,72 @@
+.itemWrap {
+  background-color: #ffffff;
+  padding: 18px 0px 0 13px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  &:nth-last-child(1) {
+    .itemRight {
+      border-bottom: none !important;
+    }
+  }
+  .itemLeft {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-bottom: 18px;
+    .headerWrap {
+      width: 48px;
+      height: 48px;
+      border-radius: 50%;
+      margin-right: 10px;
+      overflow: hidden;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+  .itemRight {
+    height: 48px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    border-bottom: 1px solid #f2f2f2;
+    padding-bottom: 18px;
+    padding-right: 13px;
+    width: 302px;
+
+    .infoWrap {
+      p {
+        font-size: 16px;
+        font-weight: 500;
+        color: #333333;
+        line-height: 22px;
+      }
+      .statusTagWrap {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-top: 1px;
+        .statusTag {
+          font-size: 12px;
+          font-family: PingFangSC-Medium, PingFang SC;
+          font-weight: 500;
+          color: #f67146;
+          line-height: 17px;
+          padding: 0 8px;
+          margin-right: 6px;
+          margin-bottom: 6px;
+          background: #ffe7da;
+          border-radius: 4px;
+        }
+      }
+    }
+    .msgIcon {
+      width: 24px;
+      height: 24px;
+    }
+  }
+}

+ 53 - 0
src/school/school-detail/modals/teacher-item.tsx

@@ -0,0 +1,53 @@
+import { defineComponent, reactive, ref } from 'vue'
+import styles from './teacher-item.module.less'
+import { Icon, ActionSheet, showToast } from 'vant'
+import { useRouter } from 'vue-router'
+import defaultIcon from '@/school/images/default-icon.jpg'
+import msgIcon from '@/school/images/msg-icon.png'
+import { postMessage } from '@/helpers/native-message'
+import { attType } from '@/constant'
+
+export default defineComponent({
+  props: ['item'],
+  name: 'teacher-item',
+  setup(props) {
+    const router = useRouter()
+    const gotoMsg = async () => {
+      try {
+        await postMessage({
+          api: 'joinChatGroup',
+          content: {
+            type: 'single', // single 单人 multi 多人
+            id: props.item.imUserId
+          }
+        })
+      } catch (e) {
+        showToast('发起聊天失败')
+      }
+    }
+    console.log(props.item)
+    return () => (
+      <>
+        <div class={styles.itemWrap} onClick={gotoMsg}>
+          <div class={styles.itemLeft}>
+            <div class={styles.headerWrap}>
+              <img src={props.item.studentAvatar ? props.item.studentAvatar : defaultIcon} alt="" />
+            </div>
+          </div>
+          <div class={styles.itemRight}>
+            <div class={styles.infoWrap}>
+              <p>{props.item.nickname}</p>
+
+              <div class={styles.statusTagWrap}>
+                {props.item.subjectName.split(',').map((item) => (
+                  <div class={styles.statusTag}>{item}</div>
+                ))}
+              </div>
+            </div>
+            <img class={styles.msgIcon} src={msgIcon} alt="" />
+          </div>
+        </div>
+      </>
+    )
+  }
+})