瀏覽代碼

训练声部” 改为和当前老师账号的 “可教授乐器” 一致

skyblued 2 年之前
父節點
當前提交
ae5b68da6f

+ 35 - 10
src/teacher/piano-room/class-arrangement/index.tsx

@@ -22,6 +22,7 @@ import ColPopup from '@/components/col-popup'
 import SelectStudents, { IStudent } from './select-students'
 import CourseSchedule from './course-schedule'
 import { checkNumberInteger } from '@/helpers/toolsValidate'
+import Voice from '../model/voice'
 const fieldProps = {
   'is-link': true,
   readonly: true,
@@ -81,11 +82,13 @@ export default defineComponent({
     const studentRef = ref('') as any
 
     // 训练声部
+    const choiceSubjectIds = ref<[]>([])
     const subjectList = ref<[]>([]) // 声部分类
     const getSubjectSelect = async () => {
       try {
-        const res = await request.get('/api-teacher/subject/subjectSelect')
-        subjectList.value = res.data || []
+        // const res = await request.get('/api-teacher/subject/subjectSelect')
+        const teachRes = await request.post('/api-teacher/teacher/querySubject')
+        subjectList.value = teachRes.data || []
       } catch {}
     }
 
@@ -122,11 +125,13 @@ export default defineComponent({
     //检查上课时间是否满足后台设置的最晚时间
     const checkClassTimeIsSatisfyLastTime = () => {
       const baseTime = dayjs()
-      const _endTime = baseTime.set('hour', Number(startTime.value.split(':')[0]))
+      const _endTime = baseTime
+        .set('hour', Number(startTime.value.split(':')[0]))
         .set('minute', Number(startTime.value.split(':')[1]))
         .add(params.singleClssTime, 'minute')
-      const _endClassTime = baseTime.set('hour', Number(endClassTime.value.split(':')[0]))
-      .set('minute', Number(endClassTime.value.split(':')[1]))
+      const _endClassTime = baseTime
+        .set('hour', Number(endClassTime.value.split(':')[0]))
+        .set('minute', Number(endClassTime.value.split(':')[1]))
       // console.log(_endTime.format('HH:mm'),_endClassTime.format('HH:mm'))
       return {
         isOk: _endTime.isBefore(_endClassTime),
@@ -203,7 +208,6 @@ export default defineComponent({
     const curriculum = ref<string[]>([])
     //  设置排课数据
     const setParmas = () => {
-      
       if (!params.courseName) {
         Toast('请填写课程名称')
         return
@@ -212,12 +216,15 @@ export default defineComponent({
         Toast('请选择训练声部')
         return
       }
-      
+
       if (!params.singleClssTime) {
         Toast('请填写单课时时长')
         return
       }
-      if (checkNumberInteger(String(params.singleClssTime)) || params.singleClssTime < 0) {
+      if (
+        checkNumberInteger(String(params.singleClssTime)) ||
+        params.singleClssTime < 0
+      ) {
         Toast('课时时长为正整数')
         return
       }
@@ -462,13 +469,31 @@ export default defineComponent({
             round
             closeable
             safe-area-inset-bottom
+            class={styles.voicePopup}
           >
-            <OrganSearch
+            <Voice
+             class={styles.voicePopupContent}
+              single
+              selectType={'Radio'}
+              subjectList={subjectList.value}
+              onChoice={val => {
+                const voice: any = subjectList.value.filter((n: any) => n.id === val)[0]
+                if(voice){
+                  params.subjectId = voice.id
+                  params.subjectName = voice.name
+                  voiceShow.value = false
+                } else {
+                  params.subjectId = 0
+                  params.subjectName = ''
+                }
+              }}
+            />
+            {/* <OrganSearch
               subjectList={subjectList.value}
               v-model={params.subjectId}
               v-model:subjectName={params.subjectName}
               onSort={() => (voiceShow.value = false)}
-            />
+            /> */}
           </Popup>
 
           <Popup position="bottom" v-model:show={timeShow.value} round>

+ 13 - 9
src/teacher/piano-room/class-arrangement/select-students/index.tsx

@@ -16,6 +16,7 @@ import Student from '../../components/student'
 import request from '@/helpers/request'
 import OrganSearch from '@/student/practice-class/model/organ-search'
 import cleanDeep from 'clean-deep'
+import Voice from '../../model/voice'
 
 export type IStudent = {
   avatar: string
@@ -59,11 +60,9 @@ export default defineComponent({
             }
           }
         )
-        if (code === 200 && data.rows.length) {
+        if (code === 200) {
           data.rows.forEach((n: IStudent) => (n.checked = false))
-        
           list.value = data.rows
-          console.log(list.value)
         }
       } catch (error) {}
     }
@@ -132,7 +131,7 @@ export default defineComponent({
             class={styles.confirmBtn}
             type="primary"
             onClick={() => {
-              let stus = cleanDeep(list.value.filter(n => n.checked)) 
+              let stus = cleanDeep(list.value.filter(n => n.checked))
               // console.log(stus)
               props.onSetStudents && props.onSetStudents(stus)
             }}
@@ -147,12 +146,17 @@ export default defineComponent({
           closeable
           safe-area-inset-bottom
         >
-          <OrganSearch
-            isReset
+          <Voice
+            class={styles.voicePopupContent}
+            single
+            selectType={'Radio'}
             subjectList={props.subjectList}
-            v-model={params.subjectId}
-            v-model:subjectName={subjectName.value}
-            onSort={() => {
+            onChoice={val => {
+              const voice: any = props.subjectList.filter(
+                (n: any) => n.id === val
+              )[0] || { name: '全部声部' }
+              params.subjectId = voice.id
+              subjectName.value = voice.name
               show.value = false
               getList()
             }}

+ 98 - 0
src/teacher/piano-room/model/voice/index.module.less

@@ -0,0 +1,98 @@
+.subjects {
+  padding: 15px 0 0;
+  .subjectContainer {
+    height: 45vh;
+    overflow-y: auto;
+  }
+  .title {
+    padding: 12px 0;
+    margin: 0 15px;
+    color: #333;
+    font-size: 16px;
+    &::before {
+      content: ' ';
+      display: inline-block;
+      width: 3px;
+      height: 16px;
+      background: #2dc7aa;
+      border-radius: 3px;
+      margin-right: 8px;
+      vertical-align: text-bottom;
+    }
+  }
+
+  .subject-list {
+    display: flex;
+    align-items: center;
+    // justify-content: space-between;
+    // justify-content: center;
+    flex-wrap: wrap;
+    padding: 0 10px;
+
+    .subject-item {
+      position: relative;
+      width: 108px;
+      height: 108px;
+      margin-right: 5px;
+      margin-left: 5px;
+      margin-bottom: 10px;
+      border-radius: 7px;
+      overflow: hidden;
+    }
+
+    .topBg {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background: linear-gradient(
+        180deg,
+        rgba(0, 0, 0, 0) 0%,
+        rgba(0, 0, 0, 0.54) 100%
+      );
+    }
+
+    .checkbox {
+      position: absolute;
+      right: 7px;
+      top: 7px;
+    }
+
+    .name {
+      position: absolute;
+      bottom: 7px;
+      left: 7px;
+      font-size: 16px;
+      font-weight: 500;
+      color: #ffffff;
+      line-height: 22px;
+    }
+
+    :global {
+      .van-checkbox__icon,
+      .van-radio__icon {
+        height: 22px;
+        .van-icon {
+          border: 0;
+          background-color: transparent;
+        }
+      }
+      .van-checkbox__icon--checked .van-icon,
+      .van-radio__icon--checked .van-icon {
+        background-color: transparent;
+        border: transparent;
+      }
+    }
+  }
+}
+
+.btns{
+    display: flex;
+    justify-content: space-around;
+    :global{
+        .van-button{
+            width: 45%;
+        }
+    }
+}

+ 311 - 0
src/teacher/piano-room/model/voice/index.tsx

@@ -0,0 +1,311 @@
+import {
+  Button,
+  Checkbox,
+  CheckboxGroup,
+  Icon,
+  Image,
+  Loading,
+  Radio,
+  RadioGroup,
+  Sticky,
+  Toast
+} from 'vant'
+import { defineComponent, PropType } from 'vue'
+import styles from './index.module.less'
+
+import checkBoxActive from '@/teacher/teacher-cert/images/checkbox_active.png'
+import checkBoxDefault from '@/teacher/teacher-cert/images/checkbox_default.png'
+import ColResult from '@/components/col-result'
+
+export default defineComponent({
+  name: 'SubjectList',
+  props: {
+    onChoice: {
+      type: Function,
+      default: (item: any) => {}
+    },
+    choiceSubjectIds: {
+      type: Array,
+      default: []
+    },
+    subjectList: {
+      type: Array,
+      default: []
+    },
+    max: {
+      // 最多可选数量
+      type: Number,
+      default: 5
+    },
+    selectType: {
+      // 选择类型,Radio:单选,Checkbox:多选
+      type: String as PropType<'Checkbox' | 'Radio'>,
+      default: 'Checkbox'
+    },
+    single: {
+      // 单选模式
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      checkBox: [],
+      checkboxRefs: [] as any,
+      radio: null as any // 单选
+    }
+  },
+  async mounted() {
+    this.checkBox = this.choiceSubjectIds as never[]
+  },
+  watch: {
+    choiceSubjectIds(val: any, oldVal) {
+      // 同步更新显示数据
+      this.checkBox = [...val] as never[]
+    }
+  },
+  methods: {
+    onSelect(id: number) {
+      if (this.selectType === 'Checkbox') {
+        if (
+          this.max === this.checkBox.length &&
+          !this.checkBox.includes(id as never)
+        ) {
+          Toast(`乐器最多选择${this.max}个`)
+        }
+        this.checkboxRefs[id].toggle()
+      } else if (this.selectType === 'Radio') {
+        this.radio = id
+      }
+    }
+  },
+  render() {
+    return (
+      <div class={styles.subjects}>
+        <div class={styles.subjectContainer}>
+          {this.subjectList.length ? (
+            this.selectType === 'Checkbox' ? (
+              <CheckboxGroup v-model={this.checkBox} max={this.max}>
+                {!this.single &&
+                  this.subjectList.map((item: any) =>
+                    item.subjects && item.subjects.length > 0 ? (
+                      <>
+                        <div class={styles.title}>{item.name}</div>
+                        <div class={styles['subject-list']}>
+                          {item.subjects &&
+                            item.subjects.map((sub: any) => (
+                              <div
+                                class={styles['subject-item']}
+                                onClick={() => this.onSelect(sub.id)}
+                              >
+                                <Image
+                                  src={sub.img || 'xxx'}
+                                  width="100%"
+                                  height="100%"
+                                  fit="cover"
+                                  v-slots={{
+                                    loading: () => (
+                                      <Loading type="spinner" size={20} />
+                                    )
+                                  }}
+                                />
+                                <div class={styles.topBg}>
+                                  <Checkbox
+                                    name={sub.id}
+                                    class={styles.checkbox}
+                                    disabled
+                                    ref={(el: any) =>
+                                      (this.checkboxRefs[sub.id] = el)
+                                    }
+                                    v-slots={{
+                                      icon: (props: any) => (
+                                        <Icon
+                                          name={
+                                            props.checked
+                                              ? checkBoxActive
+                                              : checkBoxDefault
+                                          }
+                                          size="20"
+                                        />
+                                      )
+                                    }}
+                                  />
+                                  <p class={styles.name}>{sub.name}</p>
+                                </div>
+                              </div>
+                            ))}
+                        </div>
+                      </>
+                    ) : null
+                  )}
+                {this.single ? (
+                  <div class={styles['subject-list']}>
+                    {this.subjectList.map((item: any) => (
+                      <div
+                        class={styles['subject-item']}
+                        onClick={() => this.onSelect(item.id)}
+                      >
+                        <Image
+                          src={item.img || 'xxx'}
+                          width="100%"
+                          height="100%"
+                          fit="cover"
+                          v-slots={{
+                            loading: () => <Loading type="spinner" size={20} />
+                          }}
+                        />
+                        <div class={styles.topBg}>
+                          <Checkbox
+                            name={item.id}
+                            class={styles.checkbox}
+                            disabled
+                            ref={(el: any) => (this.checkboxRefs[item.id] = el)}
+                            v-slots={{
+                              icon: (props: any) => (
+                                <Icon
+                                  name={
+                                    props.checked
+                                      ? checkBoxActive
+                                      : checkBoxDefault
+                                  }
+                                  size="20"
+                                />
+                              )
+                            }}
+                          />
+                          <p class={styles.name}>{item.name}</p>
+                        </div>
+                      </div>
+                    ))}
+                  </div>
+                ) : null}
+              </CheckboxGroup>
+            ) : (
+              <RadioGroup v-model={this.radio}>
+                {!this.single &&
+                  this.subjectList.map((item: any) =>
+                    item.subjects && item.subjects.length > 0 ? (
+                      <>
+                        <div class={styles.title}>{item.name}</div>
+                        <div class={styles['subject-list']}>
+                          {item.subjects &&
+                            item.subjects.map((sub: any) => (
+                              <div
+                                class={styles['subject-item']}
+                                onClick={() => this.onSelect(sub.id)}
+                              >
+                                <Image
+                                  src={sub.img || 'xxx'}
+                                  width="100%"
+                                  height="100%"
+                                  fit="cover"
+                                  v-slots={{
+                                    loading: () => (
+                                      <Loading type="spinner" size={20} />
+                                    )
+                                  }}
+                                />
+                                <div class={styles.topBg}>
+                                  <Radio
+                                    name={sub.id}
+                                    class={styles.checkbox}
+                                    v-slots={{
+                                      icon: (props: any) => (
+                                        <Icon
+                                          name={
+                                            props.checked
+                                              ? checkBoxActive
+                                              : checkBoxDefault
+                                          }
+                                          size="20"
+                                        />
+                                      )
+                                    }}
+                                  />
+                                  <p class={styles.name}>{sub.name}</p>
+                                </div>
+                              </div>
+                            ))}
+                        </div>
+                      </>
+                    ) : null
+                  )}
+                {this.single ? (
+                  <div class={styles['subject-list']}>
+                    {this.subjectList.map((item: any) => (
+                      <div
+                        class={styles['subject-item']}
+                        onClick={() => this.onSelect(item.id)}
+                      >
+                        <Image
+                          src={item.img || 'xxx'}
+                          width="100%"
+                          height="100%"
+                          fit="cover"
+                          v-slots={{
+                            loading: () => <Loading type="spinner" size={20} />
+                          }}
+                        />
+                        <div class={styles.topBg}>
+                          <Radio
+                            name={item.id}
+                            class={styles.checkbox}
+                            v-slots={{
+                              icon: (props: any) => (
+                                <Icon
+                                  name={
+                                    props.checked
+                                      ? checkBoxActive
+                                      : checkBoxDefault
+                                  }
+                                  size="20"
+                                />
+                              )
+                            }}
+                          />
+                          <p class={styles.name}>{item.name}</p>
+                        </div>
+                      </div>
+                    ))}
+                  </div>
+                ) : null}
+              </RadioGroup>
+            )
+          ) : (
+            <ColResult tips="暂无声部数据" btnStatus={false} />
+          )}
+        </div>
+
+        {this.subjectList.length > 0 && (
+          <Sticky offsetBottom={0} position="bottom">
+            <div class={['btnGroup', styles.btns]}>
+              <Button
+                round
+                block
+                onClick={() => {
+                  this.checkBox = []
+                  this.radio = ''
+                  this.onChoice()
+                }}
+              >
+                重置
+              </Button>
+              <Button
+                round
+                block
+                type="primary"
+                onClick={() =>
+                  this.onChoice(
+                    this.selectType === 'Checkbox' ? this.checkBox : this.radio
+                  )
+                }
+              >
+                确定
+              </Button>
+            </div>
+          </Sticky>
+        )}
+      </div>
+    )
+  }
+})