Browse Source

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

mo 2 years ago
parent
commit
b1d7578dec
50 changed files with 637 additions and 435 deletions
  1. 5 4
      public/project/css/initiation.css
  2. 6 4
      public/project/css/preRegister.css
  3. 1 1
      public/project/initiation.html
  4. 5 0
      src/components/o-empty/index.module.less
  5. 8 0
      src/router/routes-school.ts
  6. 3 1
      src/school/approval-manage/agency/index.tsx
  7. 1 1
      src/school/approval-manage/components/end-approval.tsx
  8. 5 3
      src/school/approval-manage/components/wait-approval.tsx
  9. 8 6
      src/school/approval-manage/index.module.less
  10. 8 2
      src/school/approval-manage/index.tsx
  11. 102 75
      src/school/approval-manage/subsidy/details.tsx
  12. 15 32
      src/school/approval-manage/subsidy/exercise-detail.tsx
  13. 17 11
      src/school/approval-manage/subsidy/index.tsx
  14. 10 0
      src/school/approval-manage/subsidy/subsidyTypes.ts
  15. 62 57
      src/school/attendance/components/attend-student.tsx
  16. 74 68
      src/school/attendance/components/attend-teacher.tsx
  17. 5 0
      src/school/attendance/components/attent-student.module.less
  18. 12 6
      src/school/attendance/index.tsx
  19. 3 1
      src/school/companion-teacher/companion-teacher-register.tsx
  20. 21 15
      src/school/mass-message/component/class-list/index.tsx
  21. 8 8
      src/school/mass-message/create-message.tsx
  22. 4 0
      src/school/orchestra-story/story-operation/index.module.less
  23. 13 3
      src/school/orchestra-story/story-operation/index.tsx
  24. 1 1
      src/school/orchestra/orchestra-information.tsx
  25. 1 1
      src/school/train-planning/modal/class-list/index.module.less
  26. 2 3
      src/school/train-planning/modal/class-list/index.tsx
  27. 1 1
      src/student/music-group/pre-apply/component/apply.tsx
  28. 10 6
      src/student/music-group/pre-apply/order-detail.tsx
  29. 1 1
      src/views/adapay/pay-result/index.module.less
  30. 3 3
      src/views/adapay/pay-result/index.tsx
  31. 0 1
      src/views/attendance-rule/index.tsx
  32. 12 9
      src/views/mine-orchestra/photo-list/detail.tsx
  33. 4 3
      src/views/mine-orchestra/photo-list/index.module.less
  34. 9 1
      src/views/unit-test/examination-mode/index.tsx
  35. 82 75
      src/views/unit-test/index.tsx
  36. 6 1
      src/views/unit-test/model/answer-list/index.tsx
  37. 3 1
      src/views/unit-test/model/choice-question/index.tsx
  38. 1 0
      src/views/unit-test/model/drag-question/index.module.less
  39. 12 8
      src/views/unit-test/model/drag-question/index.tsx
  40. 5 3
      src/views/unit-test/model/play-question/index.tsx
  41. 4 0
      src/views/unit-test/model/unit-audio/index.tsx
  42. 15 3
      src/views/unit-test/practice-mode/index.tsx
  43. 3 0
      src/views/unit-test/test-exercise/index.tsx
  44. 4 0
      src/views/unit-test/unit-create/index.module.less
  45. 15 7
      src/views/unit-test/unit-create/index.tsx
  46. 1 1
      src/views/unit-test/unit-create/modals/newspaper-item.tsx
  47. 5 2
      src/views/unit-test/unit-create/uni-last.tsx
  48. 26 4
      src/views/unit-test/unit-detail/index.tsx
  49. 1 1
      src/views/unit-test/unit-list/index.module.less
  50. 14 1
      src/views/unit-test/unit-list/index.tsx

+ 5 - 4
public/project/css/initiation.css

