浏览代码

更新页面

lex 2 年之前
父节点
当前提交
f9e5c5b95b

+ 3 - 1
src/components/m-header/index.tsx

@@ -4,6 +4,7 @@ import { NavBar } from 'vant';
 import { defineComponent, onMounted, reactive, watch } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import styles from './index.module.less';
+import { state } from '@/state';
 
 export default defineComponent({
   name: 'm-header',
@@ -47,7 +48,7 @@ export default defineComponent({
     const router = useRouter();
     const forms = reactive({
       title: '',
-      navBarHeight: 0 // 顶部高度
+      navBarHeight: state.navBarHeight // 顶部高度
     });
 
     const onClickLeft = () => {
@@ -65,6 +66,7 @@ export default defineComponent({
 
     onMounted(() => {
       forms.title = props.title || (route.meta.title as string);
+      forms.navBarHeight = state.navBarHeight;
     });
 
     watch(

+ 0 - 1
src/components/m-image-preview/index.tsx

@@ -57,7 +57,6 @@ export default defineComponent({
   },
   emits: ['update:show'],
   setup(props, { emit }) {
-    console.log(props.startPosition, 'update');
     const forms = reactive({
       show: false,
       index: props.startPosition + 1,

+ 57 - 0
src/helpers/utils.ts

@@ -75,3 +75,60 @@ export const formatterDatePicker = (type: any, option: any) => {
   }
   return option;
 };
+
+/**
+ * 数字转成汉字
+ * @params num === 要转换的数字
+ * @return 汉字
+ * */
+export const toChinesNum = (num: any) => {
+  const changeNum = [
+    '零',
+    '一',
+    '二',
+    '三',
+    '四',
+    '五',
+    '六',
+    '七',
+    '八',
+    '九'
+  ];
+  const unit = ['', '十', '百', '千', '万'];
+  num = parseInt(num);
+  const getWan = (temp: any) => {
+    const strArr = temp.toString().split('').reverse();
+    let newNum = '';
+    const newArr: string[] = [];
+    strArr.forEach((item: any, index: any) => {
+      newArr.unshift(
+        item === '0' ? changeNum[item] : changeNum[item] + unit[index]
+      );
+    });
+    const numArr: number[] = [];
+    newArr.forEach((m, n) => {
+      if (m !== '零') numArr.push(n);
+    });
+    if (newArr.length > 1) {
+      newArr.forEach((m, n) => {
+        if (newArr[newArr.length - 1] === '零') {
+          if (n <= numArr[numArr.length - 1]) {
+            newNum += m;
+          }
+        } else {
+          newNum += m;
+        }
+      });
+    } else {
+      newNum = newArr[0];
+    }
+
+    return newNum;
+  };
+  const overWan = Math.floor(num / 10000);
+  let noWan: any = num % 10000;
+  if (noWan.toString().length < 4) {
+    noWan = '0' + noWan;
+  }
+  return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num);
+};

+ 151 - 0
src/views/activity-record/detail.module.less

@@ -0,0 +1,151 @@
+.detail {
+  // height: 100vh;
+  // overflow: hidden;
+}
+
+.cellGroup {
+  margin-top: 12px;
+
+  .cellTitle {
+    padding: 15px 12px;
+
+    .tag {
+      font-size: 12px;
+      background-color: #F2FFFC;
+      padding: 3px 6px 2px;
+      border-radius: 3px;
+      margin-right: 6px;
+      flex-shrink: 0;
+    }
+
+    .title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #333333;
+      line-height: 22px;
+      max-width: 240px;
+    }
+  }
+
+  .cellTimerSkeleton {
+    display: flex;
+    justify-content: flex-end;
+  }
+
+  .cellTimer {
+    :global {
+      .van-cell__title {
+        flex: 0 auto;
+      }
+
+      .van-cell__title,
+      .van-cell__value {
+        color: var(--k-gray-3);
+        font-size: 14px;
+      }
+    }
+
+    .ing {
+      color: var(--k-font-primary);
+    }
+  }
+}
+
+.pTitle {
+  font-size: 14px;
+  color: var(--k-gray-2);
+  line-height: 20px;
+  margin: 20px 15px 12px;
+}
+
+.pCellGroup {
+  .imgType {
+    width: 46px;
+    height: 20px;
+    margin-right: 5px;
+    flex-shrink: 0;
+  }
+
+  .title {
+    font-size: 16px;
+    font-weight: 600;
+    color: var(--k-gray-1);
+    line-height: 22px;
+  }
+
+  .time {
+    font-size: 14px;
+    color: var(--k-gray-3);
+  }
+
+  .moreCell {
+    padding-top: 15px;
+    padding-bottom: 20px;
+  }
+
+  .valueClass {
+    .item {
+      margin-bottom: 15px;
+    }
+
+    text-align: left;
+    font-size: 15px;
+    color: var(--k-gray-1);
+
+    .label {
+      color: var(--k-gray-3);
+    }
+
+    .content {
+      font-weight: 500;
+
+      span {
+        font-size: 14px;
+        color: var(--k-font-primary);
+        margin-left: 10px;
+      }
+    }
+  }
+
+
+  .photoList {
+    display: flex;
+  }
+
+  .photo {
+    position: relative;
+    width: 76px;
+    height: 76px;
+
+    &+.photo {
+      margin-left: 7px;
+    }
+
+    :global {
+      .van-image {
+        width: inherit;
+        height: inherit;
+        border-radius: 2px;
+        overflow: hidden;
+      }
+    }
+
+    .photoMore {
+      position: absolute;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+      background: rgba(0, 0, 0, 0.5);
+      font-size: 14px;
+      color: #fff;
+      // font-weight: bold;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border-radius: 2px;
+      overflow: hidden;
+    }
+  }
+
+}

+ 168 - 2
src/views/activity-record/detail.tsx

@@ -1,8 +1,174 @@
-import { defineComponent } from 'vue';
+import MHeader from '@/components/m-header';
+import { Cell, CellGroup, Col, Icon, Row, Tag, Image } from 'vant';
+import { defineComponent, onMounted, reactive } from 'vue';
+import styles from './detail.module.less';
+import { toChinesNum } from '@/helpers/utils';
+import SOLO from './images/SOLO.png';
+import MImagePreview from '@/components/m-image-preview';
+import SkeletionIndexModal from './skeletion-index-modal';
+import SkeletionDetailModal from './skeletion-detail-modal';
+import request from '@/helpers/request';
+import { useRoute } from 'vue-router';
+import { activeStatus, activityStatus } from '@/helpers/constant';
+import dayjs from 'dayjs';
+import { formatterTimer } from './operation';
 
 export default defineComponent({
   name: 'detail-page',
   setup() {
-    return () => <>详情</>;
+    const route = useRoute();
+    // console.log(toChinesNum(11));
+    const forms = reactive({
+      id: route.query.id,
+      imageShow: false,
+      imagePreview: [] as any,
+      startPosition: 0,
+      headerLoading: true,
+      detailLoading: true,
+      detail: [] as any[],
+      headerDetail: {} as any
+    });
+
+    const getDetail = async () => {
+      try {
+        const { data } = await request.get(
+          '/api-web/schoolActivity/detail/' + forms.id
+        );
+        const { detail, ...res } = data || {};
+        forms.detail = detail;
+        forms.headerDetail = { ...res };
+      } catch {
+        //
+      } finally {
+        forms.headerLoading = false;
+        forms.detailLoading = false;
+      }
+    };
+
+    onMounted(() => {
+      // setTimeout(() => {
+      //   // forms.headerLoading = false;
+      //   // forms.detailLoading = false;
+      // }, 1000);
+      getDetail();
+    });
+    return () => (
+      <div class={styles.detail}>
+        <MHeader />
+
+        <SkeletionIndexModal
+          v-model:show={forms.headerLoading}
+          showCount={[1]}
+          isLink={false}>
+          <CellGroup inset class={styles.cellGroup}>
+            <Cell center isLink class={styles.cellTitle} clickable={false}>
+              {{
+                icon: () => (
+                  <Tag plain type="primary" class={styles.tag}>
+                    {activityStatus[forms.headerDetail.type]}
+                  </Tag>
+                ),
+                title: () => (
+                  <div class={[styles.title, 'van-ellipsis']}>
+                    {forms.headerDetail.name}
+                  </div>
+                )
+              }}
+            </Cell>
+            <Cell
+              class={styles.cellTimer}
+              center
+              title={`活动日期:${dayjs(forms.headerDetail.startTime).format(
+                'YYYY年MM月DD日'
+              )}`}
+              value={activeStatus[forms.headerDetail.status]}
+              valueClass={
+                forms.headerDetail.status === 'PROCESSING' ? styles.ing : ''
+              }></Cell>
+          </CellGroup>
+        </SkeletionIndexModal>
+
+        <SkeletionDetailModal
+          v-model:show={forms.detailLoading}
+          showCount={[1, 2]}>
+          {forms.detail.map((item: any, index: number) => (
+            <>
+              <div class={styles.pTitle}>节目{toChinesNum(index + 1)}</div>
+
+              <CellGroup inset class={styles.pCellGroup}>
+                <Cell center>
+                  {{
+                    icon: () => <img src={SOLO} class={styles.imgType} />,
+                    title: () => (
+                      <div class={[styles.title, 'van-ellipsis']}>
+                        {item.name}
+                      </div>
+                    ),
+                    value: () => {
+                      const timer = formatterTimer(item.time);
+                      return (
+                        <span class={styles.time}>
+                          {timer.minute}分{timer.secord}秒
+                        </span>
+                      );
+                    }
+                  }}
+                </Cell>
+                <Cell
+                  center
+                  class={styles.moreCell}
+                  valueClass={styles.valueClass}>
+                  <Row class={styles.item}>
+                    <Col span={5} class={styles.label}>
+                      表演乐团
+                    </Col>
+                    <Col span={19} class={styles.content}>
+                      {item.musicGroupName}
+                      <span>
+                        共{item.studentNum}名 <Icon name="arrow" />
+                      </span>
+                    </Col>
+                  </Row>
+                  <Row class={styles.item}>
+                    <Col span={5} class={styles.label}>
+                      表演团队
+                    </Col>
+                    <Col span={19} class={styles.content}>
+                      {item.subjectNameList}
+                    </Col>
+                  </Row>
+                  {item.attachmentUrl ? (
+                    <div class={styles.photoList}>
+                      {[1, 2, 3, 4, 5].map((i: any, index: number) => (
+                        <div class={styles.photo}>
+                          <Image
+                            src={
+                              'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/4854b7cb932d461fbaa4cc329666dbd6_mergeImage.png'
+                            }
+                          />
+                          {[1, 2, 3, 4, 5].length > 4 && index === 3 ? (
+                            <div class={styles.photoMore}>+8</div>
+                          ) : (
+                            ''
+                          )}
+                        </div>
+                      ))}
+                    </div>
+                  ) : (
+                    ''
+                  )}
+                </Cell>
+              </CellGroup>
+            </>
+          ))}
+        </SkeletionDetailModal>
+
+        <MImagePreview
+          v-model:show={forms.imageShow}
+          images={forms.imagePreview}
+          startPosition={forms.startPosition}
+        />
+      </div>
+    );
   }
 });

二进制
src/views/activity-record/images/ENSEMBLE.png


二进制
src/views/activity-record/images/REPRISE.png


二进制
src/views/activity-record/images/SOLO.png


二进制
src/views/activity-record/images/UNISON.png


+ 4 - 3
src/views/activity-record/index.module.less

@@ -8,10 +8,10 @@
       margin-right: 12px;
     }
   }
+}
 
-  .cellGroup {
-    margin-top: 12px;
-  }
+.cellGroup {
+  margin-top: 12px;
 
   .cellTitle {
     padding: 15px 12px;
@@ -58,6 +58,7 @@
   }
 }
 
+
 .castPopupContainer {
   --van-tab-font-size: 16px;
   --van-tabs-nav-background: #F8F9FC;

+ 15 - 2
src/views/activity-record/index.tsx

@@ -14,7 +14,7 @@ import {
 } from 'vant';
 import DropDownModal from '../site-management/drop-down-modal';
 import { activeStatus, activityStatus } from '@/helpers/constant';
-import SkeletionIndexModal from './skeletion-index.modal';
+import SkeletionIndexModal from './skeletion-index-modal';
 import MFullRefresh from '@/components/m-full-refresh';
 import MEmpty from '@/components/m-empty';
 import request from '@/helpers/request';
@@ -92,6 +92,16 @@ export default defineComponent({
       getList();
     };
 
+    // 查看详情
+    const onDetail = (item: any) => {
+      router.push({
+        path: '/activity-record-detail',
+        query: {
+          id: item.id
+        }
+      });
+    };
+
     onMounted(() => {
       for (const key in activityStatus) {
         if (Object.prototype.hasOwnProperty.call(activityStatus, key)) {
@@ -159,7 +169,10 @@ export default defineComponent({
               immediateCheck={false}>
               {forms.listState.dataShow ? (
                 forms.list.map((item: any) => (
-                  <CellGroup inset class={styles.cellGroup}>
+                  <CellGroup
+                    inset
+                    class={styles.cellGroup}
+                    onClick={() => onDetail(item)}>
                     <Cell
                       center
                       isLink

+ 1 - 1
src/views/activity-record/operation.tsx

@@ -259,7 +259,7 @@ export default defineComponent({
             name: item.name,
             type: item.type,
             musicGroupId: item.musicGroupId,
-            subjectIdList: item.subjectIdList,
+            subjectIdList: item.subjectIdList.join(','),
             studentNum: formatterStudents(item.performerList),
             studentList: item.performerList,
             time: item.time,

+ 98 - 0
src/views/activity-record/skeletion-detail-modal.tsx

@@ -0,0 +1,98 @@
+import {
+  Cell,
+  CellGroup,
+  Skeleton,
+  SkeletonImage,
+  SkeletonParagraph
+} from 'vant';
+import { defineComponent, onMounted, reactive, watch } from 'vue';
+import styles from './detail.module.less';
+
+export default defineComponent({
+  name: 'skeleton-modal',
+  props: {
+    show: {
+      type: Boolean,
+      default: false
+    },
+    showCount: {
+      type: Array,
+      default: () => [1, 2, 3]
+    },
+    isLink: {
+      type: Boolean,
+      default: true
+    }
+  },
+  setup(props, { slots }) {
+    const forms = reactive({
+      loading: false
+    });
+
+    onMounted(() => {
+      forms.loading = props.show;
+    });
+
+    watch(
+      () => props.show,
+      () => {
+        forms.loading = props.show;
+      }
+    );
+    return () => (
+      <Skeleton loading={forms.loading} style="flex-wrap: wrap">
+        {{
+          template: () => (
+            <div
+              style={{
+                height: props.isLink
+                  ? `calc(100vh - var(--header-height))`
+                  : 'auto',
+                overflow: 'hidden',
+                width: '100%'
+              }}>
+              {props.showCount.map(() => (
+                <>
+                  <SkeletonParagraph rowWidth={'20%'} class={styles.pTitle} />
+
+                  <CellGroup inset class={styles.pCellGroup}>
+                    <Cell center>
+                      {{
+                        title: () => (
+                          <SkeletonParagraph
+                            class={styles.title}
+                            rowWidth={'60%'}
+                          />
+                        ),
+                        value: () => (
+                          <SkeletonParagraph
+                            class={styles.time}
+                            rowWidth={'30%'}
+                          />
+                        )
+                      }}
+                    </Cell>
+                    <Cell
+                      center
+                      class={styles.moreCell}
+                      valueClass={styles.valueClass}>
+                      <SkeletonParagraph class={styles.item} rowWidth={'90%'} />
+                      <SkeletonParagraph class={styles.item} rowWidth={'90%'} />
+                      <div class={styles.photoList}>
+                        <SkeletonImage class={styles.photo} />
+                        <SkeletonImage class={styles.photo} />
+                        <SkeletonImage class={styles.photo} />
+                        <SkeletonImage class={styles.photo} />
+                      </div>
+                    </Cell>
+                  </CellGroup>
+                </>
+              ))}
+            </div>
+          ),
+          default: () => slots.default && slots.default()
+        }}
+      </Skeleton>
+    );
+  }
+});

+ 1 - 1
src/views/activity-record/skeletion-index.modal.tsx → src/views/activity-record/skeletion-index-modal.tsx

@@ -49,7 +49,7 @@ export default defineComponent({
                 <CellGroup inset class={styles.cellGroup}>
                   <Cell
                     center
-                    isLink
+                    isLink={props.isLink}
                     class={styles.cellTitle}
                     clickable={false}>
                     {{