| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 | import {  Button,  Cell,  CellGroup,  Checkbox,  CheckboxGroup,  Field,  Icon,  Image,  List,  Radio,  RadioGroup,  Tag,  showToast} from 'vant';import { defineComponent, onMounted, reactive, ref, watch } from 'vue';import styles from './detail.module.less';import iconTimer from '@/common/images/icon-timer.png';import iconTeacher from '@/common/images/icon-teacher-default.png';import iconEdit from '@/common/images/icon-edit.png';import iconFace1 from './images/icon-face-1.png';import iconFace2 from './images/icon-face-2.png';import iconFace3 from './images/icon-face-3.png';import iconFace4 from './images/icon-face-4.png';import iconUploadImg from './images/icon-upload-img.png';import iconUploadVideo from './images/icon-upload-video.png';import iconTips from './images/icon-tips.png';import SkeletionDetailModal from './skeletion-detail.modal';import MUploader from '@/components/m-uploader';import MUploaderInside from '@/components/m-uploader/inside';import MFullRefresh from '@/components/m-full-refresh';import { coursesStatus, evaluateStatus, problemType } from '@/helpers/constant';import MEmpty from '@/components/m-empty';import request from '@/helpers/request';import dayjs from 'dayjs';import { useRoute } from 'vue-router';import MImagePreview from '@/components/m-image-preview';import { checkFile } from '@/helpers/toolsValidate';import deepClone from '@/helpers/deep-clone';import iconVideoDefault from '@common/images/icon-video-c.png';export default defineComponent({  name: 'detail-list',  props: {    type: {      type: String,      default: ''    },    evaluateStatus: {      type: String,      default: ''    },    problemType: {      type: String,      default: ''    },    courseType: {      type: String,      default: ''    },    status: {      type: String,      default: ''    },    activeTab: {      type: String,      default: 'NotEvaluated'    }  },  setup(props) {    const route = useRoute();    const forms = reactive({      isClick: false,      imageShow: false,      startPosition: 0,      imagePreview: [] as string[],      listState: {        dataShow: true, // 判断是否有数据        loading: true,        finished: false,        refreshing: false      },      params: {        evaluateFlag: props.type === 'Evaluated' ? true : false,        evaluateStatus: '',        problemType: '',        courseType: '',        status: '',        startTime: route.query.date || '',        endTime: route.query.date || '',        page: 1,        rows: 20      },      changeType: null,      questionType: null,      evaluateList: [] as any,      problemTypeList: [] as any,      list: [],      btnLoading: false    });    const list = ref([] as any[]);    const onRefresh = () => {      forms.params.page = 1;      forms.listState.refreshing = true;      getList();    };    const getList = async () => {      try {        if (forms.isClick) return;        forms.isClick = true;        const { data } = await request.post(          '/api-web/coursePatrolEvaluation/page',          {            data: forms.params          }        );        const result = data || {};        // 格式化数据        const rows = result.rows || [];        rows.forEach((row: any) => {          const attachmentUrlList = row.attachmentUrl            ? row.attachmentUrl.split(',')            : [];          const problemTypeList = row.problemType            ? row.problemType.split(',')            : [];          row.problemTypeList = problemTypeList;          // 级别          row.submitEvaluateStatus = row.evaluateStatus || '';          // 问题类型          row.submitProblemType = problemTypeList || [];          row.submitProblemDesc = row.problemDesc || '';          // 图片和视屏          row.submitVideoList = [];          row.submitImgList = [];          attachmentUrlList.forEach((url: any) => {            // 判断是否是图片            if (checkFile(url, 'image')) {              row.submitImgList.push(url);            } else {              row.submitVideoList.push(url);            }            // 判断是否是视频          });          row.attachmentUrlList = attachmentUrlList || [];          // 判断是否评价,如果有评价则直接显示评价内容          if (!row.evaluateFlag) {            row.isEdit = true;          }          // 判断课程时间是否在当前时间之前;          if (            dayjs(dayjs().format('YYYY-MM-DD')).isAfter(              dayjs(row.courseDate).format('YYYY-MM-DD')            ) &&            !row.evaluateFlag          ) {            row.isEdit = false;            row.isDisabled = true;          }        });        // 判断是否有数据        if (forms.listState.refreshing) {          list.value = rows || [];        } else {          list.value = list.value.concat(rows || []);        }        forms.listState.finished = result.pageNo >= result.totalPage;        forms.params.page = result.pageNo + 1;      } catch {        forms.listState.finished = true;      } finally {        setTimeout(() => {          forms.listState.dataShow = list.value.length > 0;          forms.listState.refreshing = false;          forms.listState.loading = false;          forms.isClick = false;        }, 300);      }    };    // 提交评价    const onSubmit = async (item: any) => {      try {        const url = [...item.submitImgList, ...item.submitVideoList];        //        if (!item.submitEvaluateStatus) {          showToast('请选择评价');          return;        }        // 当选择“不合格”的时候,问题类型、问题描述、上传附件为必填项        if (item.submitEvaluateStatus === 'UNQUALIFIED') {          if (            !item.submitProblemType ||            (item.submitProblemType && item.submitProblemType.length <= 0)          ) {            showToast('请选择问题类型');            return;          }          if (!item.submitProblemDesc) {            showToast('请输入问题描述');            return;          }          if (item.submitProblemDesc.length < 3) {            showToast('问题描述最少输入3个字');            return;          }          // 最大支持3-50汉字          if (            item.submitProblemDesc.length < 3 ||            item.submitProblemDesc.length <= 50          )            if (url.length <= 0) {              showToast('请上传附件');              return;            }        }        const params = {          id: item.id,          evaluateStatus: item.submitEvaluateStatus,          problemType: item.submitProblemType.join(','),          problemDesc: item.submitProblemDesc,          attachmentUrl: url.join(',')        };        forms.btnLoading = true;        if (item.evaluateFlag) {          // 修改          await request.post('/api-web/coursePatrolEvaluation/update', {            // hideLoading: false,            data: params          });        } else {          // 添加          await request.post('/api-web/coursePatrolEvaluation/save', {            // hideLoading: false,            data: {              ...params,              courseScheduleId: item.courseScheduleId            }          });        }        forms.btnLoading = false;        list.value = [];        onRefresh();      } catch {        //        forms.btnLoading = false;      }    };    const onShowPreView = (attachmentUrlList: string[], index: number) => {      forms.imagePreview = deepClone(attachmentUrlList);      forms.imageShow = true;      forms.startPosition = index;    };    const formatFace = (type: string) => {      if (type === 'EXCELLENT') {        return iconFace1;      } else if (type === 'GOOD') {        return iconFace2;      } else if (type === 'QUALIFIED') {        return iconFace3;      } else if (type === 'UNQUALIFIED') {        return iconFace4;      } else {        return iconFace1;      }    };    onMounted(() => {      for (const key in evaluateStatus) {        if (Object.prototype.hasOwnProperty.call(evaluateStatus, key)) {          forms.evaluateList.push({            text: evaluateStatus[key],            value: key          });        }      }      for (const key in problemType) {        if (Object.prototype.hasOwnProperty.call(problemType, key)) {          forms.problemTypeList.push({            text: problemType[key],            value: key          });        }      }      getList();    });    // 监听    watch(      () => [        props.evaluateStatus,        props.problemType,        props.courseType,        props.status      ],      () => {        forms.params.evaluateStatus = props.evaluateStatus;        forms.params.problemType = props.problemType;        forms.params.courseType = props.courseType;        forms.params.status = props.status;        list.value = [];        onRefresh();      }    );    watch(      () => props.activeTab,      () => {        if (props.type === props.activeTab) {          forms.params.evaluateStatus = props.evaluateStatus;          forms.params.problemType = props.problemType;          forms.params.courseType = props.courseType;          forms.params.status = props.status;          list.value = [];          onRefresh();        }      }    );    return () => (      <div>        <SkeletionDetailModal v-model:show={forms.listState.loading}>          <MFullRefresh            v-model:modelValue={forms.listState.refreshing}            onRefresh={() => onRefresh()}            style={{              minHeight: `calc(100vh - var(--header-height) - var(--van-tabs-line-height))`            }}>            <List              finished={forms.listState.finished}              finishedText=" "              style={{ overflow: 'hidden', marginBottom: '18px' }}              onLoad={getList}              offset={100}              immediateCheck={false}>              {forms.listState.dataShow ? (                list.value.map((item: any) => {                  return (                    <CellGroup inset class={styles.cellGroup}>                      <Cell center class={styles.timerCell} border={false}>                        {{                          icon: () => (                            <Icon name={iconTimer} class={styles.iconTimer} />                          ),                          title: () => (                            <div class={styles.timer}>                              {dayjs(item.startClassTime).format(                                'YYYY-MM-DD HH:mm'                              )}                              ~{dayjs(item.endClassTime).format('HH:mm')}                            </div>                          ),                          value: () => (                            <div                              class={styles.eStatus}                              onClick={() => {                                if (item.isDisabled) return;                                item.isEdit = true;                              }}>                              {/* 判断是否评价 */}                              {item.evaluateFlag ? (                                <>                                  <div class={styles.evaluateResult}>                                    <Icon                                      name={formatFace(item.evaluateStatus)}                                      class={styles.iconFace}                                    />                                    <span                                      class={[                                        styles.sLevel,                                        item.evaluateStatus === 'UNQUALIFIED'                                          ? styles.error                                          : styles.success                                      ]}>                                      {evaluateStatus[item.evaluateStatus]}                                    </span>                                  </div>                                  <Icon                                    name={iconEdit}                                    class={styles.iconEdit}                                  />                                </>                              ) : (                                <span                                  class={[                                    styles.sLevel,                                    item.courseStatus === 'UNDERWAY'                                      ? styles.success                                      : '',                                    item.courseStatus == 'OVER'                                      ? styles.over                                      : ''                                  ]}>                                  {coursesStatus[item.courseStatus]}                                </span>                              )}                            </div>                          )                        }}                      </Cell>                      <Cell center class={styles.usernameCell}>                        {{                          icon: () => (                            <Image                              src={item.teacherAvatar || iconTeacher}                              class={styles.iconTeacher}                              fit="cover"                            />                          ),                          title: () => (                            <div>                              <div class={styles.classname}>                                {item.courseName}                              </div>                              <div class={styles.name}>{item.teacherName}</div>                            </div>                          ),                          value: () => (                            <div class={styles.photoList}>                              {item.attachmentUrlList.map(                                (file: string, index: number) =>                                  index < 3 && (                                    <div                                      class={styles.photo}                                      onClick={(e: MouseEvent) => {                                        e.stopPropagation();                                        e.preventDefault();                                        onShowPreView(                                          item.attachmentUrlList,                                          index                                        );                                      }}>                                      {checkFile(file, 'image') ? (                                        <Image                                          src={                                            file                                          }                                          fit="cover"                                        />                                      ) : (                                        <video                                          poster={iconVideoDefault}                                          src={file + '#t=1,4'}                                          controls={false}></video>                                      )}                                      {/* 判断是否大于三个 */}                                      {item.attachmentUrlList.length > 3 &&                                      index === 2 ? (                                        <div class={styles.photoMore}>                                          +{item.attachmentUrlList.length - 3}                                        </div>                                      ) : (                                        ''                                      )}                                    </div>                                  )                              )}                            </div>                          )                        }}                      </Cell>                      {/* 展示结果 */}                      {(item.submitProblemType.length > 0 ||                        item.problemDesc) &&                      !item.isEdit ? (                        <Cell center class={styles.resultCell}>                          {item.problemTypeList.length > 0 ? (                            <div class={styles.typeGroup}>                              {item.problemTypeList.map((type: string) => (                                <Tag type="primary" plain>                                  {problemType[type]}                                </Tag>                              ))}                            </div>                          ) : (                            ''                          )}                          {item.problemDesc ? (                            <div class={styles.result}>{item.problemDesc}</div>                          ) : (                            ''                          )}                        </Cell>                      ) : (                        ''                      )}                      {/* 未开始的不能进行评价 */}                      {item.isEdit && item.courseStatus != 'NOT_START' ? (                        <Cell center class={styles.operationCell}>                          <RadioGroup                            class={styles.typeGroup}                            v-model={item.submitEvaluateStatus}>                            {forms.evaluateList.map((child: any) => (                              <Tag                                type={                                  item.submitEvaluateStatus === child.value                                    ? 'primary'                                    : 'default'                                }                                plain>                                <Radio name={child.value} />                                {child.text}                              </Tag>                            ))}                          </RadioGroup>                          {/* 当选择“不合格”的时候,问题类型、问题描述、上传附件为必填项 当选择除不合格的其他选项时,问题类型、问题描述不展示,桑川附件为选填 */}                          {item.submitEvaluateStatus === 'UNQUALIFIED' ? (                            <>                              <div class={styles.operationTitle}>问题类型</div>                              <CheckboxGroup                                class={styles.typeGroup}                                v-model={item.submitProblemType}>                                {forms.problemTypeList.map((child: any) => (                                  <Tag                                    type={                                      item.submitProblemType.includes(                                        child.value                                      )                                        ? 'primary'                                        : 'default'                                    }                                    plain>                                    <Checkbox name={child.value} />                                    {child.text}                                  </Tag>                                ))}                              </CheckboxGroup>                              <div class={styles.operationTitle}>问题描述</div>                              <Field                                type="textarea"                                rows={2}                                v-model={item.submitProblemDesc}                                maxlength={50}                                class={styles.questionContent}                                placeholder="请输入问题描述..."                                border={false}                              />                            </>                          ) : (                            ''                          )}                          <div class={styles.operationTitle}>上传附件</div>                          <div class={styles.uploadGroup}>                            <MUploader                              uploadIcon={iconUploadImg}                              maxCount={5}                              native                              v-model:modelValue={item.submitImgList}>                              <MUploaderInside                                uploadIcon={iconUploadVideo}                                uploadType="VIDEO"                                accept=".mp4"                                uploadSize={50}                                native                                maxCount={3}                                v-model:modelValue={item.submitVideoList}                              />                            </MUploader>                          </div>                          <div                            class={[                              styles.btnGroup,                              !item.evaluateFlag ? styles.singleBtn : ''                            ]}>                            {/* 评价之后才能取消 */}                            {item.evaluateFlag ? (                              <Button                                type="default"                                round                                block                                onClick={() => (item.isEdit = false)}>                                取消                              </Button>                            ) : (                              ''                            )}                            <Button                              type="primary"                              round                              block                              disabled={forms.btnLoading}                              loading={forms.btnLoading}                              onClick={() => onSubmit(item)}>                              确认                            </Button>                          </div>                        </Cell>                      ) : (                        ''                      )}                      {/* 课程是否已经结束 - 未评价 */}                      {item.isDisabled ? (                        <div class={styles.tips}>                          <Icon name={iconTips} class={styles.iconTips} />                          昨天及昨天之前课程不可评价                        </div>                      ) : (                        ''                      )}                    </CellGroup>                  );                })              ) : (                <MEmpty                  style={{                    minHeight: `calc(100vh - var(--header-height))`                  }}                  description="暂无数据"                />              )}            </List>          </MFullRefresh>        </SkeletionDetailModal>        <MImagePreview          teleport="body"          v-model:show={forms.imageShow}          images={forms.imagePreview}          startPosition={forms.startPosition}        />      </div>    );  }});
 |