@@ -72,7 +72,7 @@ span {
 }
 
 .van-form {
-  margin-top: 164px;
+  /* margin-top: 164px; */
   background: linear-gradient(180deg, rgba(255, 239, 216, 0) 0%, #ffdab0 100%);
   overflow: hidden;
 }
@@ -91,14 +91,15 @@ span {
 
 .title {
   text-shadow: 0px 2px 3px rgba(255, 96, 0, 0.5);
-  position: absolute;
   font-size: 26px;
   line-height: 37px;
   color: #ffffff;
-  top: 0;
-  left: 24px;
+  /* top: 0; */
+  /* left: 24px; */
   width: 57%;
+  padding-left: 24px;
   height: 154px;
+  margin-bottom: 10px;
   display: flex;
   justify-content: center;
   align-items: center;

+ 6 - 4
public/project/css/preRegister.css

@@ -72,7 +72,7 @@ span {
 }
 
 .van-form {
-  margin-top: 164px;
+  /* margin-top: 164px; */
   background: linear-gradient(180deg, rgba(238, 225, 255, 0) 0%, #EEE1FF 100%);
   overflow: hidden;
 }
@@ -91,14 +91,16 @@ span {
 
 .title {
   text-shadow: 0px 2px 3px #704CA7;
-  position: absolute;
+  /* position: absolute; */
   font-size: 26px;
   line-height: 37px;
   color: #ffffff;
-  top: 0;
-  left: 24px;
+  /* top: 0; */
+  /* left: 24px; */
   width: 57%;
+  padding-left: 24px;
   height: 154px;
+  margin-bottom: 10px;
   display: flex;
   justify-content: center;
   align-items: center;

+ 1 - 1
public/project/initiation.html

@@ -240,7 +240,7 @@
           </template>
         </van-field>
         <van-field label="所学乐器" v-if="stu.hasLearningExperience==1" name="learningSubjectName"
-          v-model="stu.learningSubjectName" placeholder="(非必填)请选择所学乐器"></van-field>
+          v-model="stu.learningSubjectName" placeholder="(非必填)请输入所学乐器"></van-field>
         <van-field label="是否报名参加管乐团家长会了解相关情况" name="joinParentMeeting"
           :rules="[{ required: true, message: '请选择是否报名参加管乐团家长会了解相关情况' }]">
           <template #input>

+ 5 - 0
src/components/o-empty/index.module.less

@@ -2,6 +2,11 @@
   padding: 14px;
   text-align: center;
   margin: 0 auto;
+  box-sizing: border-box;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
   .tips {
     font-size: 14px;
     color: #333;

+ 8 - 0
src/router/routes-school.ts

@@ -319,6 +319,14 @@ export default [
         }
       },
       {
+        path: '/subsidy-exercise-details',
+        name: 'subsidy-exercise-details',
+        component: () => import('@/school/approval-manage/subsidy/details'),
+        meta: {
+          title: '补助明细'
+        }
+      },
+      {
         path: '/subsidy-grant-detail',
         name: 'subsidy-grant-detail',
         component: () => import('@/school/approval-manage/subsidy/grant-detail'),

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

@@ -9,6 +9,7 @@ import { state } from '@/state'
 import OFullRefresh from '@/components/o-full-refresh'
 import OEmpty from '@/components/o-empty'
 import { useRouter } from 'vue-router'
+import { approvalManageStrips } from '..'
 
 interface ISalaryRecord {
   /**学校补助确认记录ID */
@@ -85,6 +86,7 @@ export default defineComponent({
               endDate: n?.endDate?.split(' ')[0] || ''
             }
           })
+          approvalManageStrips.agencty = data.salaryRecordList.length
         }
         data.schoolWeekPhoto = res?.data?.schoolWeekPhoto || {}
         data.schoolWeekNews = res?.data?.schoolWeekNews || {}
@@ -125,7 +127,7 @@ export default defineComponent({
                         center
                         label={`${item.startDate} 至 ${item.endDate}`}
                         isLink
-                        to={'/approval-manage-subsidy?salaryId=' + (item.id || '')}
+                        to={'/approval-manage-subsidy?display=1&salaryId=' + (item.id || '')}
                       >
                         {{
                           title: () => (

+ 1 - 1
src/school/approval-manage/components/end-approval.tsx

@@ -69,7 +69,7 @@ export default defineComponent({
           loading={loading.value}
           loading-text=" "
           finished={finished.value}
-          finished-text="没有更多了"
+          finished-text=" "
           onLoad={getList}
         >
           <TransitionGroup name="van-fade">

+ 5 - 3
src/school/approval-manage/components/wait-approval.tsx

@@ -7,13 +7,14 @@ import { useRouter } from 'vue-router'
 import styles from './wait-approval.module.less'
 import request from '@/helpers/request'
 import ApprovalItem from './approval-item'
+import { approvalManageStrips } from '..'
 export default defineComponent({
   name: 'wait-approval',
-  setup() {
+  setup(props, { emit }) {
     const router = useRouter()
     const forms = reactive({
       page: 1,
-      rows: 20
+      rows: 1000
     })
 
     const refreshing = ref(false)
@@ -39,6 +40,7 @@ export default defineComponent({
           forms.page = res.data.current + 1
           list.value = list.value.concat(res.data.rows || [])
           finished.value = !res.data.next
+          approvalManageStrips.approval = list.value.length
         } else {
           finished.value = false
         }
@@ -68,7 +70,7 @@ export default defineComponent({
         <List
           loading={loading.value}
           finished={finished.value}
-          finished-text="没有更多了"
+          finished-text=" "
           loading-text=" "
           onLoad={getList}
         >

+ 8 - 6
src/school/approval-manage/index.module.less

@@ -36,7 +36,7 @@
     }
   }
 }
-.wrap{
+.wrap {
   padding: 12px 0;
   box-sizing: border-box;
 }
@@ -108,8 +108,8 @@
 }
 .tipItem {
   margin: 0;
-  :global{
-    .van-cell{
+  :global {
+    .van-cell {
       padding: 25px 25px 20px 25px;
     }
   }
@@ -169,13 +169,15 @@
     font-size: 16px;
     color: #333;
     padding-bottom: 6px;
+    line-height: 22px;
   }
   .itemContentTitleDetail {
     font-size: 14px;
   }
   .itemContentLabel {
-    font-size: 14px;
+    font-size: 12px;
     color: #777;
+    line-height: 20px;
   }
 }
 
@@ -229,7 +231,7 @@
     margin-left: 5px;
   }
 }
-.confirmBtn{
+.confirmBtn {
   position: fixed;
   left: 0;
   bottom: 0;
@@ -237,4 +239,4 @@
   padding: 15px 25px;
   background: #fff;
   z-index: 10;
-}
+}

+ 8 - 2
src/school/approval-manage/index.tsx

@@ -8,11 +8,16 @@ import OSticky from '@/components/o-sticky'
 import OHeader from '@/components/o-header'
 import { state } from '@/state'
 const activeName = ref('wait')
+export const approvalManageStrips = reactive({
+  agencty: 0,
+  approval: 0
+})
 export default defineComponent({
   name: 'approval-manage',
   setup() {
     const router = useRouter()
     const headerHeight = ref(0)
+    
     return () => (
       <div>
         <OSticky
@@ -30,13 +35,14 @@ export default defineComponent({
           sticky
           offsetTop={headerHeight.value}
           swipeable
+          titleActiveColor='var(--van-primary)'
         >
           {state.user?.data?.manageAdmin && (
-            <Tab name="wait" title="处理事项">
+            <Tab name="wait" title={`处理事项${approvalManageStrips.agencty ? " (" + approvalManageStrips.agencty +")" : ''}`}>
               <Agency />
             </Tab>
           )}
-          <Tab name="end" title="我的审批">
+          <Tab name="end" title={`我的审批${approvalManageStrips.approval ? " (" + approvalManageStrips.approval +")" : ''}`}>
             <MyApproval />
           </Tab>
         </Tabs>

+ 102 - 75
src/school/approval-manage/subsidy/details.tsx

@@ -1,93 +1,120 @@
 import { Cell, Grid, GridItem } from 'vant'
-import { defineComponent, PropType } from 'vue'
+import { defineComponent, onMounted, PropType } from 'vue'
 import styles from '../index.module.less'
 import iconA from '../images/icon-photo.png'
 import iconTime from '../images/icon-time.png'
 import iconPrimary from '../images/icon-primary.png'
 import iconError from '../images/icon-error.png'
-import {courseEmnu} from '@/constant'
+import { courseEmnu } from '@/constant'
+import { courseSalaryRecordDetailItem } from './exercise-detail'
+import OSticky from '@/components/o-sticky'
+import OHeader from '@/components/o-header'
+import OEmpty from '@/components/o-empty'
+import dayjs from 'dayjs'
+import { getSecondRPM } from '@/helpers/utils'
 
 export default defineComponent({
   name: 'subsidy-detail',
-  props: {
-    item: {
-      type: Object,
-      default: () => {}
+  setup() {
+    const record: ICourseSalaryRecordDetailItem = courseSalaryRecordDetailItem.value! || ''
+    if (Array.isArray(record?.courseScheduleTeacherAttendanceList)) {
+      record.courseScheduleTeacherAttendanceList.forEach((n: any) => {
+        n.times =
+          (n?.startTime ? dayjs(n.startTime).format('YYYY-MM-DD HH:mm') : '') +
+          ' ~ ' +
+          (n?.endTime ? dayjs(n.endTime).format('HH:mm') : '')
+        n.signInTime = n?.signInTime?.split(' ')[1]
+        n.signOutTime = n?.signOutTime?.split(' ')[1]
+      })
     }
-  },
-  setup(props) {
-    console.log("🚀 ~ props", props)
-    const item = (props?.item || {}) as ICourseSalaryRecordDetailItem
     return () => (
-      <div class={styles.wrap}>
-        <div class={[styles.item, styles.listItem]}>
-          <Cell border={false} center class={styles.listItem} title="补助标准" value={`${item.standardSalary}元/天`} />
-          <Cell
-            border={false}
-            center
-            class={styles.listItem}
-            title="补助课程"
-            value={courseEmnu[item.courseType]}
-          />
-          <Cell
-            border={false}
-            center
-            class={styles.listItem}
-            title="课件使用未达标"
-            value={`-${item.reduceSalary}元`}
-          />
-          <Cell border={false} center class={styles.listItem} title="早退" value={`-0.00元`} />
-          <Cell
-            border={false}
-            center
-            class={styles.listItem}
-            title="实际补助金额"
-            value={`${item.actualSalary}元`}
-          />
-        </div>
+      <div>
+        <OSticky>
+          <OHeader />
+        </OSticky>
+        {!!record && (
+          <div class={styles.wrap}>
+            <div class={[styles.item, styles.listItem]}>
+              <Cell
+                border={false}
+                center
+                class={styles.listItem}
+                title="补助标准"
+                value={`${record.standardSalary}元/天`}
+              />
+              <Cell
+                border={false}
+                center
+                class={styles.listItem}
+                title="补助课程"
+                value={courseEmnu[record.courseType]}
+              />
+              <Cell
+                border={false}
+                center
+                class={styles.listItem}
+                title="课件使用未达标"
+                value={`-${record.reduceSalary}元`}
+              />
+              <Cell border={false} center class={styles.listItem} title="早退" value={`-0.00元`} />
+              <Cell
+                border={false}
+                center
+                class={styles.listItem}
+                title="实际补助金额"
+                value={`${record.actualSalary}元`}
+              />
+            </div>
 
-        {item?.courseScheduleTeacherAttendanceList.map((item: ICourseScheduleTeacherAttendance) => (
-          <div class={styles.item}>
-            <Cell center>
-              {{
-                title: () => (
-                  <div class={styles.itemTitle}>
-                    <img class={styles.titleIcon} src={iconTime} />
-                    <span>{item.startTime} - {item.endTime}</span>
-                  </div>
-                )
-              }}
-            </Cell>
-            <div class={styles.itemContent}>
-              <div class={styles.itemContentTitle}>
-                <span>{item.classGroupName}-{item.teacherName}</span>
-                <span
-                  class={styles.itemContentTitleDetail}
-                  style={{ color: 1 ? '#358AF5' : '#F44541' }}
-                >
-                  课件使用:15/20分钟
-                </span>
-              </div>
-              <div class={styles.itemContentLabel}>{item.orchestraName}</div>
-              <div class={styles.times}>
-                <div class={[styles.timesItem, styles.startTime]}>
-                  <div class={styles.startTimeTop}>
-                    <span>签到时间</span>
-                    <img src={item.signInStatus === 'NORMAL' ? iconPrimary : iconError} />
+            {record?.courseScheduleTeacherAttendanceList?.map(
+              (item: ICourseScheduleTeacherAttendance) => (
+                <div class={styles.item}>
+                  <Cell center>
+                    {{
+                      title: () => (
+                        <div class={styles.itemTitle}>
+                          <img class={styles.titleIcon} src={iconTime} />
+                          <span>{item.times}</span>
+                        </div>
+                      )
+                    }}
+                  </Cell>
+                  <div class={styles.itemContent}>
+                    <div class={styles.itemContentTitle}>
+                      <span>
+                        {item.classGroupName}-{item.teacherName}
+                      </span>
+                      <span
+                        class={styles.itemContentTitleDetail}
+                        style={{ color: 1 ? '#358AF5' : '#F44541' }}
+                      >
+                        课件使用:{getSecondRPM(item.coursewarePlayTime)}/{getSecondRPM(item.adviseStudyTimeSecond)}分钟
+                      </span>
+                    </div>
+                    <div class={styles.itemContentLabel}>{item.orchestraName}</div>
+                    <div class={styles.times}>
+                      <div class={[styles.timesItem, styles.startTime]}>
+                        <div class={styles.startTimeTop}>
+                          <span>签到时间</span>
+                          <img src={item.signInStatus === 'NORMAL' ? iconPrimary : iconError} />
+                        </div>
+                        <div class={styles.startTimeBottom}>{item.signInTime}</div>
+                      </div>
+                      <div class={[styles.timesItem, styles.endTime]}>
+                        <div class={styles.startTimeTop}>
+                          <span>签退时间</span>
+                          <img src={item.signOutStatus === 'NORMAL' ? iconPrimary : iconError} />
+                        </div>
+                        <div class={styles.startTimeBottom}>{item.signOutTime}</div>
+                      </div>
+                    </div>
                   </div>
-                  <div class={styles.startTimeBottom}>{item.signInTime}</div>
                 </div>
-                <div class={[styles.timesItem, styles.endTime]}>
-                  <div class={styles.startTimeTop}>
-                    <span>签退时间</span>
-                    <img src={item.signOutStatus === 'NORMAL' ?iconPrimary : iconError} />
-                  </div>
-                  <div class={styles.startTimeBottom}>{item.signOutTime}</div>
-                </div>
-              </div>
-            </div>
+              )
+            )}
           </div>
-        ))}
+        )}
+        {!record && <OEmpty tips="暂无明细" />}
       </div>
     )
   }

+ 15 - 32
src/school/approval-manage/subsidy/exercise-detail.tsx

@@ -2,7 +2,7 @@ import { Cell, Grid, GridItem, NavBar, Popup, Sticky } from 'vant'
 import { defineComponent, onMounted, reactive, ref } from 'vue'
 import styles from '../index.module.less'
 import iconA from '../images/icon-photo.png'
-import { useRoute } from 'vue-router'
+import { useRoute, useRouter } from 'vue-router'
 import request from '@/helpers/request'
 import { state } from '@/state'
 import OFullRefresh from '@/components/o-full-refresh'
@@ -10,10 +10,13 @@ import Details from './details'
 import OHeader from '@/components/o-header'
 import OSticky from '@/components/o-sticky'
 
+export const courseSalaryRecordDetailItem = ref<ICourseSalaryRecordDetailItem>()
+
 export default defineComponent({
   name: 'subsidy-exercise-detail',
   setup() {
     const route = useRoute()
+    const router = useRouter()
     const refreshing = ref(false)
     const modelData = reactive({
       show: false,
@@ -22,6 +25,8 @@ export default defineComponent({
     const data = reactive({
       /**补助明细 */
       record: {
+        userName: '',
+        avatar: '',
         courseSalaryRecordDetailList: [] as ICourseSalaryRecordDetailItem[]
       } as ICourseSalaryRecordDetail
     })
@@ -29,9 +34,9 @@ export default defineComponent({
       request
         .post(`${state.platformApi}/schoolWeekSalaryRecord/detailInfo/course`, {
           data: {
-            id: route.query.id,
-            userId: state.user.data.id
-          }
+            ...route.query
+          },
+          hideLoading: refreshing.value
         })
         .then((res: any) => {
           data.record = res?.data || {}
@@ -61,10 +66,10 @@ export default defineComponent({
             <div class={styles.item}>
               <Cell center class={styles.rewardItem}>
                 {{
-                  icon: () => <img class={styles.itemPicture} src={iconA} />,
+                  icon: () => <img class={styles.itemPicture} src={data.record.avatar || iconA} />,
                   title: () => (
                     <div class={styles.itemTitle}>
-                      <span>邓同学</span>
+                      <span>{data.record.userName}</span>
                     </div>
                   ),
                   value: () => (
@@ -86,8 +91,10 @@ export default defineComponent({
                   value={`${item.days}天`}
                   isLink
                   onClick={() => {
-                    modelData.show = true
-                    modelData.row = item
+                    courseSalaryRecordDetailItem.value = item
+                    router.push({
+                      path: '/subsidy-exercise-details'
+                    })
                   }}
                 >
                   {{
@@ -129,30 +136,6 @@ export default defineComponent({
             ))}
           </div>
         </OFullRefresh>
-        <Popup
-          v-model:show={modelData.show}
-          position="bottom"
-          closeable
-          style={{
-            width: '100vw',
-            height: '80vh',
-            '--van-popup-background': 'rgba(246,246,246,1)',
-            '--van-nav-bar-icon-color': '#333',
-            '--van-popup-close-icon-margin':
-              'calc(var(--van-nav-bar-height) / 2 - var(--van-popup-close-icon-size) / 2)'
-          }}
-        >
-          <NavBar title="补助明细" />
-          <div
-            style={{
-              height: 'calc(80vh - var(--van-nav-bar-height))',
-              overflow: 'hidden',
-              'overflow-y': 'auto'
-            }}
-          >
-            <Details item={modelData.row || {}} />
-          </div>
-        </Popup>
       </div>
     )
   }

+ 17 - 11
src/school/approval-manage/subsidy/index.tsx

@@ -17,12 +17,13 @@ export default defineComponent({
     const router = useRouter()
     const dialog = ref(false)
     const refreshing = ref(false)
+    const recordId = ref('')
     const data = reactive({
       startDate: '',
       endDate: '',
       manageSalary: '',
       courseSalary: '',
-      practiceSalary: '',
+      trainingSalary: '',
       /**管理补助 */
       manageSalaryInfo: {} as any,
       /**训练补助 */
@@ -47,7 +48,8 @@ export default defineComponent({
             endDate = '',
             manageSalary,
             courseSalary,
-            practiceSalary
+            trainingSalary,
+            id
           } = res.data
           data.courseSalaryInfo = courseSalaryInfo
           data.manageSalaryInfo = manageSalaryInfo
@@ -56,7 +58,8 @@ export default defineComponent({
           data.endDate = endDate?.split(' ')[0] || ''
           data.manageSalary = manageSalary
           data.courseSalary = courseSalary
-          data.practiceSalary = practiceSalary
+          data.trainingSalary = trainingSalary
+          recordId.value = id
         }
       } catch (error) {}
       refreshing.value = false
@@ -85,6 +88,7 @@ export default defineComponent({
             class={styles.rightTip}
             rightText="?"
             onClickRight={() => (dialog.value = true)}
+            title={route.query.display ? '补助详情' : '补助确认'}
           ></OHeader>
         </OSticky>
         <OFullRefresh
@@ -127,7 +131,7 @@ export default defineComponent({
                   <GridItem>
                     <div class={styles.gridItem}>
                       <div class={styles.gridItemTop}>
-                        <span class={styles.topNum}>{data.practiceSalary || 0}</span>元
+                        <span class={styles.topNum}>{data.trainingSalary || 0}</span>元
                       </div>
                       <div>练习奖励</div>
                     </div>
@@ -293,7 +297,7 @@ export default defineComponent({
                       center
                       title={teacher.userName}
                       isLink
-                      to={'/subsidy-exercise-detail?id=' + teacher.id}
+                      to={`/subsidy-exercise-detail?id=${recordId.value}&userId=${teacher.userId}`}
                     >
                       {{
                         icon: () => (
@@ -318,13 +322,15 @@ export default defineComponent({
             </div>
           </div>
         </OFullRefresh>
-        <div class={styles.confirmBtn}>
-          <div class="van-safe-area-bottom">
-            <Button block type="primary" round onClick={sendConfirm}>
-              确认无误
-            </Button>
+        {route.query.display && (
+          <div class={styles.confirmBtn}>
+            <div class="van-safe-area-bottom">
+              <Button block type="primary" round onClick={sendConfirm}>
+                确认无误
+              </Button>
+            </div>
           </div>
-        </div>
+        )}
         <Dialog v-model:show={dialog.value} confirmButtonText="我知道了">
           <div class={[styles.item, styles.tipItem]}>
             <Cell center border={false}>

+ 10 - 0
src/school/approval-manage/subsidy/subsidyTypes.ts

@@ -156,6 +156,10 @@ interface ICourseSalaryRecordDetail {
   actualSalary: number
   /**预计补助金额 */
   expectSalary: number
+  /**老师名字 */
+  userName: string
+  /**老师头像 */
+  avatar: string
 }
 /**课程补助详情数据集合 */
 interface ICourseSalaryRecordDetailItem {
@@ -189,6 +193,12 @@ interface ICourseSalaryRecordDetailItem {
 }
 /**伴学指导签到 */
 interface ICourseScheduleTeacherAttendance {
+  /** 播放时长 */
+  coursewarePlayTime: number
+  /**建议学习时长 */
+  adviseStudyTimeSecond: number
+  /**上课时间 */
+  times: string
   /**老师名称 */
   teacherName: string
   /**乐团名称 */

+ 62 - 57
src/school/attendance/components/attend-student.tsx

@@ -174,73 +174,78 @@ export default defineComponent({
     }
     return () => (
       <div
-        class={!showContact.value && 'emptyRootContainer'}
-        style={{ minHeight: `calc(100vh - ${toTop.value}px)` }}
+
+      // style={{ minHeight: `calc(100vh - ${toTop.value}px)` }}
       >
-        {/* <OSticky position="top" background="#F8F8F8"> */}
-        <Sticky offsetTop={toTop.value} style={{ width: '100%' }}>
-          <div class={styles.chioseWrap}>
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={[styles.searchBand, styles.orchestraBand]}
-                onClick={() => {
-                  state.showPopoverTime = true
-                }}
-              >
-                <p> {forms.timeName} </p>
-                <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
-              </div>
+        {/* <Sticky offsetTop={toTop.value} style={{ width: '100%' }}> */}
+        <div class={styles.chioseWrap}>
+          <div style={{ background: '#F8F8F8' }}>
+            <div
+              class={[styles.searchBand, styles.orchestraBand]}
+              onClick={() => {
+                state.showPopoverTime = true
+              }}
+            >
+              <p> {forms.timeName} </p>
+              <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
             </div>
+          </div>
 
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={[styles.searchBand, styles.orchestraBand]}
-                onClick={() => {
-                  state.showPopoverOrchestra = true
-                }}
-              >
-                <p> {forms.orchestraName}</p>
+          <div style={{ background: '#F8F8F8' }}>
+            <div
+              class={[styles.searchBand, styles.orchestraBand]}
+              onClick={() => {
+                state.showPopoverOrchestra = true
+              }}
+            >
+              <p> {forms.orchestraName}</p>
 
-                <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
-              </div>
+              <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
             </div>
-            <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-              <div
-                class={[styles.searchBand, styles.orchestraBand]}
-                onClick={() => {
-                  state.showPopoverSubject = true
-                }}
-              >
-                <p> {forms.subjectName}</p>
+          </div>
+          <div style={{ background: '#F8F8F8' }}>
+            <div
+              class={[styles.searchBand, styles.orchestraBand]}
+              onClick={() => {
+                state.showPopoverSubject = true
+              }}
+            >
+              <p> {forms.subjectName}</p>
 
-                <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
-              </div>
+              <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
             </div>
           </div>
-        </Sticky>
-        {/* </OSticky> */}
+        </div>
+        {/* </Sticky> */}
 
-        {showContact.value ? (
-          <OFullRefresh
-            v-model:modelValue={refreshing.value}
-            onRefresh={onRefresh}
-            style="min-height: 100vh;"
-          >
-            <List
-              loading-text=" "
-              // v-model:loading={loading.value}
-              finished={finished.value}
-              finished-text="没有更多了"
-              onLoad={getList}
+        <div
+          style={{
+            overflowY: 'auto',
+            height: 'calc(100vh - var(--van-tabs-line-height) - var(--header-height) - 1.01333rem)'
+          }}
+        >
+          {showContact.value ? (
+            <OFullRefresh
+              v-model:modelValue={refreshing.value}
+              onRefresh={onRefresh}
+              style="min-height: calc(100vh - var(--van-tabs-line-height) - var(--header-height) - 1.01333rem);"
             >
-              {list.value.map((item: any) => (
-                <StudentAttItem item={item}></StudentAttItem>
-              ))}
-            </List>
-          </OFullRefresh>
-        ) : (
-          <OEmpty tips="暂无考勤"></OEmpty>
-        )}
+              <List
+                loading-text=" "
+                // v-model:loading={loading.value}
+                finished={finished.value}
+                finished-text=" "
+                onLoad={getList}
+              >
+                {list.value.map((item: any) => (
+                  <StudentAttItem item={item}></StudentAttItem>
+                ))}
+              </List>
+            </OFullRefresh>
+          ) : (
+            <OEmpty tips="暂无考勤"></OEmpty>
+          )}
+        </div>
 
         <Popup v-model:show={state.showPopoverTime} position="bottom" style="{ height: '30%' }">
           <DatePicker

+ 74 - 68
src/school/attendance/components/attend-teacher.tsx

@@ -165,86 +165,92 @@ export default defineComponent({
     }
     return () => (
       <div
-        class={!showContact.value && 'emptyRootContainer'}
-        style={{ minHeight: `calc(100vh - ${toTop.value}px)` }}
+      // class={!showContact.value && 'emptyRootContainer'}
+      // style={{ minHeight: `calc(100vh - ${toTop.value}px)` }}
       >
-        <Sticky offsetTop={toTop.value} style={{ width: '100%' }}>
-          <div>
-            <OSearch
-              placeholder="请输入伴学指导姓名"
-              inputBackground="white"
-              background="#f6f6f6"
-              onSearch={(val: any) => {
-                console.log(val, 'onSearch')
-                forms.keyword = val
-                refreshing.value = true
-                getList()
-              }}
-            ></OSearch>
-            <div class={styles.chioseWrap}>
-              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-                <div
-                  class={[styles.searchBand, styles.orchestraBand]}
-                  onClick={() => {
-                    state.showPopoverTime = true
-                  }}
-                >
-                  <p> {forms.timeName}</p>
+        {/* <Sticky offsetTop={toTop.value} style={{ width: '100%' }}> */}
+        <>
+          <OSearch
+            placeholder="请输入伴学指导姓名"
+            inputBackground="white"
+            background="#f6f6f6"
+            onSearch={(val: any) => {
+              console.log(val, 'onSearch')
+              forms.keyword = val
+              refreshing.value = true
+              getList()
+            }}
+          ></OSearch>
+          <div class={styles.chioseWrap}>
+            <div style={{ background: '#F8F8F8' }}>
+              <div
+                class={[styles.searchBand, styles.orchestraBand]}
+                onClick={() => {
+                  state.showPopoverTime = true
+                }}
+              >
+                <p> {forms.timeName}</p>
 
-                  <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
-                </div>
+                <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
               </div>
+            </div>
 
-              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-                <div
-                  class={[styles.searchBand, styles.orchestraBand]}
-                  onClick={() => {
-                    state.showPopoverOrchestra = true
-                  }}
-                >
-                  <p>{forms.orchestraName}</p>
+            <div style={{ background: '#F8F8F8' }}>
+              <div
+                class={[styles.searchBand, styles.orchestraBand]}
+                onClick={() => {
+                  state.showPopoverOrchestra = true
+                }}
+              >
+                <p>{forms.orchestraName}</p>
 
-                  <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
-                </div>
+                <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
               </div>
-              <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
-                <div
-                  class={[styles.searchBand, styles.orchestraBand]}
-                  onClick={() => {
-                    state.showPopoverSubject = true
-                  }}
-                >
-                  <p> {forms.courseTypeName}</p>
+            </div>
+            <div style={{ background: '#F8F8F8' }}>
+              <div
+                class={[styles.searchBand, styles.orchestraBand]}
+                onClick={() => {
+                  state.showPopoverSubject = true
+                }}
+              >
+                <p> {forms.courseTypeName}</p>
 
-                  <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
-                </div>
+                <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
               </div>
             </div>
           </div>
-        </Sticky>
+        </>
+        {/* </Sticky> */}
 
-        {showContact.value ? (
-          <OFullRefresh
-            v-model:modelValue={refreshing.value}
-            onRefresh={onRefresh}
-            style="min-height: 100vh;"
-          >
-            <List
-              loading-text=" "
-              // v-model:loading={loading.value}
-              finished={finished.value}
-              finished-text="没有更多了"
-              onLoad={getList}
+        <div
+          style={{
+            overflowY: 'auto',
+            height: 'calc(100vh - var(--van-tabs-line-height) - var(--header-height)  - 2.45333rem)'
+          }}
+        >
+          {showContact.value ? (
+            <OFullRefresh
+              v-model:modelValue={refreshing.value}
+              onRefresh={onRefresh}
+              style="min-height: calc(100vh - var(--van-tabs-line-height) - var(--header-height) - 2.45333rem)"
             >
-              {list.value.map((item: any) => (
-                <TeacherAttItem item={item}></TeacherAttItem>
-              ))}
-            </List>
-          </OFullRefresh>
-        ) : (
-          <OEmpty tips="暂无考勤" />
-        )}
-
+              <List
+                loading-text=" "
+                // v-model:loading={loading.value}
+                finished={finished.value}
+                finished-text=" "
+                onLoad={getList}
+              >
+                {list.value.map((item: any) => (
+                  <TeacherAttItem item={item}></TeacherAttItem>
+                ))}
+              </List>
+            </OFullRefresh>
+          ) : (
+            <OEmpty tips="暂无考勤" />
+          )}
+        </div>
         <Popup v-model:show={state.showPopoverTime} position="bottom" style="{ height: '30%' }">
           <DatePicker
             onCancel={() => {

+ 5 - 0
src/school/attendance/components/attent-student.module.less

@@ -7,6 +7,7 @@
   color: #333;
   font-weight: 500;
   font-size: 14px;
+  line-height: 38px;
   .orchestraBand {
     display: flex;
     flex-direction: row;
@@ -18,4 +19,8 @@
       white-space: nowrap;
     }
   }
+
+  & > div {
+    padding: 0 13px;
+  }
 }

+ 12 - 6
src/school/attendance/index.tsx

@@ -20,22 +20,28 @@ export default defineComponent({
     const getHeight = (dataHeight: number) => {
       state.heightV = dataHeight
       console.log(state.heightV, '获取高度')
+      document.documentElement.style.setProperty('--header-height', dataHeight + 'px')
     }
     return () => (
       <>
         <OSticky position="top" background="#F8F8F8" onGetHeight={getHeight} ref={stickyRef}>
           <OHeader></OHeader>
-          <Tabs v-model:active={activeName.value}>
-            <Tab name="student" title="学生考勤"></Tab>
-            <Tab name="teacher" title="伴学指导考勤"></Tab>
-          </Tabs>
         </OSticky>
 
-        {activeName.value == 'student' ? (
+        <Tabs v-model:active={activeName.value} sticky swipeable offsetTop={state.heightV}>
+          <Tab name="student" title="学生考勤">
+            <AttendStudent toHeight={state.heightV} />
+          </Tab>
+          <Tab name="teacher" title="伴学指导考勤">
+            <AttendTeacher toHeight={state.heightV} />
+          </Tab>
+        </Tabs>
+
+        {/* {activeName.value == 'student' ? (
           <AttendStudent toHeight={state.heightV}></AttendStudent>
         ) : (
           <AttendTeacher toHeight={state.heightV}></AttendTeacher>
-        )}
+        )} */}
       </>
     )
   }

+ 3 - 1
src/school/companion-teacher/companion-teacher-register.tsx

@@ -365,13 +365,15 @@ export default defineComponent({
           : []
         state.popupSelectSubjects = subjects || []
         // 显示声部
+        const tempSubject: any = []
         subjects.forEach((subject: any) => {
           const item = state.columnSubject.find((item: any) => item.value === subject)
 
           if (item) {
-            state.selectSubjects.push(item)
+            tempSubject.push(item)
           }
         })
+        state.selectSubjects = tempSubject || []
 
         let cityCodeName = ''
         state.columns.forEach((p: any) => {

+ 21 - 15
src/school/mass-message/component/class-list/index.tsx

@@ -167,21 +167,23 @@ export default defineComponent({
         class={[styles.practiceClass, !forms.listState.dataShow && 'emptyRootContainer']}
         style={{ 'min-height': `calc(100vh - ${props.height}px - ${props.bottomHeight}px)` }}
       >
-        <Sticky position="top" offsetTop={props.height} style={{ width: '100%' }}>
-          <div
-            style={{
-              padding: '12px 13px',
-              background: '#f6f6f6',
-              display: 'flex',
-              alignItems: 'center'
-            }}
-          >
-            <div class={styles.searchBand} onClick={() => (forms.showPopover = true)}>
-              <div class={['van-ellipsis', styles.bandName]}>{forms.orchestraName}</div>
-              <Icon name={forms.showPopover ? 'arrow-up' : 'arrow-down'} />
+        {forms.orchestraList.length > 0 && (
+          <Sticky position="top" offsetTop={props.height} style={{ width: '100%' }}>
+            <div
+              style={{
+                padding: '12px 13px',
+                background: '#f6f6f6',
+                display: 'flex',
+                alignItems: 'center'
+              }}
+            >
+              <div class={styles.searchBand} onClick={() => (forms.showPopover = true)}>
+                <div class={['van-ellipsis', styles.bandName]}>{forms.orchestraName}</div>
+                <Icon name={forms.showPopover ? 'arrow-up' : 'arrow-down'} />
+              </div>
             </div>
-          </div>
-        </Sticky>
+          </Sticky>
+        )}
 
         {forms.listState.dataShow ? (
           <List
@@ -211,7 +213,11 @@ export default defineComponent({
               // }}
             >
               {forms.list.map((item: any) => (
-                <CellGroup class={styles.classCellGroup} onClick={() => onSelect(item.id)}>
+                <CellGroup
+                  class={styles.classCellGroup}
+                  onClick={() => onSelect(item.id)}
+                  border={false}
+                >
                   <Cell center titleStyle={{ flex: '0 auto' }} valueClass={styles.classCheckbox}>
                     {{
                       icon: () => <Image src={iconTeacher} class={styles.img} />,

+ 8 - 8
src/school/mass-message/create-message.tsx

@@ -93,12 +93,12 @@ export default defineComponent({
         const tempName = file.name || ''
         const fileName = '/i-m/' + (tempName && tempName.replace(/ /gi, '_'))
         const key = new Date().getTime() + fileName
-        showLoadingToast({
-          message: '加载中...',
-          forbidClick: true,
-          loadingType: 'spinner',
-          duration: 0
-        })
+        // showLoadingToast({
+        //   message: '加载中...',
+        //   forbidClick: true,
+        //   loadingType: 'spinner',
+        //   duration: 0
+        // })
         const res = await request.post(signUrl, {
           hideLoading: true,
           data: {
@@ -134,14 +134,14 @@ export default defineComponent({
         })
         // console.log(getOssUploadUrl(state.bucket) + key)
         const uploadUrl = getOssUploadUrl(forms.bucket) + key
-        closeToast()
+        // closeToast()
 
         // state.fileList.push({ url: uploadUrl })
         files.url = uploadUrl
         files.status = 'done'
       } catch (error) {
         files.status = 'failed'
-        closeToast()
+        // closeToast()
         console.log(error, 'uploadFile')
       }
     }

+ 4 - 0
src/school/orchestra-story/story-operation/index.module.less

@@ -58,6 +58,10 @@
   // .radioSection + .radioSection {
   //   margin-left: 12px;
   // }
+
+  .orchestraName {
+    max-width: 180px;
+  }
 }
 
 .uploader {

+ 13 - 3
src/school/orchestra-story/story-operation/index.tsx

@@ -37,7 +37,7 @@ export default defineComponent({
       orchestraStatus: false,
       orchestraList: [] as any,
       selectOrchestra: {} as any,
-      createTime: new Date() as any,
+      createTime: dayjs(dayjs().format('YYYY-MM-DD')).toDate() as any,
       createTimeStatus: false,
       currentDate: [dayjs().format('YYYY'), dayjs().format('MM'), dayjs().format('DD')],
       storyType: 'IMAGE',
@@ -258,13 +258,23 @@ export default defineComponent({
           <Field
             inputAlign="right"
             label="所属乐团"
-            modelValue={forms.selectOrchestra.text}
-            placeholder="请选择所属乐团"
+            // modelValue={forms.selectOrchestra.text}
+            // placeholder="请选择所属乐团"
             onClick={() => {
               forms.orchestraStatus = true
             }}
             readonly
             isLink
+            v-slots={{
+              input: () =>
+                forms.selectOrchestra.text ? (
+                  <div class={[styles.orchestraName, 'van-ellipsis']}>
+                    {forms.selectOrchestra.text}
+                  </div>
+                ) : (
+                  <div style={{ color: '#c8c9cc' }}>请选择所属乐团</div>
+                )
+            }}
           />
           <Field
             inputAlign="right"

+ 1 - 1
src/school/orchestra/orchestra-information.tsx

@@ -172,7 +172,7 @@ export default defineComponent({
               {state.list.map((item: any, index: number) => (
                 <Cell center class={styles.cell} onClick={() => onDetail(item)}>
                   {{
-                    icon: () => <Image src={item.coverImage} class={styles.img} />,
+                    icon: () => <Image src={item.coverImage} class={styles.img} fit="cover" />,
                     title: () => (
                       <div>
                         <div class={[styles.title, 'van-ellipsis']}>{item.title}</div>

+ 1 - 1
src/school/train-planning/modal/class-list/index.module.less

@@ -7,7 +7,7 @@
   }
   :global {
     .van-cell__title {
-      flex: 1 auto;
+      // flex: 1 auto;
     }
   }
 

+ 2 - 3
src/school/train-planning/modal/class-list/index.tsx

@@ -86,6 +86,7 @@ export default defineComponent({
               state.selectItem = item
               state.teacherStatus = true
             }}
+            valueClass={[styles.teacherName, 'van-ellipsis']}
           >
             {{
               title: () => (
@@ -97,9 +98,7 @@ export default defineComponent({
                   <div class={[styles.name, 'van-ellipsis']}>{item.orchestraName}</div>
                 </div>
               ),
-              value: () => (
-                <span class={[styles.teacherName, 'van-ellipsis']}>{item.teacherName}</span>
-              )
+              value: () => <>{item.teacherName}</>
             }}
           </Cell>
         ))}

+ 1 - 1
src/student/music-group/pre-apply/component/apply.tsx

@@ -382,7 +382,7 @@ export default defineComponent({
 
         <Dialog
           v-model:show={state.subjectChangeStatus}
-          message={'您已报名,不能更换声部'}
+          message={'您已有报名订单,不可更换声部'}
           messageAlign="center"
           confirmButtonText="确定"
         >

+ 10 - 6
src/student/music-group/pre-apply/order-detail.tsx

@@ -177,13 +177,17 @@ export default defineComponent({
           // console.log(data)
           if (data.status !== 'WAIT_PAY' && data.status !== 'PAYING') {
             // 默认关闭支付二维码弹窗
-            state.showQrcode = false
+            // state.showQrcode = false
             clearInterval(orderTimer)
-            setTimeout(() => {
-              window.location.replace(
-                window.location.origin + '/#/payment-result?orderNo=' + state.orderNo
-              )
-            }, 100)
+            // window.location.replace(
+            //   window.location.origin + '/#/payment-result?orderNo=' + state.orderNo
+            // )
+            router.replace({
+              path: 'payment-result',
+              query: {
+                orderNo: state.orderNo
+              }
+            })
           }
         } catch {
           //

+ 1 - 1
src/views/adapay/pay-result/index.module.less

@@ -50,6 +50,6 @@
 .error-icon {
   display: block;
   color: #ffb07b;
-  font-size: 16px;
+  font-size: 22px;
   margin-bottom: 20px;
 }

+ 3 - 3
src/views/adapay/pay-result/index.tsx

@@ -32,6 +32,8 @@ export default defineComponent({
       payInfo: {} as any
     })
 
+    console.log(state.errorText)
+
     const init = () => {
       const query = route.query
       console.log(query)
@@ -203,9 +205,7 @@ export default defineComponent({
 
         {!state.browserStatus && (
           <div class={styles['error-text']}>
-            {state.errorText && (
-              <Icon v-if="errorText" class={styles['error-icon']} name="warning-o" />
-            )}
+            {state.errorText && <Icon class={styles['error-icon']} name="warning-o" />}
             {state.errorText}
           </div>
         )}

+ 0 - 1
src/views/attendance-rule/index.tsx

@@ -69,7 +69,6 @@ export default defineComponent({
                 class={styles.collapseWrap}
                 style={{ height: `calc(100vh - ${state.wrapHeight}px)` }}
               >
-                {state.wrapHeight}
                 <div class={styles.mainMsg}>
                   <img src={clockIcon} alt="" class={styles.clockIcon} />
                   <p>以课程时间12:00:00 ~ 13:00:00为例</p>

+ 12 - 9
src/views/mine-orchestra/photo-list/detail.tsx

@@ -105,15 +105,18 @@ export default defineComponent({
           >
             <div class={styles.phoneListDetail}>
               <TransitionGroup name="van-fade">
-                {data.list.map((item: any, index: number) => (
-                  <div
-                    key={`index-${index}`}
-                    class={styles.gridItem}
-                    onClick={() => onShowImage(index)}
-                  >
-                    <OImage class={styles.gridImg} src={item.fileUrl} />
-                  </div>
-                ))}
+                <div>
+                  {data.list.map((item: any, index: number) => (
+                    <div
+                      key={`index-${index}`}
+                      class={styles.gridItem}
+                      onClick={() => onShowImage(index)}
+                    >
+                      <OImage class={styles.gridImg} src={item.fileUrl} />
+                    </div>
+                  ))}
+                </div>
+
                 {!data.loading && !data.list.length && (
                   <OEmpty key="OEmpty1" btnStatus={false} tips="暂无照片" />
                 )}

+ 4 - 3
src/views/mine-orchestra/photo-list/index.module.less

@@ -42,18 +42,19 @@
   }
 }
 
-.phoneListDetail{
+.phoneListDetail {
   position: relative;
   box-sizing: border-box;
   display: flex;
   flex-wrap: wrap;
   min-height: calc(100vh - var(--header-height));
-  .gridItem{
+  .gridItem {
     padding: 1.5px;
     width: calc(100vw / 3);
     height: calc(100vw / 3);
     box-sizing: border-box;
-    .gridImg{
+    display: inline-block;
+    .gridImg {
       width: 100%;
       height: 100%;
       border-radius: 0;

+ 9 - 1
src/views/unit-test/examination-mode/index.tsx

@@ -11,7 +11,7 @@ import {
   SwipeItem,
   Tag
 } from 'vant'
-import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue'
+import { defineComponent, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import styles from './index.module.less'
 import iconQuestionNums from '../images/icon-question-nums.png'
@@ -92,6 +92,7 @@ export default defineComponent({
       const minu = dayjs(startTime).add(timeMinutes, 'minute').diff(dayjs(nowTime))
       // 时间到了考试结束
       if (minu <= 0) {
+        eventUnit.emit('unitAudioStop')
         await onConfirmExam()
         state.visiableExam = true
       } else {
@@ -173,6 +174,7 @@ export default defineComponent({
         // 判断是否是最后一题
         // console.log(state.questionList.length, state.currentIndex, userAnswerList, '-----')
         if (state.questionList.length === state.currentIndex + 1) {
+          eventUnit.emit('unitAudioStop')
           state.visiableSure = true
           return
         }
@@ -253,6 +255,7 @@ export default defineComponent({
       //   router.back()
       // })
       state.quitStatus = true
+      eventUnit.emit('unitAudioStop')
     }
 
     const onAfter = () => {
@@ -270,6 +273,10 @@ export default defineComponent({
       window.addEventListener('popstate', onBack, false)
     })
 
+    onUnmounted(() => {
+      eventUnit.emit('unitAudioStop')
+    })
+
     return () => (
       <div class={styles.unitDetail}>
         <Cell center class={styles.unitSection} border={false}>
@@ -294,6 +301,7 @@ export default defineComponent({
                     format={'mm:ss'}
                     autoStart={false}
                     onFinish={async () => {
+                      eventUnit.emit('unitAudioStop')
                       await onConfirmExam()
                       state.visiableExam = true
                     }}

+ 82 - 75
src/views/unit-test/index.tsx

@@ -3,7 +3,7 @@ import OHeader from '@/components/o-header'
 import OSearch from '@/components/o-search'
 import OSticky from '@/components/o-sticky'
 import { ActionSheet, Button, Cell, CellGroup, Icon, Image, List, Popup } from 'vant'
-import { defineComponent, onMounted, reactive } from 'vue'
+import { defineComponent, onMounted, reactive, TransitionGroup } from 'vue'
 import styles from './index.module.less'
 import iconEdit from './images/icon-edit.png'
 import { useRouter } from 'vue-router'
@@ -214,88 +214,95 @@ export default defineComponent({
                 <source src="horse.ogg" type="audio/ogg" />
                 您的浏览器不支持该音频格式。
               </audio> */}
-              {form.list.map((item: any) => (
-                <CellGroup inset class={styles.cellGroup} border={false}>
-                  <Cell
-                    center
-                    // isLink
-                    clickable={false}
-                    titleStyle={{ flex: '1 auto' }}
-                    valueClass={[
-                      styles['no-start'],
-                      item.status === 'A_PASS' && styles.pass,
-                      item.status === 'B_NO_PASS' && styles['no-pass']
-                    ]}
-                  >
-                    {{
-                      icon: () => <Image src={iconEdit} class={styles.img} />,
-                      title: () => (
-                        <div class={[styles.unitTitle, 'van-ellipsis']}>{item.name}</div>
-                      ),
-                      value: () => unitTestStatus[item.status]
-                    }}
-                  </Cell>
-                  <Cell center class={styles.unitSection}>
-                    {{
-                      title: () => (
-                        <div class={styles.unitInformation}>
-                          <div>
-                            <div class={styles.name}>{item.orchestraName}</div>
-                            <div class={styles.endTime}>
-                              截止时间:
-                              {dayjs(item.expiryDate || new Date()).format('YYYY-MM-DD HH:mm')}
+              <TransitionGroup name="van-fade">
+                {form.list.map((item: any) => (
+                  <CellGroup inset class={styles.cellGroup} border={false}>
+                    <Cell
+                      center
+                      // isLink
+                      clickable={false}
+                      titleStyle={{ flex: '1 auto' }}
+                      valueClass={[
+                        styles['no-start'],
+                        item.status === 'A_PASS' && styles.pass,
+                        item.status === 'B_NO_PASS' && styles['no-pass']
+                      ]}
+                    >
+                      {{
+                        icon: () => <Image src={iconEdit} class={styles.img} />,
+                        title: () => (
+                          <div class={[styles.unitTitle, 'van-ellipsis']}>{item.name}</div>
+                        ),
+                        value: () => unitTestStatus[item.status]
+                      }}
+                    </Cell>
+                    <Cell center class={styles.unitSection}>
+                      {{
+                        title: () => (
+                          <div class={styles.unitInformation}>
+                            <div>
+                              <div class={styles.name}>{item.orchestraName}</div>
+                              <div class={styles.endTime}>
+                                截止时间:
+                                {dayjs(item.expiryDate || new Date()).format('YYYY-MM-DD HH:mm')}
+                              </div>
                             </div>
+                            {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
+                              <span>
+                                {item.score || 0}
+                                <i>分</i>
+                              </span>
+                            ) : (
+                              ''
+                            )}
                           </div>
-                          {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
-                            <span>
-                              {item.score || 0}
-                              <i>分</i>
-                            </span>
-                          ) : (
-                            ''
-                          )}
-                        </div>
-                      ),
+                        ),
 
-                      label: () => (
-                        <div class={styles.unitBtnGroup}>
-                          <Button
-                            color="#FFF0E6"
-                            round
-                            block
-                            style={{ color: '#F67146' }}
-                            onClick={() => {
-                              router.push({
-                                path: '/test-exercise',
-                                query: {
-                                  id: item.unitExaminationId
-                                }
-                              })
-                            }}
-                          >
-                            练习模式
-                          </Button>
-                          {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
-                            <Button type="primary" round block onClick={() => onUnitTestLook(item)}>
-                              查看测验
-                            </Button>
-                          ) : (
+                        label: () => (
+                          <div class={styles.unitBtnGroup}>
                             <Button
-                              type="primary"
+                              color="#FFF0E6"
                               round
                               block
-                              disabled={dayjs().isAfter(dayjs(item.expiryDate))}
-                              onClick={() => onUnitTestStart(item)}
+                              style={{ color: '#F67146' }}
+                              onClick={() => {
+                                router.push({
+                                  path: '/test-exercise',
+                                  query: {
+                                    id: item.unitExaminationId
+                                  }
+                                })
+                              }}
                             >
-                              {item.status === 'C_ING' ? '继续测验' : '开始测验'}
+                              练习模式
                             </Button>
-                          )}
-                        </div>
-                      )
-                    }}
-                  </Cell>
-                </CellGroup>
-              ))}
+                            {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
+                              <Button
+                                type="primary"
+                                round
+                                block
+                                onClick={() => onUnitTestLook(item)}
+                              >
+                                查看测验
+                              </Button>
+                            ) : (
+                              <Button
+                                type="primary"
+                                round
+                                block
+                                disabled={dayjs().isAfter(dayjs(item.expiryDate))}
+                                onClick={() => onUnitTestStart(item)}
+                              >
+                                {item.status === 'C_ING' ? '继续测验' : '开始测验'}
+                              </Button>
+                            )}
+                          </div>
+                        )
+                      }}
+                    </Cell>
+                  </CellGroup>
+                ))}
+              </TransitionGroup>
             </List>
           </OFullRefresh>
         ) : (

+ 6 - 1
src/views/unit-test/model/answer-list/index.tsx

@@ -38,6 +38,7 @@ export default defineComponent({
   },
   emits: ['select'],
   setup(props, { emit }) {
+    console.log(props.lookType, 'lookType')
     /**
      * @description 检查用户是否答对
      * @returns Boolean
@@ -85,7 +86,11 @@ export default defineComponent({
                     props.lookType === 'RESULT' &&
                       (formatUserResult(item.id) ? styles.yes : styles.no),
                     props.lookType === 'CLICK' && index === props.index && styles.answered,
-                    item.showAnalysis ? (item.analysis.userResult ? styles.yes : styles.no) : ''
+                    props.lookType !== 'CLICK' && item.showAnalysis
+                      ? item.analysis.userResult
+                        ? styles.yes
+                        : styles.no
+                      : ''
                   ]}
                 >
                   {index + 1}

+ 3 - 1
src/views/unit-test/model/choice-question/index.tsx

@@ -128,7 +128,9 @@ export default defineComponent({
                     </div>
                   )}
                 </div>
-                {props.showRate && <div class={styles.answerChoice}>{item.selectRate}%人选择</div>}
+                {props.showRate && (
+                  <div class={styles.answerChoice}>{item.selectRate || 0}%人选择</div>
+                )}
               </div>
             ))}
           </div>

+ 1 - 0
src/views/unit-test/model/drag-question/index.module.less

@@ -101,6 +101,7 @@
 
   .imgs {
     height: 56px;
+    width: auto;
     :global {
       .van-image__img {
         width: auto;

+ 12 - 8
src/views/unit-test/model/drag-question/index.tsx

@@ -95,7 +95,7 @@ export default defineComponent({
       const result: any = []
 
       list.forEach((item: any, index: number) => {
-        console.log(item, 'item')
+        // console.log(item, 'item')
         result.push({
           answerId: item.answerId,
           answer: item.answer,
@@ -108,7 +108,7 @@ export default defineComponent({
     // 修改题目逻辑
     const onSelectAnswer = (item: any) => {
       // 判断是否已经选中了
-      if (item.checked) return
+      if (item.checked || props.readOnly) return
       const result: any = []
       state.options.forEach((option: any, index: any) => {
         // console.log(option, '------')
@@ -121,10 +121,15 @@ export default defineComponent({
       result.push({
         answerId: item.examinationQuestionAnswerId,
         answer: item.questionAnswer,
-        answerExtra: state.options.length + 1
+        answerExtra: state.list.length + 1
       })
 
-      state.list = result
+      state.list.push({
+        answerId: item.examinationQuestionAnswerId,
+        answer: item.questionAnswer,
+        answerExtra: state.list.length + 1
+      })
+      // console.log(state.list, result, 'result lis4t')
       emit('update:value', result)
 
       initOptions()
@@ -133,7 +138,6 @@ export default defineComponent({
     const answers = computed(() => {
       const list: any = props.data.answers || []
       const value: any = props.value || []
-      console.log(list, value, '1212')
       list.forEach((item: any) => {
         const tempIndex = value.findIndex(
           (c: any) => c.answerId === item.examinationQuestionAnswerId
@@ -147,7 +151,7 @@ export default defineComponent({
     const initOptions = () => {
       const answers = props.data.answers || []
       const userAnswer = props.data.userAnswer || [] // 用户填写的答案
-      console.log(answers, userAnswer)
+      // console.log(answers, userAnswer)
       state.options = []
       if (userAnswer.length > 0) {
         userAnswer.forEach((answer: any, index: any) => {
@@ -160,8 +164,8 @@ export default defineComponent({
             index: answer.answerId, // 左边的值
             leftValue: answer.answer, // 左边的值
             rightValue: answer.answerExtra, // 右边的值
-            leftType: rightOption.questionAnswerTypeCode || 'TXT', // 左边类型
-            rightType: rightOption.questionExtraTypeCode || 'TXT', // 右边类型
+            leftType: rightOption ? rightOption.questionAnswerTypeCode || 'TXT' : 'TXT', // 左边类型
+            rightType: rightOption ? rightOption.questionExtraTypeCode || 'TXT' : 'TXT', // 右边类型
             rightIndex: rightValue ? rightValue.examinationQuestionAnswerId : ''
           }
           state.options.push(tmp)

+ 5 - 3
src/views/unit-test/model/play-question/index.tsx

@@ -67,7 +67,7 @@ export default defineComponent({
   },
   emits: ['update:value'],
   setup(props, { emit }) {
-    console.log(props)
+    console.log(props, 'props')
     const state = reactive({
       list: [] as any,
       score: 0
@@ -235,11 +235,13 @@ export default defineComponent({
               </Cell>
             )}
 
-            {(!props.readOnly || !props.showScore) && (
+            {(!props.readOnly || props.showScore) && (
               <div class={['van-hairline--top', styles.unitScoreNum]}>
                 <div class={styles.score}>{state.score}</div>
                 <div class={styles.scoreTitle}>评测分数</div>
-                <div class={styles.scoreTips}>多次评测取完整评测的最高分数</div>
+                {!props.showScore && (
+                  <div class={styles.scoreTips}>多次评测取完整评测的最高分数</div>
+                )}
               </div>
             )}
           </div>

+ 4 - 0
src/views/unit-test/model/unit-audio/index.tsx

@@ -38,6 +38,10 @@ export default defineComponent({
       state.duration = Math.ceil(htick.duration())
     })
 
+    htick.on('end', (val: any) => {
+      state.audioStatus = 'stopped'
+    })
+
     eventUnit.on('unitAudioStop', () => {
       htick.stop()
       state.audioStatus = 'stopped'

+ 15 - 3
src/views/unit-test/practice-mode/index.tsx

@@ -13,7 +13,7 @@ import {
   SwipeItem,
   Tag
 } from 'vant'
-import { computed, defineComponent, nextTick, onMounted, reactive, ref } from 'vue'
+import { computed, defineComponent, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import styles from './index.module.less'
 import iconButtonList from '../images/icon-button-list.png'
@@ -43,6 +43,7 @@ export default defineComponent({
     const state = reactive({
       examId: route.query.examId,
       name: route.query.name,
+      courseTypeCode: route.query.courseTypeCode,
       visiableError: false,
       visiableAnswer: false,
       visiableResult: false,
@@ -77,6 +78,7 @@ export default defineComponent({
             page: 1,
             row: 50,
             categoryId: state.id
+            // courseTypeCode: state.courseTypeCode
           }
         })
         const temp = data || []
@@ -148,6 +150,7 @@ export default defineComponent({
 
         // 判断是否是最后一题
         if (state.questionList.length === state.currentIndex + 1) {
+          eventUnit.emit('unitAudioStop')
           state.visiableSure = true
           return
         }
@@ -275,7 +278,7 @@ export default defineComponent({
     // 下一个考点
     const onConfirmResult = () => {
       const knowledgelist = state.knowledgelist || []
-      console.log('🚀 ~ file: index.tsx:246 ~ onConfirmResult ~ knowledgelist', knowledgelist)
+      // console.log('🚀 ~ file: index.tsx:246 ~ onConfirmResult ~ knowledgelist', knowledgelist)
       // 当前正在考试的节点
       const knownleIndex = knowledgelist.findIndex((item: any) => item.id === state.id)
       console.log('🚀 ~ file: index.tsx:249 ~ onConfirmResult ~ knownleIndex', knownleIndex)
@@ -307,6 +310,7 @@ export default defineComponent({
       //   onAfter()
       // })
       state.quitStatus = true
+      eventUnit.emit('unitAudioStop')
     }
 
     const onAfter = () => {
@@ -323,6 +327,11 @@ export default defineComponent({
       window.history.pushState(null, '', document.URL)
       window.addEventListener('popstate', onBack, false)
     })
+
+    onUnmounted(() => {
+      // 关闭所有音频
+      eventUnit.emit('unitAudioStop')
+    })
     return () => (
       <div class={styles.unitDetail}>
         <OSticky position="top">
@@ -331,7 +340,10 @@ export default defineComponent({
               right: () => (
                 <span
                   style="color: var(--van-primary-color)"
-                  onClick={() => (state.visiableSure = true)}
+                  onClick={() => {
+                    eventUnit.emit('unitAudioStop')
+                    state.visiableSure = true
+                  }}
                 >
                   结束练习
                 </span>

+ 3 - 0
src/views/unit-test/test-exercise/index.tsx

@@ -13,6 +13,7 @@ export default defineComponent({
     const state = reactive({
       id: route.query.id,
       name: '',
+      courseTypeCode: '',
       visiableNotice: false,
       list: [] as any
     })
@@ -27,6 +28,7 @@ export default defineComponent({
         })
         state.list = data.lists || []
         state.name = data.unitExaminationName
+        state.courseTypeCode = data.courseTypeCode
         console.log(data)
       } catch {
         //
@@ -39,6 +41,7 @@ export default defineComponent({
         query: {
           examId: state.id, // 单元测试编号
           id: item.id,
+          courseTypeCode: state.courseTypeCode,
           name: state.name
         }
       })

+ 4 - 0
src/views/unit-test/unit-create/index.module.less

@@ -9,6 +9,10 @@
         color: #333 !important;
       }
     }
+
+    .orchestraName {
+      max-width: 200px;
+    }
   }
 }
 .wall {

+ 15 - 7
src/views/unit-test/unit-create/index.tsx

@@ -129,8 +129,8 @@ export default defineComponent({
               {/*      onClick={() => setAddress()} */}
               <CellGroup inset>
                 <Field
-                  v-model={forms.value.orchestraName}
-                  placeholder="选择乐团"
+                  // v-model={forms.value.orchestraName}
+                  placeholder="选择乐团"
                   readonly
                   input-align="right"
                   onClick={() => {
@@ -144,14 +144,22 @@ export default defineComponent({
                         {/* <Image width={19} height={18} src={locIcon}></Image> */}
                       </div>
                     ),
-                    label: () => <p class={styles.addP}>选择乐团</p>
+                    label: () => <p class={styles.addP}>选择乐团</p>,
+                    input: () =>
+                      forms.value.orchestraName ? (
+                        <div class={[styles.orchestraName, 'van-ellipsis']}>
+                          {forms.value.orchestraName}
+                        </div>
+                      ) : (
+                        <div style={{ color: '#c8c9cc' }}>请选择乐团</div>
+                      )
                   }}
                 </Field>
                 <Field
                   rows={3}
                   v-model={forms.value.classGroupName}
                   maxlength={50}
-                  placeholder="测验班级"
+                  placeholder="请选择测验班级"
                   readonly
                   input-align="right"
                   onClick={() => {
@@ -176,7 +184,7 @@ export default defineComponent({
                   rows={3}
                   v-model={forms.value.unitName}
                   maxlength={50}
-                  placeholder="测验内容"
+                  placeholder="请选择测验内容"
                   readonly
                   input-align="right"
                   onClick={chioseLesson}
@@ -213,7 +221,7 @@ export default defineComponent({
         <Popup v-model:show={state.showPopoverOrchestra} position="bottom" round>
           <Picker
             columns={state.actions}
-            columnsFieldNames={{ text: 'name', value: 'id' }}
+            columnsFieldNames={{ text: 'name', value: 'value' }}
             onCancel={() => (state.showPopoverOrchestra = false)}
             onConfirm={checkOrchestra}
           />
@@ -222,7 +230,7 @@ export default defineComponent({
         <Popup v-model:show={state.showPopoverClass} position="bottom" round>
           <Picker
             columns={state.classList}
-            columnsFieldNames={{ text: 'name', value: 'id' }}
+            columnsFieldNames={{ text: 'name', value: 'value' }}
             onCancel={() => (state.showPopoverOrchestra = false)}
             onConfirm={checkClass}
           />

+ 1 - 1
src/views/unit-test/unit-create/modals/newspaper-item.tsx

@@ -49,7 +49,7 @@ export default defineComponent({
                 <Icon name={clockIcon} class={styles.clockIcon}></Icon> 测验时长:
                 <span style={{ color: '#F67146' }}>{props.item?.timeMinutes || 0} </span> 分钟
               </div>
-              <Icon name="arrow" color="#777"></Icon>
+              {/* <Icon name="arrow" color="#777"></Icon> */}
             </div>
           </div>
         </div>

+ 5 - 2
src/views/unit-test/unit-create/uni-last.tsx

@@ -84,18 +84,21 @@ export default defineComponent({
           }
         )
 
-        forms.value.classGroupId = route.query.courseScheduleId
+        forms.value.classGroupId = data.classGroupId
         forms.value.classGroupName = data.classGroupName
         forms.value.testName = data.lessonCoursewareExaminationMapperName
         forms.value.orchestraName = data.orchestraName
-        forms.value.coursewareName = data.LessonCoursewareName
+        forms.value.coursewareName = data.lessonCoursewareName
         forms.value.lessonCoursewareId = data.lessonCoursewareExaminationMapper.lessonCoursewareId
         forms.value.preStudentNum = data.studentNum || 0
+        forms.value.testId = data.lessonCoursewareExaminationMapper.id
 
         const details = data.lessonCoursewareExaminationMapper.details || []
         details.forEach((item: any) => {
           datas.uniDetail[item.level] = item
         })
+
+        console.log(forms.value, 'forms')
       } catch (e) {
         console.log(e)
       }

+ 26 - 4
src/views/unit-test/unit-detail/index.tsx

@@ -52,10 +52,11 @@ export default defineComponent({
         temp.forEach((item: any) => {
           item.userAnswer = formatUserAnswers(item, studentAnswerJson)
           item.showAnalysis = true
+          item.showScore = true
           item.analysis = {
             message: item.answerAnalysis,
             topic: true, // 是否显示结果
-            showScore: true,
+
             userResult: formatUserResult(item.id) // 用户答题对错
           }
         })
@@ -90,9 +91,23 @@ export default defineComponent({
         // 问题列表
         const temp = data.examinationQuestionAdds || []
         temp.forEach((item: any) => {
-          item.userAnswer = formatTeacherAnswer(item.rightAnswers || [])
+          const rightAnswers = item.rightAnswers || []
+          // const answers = item.answers || []
+          // answers.forEach((answer: any) => {
+          //   const child = rightAnswers.find(
+          //     (right: any) =>
+          //       right.examinationQuestionAnswerId === answer.examinationQuestionAnswerId
+          //   )
+          //   if (child) {
+          //     answer.selectRate = child.selectRate
+          //   }
+          // })
+          // item.answers = answers
+
+          item.userAnswer = formatTeacherAnswer(rightAnswers)
           item.showAnalysis = true
           item.showRate = true
+          item.showScore = false
           item.analysis = {
             message: item.answerAnalysis,
             topic: false // 是否显示结果
@@ -101,6 +116,7 @@ export default defineComponent({
         // 问题列表
         state.questionList = temp
         // 正确答案
+        console.log(state.questionList, 'state.questionList')
       } catch {
         //
       }
@@ -109,7 +125,6 @@ export default defineComponent({
      * @description 初始化正确答案
      */
     const formatTeacherAnswer = (answers: any) => {
-      console.log(answers)
       const result: any = []
       answers.forEach((answer: any) => {
         // rightAnswerFlag 说明是正确的
@@ -184,7 +199,7 @@ export default defineComponent({
             size = 0
           }
           const rect = useRect(currentItemDom)
-          console.log('🚀 ~ setTimeout ~ currentItemDom', currentItemDom)
+          // console.log('🚀 ~ setTimeout ~ currentItemDom', currentItemDom)
           console.log('🚀 ~ setTimeout ~ rect', rect, state.currentIndex)
 
           state.swipeHeight = rect.height
@@ -199,6 +214,9 @@ export default defineComponent({
       try {
         state.nextStatus = true
         if (state.questionList.length === state.currentIndex + 1) {
+          // 关闭所有音频
+          eventUnit.emit('unitAudioStop')
+
           router.back()
         }
         swipeRef.value?.next()
@@ -220,6 +238,10 @@ export default defineComponent({
       resizeSwipeItemHeight()
     })
 
+    onUnmounted(() => {
+      // 关闭所有音频
+      eventUnit.emit('unitAudioStop')
+    })
     return () => (
       <div class={styles.unitDetail}>
         <Cell center class={styles.unitSection} border={false}>

+ 1 - 1
src/views/unit-test/unit-list/index.module.less

@@ -66,7 +66,7 @@
     }
   }
   .liveList {
-    padding: 12px 13px 0;
+    padding: 0 13px 0;
   }
 }
 

+ 14 - 1
src/views/unit-test/unit-list/index.tsx

@@ -3,7 +3,7 @@ import OHeader from '@/components/o-header'
 import OSearch from '@/components/o-search'
 import OSticky from '@/components/o-sticky'
 import { ActionSheet, Button, Cell, CellGroup, Icon, Image, List, showToast } from 'vant'
-import { defineComponent, onMounted, reactive, ref } from 'vue'
+import { defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue'
 import styles from './index.module.less'
 import iconEdit from '../images/icon-edit.png'
 import iconAdd from '@common/images/icon_add.png'
@@ -12,6 +12,7 @@ import UnitListItem from './models/unit-list-item'
 import OFullRefresh from '@/components/o-full-refresh'
 import { state } from '@/state'
 import request from '@/helpers/request'
+import { postMessage } from '@/helpers/native-message'
 export default defineComponent({
   name: 'unit-list',
   setup() {
@@ -90,6 +91,18 @@ export default defineComponent({
     }
     onMounted(() => {
       getList()
+
+      // 处理返回上一页的问题
+      window.history.pushState(null, '', document.URL)
+      window.addEventListener('popstate', onBack, false)
+    })
+
+    const onBack = () => {
+      postMessage({ api: 'back' })
+    }
+
+    onUnmounted(() => {
+      window.removeEventListener('popstate', onBack)
     })
 
     const createUnit = () => {