Browse Source

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

mo 2 năm trước cách đây
mục cha
commit
f6f3abe862
40 tập tin đã thay đổi với 1162 bổ sung702 xóa
  1. 1 0
      public/MP_verify_JBxw7GJRojiTpURa.txt
  2. 1 1
      public/project/manageTeacher.html
  3. 4 4
      src/helpers/utils.ts
  4. 8 1
      src/router/routes-student.ts
  5. 1 1
      src/school/approval-manage/course-adjust.tsx
  6. 10 0
      src/school/companion-teacher/companion-detail.module.less
  7. 27 17
      src/school/companion-teacher/companion-detail.tsx
  8. 12 0
      src/school/companion-teacher/index.module.less
  9. 72 45
      src/school/companion-teacher/index.tsx
  10. 2 0
      src/school/manage-teacher/index.module.less
  11. 1 1
      src/school/manage-teacher/index.tsx
  12. 2 1
      src/school/manage-teacher/menu-function.tsx
  13. 6 5
      src/school/orchestra/compontent/information.tsx
  14. 12 0
      src/school/orchestra/compontent/photo.module.less
  15. 109 21
      src/school/orchestra/compontent/photo.tsx
  16. 7 6
      src/school/orchestra/compontent/plan.tsx
  17. BIN
      src/school/orchestra/images/icon_more.png
  18. 18 19
      src/school/train-planning/component/course-preview/index.tsx
  19. 1 1
      src/school/train-planning/component/practice-detail/index.tsx
  20. 11 2
      src/school/train-planning/component/practice/index.tsx
  21. 11 5
      src/school/train-planning/component/standard/index.tsx
  22. 1 1
      src/school/train-planning/create.ts
  23. 2 0
      src/school/train-planning/modal/calendar/index.tsx
  24. 8 1
      src/school/train-planning/modal/practice-class/index.tsx
  25. 18 8
      src/school/train-planning/modal/timer/index.tsx
  26. 2 2
      src/student/main.ts
  27. 3 3
      src/student/music-group/pre-apply/component/addres.tsx
  28. 15 21
      src/student/music-group/pre-apply/component/order.tsx
  29. 253 179
      src/student/music-group/pre-apply/component/payment.tsx
  30. 9 4
      src/student/music-group/pre-apply/index.tsx
  31. 195 46
      src/student/music-group/pre-apply/order-detail.tsx
  32. 110 13
      src/student/music-group/shop-address/address-operation.tsx
  33. 66 15
      src/student/music-group/shop-address/index.tsx
  34. BIN
      src/student/payment-result/images/icon_refunded.png
  35. BIN
      src/student/payment-result/images/icon_refunding.png
  36. BIN
      src/student/payment-result/images/icon_success.png
  37. 4 0
      src/student/payment-result/index.module.less
  38. 16 0
      src/student/payment-result/index.tsx
  39. 25 127
      src/views/adapay/pay-define/index.tsx
  40. 119 152
      src/views/adapay/pay-result/index.tsx

+ 1 - 0
public/MP_verify_JBxw7GJRojiTpURa.txt

@@ -0,0 +1 @@
+JBxw7GJRojiTpURa

+ 1 - 1
public/project/manageTeacher.html

@@ -104,7 +104,7 @@
         <div class="submit-container">
           <p class="submit-title">恭喜您已成功登记为</p>
           <p class="submit-o">{{ decodeURI(name) }} <span>【管理老师】</span></p>
-          <p class="submit-tips">请下载管乐团管理端APP进行授课</p>
+          <p class="submit-tips">请下载管乐团管理端APP</p>
           <van-button type="primary" color="#64A9FF" block round @click="submitStatus = false">立即下载</van-button>
         </div>
       </div>

+ 4 - 4
src/helpers/utils.ts

@@ -32,10 +32,10 @@ export const browser = () => {
 }
 
 // 获取授权的code码
-export const getUrlCode = () => {
+export const getUrlCode = (name = 'code') => {
   // 截取url中的code方法
   const url = location.search;
-  const theRequest = new Object();
+  const theRequest: any = new Object();
   if (url.indexOf("?") != -1) {
     const str = url.substr(1);
     const strs = str.split("&");
@@ -43,8 +43,8 @@ export const getUrlCode = () => {
       theRequest[strs[i].split("=")[0]] = strs[i].split("=")[1];
     }
   }
-  console.log(theRequest);
-  return theRequest;
+  console.log(theRequest, 'theRequest');
+  return theRequest[name];
 
 };
 

+ 8 - 1
src/router/routes-student.ts

@@ -7,7 +7,14 @@ type metaType = {
 }
 
 const noLoginRouter = [
-
+  {
+    path: '/payment-result',
+    name: 'payment-result',
+    component: () => import('@/student/payment-result/index'),
+    meta: {
+      title: '支付详情'
+    }
+  }
 ]
 
 export default [

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

@@ -200,7 +200,7 @@ export default defineComponent({
           </div>
 
           {/* 选择训练开始日期 */}
-          <OPopup v-model:modelValue={state.showPopoverTime} position="bottom">
+          <OPopup v-model:modelValue={state.showPopoverTime} position="bottom" destroy>
             <Calendar
               list={state.calendarList}
               nextMonth={(date: Date) => getList(date)}

+ 10 - 0
src/school/companion-teacher/companion-detail.module.less

@@ -4,6 +4,16 @@
   border-radius: 10px;
 }
 
+.subjectContainer {
+  display: flex;
+  & > span {
+    flex-shrink: 0;
+  }
+  .tagSubject {
+    margin-right: 10px;
+  }
+}
+
 .detailCell {
   padding: 15px 13px;
 

+ 27 - 17
src/school/companion-teacher/companion-detail.tsx

@@ -24,6 +24,7 @@ import request from '@/helpers/request'
 import { state as baseState } from '@/state'
 import { useRoute, useRouter } from 'vue-router'
 import OEmpty from '@/components/o-empty'
+import detailItem from '../exercise-record/modals/detail-item'
 
 export default defineComponent({
   name: 'companion-detail',
@@ -117,15 +118,6 @@ export default defineComponent({
                 <div class={styles.teacherContent}>
                   <div class={styles.content}>
                     <p class={[styles.name, 'van-ellipsis']}>{state.detail.nickname}</p>
-                    {state.detail.subjectName ? (
-                      <p class={styles.subjects}>
-                        {state.detail.subjectNames.map((subject: any) => (
-                          <Tag type="primary">{subject}</Tag>
-                        ))}
-                      </p>
-                    ) : (
-                      ''
-                    )}
                   </div>
                   <div class={styles.classNum}>
                     <p class={styles.num}>
@@ -145,6 +137,23 @@ export default defineComponent({
               )
             }}
           </Cell>
+          <Cell>
+            {{
+              title: () => (
+                <div class={styles.subjectContainer}>
+                  <span>声部:</span>
+                  <div>
+                    {state.detail.subjectNames &&
+                      state.detail.subjectNames.map((subject: any) => (
+                        <Tag type="primary" class={styles.tagSubject}>
+                          {subject}
+                        </Tag>
+                      ))}
+                  </div>
+                </div>
+              )
+            }}
+          </Cell>
         </CellGroup>
 
         <div class={styles.sectionTitle}>
@@ -189,19 +198,20 @@ export default defineComponent({
           {state.classList.length <= 0 && <OEmpty btnStatus={false} tips="暂无班级" />}
         </CellGroup>
 
-        <OSticky position="bottom">
-          <div class={['btnGroup']} style={{ paddingLeft: '13px', paddingRight: '13px' }}>
-            <Button type="primary" round block onClick={onDetail}>
-              解除绑定
-            </Button>
-          </div>
-        </OSticky>
+        {state.detail.delFalg && (
+          <OSticky position="bottom">
+            <div class={['btnGroup']} style={{ paddingLeft: '13px', paddingRight: '13px' }}>
+              <Button type="primary" round block onClick={onDetail}>
+                解除绑定
+              </Button>
+            </div>
+          </OSticky>
+        )}
 
         <Popup
           v-model:show={state.showMessage}
           position="bottom"
           style={{ background: 'transparent' }}
-          safeAreaInsetBottom={true}
         >
           <div class={styles.codeContainer}>
             <div class={styles.codeBottom}>

+ 12 - 0
src/school/companion-teacher/index.module.less

@@ -5,6 +5,16 @@
   color: #333333;
 }
 
+.subjectContainer {
+  display: flex;
+  & > span {
+    flex-shrink: 0;
+  }
+  .tagSubject {
+    margin-right: 10px;
+  }
+}
+
 .manageCell {
   padding: 15px 13px;
   :global {
@@ -104,6 +114,8 @@
       font-weight: bold;
       color: #ffffff;
       text-shadow: 1px 1px 7px #f4672a;
+      max-width: 90%;
+      padding-left: 5%;
     }
 
     .codeName {

+ 72 - 45
src/school/companion-teacher/index.tsx

@@ -2,7 +2,19 @@ import OHeader from '@/components/o-header'
 import OQrcode from '@/components/o-qrcode'
 import OSearch from '@/components/o-search'
 import OSticky from '@/components/o-sticky'
-import { ActionSheet, Cell, Grid, GridItem, Icon, Image, List, Picker, Popup, Tag } from 'vant'
+import {
+  ActionSheet,
+  Cell,
+  CellGroup,
+  Grid,
+  GridItem,
+  Icon,
+  Image,
+  List,
+  Picker,
+  Popup,
+  Tag
+} from 'vant'
 import { defineComponent, onMounted, reactive } from 'vue'
 import styles from './index.module.less'
 import iconSaveImage from '@/school/orchestra/images/icon-save-image.png'
@@ -41,7 +53,7 @@ export default defineComponent({
       statusText: '状态',
       params: {
         keyword: null,
-        status: null,
+        delFlag: null,
         subjectId: null,
         page: 1,
         rows: 20
@@ -191,49 +203,63 @@ export default defineComponent({
             immediateCheck={false}
           >
             {form.list.map((item: any) => (
-              <Cell center isLink class={styles.manageCell} onClick={() => onDetail(item)}>
-                {{
-                  icon: () => (
-                    <Image class={styles.img} src={item.avatar ? item.avatar : iconTeacher} />
-                  ),
-                  title: () => (
-                    <div class={styles.teacherContent}>
-                      <div class={styles.content}>
-                        <p class={[styles.name, 'van-ellipsis']}>{item.nickname}</p>
-                        <p class={styles.subjects}>
+              <CellGroup inset style={{ marginBottom: '12px' }}>
+                <Cell center isLink class={styles.manageCell} onClick={() => onDetail(item)}>
+                  {{
+                    icon: () => (
+                      <Image class={styles.img} src={item.avatar ? item.avatar : iconTeacher} />
+                    ),
+                    title: () => (
+                      <div class={styles.teacherContent}>
+                        <div class={styles.content}>
+                          <p class={[styles.name, 'van-ellipsis']}>{item.nickname}</p>
+                        </div>
+                        <div class={styles.classNum}>
+                          <p class={styles.num}>
+                            {item.completedCourseScheduleNum || 0}/
+                            {item.totalCourseScheduleNum || 0}
+                          </p>
+                          <p class={styles.numText}>课时</p>
+                        </div>
+                        <div
+                          class={styles.message}
+                          onClick={(e: any) => {
+                            e.stopPropagation()
+                            e.preventDefault()
+                            form.showMessage = true
+                            form.selectItem = item
+                          }}
+                        >
+                          <Image class={styles.messageImg} src={iconMessage} />
+                        </div>
+                      </div>
+                    ),
+                    value: () => (
+                      <span class={[styles.status, item.delFlag ? styles.frozen : '']}>
+                        {!item.delFlag ? '绑定' : '解绑'}
+                      </span>
+                    )
+                  }}
+                </Cell>
+                <Cell>
+                  {{
+                    title: () => (
+                      <div class={styles.subjectContainer}>
+                        <span>声部:</span>
+                        <div>
                           {item.subjectNames &&
                             item.subjectNames.length > 0 &&
                             item.subjectNames.map((subject: any) => (
-                              <Tag type="primary">{subject}</Tag>
+                              <Tag type="primary" class={styles.tagSubject}>
+                                {subject}
+                              </Tag>
                             ))}
-                        </p>
+                        </div>
                       </div>
-                      <div class={styles.classNum}>
-                        <p class={styles.num}>
-                          {item.completedCourseScheduleNum || 0}/{item.totalCourseScheduleNum || 0}
-                        </p>
-                        <p class={styles.numText}>课时</p>
-                      </div>
-                      <div
-                        class={styles.message}
-                        onClick={(e: any) => {
-                          e.stopPropagation()
-                          e.preventDefault()
-                          form.showMessage = true
-                          form.selectItem = item
-                        }}
-                      >
-                        <Image class={styles.messageImg} src={iconMessage} />
-                      </div>
-                    </div>
-                  ),
-                  value: () => (
-                    <span class={[styles.status, item.status === 'LOCKED' ? styles.frozen : '']}>
-                      {manageTeacherType[item.status]}
-                    </span>
-                  )
-                }}
-              </Cell>
+                    )
+                  }}
+                </Cell>
+              </CellGroup>
             ))}
           </List>
         ) : (
@@ -244,12 +270,11 @@ export default defineComponent({
           v-model:show={form.showQrcode}
           position="bottom"
           style={{ background: 'transparent' }}
-          safeAreaInsetBottom={true}
         >
           <div class={styles.codeContainer}>
             <div class={styles.codeImg}>
               <div class={styles.codeContent}>
-                <h2 class={styles.codeTitle}>{form.schoolName}</h2>
+                <h2 class={[styles.codeTitle, 'van-ellipsis']}>{form.schoolName}</h2>
                 <div class={styles.codeName}>邀请您成为乐团伴学老师</div>
 
                 <div class={styles.codeQr}>
@@ -355,14 +380,16 @@ export default defineComponent({
           actions={
             [
               { name: '全部', id: 'ALL' },
+              { name: '解绑', id: true },
+              { name: '绑定', id: false }
               // { name: '注销', id: 'CANCEL' },
-              { name: '冻结', id: 'LOCKED' },
-              { name: '正常', id: 'ACTIVATION' }
+              // { name: '冻结', id: 'LOCKED' },
+              // { name: '正常', id: 'ACTIVATION' }
             ] as any
           }
           onSelect={(val: any) => {
             form.statusText = val.name
-            form.params.status = val.id === 'ALL' ? null : val.id
+            form.params.delFlag = val.id === 'ALL' ? null : val.id
             form.oPopover = false
             onSearch()
           }}

+ 2 - 0
src/school/manage-teacher/index.module.less

@@ -58,6 +58,8 @@
       font-weight: bold;
       color: #ffffff;
       text-shadow: 1px 1px 7px #f4672a;
+      max-width: 90%;
+      padding-left: 5%;
     }
 
     .codeName {

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

@@ -178,7 +178,7 @@ export default defineComponent({
           <div class={styles.codeContainer}>
             <div class={styles.codeImg}>
               <div class={styles.codeContent}>
-                <h2 class={styles.codeTitle}>{form.schoolName}</h2>
+                <h2 class={[styles.codeTitle, 'van-ellipsis']}>{form.schoolName}</h2>
                 <div class={styles.codeName}>邀请您成为乐团管理老师</div>
 
                 <div class={styles.codeQr}>

+ 2 - 1
src/school/manage-teacher/menu-function.tsx

@@ -64,7 +64,8 @@ export default defineComponent({
                 buttonImage: item.buttonImage,
                 sortOrder: item.order,
                 id: item.id,
-                title: item.title
+                title: item.title,
+                homePage: item.homePage
               })
             }
           })

+ 6 - 5
src/school/orchestra/compontent/information.tsx

@@ -54,10 +54,12 @@ export default defineComponent({
       val.color = 'var(--van-primary-color)'
       state.actionText = val.text
       state.actionType = val.value
-      if (val === 'up') {
+
+      if (val.value === 'up') {
         state.params.startTime = dayjs().year() + '-03-01 00:00:00'
         state.params.endTime = dayjs().year() + '-09-01 00:00:00'
-      } else if (val === 'down') {
+      } else if (val.value === 'down') {
+        console.log(dayjs().add(1, 'year'), 'dayjs().add(1, ')
         state.params.startTime = dayjs().year() + '-09-01 00:00:00'
         state.params.endTime = dayjs().add(1, 'year').year() + '-03-01 00:00:00'
       }
@@ -70,11 +72,10 @@ export default defineComponent({
         state.params.startTime = date.selectedValues[0] + '-03-01 00:00:00'
         state.params.endTime = date.selectedValues[0] + '-09-01 00:00:00'
       } else if (state.actionType == 'down') {
-        state.params.startTime = date.selectedValues[0] + 1 + '-03-01 00:00:00'
-        state.params.endTime = date.selectedValues[0] + 1 + '-09-01 00:00:00'
+        state.params.startTime = date.selectedValues[0] + '-09-01 00:00:00'
+        state.params.endTime = Number(date.selectedValues[0]) + 1 + '-03-01 00:00:00'
       }
       state.timeShow = false
-      console.log(state.params)
       onSearch()
     }
 

+ 12 - 0
src/school/orchestra/compontent/photo.module.less

@@ -14,7 +14,19 @@
   justify-content: space-between;
   flex-wrap: wrap;
   .item {
+    position: relative;
     padding-top: 12px;
+    .more {
+      display: inline-block;
+      position: absolute;
+      top: 18px;
+      right: 6px;
+      background: url('../images/icon_more.png') center center no-repeat;
+      background-size: contain;
+      width: 24px;
+      height: 24px;
+      z-index: 9;
+    }
     .img {
       width: 170px;
       height: 170px;

+ 109 - 21
src/school/orchestra/compontent/photo.tsx

@@ -1,6 +1,17 @@
 import OEmpty from '@/components/o-empty'
 import request from '@/helpers/request'
-import { Button, Dialog, Field, Image, List, Popup, showToast } from 'vant'
+import {
+  ActionSheet,
+  Button,
+  Dialog,
+  Field,
+  Image,
+  List,
+  Popover,
+  Popup,
+  showConfirmDialog,
+  showToast
+} from 'vant'
 import { defineComponent, onMounted, reactive } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import styles from './photo.module.less'
@@ -12,6 +23,7 @@ export default defineComponent({
     const route = useRoute()
     const router = useRouter()
     const state = reactive({
+      oPopover: false,
       status: false,
       isLoading: false,
       photoName: null, // 相册名称
@@ -21,11 +33,12 @@ export default defineComponent({
         loading: false,
         finished: false
       },
-
       params: {
         page: 1,
         rows: 20
-      }
+      },
+      selectItem: {} as any,
+      selectType: 'add'
     })
 
     const onAddPhoto = async () => {
@@ -35,30 +48,47 @@ export default defineComponent({
           state.status = true
           return
         }
-        await request.post('/api-school/orchestraPhotoAlbum/save', {
-          data: {
-            orchestraId: route.query.id,
-            name: state.photoName
-          }
-        })
+        if (state.selectType === 'add') {
+          await request.post('/api-school/orchestraPhotoAlbum/save', {
+            data: {
+              orchestraId: route.query.id,
+              name: state.photoName
+            }
+          })
+          setTimeout(() => {
+            showToast('添加成功')
+          }, 100)
+        } else {
+          await request.post('/api-school/orchestraPhotoAlbum/update', {
+            data: {
+              id: state.selectItem.id,
+              orchestraId: route.query.id,
+              name: state.photoName
+            }
+          })
+          setTimeout(() => {
+            showToast('修改成功')
+          }, 100)
+        }
+        state.status = false
         setTimeout(() => {
-          showToast('添加成功')
-          state.status = false
           state.photoName = null
-        }, 100)
-        setTimeout(() => {
-          state.params.page = 1
-          state.list = []
-          state.listState.dataShow = true // 判断是否有数据
-          state.listState.loading = false
-          state.listState.finished = false
-          getList()
+          onSearch()
         }, 1100)
       } catch {
         //
       }
     }
 
+    const onSearch = () => {
+      state.params.page = 1
+      state.list = []
+      state.listState.dataShow = true // 判断是否有数据
+      state.listState.loading = false
+      state.listState.finished = false
+      getList()
+    }
+
     // 班级列表
     const getList = async () => {
       try {
@@ -100,12 +130,49 @@ export default defineComponent({
       })
     }
 
+    const onRename = async () => {
+      state.photoName = state.selectItem.name
+      state.status = true
+    }
+
+    const onRemove = async () => {
+      showConfirmDialog({
+        message: '您确认删除该相册吗?'
+      }).then(async () => {
+        try {
+          await request.post('/api-school/orchestraPhotoAlbum/remove', {
+            requestType: 'form',
+            data: {
+              id: state.selectItem.id
+            }
+          })
+          setTimeout(() => {
+            showToast('删除成功')
+          }, 100)
+
+          setTimeout(() => {
+            onSearch()
+          }, 1100)
+        } catch {
+          //
+        }
+      })
+    }
+
     onMounted(() => {
       getList()
     })
     return () => (
       <div class={styles.phone}>
-        <Button icon="plus" block class={styles.addPhone} onClick={() => (state.status = true)}>
+        <Button
+          icon="plus"
+          block
+          class={styles.addPhone}
+          onClick={() => {
+            state.status = true
+            state.selectType = 'add'
+          }}
+        >
           新建相册
         </Button>
 
@@ -120,6 +187,17 @@ export default defineComponent({
             <div class={styles.phoneContainer}>
               {state.list.map((item: any) => (
                 <div class={styles.item} onClick={() => onDetail(item)}>
+                  {/* <i class={styles.more}></i> */}
+                  <i
+                    class={styles.more}
+                    onClick={(e: any) => {
+                      e.stopPropagation()
+                      state.oPopover = true
+                      state.selectItem = item
+                      state.selectType = 'update'
+                    }}
+                  ></i>
+
                   {item.coverUrl ? (
                     <Image class={styles.img} src={item.coverUrl} />
                   ) : (
@@ -142,7 +220,7 @@ export default defineComponent({
           <div class={styles.container}>
             <div class={styles.dialogTitle}>
               <i></i>
-              新建相册
+              {state.selectType === 'add' ? '新建相册' : '重命名相册'}
             </div>
             <Field
               class={styles.phoneName}
@@ -169,6 +247,16 @@ export default defineComponent({
             </div>
           </div>
         </Popup>
+
+        <ActionSheet
+          cancelText="取消"
+          v-model:show={state.oPopover}
+          closeOnClickAction
+          actions={[
+            { name: '重命名', callback: () => onRename() },
+            { name: '删除', color: '#F44541', callback: () => onRemove() }
+          ]}
+        />
       </div>
     )
   }

+ 7 - 6
src/school/orchestra/compontent/plan.tsx

@@ -49,10 +49,12 @@ export default defineComponent({
       val.color = 'var(--van-primary-color)'
       state.actionText = val.text
       state.actionType = val.value
-      if (val === 'up') {
+
+      if (val.value === 'up') {
         state.params.startTime = dayjs().year() + '-03-01 00:00:00'
         state.params.endTime = dayjs().year() + '-09-01 00:00:00'
-      } else if (val === 'down') {
+      } else if (val.value === 'down') {
+        console.log(dayjs().add(1, 'year'), 'dayjs().add(1, ')
         state.params.startTime = dayjs().year() + '-09-01 00:00:00'
         state.params.endTime = dayjs().add(1, 'year').year() + '-03-01 00:00:00'
       }
@@ -65,11 +67,10 @@ export default defineComponent({
         state.params.startTime = date.selectedValues[0] + '-03-01 00:00:00'
         state.params.endTime = date.selectedValues[0] + '-09-01 00:00:00'
       } else if (state.actionType == 'down') {
-        state.params.startTime = date.selectedValues[0] + 1 + '-03-01 00:00:00'
-        state.params.endTime = date.selectedValues[0] + 1 + '-09-01 00:00:00'
+        state.params.startTime = date.selectedValues[0] + '-09-01 00:00:00'
+        state.params.endTime = Number(date.selectedValues[0]) + 1 + '-03-01 00:00:00'
       }
       state.timeShow = false
-      console.log(state.params)
       onSearch()
     }
 
@@ -116,7 +117,7 @@ export default defineComponent({
       getList()
     })
     return () => (
-      <div style={{ paddingTop: '12px' }}>
+      <div>
         <div style={{ padding: '12px 13px 16px', background: '#F8F8F8' }}>
           <div class={styles.searchBand} onClick={() => (state.timeShow = true)}>
             {state.currentData[0]}年 <Icon name={state.showPopover ? 'arrow-up' : 'arrow-down'} />

BIN
src/school/orchestra/images/icon_more.png


+ 18 - 19
src/school/train-planning/component/course-preview/index.tsx

@@ -208,24 +208,23 @@ export default defineComponent({
             ))}
           </Tabs>
 
-          {state.courseValue && (
-            <Tabs
-              swipeThreshold={3}
-              class={styles.courseTabs}
-              v-model:active={state.courseValue}
-              lineHeight={0}
-              shrink
-              lazyRender
-              ref={courseTabsRef}
-              onChange={(val: any) => {
-                state.selectCourse = forms.planList.course[val]
-              }}
-            >
-              {state.selectClasses.map((item: any) => (
-                <Tab title={item.className} name={item.classGroupId}></Tab>
-              ))}
-            </Tabs>
-          )}
+          {/* {state.courseValue && ( */}
+          <Tabs
+            swipeThreshold={3}
+            class={styles.courseTabs}
+            v-model:active={state.courseValue}
+            lineHeight={0}
+            shrink
+            ref={courseTabsRef}
+            onChange={(val: any) => {
+              state.selectCourse = forms.planList.course[val]
+            }}
+          >
+            {state.selectClasses.map((item: any) => (
+              <Tab title={item.className} name={item.classGroupId}></Tab>
+            ))}
+          </Tabs>
+          {/* )} */}
         </OSticky>
 
         {state.selectCourse.map((item: any) => (
@@ -290,7 +289,7 @@ export default defineComponent({
             </div>
             <Cell center class={styles.cellTeacher}>
               {{
-                icon: () => <Image src={iconTeacher} class={styles.img} />,
+                icon: () => <Image src={item.teacherAvatar || iconTeacher} class={styles.img} />,
                 title: () => (
                   <div class={styles.teacherInfo}>
                     <p class={styles.teacherName}>{item.teacherName}</p>

+ 1 - 1
src/school/train-planning/component/practice-detail/index.tsx

@@ -243,10 +243,10 @@ export default defineComponent({
           v-model:modelValue={forms.classStatus}
           position="bottom"
           style={{ background: '#f6f6f6' }}
-          destroy
         >
           <PracticeClass
             onClose={() => (forms.classStatus = false)}
+            classType={f.selectItem.classType}
             onConfirm={(val: any) => {
               console.log(val, 'val')
               f.selectItem.classIdList = val

+ 11 - 2
src/school/train-planning/component/practice/index.tsx

@@ -123,10 +123,15 @@ export default defineComponent({
             inputAlign="right"
             placeholder="请选择课程周次"
             readonly
-            isLink
             modelValue={weekFormat(forms.week)}
+            // isLink
             onClick={() => {
-              forms.weekStatus = true
+              // forms.weekStatus = true
+
+              if (!forms.trainStartDate) {
+                showToast('请选择课程开始日期')
+                return
+              }
             }}
           />
 
@@ -191,6 +196,10 @@ export default defineComponent({
             onConfirm={(date: any) => {
               forms.calendarStatus = false
               forms.trainStartDate = date.selectedValues.join('-')
+
+              const days = dayjs(forms.trainStartDate).day()
+              const selectDays = weekdays[days === 0 ? 6 : days - 1]
+              forms.week = selectDays.value
             }}
           />
         </Popup>

+ 11 - 5
src/school/train-planning/component/standard/index.tsx

@@ -195,12 +195,8 @@ export default defineComponent({
             label="训练周次"
             placeholder="请选择训练周次"
             modelValue={weekFormat(forms.week)}
-            isLink
             inputAlign="right"
             readonly
-            onClick={() => {
-              forms.weekStatus = true
-            }}
           />
           <Cell
             title="训练次数"
@@ -270,14 +266,23 @@ export default defineComponent({
         </Popup>
 
         {/* 选择训练开始日期 */}
-        <OPopup v-model:modelValue={forms.calendarStatus} position="bottom">
+        <OPopup v-model:modelValue={forms.calendarStatus} position="bottom" destroy>
           <Calendar
             list={forms.calendarList}
             nextMonth={(date: Date) => getList(date)}
             prevMonth={(date: Date) => getList(date)}
             onSelect={(date: any) => {
               forms.calendarStatus = false
+              console.log(date, 'data')
+              if (forms.trainStartDate == date) {
+                console.log('true ------')
+              }
               forms.trainStartDate = date
+
+              const days = dayjs(date).day()
+              const selectDays = weekdays[days === 0 ? 6 : days - 1]
+              forms.week = selectDays.value
+
               forms.calendarList.forEach((item: any) => {
                 if (dayjs(item.calendarDate).isSame(date)) {
                   forms.timerList = { ...item }
@@ -296,6 +301,7 @@ export default defineComponent({
           v-model:modelValue={forms.timerStatus}
           position="bottom"
           style={{ background: '#F6F6F6' }}
+          destroy
         >
           <Timer
             timerList={forms.timerList}

+ 1 - 1
src/school/train-planning/create.ts

@@ -52,7 +52,7 @@ const original = () => {
     classStatus: false, // 班级设置伴学老师
     timerStatus: false, // 时间状态
     skipHoliday: 1, // 是否节假日
-    week: null, // 周次
+    week: null as any, // 周次
     times: 16, // 训练次数
     trainTimer: 120, // 默认120分钟
     classList: [] as any, // 没有设置伴学指导的数据

+ 2 - 0
src/school/train-planning/modal/calendar/index.tsx

@@ -120,12 +120,14 @@ export default defineComponent({
       if (this.arrowStatus) return
       const tempDate = dayjs(this.currentDate).subtract(1, 'month')
       this._monthChange(tempDate)
+      // this._dayChange(this.minDate)
       this.prevMonth && this.prevMonth(this.minDate)
     },
     onNextMonth() {
       // 下一月
       const tempDate = dayjs(this.currentDate).add(1, 'month')
       this._monthChange(tempDate)
+      // this._dayChange(this.minDate)
       this.nextMonth && this.nextMonth(this.minDate)
     },
     _monthChange(date: any) {

+ 8 - 1
src/school/train-planning/modal/practice-class/index.tsx

@@ -24,6 +24,12 @@ import OEmpty from '@/components/o-empty'
 
 export default defineComponent({
   name: 'practice-class',
+  props: {
+    classType: {
+      type: String,
+      default: ''
+    }
+  },
   emits: ['close', 'confirm'],
   setup(props, { slots, attrs, emit }) {
     const forms = reactive({
@@ -84,7 +90,8 @@ export default defineComponent({
             page: 1,
             rows: 20,
             schoolId: baseState.user.data.school.id,
-            orchestraId: forms.orchestraId
+            orchestraId: forms.orchestraId,
+            classType: props.classType
             // orchestraType: 'DELIVERY'
           }
         })

+ 18 - 8
src/school/train-planning/modal/timer/index.tsx

@@ -1,6 +1,8 @@
 import OHeader from '@/components/o-header'
 import item from '@/student/coupons/item'
 import dayjs from 'dayjs'
+// import isBetween from 'dayjs/plugin/isBetween'
+// dayjs.extend(isBetween)
 import { Button, Cell, CellGroup, Popup, showToast, Sticky, TimePicker } from 'vant'
 import { defineComponent, onMounted, reactive, watch } from 'vue'
 import styles from './index.module.less'
@@ -99,31 +101,39 @@ export default defineComponent({
 
     // 确认时间
     const onConfirm = (val: any) => {
-      console.log(val, 'val')
+      // console.log(val, 'val')
       const selectedValues = val.selectedValues
       const tempDate = dayjs(state.calendarDate)
         .hour(selectedValues[0])
         .minute(selectedValues[1])
         .second(0)
-      console.log(dayjs(tempDate).format('YYYY-MM-DD HH:mm:ss'), 'first', dayjs(tempDate).minute())
+      // console.log(dayjs(tempDate).format('YYYY-MM-DD HH:mm:ss'), 'first', dayjs(tempDate).minute())
       // 时间加上每节课的时间,
       const lastDate = dayjs(tempDate).minute(props.times + dayjs(tempDate).minute())
       console.log(dayjs(lastDate).format('YYYY-MM-DD HH:mm:ss'), 'second')
       console.log(
         dayjs(tempDate).format('YYYY-MM-DD HH:mm:ss'),
         tempDate.toDate(),
-        'second tempDate'
+        'second tempDate',
+        state.useTimer
       )
 
       let isActive = false
       state.useTimer.forEach((item: any) => {
-        if (dayjs(lastDate).isAfter(item.endTime)) {
+        // if (dayjs(lastDate).isBetween(item.startTime, item.endTime, null, '[]')) {
+        //   isActive = true
+        // }
+        // 判断课程的时间范围在不在可排课时间范围内
+        if (
+          dayjs(tempDate).valueOf() >= dayjs(item.startTime).valueOf() &&
+          dayjs(lastDate).valueOf() <= dayjs(item.endTime).valueOf()
+        ) {
           isActive = true
         }
       })
 
-      console.log(isActive, 'isActive')
-      if (isActive) {
+      // console.log(isActive, 'isActive')
+      if (!isActive) {
         showToast('您选择的时间超过可排课时间范围')
         return
       }
@@ -176,9 +186,9 @@ export default defineComponent({
       <div class={styles.timer}>
         <OHeader title="训练时间" desotry={false} />
 
-        <div class={styles.selectTimer}>{dayjs(state.calendarDate).format('YYYY年MM月DD日')}</div>
+        {/* <div class={styles.selectTimer}>{dayjs(state.calendarDate).format('YYYY年MM月DD日')}</div> */}
 
-        <CellGroup inset class={styles.cellGroup}>
+        <CellGroup inset class={styles.cellGroup} style={{ marginTop: '12px' }}>
           {state.useTimer.map((item: any) => (
             <Cell
               center

+ 2 - 2
src/student/main.ts

@@ -8,8 +8,8 @@ import 'normalize.css'
 import '../styles/index.less'
 
 
-import Vconsole from 'vconsole'
-const vconsole = new Vconsole()
+// import Vconsole from 'vconsole'
+// const vconsole = new Vconsole()
 const app = createApp(App)
 app.use(router)
 

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

@@ -27,9 +27,9 @@ export default defineComponent({
 
     const addressInfo = computed(() => {
       return [
-        props.item.province,
-        props.item.city,
-        props.item.region,
+        props.item.provinceName,
+        props.item.cityName,
+        props.item.regionName,
         props.item.detailAddress
       ].join('')
     })

+ 15 - 21
src/student/music-group/pre-apply/component/order.tsx

@@ -43,7 +43,13 @@ export default defineComponent({
         if (form.list.length > 0 && result.current === 1) {
           return
         }
-        form.list = form.list.concat(result.rows || [])
+        const rows = result.rows || []
+        rows.goodsInfos &&
+          rows.goodsInfos.forEach((item: any) => {
+            const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
+            item.goodsUrl = img
+          })
+        form.list = form.list.concat(rows)
         form.listState.finished = result.current >= result.pages
         form.params.page = result.current + 1
         form.listState.dataShow = form.list.length > 0
@@ -88,24 +94,12 @@ export default defineComponent({
                   {{
                     title: () => (
                       <Grid border={false}>
-                        <GridItem>
-                          <Image
-                            class={styles.img}
-                            src="https://daya.ks3-cn-beijing.ksyuncs.com/12/1670231208704.png"
-                          />
-                        </GridItem>
-                        <GridItem>
-                          <Image
-                            class={styles.img}
-                            src="https://daya.ks3-cn-beijing.ksyuncs.com/12/1670231208704.png"
-                          />
-                        </GridItem>
-                        <GridItem>
-                          <Image
-                            class={styles.img}
-                            src="https://daya.ks3-cn-beijing.ksyuncs.com/12/1670231208704.png"
-                          />
-                        </GridItem>
+                        {item.goodsInfos &&
+                          item.goodsInfos.map((goods: any) => (
+                            <GridItem>
+                              <Image class={styles.img} src={goods.goodsUrl} />
+                            </GridItem>
+                          ))}
                       </Grid>
                     )
                   }}
@@ -117,7 +111,7 @@ export default defineComponent({
                     ),
                     value: () => (
                       <div class={styles.btns}>
-                        {item.status === 'WAIT_PAY' && (
+                        {/* {item.status === 'WAIT_PAY' && (
                           <>
                             <Button round plain color="#AAAAAA">
                               修改订单
@@ -126,7 +120,7 @@ export default defineComponent({
                               继续支付
                             </Button>
                           </>
-                        )}
+                        )} */}
                       </div>
                     )
                   }}

+ 253 - 179
src/student/music-group/pre-apply/component/payment.tsx

@@ -1,5 +1,16 @@
 import OSticky from '@/components/o-sticky'
-import { Button, Cell, CellGroup, Checkbox, CheckboxGroup, Icon, Image, showToast, Tag } from 'vant'
+import {
+  Button,
+  Cell,
+  CellGroup,
+  Checkbox,
+  CheckboxGroup,
+  Icon,
+  Image,
+  showConfirmDialog,
+  showToast,
+  Tag
+} from 'vant'
 import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue'
 import styles from '../index.module.less'
 import radioCheck from '@/common/images/icon-radio-check.png'
@@ -30,6 +41,41 @@ export default defineComponent({
       }
     })
 
+    // 查询未支付订单
+    const paymentOrderUnpaid = async () => {
+      try {
+        const { data } = await request.get('/api-student/userPaymentOrder/unpaid')
+        console.log(data, 'data')
+        // 判断是否有待支付订单
+        if (data.id) {
+          showConfirmDialog({
+            message: '您有待支付的订单,是否继续支付',
+            cancelButtonText: '取消订单',
+            confirmButtonText: '继续支付'
+          })
+            .then(() => {
+              const paymentConfig = data.paymentConfig
+              router.push({
+                path: '/orderDetail',
+                query: {
+                  config: JSON.stringify(paymentConfig.paymentConfig),
+                  orderNo: paymentConfig.orderNo
+                }
+              })
+            })
+            .catch(async () => {
+              try {
+                await request.post('/api-student/userPaymentOrder/cancelPayment/' + data.orderNo)
+              } catch {
+                //
+              }
+            })
+        }
+      } catch {
+        //
+      }
+    }
+
     // 获取商品信息
     const registerGoods = async () => {
       try {
@@ -37,8 +83,14 @@ export default defineComponent({
           '/api-student/orchestraRegister/registerGoods/' + route.query.id
         )
 
-        const details = data.details || []
+        // 获取已经购买商品信息
+        const paymentOrderDetails = data.paymentOrderDetails || []
+        paymentOrderDetails.forEach((item: any) => {
+          state.paymentOrderDetails.push(item.goodsType)
+        })
 
+        // 初始化数据商品数据
+        const details = data.details || []
         details.forEach((item: any) => {
           if (item.goodsType === 'INSTRUMENTS') {
             const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
@@ -54,9 +106,10 @@ export default defineComponent({
           state.details = details
 
           // 默认选中所有的
-          state.check.push(item.goodsId)
+          if (!state.paymentOrderDetails.includes(item.goodsType)) {
+            state.check.push(item.goodsId)
+          }
         })
-        state.paymentOrderDetails = data.paymentOrderDetails || []
 
         calcPrice()
       } catch {
@@ -80,7 +133,10 @@ export default defineComponent({
       }
       details.forEach((item: any) => {
         // 是否选中
-        if (state.check.includes(item.goodsId)) {
+        if (
+          state.check.includes(item.goodsId) &&
+          !state.paymentOrderDetails.includes(item.goodsType)
+        ) {
           tempPrice.needPrice += parseFloat(item.currentPrice)
           tempPrice.originalPrice += parseFloat(item.originalPrice)
         }
@@ -138,7 +194,10 @@ export default defineComponent({
         const details = state.details
         details.forEach((item: any) => {
           // 是否选中
-          if (state.check.includes(item.goodsId)) {
+          if (
+            state.check.includes(item.goodsId) &&
+            !state.paymentOrderDetails.includes(item.goodsType)
+          ) {
             params.push({
               goodsId: item.goodsId,
               goodsNum: 1,
@@ -173,8 +232,7 @@ export default defineComponent({
           path: '/orderDetail',
           query: {
             config: JSON.stringify(data.paymentConfig),
-            orderNo: data.orderNo,
-            id: route.query.id
+            orderNo: data.orderNo
           }
         })
       } catch (e: any) {
@@ -185,6 +243,8 @@ export default defineComponent({
     }
 
     onMounted(() => {
+      // 查询未支付订单
+      paymentOrderUnpaid()
       registerGoods()
     })
     return () => (
@@ -204,179 +264,193 @@ export default defineComponent({
             calcPrice()
           }}
         >
-          <div class={styles.applyTitle}>乐器</div>
-          <CellGroup
-            inset
-            class={[styles.mlr13, styles.sectionCell]}
-            onClick={() => onSelect(state.goodsInfo.goodsId)}
-          >
-            <Cell border={false}>
-              {{
-                icon: () => (
-                  <Checkbox
-                    name={state.goodsInfo.goodsId}
-                    class={styles.checkbox}
-                    ref={(el: any) => (state.checkboxRefs[state.goodsInfo.goodsId] = el)}
-                    v-slots={{
-                      icon: (props: any) => (
-                        <Icon
-                          class={styles.iconChecked}
-                          name={props.checked ? radioCheck : radioDefault}
-                        />
-                      )
-                    }}
-                  />
-                ),
-                title: () => (
-                  <div class={styles.section}>
-                    <Image class={styles.img} src={state.goodsInfo.goodsUrl} />
-                    <div class={styles.sectionContent}>
-                      <h2>{state.goodsInfo.goodsName}</h2>
-                      <Tag type="primary">{state.goodsInfo.brandName}</Tag>
-                      <p class={styles.model}>{state.goodsInfo.desciption}</p>
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-            <Cell>
-              {{
-                title: () => (
-                  <div class={styles.extra}>
-                    <div class={styles.sectionPrice}>
-                      <p class={styles.price}>
-                        新团特惠:<span>¥{moneyFormat(state.goodsInfo.currentPrice)}</span>
-                      </p>
-                      <p class={styles.originPrice}>
-                        原价:<del>¥{moneyFormat(state.goodsInfo.originalPrice)}</del>
-                      </p>
-                    </div>
-                    <div class={styles.sectionTips}>
-                      赠价值{state.repaireInfo.originalPrice}元乐器维保服务一年
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-          </CellGroup>
+          {/* 判断是否已经购买乐器 */}
+          {!state.paymentOrderDetails.includes('INSTRUMENTS') && (
+            <>
+              <div class={styles.applyTitle}>乐器</div>
+              <CellGroup
+                inset
+                class={[styles.mlr13, styles.sectionCell]}
+                onClick={() => onSelect(state.goodsInfo.goodsId)}
+              >
+                <Cell border={false}>
+                  {{
+                    icon: () => (
+                      <Checkbox
+                        name={state.goodsInfo.goodsId}
+                        class={styles.checkbox}
+                        ref={(el: any) => (state.checkboxRefs[state.goodsInfo.goodsId] = el)}
+                        v-slots={{
+                          icon: (props: any) => (
+                            <Icon
+                              class={styles.iconChecked}
+                              name={props.checked ? radioCheck : radioDefault}
+                            />
+                          )
+                        }}
+                      />
+                    ),
+                    title: () => (
+                      <div class={styles.section}>
+                        <Image class={styles.img} src={state.goodsInfo.goodsUrl} />
+                        <div class={styles.sectionContent}>
+                          <h2>{state.goodsInfo.goodsName}</h2>
+                          <Tag type="primary">{state.goodsInfo.brandName}</Tag>
+                          <p class={styles.model}>{state.goodsInfo.desciption}</p>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+                <Cell>
+                  {{
+                    title: () => (
+                      <div class={styles.extra}>
+                        <div class={styles.sectionPrice}>
+                          <p class={styles.price}>
+                            新团特惠:<span>¥{moneyFormat(state.goodsInfo.currentPrice)}</span>
+                          </p>
+                          <p class={styles.originPrice}>
+                            原价:<del>¥{moneyFormat(state.goodsInfo.originalPrice)}</del>
+                          </p>
+                        </div>
+                        <div class={styles.sectionTips}>
+                          赠价值{state.repaireInfo.originalPrice}元乐器维保服务一年
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+              </CellGroup>
+            </>
+          )}
 
-          <div class={styles.applyTitle}>教材</div>
-          <CellGroup
-            inset
-            class={[styles.mlr13, styles.sectionCell]}
-            onClick={() => {
-              return
-              // onSelect(state.textBookInfo.goodsId)
-            }}
-          >
-            <Cell border={false}>
-              {{
-                icon: () => (
-                  <Checkbox
-                    name={state.textBookInfo.goodsId}
-                    disabled
-                    class={styles.checkbox}
-                    ref={(el: any) => (state.checkboxRefs[state.textBookInfo.goodsId] = el)}
-                    v-slots={{
-                      icon: (props: any) => (
-                        <Icon
-                          class={styles.iconChecked}
-                          name={props.checked ? radioCheck : radioDefault}
-                        />
-                      )
-                    }}
-                  />
-                ),
-                title: () => (
-                  <div class={styles.section}>
-                    <Image class={styles.img} src={state.textBookInfo.goodsUrl} />
-                    <div class={styles.sectionContent}>
-                      <h2>{state.textBookInfo.goodsName}</h2>
-                      <Tag type="primary">{state.textBookInfo.brandName}</Tag>
-                      <p class={styles.model}>{state.textBookInfo.description}</p>
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-            <Cell>
-              {{
-                title: () => (
-                  <div class={styles.extra}>
-                    <div class={styles.sectionPrice}>
-                      <p class={styles.price}>
-                        新团特惠:
-                        <span class={styles.free}>
-                          {state.textBookInfo.currentPrice > 0
-                            ? moneyFormat(state.textBookInfo.currentPrice)
-                            : '免费赠送'}
-                        </span>
-                      </p>
-                      <p class={styles.originPrice}>
-                        原价:<del>¥{moneyFormat(state.textBookInfo.originalPrice)}</del>
-                      </p>
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-          </CellGroup>
+          {/* 判断是否已经购买教材 */}
+          {!state.paymentOrderDetails.includes('TEXTBOOK') && (
+            <>
+              <div class={styles.applyTitle}>教材</div>
+              <CellGroup
+                inset
+                class={[styles.mlr13, styles.sectionCell]}
+                onClick={() => {
+                  return
+                  // onSelect(state.textBookInfo.goodsId)
+                }}
+              >
+                <Cell border={false}>
+                  {{
+                    icon: () => (
+                      <Checkbox
+                        name={state.textBookInfo.goodsId}
+                        disabled
+                        class={styles.checkbox}
+                        ref={(el: any) => (state.checkboxRefs[state.textBookInfo.goodsId] = el)}
+                        v-slots={{
+                          icon: (props: any) => (
+                            <Icon
+                              class={styles.iconChecked}
+                              name={props.checked ? radioCheck : radioDefault}
+                            />
+                          )
+                        }}
+                      />
+                    ),
+                    title: () => (
+                      <div class={styles.section}>
+                        <Image class={styles.img} src={state.textBookInfo.goodsUrl} />
+                        <div class={styles.sectionContent}>
+                          <h2>{state.textBookInfo.goodsName}</h2>
+                          <Tag type="primary">{state.textBookInfo.brandName}</Tag>
+                          <p class={styles.model}>{state.textBookInfo.description}</p>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+                <Cell>
+                  {{
+                    title: () => (
+                      <div class={styles.extra}>
+                        <div class={styles.sectionPrice}>
+                          <p class={styles.price}>
+                            新团特惠:
+                            <span class={styles.free}>
+                              {state.textBookInfo.currentPrice > 0
+                                ? moneyFormat(state.textBookInfo.currentPrice)
+                                : '免费赠送'}
+                            </span>
+                          </p>
+                          <p class={styles.originPrice}>
+                            原价:<del>¥{moneyFormat(state.textBookInfo.originalPrice)}</del>
+                          </p>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+              </CellGroup>
+            </>
+          )}
 
-          <div class={styles.applyTitle}>乐团学习系统</div>
-          <CellGroup
-            inset
-            class={[styles.mlr13, styles.sectionCell]}
-            onClick={() => onSelect(state.vipInfo.goodsId)}
-          >
-            <Cell border={false}>
-              {{
-                icon: () => (
-                  <Checkbox
-                    name={state.vipInfo.goodsId}
-                    class={styles.checkbox}
-                    ref={(el: any) => (state.checkboxRefs[state.vipInfo.goodsId] = el)}
-                    onClick={(e: Event) => {
-                      e.stopPropagation()
-                    }}
-                    v-slots={{
-                      icon: (props: any) => (
-                        <Icon
-                          class={styles.iconChecked}
-                          name={props.checked ? radioCheck : radioDefault}
-                        />
-                      )
-                    }}
-                  />
-                ),
-                title: () => (
-                  <div class={styles.section}>
-                    <Image class={styles.img} src={state.vipInfo.goodsUrl} />
-                    <div class={styles.sectionContent}>
-                      <h2>{state.vipInfo.goodsName}</h2>
-                      <Tag type="primary">6个月</Tag>
-                      <p class={styles.model}>{state.vipInfo.description}</p>
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-            <Cell>
-              {{
-                title: () => (
-                  <div class={styles.extra}>
-                    <div class={styles.sectionPrice}>
-                      <p class={styles.price}>
-                        新团特惠:<span>¥{moneyFormat(state.vipInfo.currentPrice)}</span>
-                      </p>
-                      <p class={styles.originPrice}>
-                        原价:<del>¥{moneyFormat(state.vipInfo.originalPrice)}</del>
-                      </p>
-                    </div>
-                  </div>
-                )
-              }}
-            </Cell>
-          </CellGroup>
+          {!state.paymentOrderDetails.includes('VIP') && (
+            <>
+              <div class={styles.applyTitle}>乐团学习系统</div>
+              <CellGroup
+                inset
+                class={[styles.mlr13, styles.sectionCell]}
+                onClick={() => onSelect(state.vipInfo.goodsId)}
+              >
+                <Cell border={false}>
+                  {{
+                    icon: () => (
+                      <Checkbox
+                        name={state.vipInfo.goodsId}
+                        class={styles.checkbox}
+                        ref={(el: any) => (state.checkboxRefs[state.vipInfo.goodsId] = el)}
+                        onClick={(e: Event) => {
+                          e.stopPropagation()
+                        }}
+                        v-slots={{
+                          icon: (props: any) => (
+                            <Icon
+                              class={styles.iconChecked}
+                              name={props.checked ? radioCheck : radioDefault}
+                            />
+                          )
+                        }}
+                      />
+                    ),
+                    title: () => (
+                      <div class={styles.section}>
+                        <Image class={styles.img} src={state.vipInfo.goodsUrl} />
+                        <div class={styles.sectionContent}>
+                          <h2>{state.vipInfo.goodsName}</h2>
+                          <Tag type="primary">6个月</Tag>
+                          <p class={styles.model}>{state.vipInfo.description}</p>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+                <Cell>
+                  {{
+                    title: () => (
+                      <div class={styles.extra}>
+                        <div class={styles.sectionPrice}>
+                          <p class={styles.price}>
+                            新团特惠:<span>¥{moneyFormat(state.vipInfo.currentPrice)}</span>
+                          </p>
+                          <p class={styles.originPrice}>
+                            原价:<del>¥{moneyFormat(state.vipInfo.originalPrice)}</del>
+                          </p>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </Cell>
+              </CellGroup>
+            </>
+          )}
         </CheckboxGroup>
 
         <OSticky position="bottom" background="white">

+ 9 - 4
src/student/music-group/pre-apply/index.tsx

@@ -19,10 +19,14 @@ export default defineComponent({
       tabValue: 'apply',
       heightV: 235,
       registerInfo: {} as any,
-      purchase: false // 购买状态
+      purchase: false, // 购买状态
+      register: true // 是否注册
     })
 
-    const onNext = (name: string) => {
+    const onNext = async (name: string) => {
+      if (name === 'payment') {
+        await getRegisterStatus()
+      }
       state.tabValue = name
     }
 
@@ -34,6 +38,7 @@ export default defineComponent({
         state.registerInfo = data || {}
 
         // 判断是否报名注册过
+        state.register = data.register
         if (data.register) {
           state.tabValue = 'payment'
         }
@@ -93,8 +98,8 @@ export default defineComponent({
         <Sticky position="top">
           <Tabs lineWidth={20} lineHeight={4} v-model:active={state.tabValue}>
             <Tab title="报名信息" name="apply" disabled={state.purchase}></Tab>
-            <Tab title="缴费信息" name="payment" disabled={state.purchase}></Tab>
-            <Tab title="我的订单" name="order"></Tab>
+            <Tab title="缴费信息" name="payment" disabled={state.purchase || !state.register}></Tab>
+            <Tab title="我的订单" name="order" disabled={!state.register}></Tab>
           </Tabs>
         </Sticky>
 

+ 195 - 46
src/student/music-group/pre-apply/order-detail.tsx

@@ -1,15 +1,24 @@
 import OHeader from '@/components/o-header'
-import { defineComponent, onMounted, reactive } from 'vue'
+import { defineComponent, onMounted, reactive, ref } from 'vue'
 import styles from './order-detail.module.less'
 import Addres from './component/addres'
 import OSticky from '@/components/o-sticky'
-import { Button, Cell, CellGroup, Image, Popup, Tag } from 'vant'
+import {
+  Button,
+  Cell,
+  CellGroup,
+  Image,
+  Popup,
+  showConfirmDialog,
+  showDialog,
+  showToast,
+  Tag
+} from 'vant'
 import Payment from '@/views/adapay/payment'
 import { useRoute, useRouter } from 'vue-router'
 import OQrcode from '@/components/o-qrcode'
 import request from '../request-music'
-import item from '@/student/coupons/item'
-import { moneyFormat } from '@/helpers/utils'
+import { browser, moneyFormat } from '@/helpers/utils'
 import { state as baseState } from '@/state'
 
 export default defineComponent({
@@ -18,14 +27,19 @@ export default defineComponent({
     const route = useRoute()
     const router = useRouter()
     const state = reactive({
+      orderTimer: null as any,
       paymentStatus: false,
       showQrcode: false,
       qrCodeUrl: '',
+      pay_channel: '',
       orderNo: route.query.orderNo,
       orderInfo: {} as any, // 订单信息
-      goodsInfos: [] as any // 订单信息列表
+      goodsInfos: [] as any, // 订单信息列表
+      config: route.query.config ? JSON.parse(route.query.config as any) : {}
     })
 
+    const addressDetails = ref<any>({})
+
     const getOrderDetails = async () => {
       try {
         const { data } = await request.get('/api-student/userPaymentOrder/detail/' + state.orderNo)
@@ -37,16 +51,183 @@ export default defineComponent({
           item.goodsUrl = img
         })
         state.goodsInfos = goodsInfos
+
+        if (!addressDetails.value.id) {
+          addressDetails.value = data.addresses || {}
+        }
+
+        // 判断订单状态,如果不是待支付则返回
+        // WAIT_PAY: '待支付',
+        // PAYING: '支付中',
+        // PAID: '已付款',
+        // TIMEOUT: '订单超时',
+        // FAIL: '支付失败',
+        // CLOSED: '订单关闭',
+        // REFUNDING: '退款中',
+        // REFUNDED: '已退款'
+        if (data.status !== 'WAIT_PAY') {
+          // status
+          showConfirmDialog({
+            message: '订单处理中,请稍等',
+            showCancelButton: false
+          }).then(() => {
+            router.back()
+          })
+        }
       } catch {
         //
       }
     }
 
-    const onSubmit = () => {
-      state.paymentStatus = true
+    const onConfirm = (val: any) => {
+      const config: any = state.config
+      state.pay_channel = val.pay_channel
+      if (val.payCode === 'payResult') {
+        router.push({
+          path: '/payResult',
+          query: {
+            pay_channel: val.pay_channel,
+            wxAppId: config.wxAppId,
+            body: config.body,
+            price: config.price,
+            orderNo: config.merOrderNo,
+            userId: config.userId
+          }
+        })
+      } else {
+        console.log(baseState.user)
+        state.qrCodeUrl =
+          window.location.origin +
+          '/orchestra-student/#/payDefine?pay_channel=' +
+          val.pay_channel +
+          '&wxAppId=' +
+          config.wxAppId +
+          '&body=' +
+          config.body +
+          '&price=' +
+          config.price +
+          '&orderNo=' +
+          config.merOrderNo +
+          '&userId=' +
+          config.userId
+        console.log(state.qrCodeUrl, 'qrCodeUrl')
+        state.showQrcode = true
+        state.paymentStatus = false
+
+        setTimeout(() => {
+          getPaymentOrderStatus()
+        }, 300)
+      }
+    }
+
+    const getPaymentOrderStatus = async () => {
+      // 循环查询订单
+      // const orderNo = state.orderNo
+      const orderTimer = setInterval(async () => {
+        // 判断是否在当前路由,如果不是则清除定时器
+        if (route.name != 'orderDetail') {
+          clearInterval(orderTimer)
+          return
+        }
+        state.orderTimer = orderTimer
+        try {
+          const { data } = await request.post(
+            '/api-student/open/userOrder/paymentStatus/' + state.orderNo,
+            {
+              hideLoading: true
+            }
+          )
+          console.log(data)
+          if (data.status !== 'WAIT_PAY') {
+            clearInterval(orderTimer)
+            window.location.replace(
+              window.location.origin +
+                '/orchestra-student/#/payment-result?orderNo=' +
+                state.orderNo
+            )
+          }
+        } catch {
+          //
+          clearInterval(orderTimer)
+        }
+      }, 5000)
+    }
+
+    const beforeSubmit = () => {
+      const pt = state.config.paymentChannel
+      let payCode = 'qrCode'
+      // 判断当前浏览器
+      if (browser().weixin) {
+        // 微信浏览器
+        if (pt == 'alipay_qr' || pt == 'alipay_wap') {
+          payCode = 'qrCode'
+        } else if (pt == 'wx_pub') {
+          payCode = 'pay'
+        }
+      } else if (browser().alipay) {
+        // 支付宝浏览器
+        if (pt == 'alipay_wap') {
+          // 支付宝 H5 支付
+          payCode = 'pay'
+        } else {
+          payCode = 'qrCode'
+        }
+      } else {
+        payCode = 'qrCode'
+      }
+
+      onConfirm({
+        payCode: payCode == 'qrCode' ? 'payDefine' : 'payResult',
+        pay_channel: pt
+      })
+    }
+
+    const onSubmit = async () => {
+      // 请选择收货地址
+      if (!addressDetails.value.id) {
+        showToast('请选择收货地址')
+        return
+      }
+
+      try {
+        await request.post('/api-student/userPaymentOrder/updateReceiveAddress', {
+          data: {
+            orderNo: state.orderNo,
+            orderType: 'ORCHESTRA',
+            receiveAddress: addressDetails.value.id
+          }
+        })
+
+        const pt = state.config.paymentChannel
+        // 判断是否有支付方式
+        if (pt) {
+          beforeSubmit()
+        } else {
+          state.paymentStatus = true
+        }
+      } catch {
+        //
+      }
+    }
+
+    const onBackOut = async () => {
+      // api-student/userPaymentOrder/cancelPayment/{orderNo}
+      try {
+        await request.post('/api-student/userPaymentOrder/cancelPayment/' + state.orderNo)
+
+        router.back()
+      } catch {
+        //
+      }
     }
 
     onMounted(() => {
+      // 获取收货地址
+      let details = sessionStorage.getItem('addressDetails')
+      details = details ? JSON.parse(details) : {}
+      addressDetails.value = details
+      sessionStorage.removeItem('addressDetails')
+
       getOrderDetails()
     })
     return () => (
@@ -54,7 +235,7 @@ export default defineComponent({
         <OHeader />
         <div class={styles.cartConfirm}>
           <div class={styles.cartConfirmBox}>
-            <Addres />
+            <Addres item={addressDetails.value} />
           </div>
 
           <CellGroup style={{ margin: 0 }}>
@@ -112,43 +293,8 @@ export default defineComponent({
           <Payment
             paymentConfig={state.orderInfo}
             onClose={() => (state.paymentStatus = false)}
-            onBackOut={() => {
-              console.log('back')
-              // router.back()
-            }}
-            onConfirm={(val: any) => {
-              const config: any = route.query.config ? JSON.parse(route.query.config as any) : {}
-              if (val.payCode === 'payResult') {
-                router.push({
-                  path: '/payResult',
-                  query: {
-                    pay_channel: val.pay_channel,
-                    wxAppId: config.wxAppId,
-                    body: config.body,
-                    price: config.price
-                  }
-                })
-              } else {
-                console.log(baseState.user)
-                state.qrCodeUrl =
-                  window.location.origin +
-                  '/orchestra-student/#/payCenter?pay_channel=' +
-                  val.pay_channel +
-                  '&wxAppId=' +
-                  config.wxAppId +
-                  '&body=' +
-                  config.body +
-                  '&price=' +
-                  config.price +
-                  '&orderNo=' +
-                  config.merOrderNo +
-                  '&userId=' +
-                  config.userId
-                console.log(state.qrCodeUrl, 'qrCodeUrl')
-                state.showQrcode = true
-                state.paymentStatus = false
-              }
-            }}
+            onBackOut={onBackOut}
+            onConfirm={(val: any) => onConfirm(val)}
           />
         </Popup>
 
@@ -163,7 +309,10 @@ export default defineComponent({
             <div class={styles.codeImg}>
               <div class={styles.codeContent}>
                 <h2 class={styles.codeTitle}>乐团报名</h2>
-                <div class={styles.codeName}>请截图下方二维码 登录支付宝扫码支付</div>
+                <div class={styles.codeName}>
+                  请截图下方二维码 登录{state.pay_channel === 'wx_pub' ? '微信' : '支付宝'}
+                  扫码支付
+                </div>
 
                 <div class={styles.codeQr}>
                   <OQrcode text={state.qrCodeUrl} size={'400'} />

+ 110 - 13
src/student/music-group/shop-address/address-operation.tsx

@@ -1,14 +1,20 @@
 import OSticky from '@/components/o-sticky'
-import { Button, Cell, CellGroup, Field, Picker, Popup, Switch } from 'vant'
-import { defineComponent, reactive } from 'vue'
+import { Button, Cell, CellGroup, Field, Picker, Popup, showToast, Switch } from 'vant'
+import { defineComponent, onMounted, reactive } from 'vue'
 import request from '../request-music'
 import styles from './index.module.less'
 import { areas } from '@/helpers/area'
+import { verifiyNumberInteger } from '@/helpers/toolsValidate'
+import { router } from '@/router/routes-common'
+import { useRoute, useRouter } from 'vue-router'
 
 export default defineComponent({
   name: 'address-operation',
   setup() {
+    const route = useRoute()
+    const router = useRouter()
     const state = reactive({
+      isClick: false,
       showPicker: false,
       defaultStatus: false,
       phoneNumber: null,
@@ -20,18 +26,109 @@ export default defineComponent({
       detailAddress: null
     })
 
+    const onFormatterInt = (val: any) => {
+      if (val && val >= 1) {
+        return verifiyNumberInteger(val)
+      } else {
+        return ''
+      }
+    }
+
     const onSubmit = async () => {
       try {
-        await request.post('/api-student/userReceiveAddress/save', {
-          data: {}
-        })
-      } catch {}
+        if (!state.name) {
+          showToast('请选择收货人')
+          return
+        }
+        if (!state.phoneNumber) {
+          showToast('请输入手机号')
+          return
+        }
+        if (!state.pcrStr) {
+          showToast('请选择所在地区')
+          return
+        }
+        if (!state.detailAddress) {
+          showToast('请输入详细地址')
+          return
+        }
+        state.isClick = true
+        const params: any = {
+          name: state.name,
+          phoneNumber: state.phoneNumber,
+          province: state.province,
+          city: state.city,
+          region: state.region,
+          detailAddress: state.detailAddress,
+          defaultStatus: state.defaultStatus
+        }
+        if (route.query.id) {
+          await request.post('/api-student/userReceiveAddress/update', {
+            data: {
+              id: route.query.id,
+              ...params
+            }
+          })
+          setTimeout(() => {
+            showToast('修改成功')
+          }, 100)
+        } else {
+          await request.post('/api-student/userReceiveAddress/save', {
+            data: {
+              ...params
+            }
+          })
+          setTimeout(() => {
+            showToast('添加成功')
+          }, 100)
+        }
+
+        setTimeout(() => {
+          state.isClick = false
+          router.back()
+        }, 1100)
+      } catch (e: any) {
+        //
+        state.isClick = false
+        console.log(e)
+      }
+    }
+
+    const getDetails = async () => {
+      try {
+        const { data } = await request.get(
+          '/api-student/userReceiveAddress/detail/' + route.query.id
+        )
+
+        state.name = data.name
+        state.phoneNumber = data.phoneNumber
+        state.province = data.province
+        state.city = data.city
+        state.region = data.region ? data.region : ''
+        state.pcrStr = (data.provinceName || '') + (data.cityName || '') + (data.regionName || '')
+        state.detailAddress = data.detailAddress
+        state.defaultStatus = data.defaultStatus
+      } catch {
+        //
+      }
     }
+    onMounted(() => {
+      // 判断是否有编号,有则为修改
+      if (route.query.id) {
+        getDetails()
+      }
+    })
     return () => (
       <div class={styles.operation}>
         <CellGroup inset class={styles.form}>
           <Field label="收货人" placeholder="请输入收货人姓名" v-model={state.name} />
-          <Field label="手机号" placeholder="请输入收货人人手机号" v-model={state.phoneNumber} />
+          <Field
+            label="手机号"
+            placeholder="请输入收货人人手机号"
+            v-model={state.phoneNumber}
+            maxlength={11}
+            formatter={onFormatterInt}
+          />
           <Field
             label="所在地区"
             placeholder="省、市、区、街道"
@@ -59,7 +156,7 @@ export default defineComponent({
 
         <OSticky position="bottom">
           <div class="btnGroup">
-            <Button type="primary" block round>
+            <Button type="primary" block round onClick={onSubmit} disabled={state.isClick}>
               确认
             </Button>
           </div>
@@ -79,20 +176,20 @@ export default defineComponent({
                 selectedOptions.forEach((item: any, index: number) => {
                   state.pcrStr += item.name
                   if (index === 0) {
-                    state.province = item.id
+                    state.province = item.code
                   } else if (index === 1) {
-                    state.city = item.id
+                    state.city = item.code
                   }
                 })
               } else {
                 selectedOptions.forEach((item: any, index: number) => {
                   state.pcrStr += item.name
                   if (index === 0) {
-                    state.province = item.id
+                    state.province = item.code
                   } else if (index === 1) {
-                    state.city = item.id
+                    state.city = item.code
                   } else if (index === 2) {
-                    state.region = item.id
+                    state.region = item.code
                   }
                 })
               }

+ 66 - 15
src/student/music-group/shop-address/index.tsx

@@ -1,5 +1,5 @@
-import { Button, Cell, SwipeCell, Tag, Image, Icon, showConfirmDialog, List } from 'vant'
-import { defineComponent, onMounted, reactive } from 'vue'
+import { Button, Cell, SwipeCell, Tag, Image, Icon, showConfirmDialog, List, showToast } from 'vant'
+import { defineComponent, onMounted, onUpdated, reactive } from 'vue'
 import styles from './index.module.less'
 import iconEdit from '../pre-apply/images/icon-edit.png'
 import OSticky from '@/components/o-sticky'
@@ -22,13 +22,33 @@ export default defineComponent({
       params: {
         page: 1,
         rows: 20
-      }
+      },
+      selectItem: {} // 选择的地址
     })
-    const onBeforeClose = ({ position }: any) => {
+    const onBeforeClose = ({ position }: any, item: any) => {
       if (position === 'right') {
         showConfirmDialog({
           title: '确定删除吗?'
-        }).then(() => {
+        }).then(async () => {
+          await request.post('/api-student/userReceiveAddress/remove', {
+            requestType: 'form',
+            data: {
+              id: item.id
+            }
+          })
+
+          setTimeout(() => {
+            showToast('删除成功')
+          }, 100)
+
+          setTimeout(() => {
+            form.params.page = 1
+            form.list = []
+            form.listState.dataShow = true // 判断是否有数据
+            form.listState.loading = false
+            form.listState.finished = false
+            getList()
+          }, 1100)
           return true
         })
       } else {
@@ -36,6 +56,15 @@ export default defineComponent({
       }
     }
 
+    const onUpdate = (item: any) => {
+      router.push({
+        path: '/addressOperation',
+        query: {
+          id: item.id
+        }
+      })
+    }
+
     // api-student/userReceiveAddress/page
     const getList = async () => {
       try {
@@ -64,9 +93,14 @@ export default defineComponent({
       }
     }
 
+    // 选择地址
+    const onDetails = (item: any) => {
+      sessionStorage.setItem('addressDetails', JSON.stringify(item))
+      router.back()
+    }
+
     onMounted(() => {
       getList()
-      console.log('1111')
     })
     return () => (
       <div class={styles.shopAddress}>
@@ -80,26 +114,43 @@ export default defineComponent({
             immediateCheck={false}
           >
             {form.list.map((item: any) => (
-              <SwipeCell class={styles.swipeCell} beforeClose={onBeforeClose}>
+              <SwipeCell
+                class={styles.swipeCell}
+                beforeClose={(args: any) => onBeforeClose(args, item)}
+              >
                 {{
                   default: () => (
-                    <Cell center>
+                    <Cell center onClick={() => onDetails(item)}>
                       {{
                         title: () => (
                           <div class={styles.title}>
-                            <span class={styles.name}>小林林</span>
-                            <span class={styles.phone}>15353535353</span>
-                            <Tag round color="#FF8057">
-                              默认
-                            </Tag>
+                            <span class={styles.name}>{item.name}</span>
+                            <span class={styles.phone}>{item.phoneNumber}</span>
+                            {item.defaultStatus && (
+                              <Tag round color="#FF8057">
+                                默认
+                              </Tag>
+                            )}
                           </div>
                         ),
                         label: () => (
                           <div class={styles.content}>
-                            湖北省武汉市武昌区水果湖街街道楚河汉街总部国际A座3801
+                            {item.provinceName}
+                            {item.cityName}
+                            {item.regionName}
+                            {item.detailAddress}
                           </div>
                         ),
-                        'right-icon': () => <Icon name={iconEdit} size="18" />
+                        'right-icon': () => (
+                          <Icon
+                            name={iconEdit}
+                            size="18"
+                            onClick={(e: Event) => {
+                              e.stopPropagation()
+                              onUpdate(item)
+                            }}
+                          />
+                        )
                       }}
                     </Cell>
                   ),

BIN
src/student/payment-result/images/icon_refunded.png


BIN
src/student/payment-result/images/icon_refunding.png


BIN
src/student/payment-result/images/icon_success.png


+ 4 - 0
src/student/payment-result/index.module.less

@@ -0,0 +1,4 @@
+.paymentTitle {
+  min-height: 226px;
+  background: linear-gradient(180deg, #ffe4d4 0%, #ffffff 100%);
+}

+ 16 - 0
src/student/payment-result/index.tsx

@@ -0,0 +1,16 @@
+import OHeader from '@/components/o-header'
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+
+export default defineComponent({
+  name: 'payment-result',
+  setup() {
+    return () => (
+      <div class={styles.paymentResult}>
+        <div class={styles.paymentTitle}>
+          <OHeader border={false} background="transparent" />
+        </div>
+      </div>
+    )
+  }
+})

+ 25 - 127
src/views/adapay/pay-define/index.tsx

@@ -13,7 +13,7 @@ export default defineComponent({
     const state = reactive({
       browserStatus: false,
       errorText: '',
-      code: (route.query.code || '') as any,
+      code: null as any,
       pay_channel: route.query.pay_channel as any,
       wxAppId: route.query.wxAppId as any,
       body: route.query.body as any,
@@ -47,20 +47,6 @@ export default defineComponent({
 
         console.log(data, 'payment')
         scanCodePay(data.reqParams)
-        // let payment = result.data
-        //           if (payment.status === "succeeded") {
-        //             this.scanCodePay(payment);
-        //           } else if (payment.status == "failed") {
-        //             this.browserStatus = false;
-        //             this.errorText = payment.error_msg;
-        //             document.title = "ERROR";
-        //           } else if (payment.status == "pending") {
-        //             this.$dialog.alert({
-        //               title: "提示",
-        //               message: "订单处理中...",
-        //               confirmButtonColor: "#269a93",
-        //             });
-        //           }
       } catch (e) {
         //
         console.log(e)
@@ -117,134 +103,41 @@ export default defineComponent({
             res.err_msg == 'get_brand_wcpay_request:cancel' ||
             res.err_msg == 'get_brand_wcpay_request:fail'
           ) {
-            alert('支付失败')
+            window.location.replace(
+              location.origin + '/orchestra-student/#/payment-result?orderNo=' + state.orderNo
+            )
           } else {
             // 使用以上方式判断前端返回,微信团队郑重提示:
             //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
-            alert('支付成功')
+            // alert('支付成功')
+            window.location.replace(
+              location.origin + '/orchestra-student/#/payment-result?orderNo=' + state.orderNo
+            )
           }
         }
       )
     }
 
-    //  getPayment: throttle(function() {
-    //   try {
-    //     if (!(parseFloat(this.amount) > 0)) {
-    //       this.$toast("f");
-    //       return;
-    //     }
-    //     removeAuthToken();
-    //     const returnUrl = this.returnUrl.replace(/\^\^/gi, "&");
-    //     let that = this,
-    //       payMap = {
-    //         orderNo: this.orderNo,
-    //         sign: this.sign,
-    //         amount: numeral(this.amount).format("0.00"),
-    //         payChannel: this.payType, // 支付渠道
-    //         orderBody: this.orderBody,
-    //         orderSubject: this.orderSubject,
-    //         tenantId: this.tenantId,
-    //         returnUrl: returnUrl,
-    //         notifyUrl: this.notifyUrl,
-    //         platform: this.platform,
-    //       };
-    //     // 判断是否是微信公众号支付
-    //     if (this.payType == "wx_pub") {
-    //       payMap.code = this.code;
-    //     }
-    //     this.$toast.loading({
-    //       duration: 0,
-    //       message: "加载中...",
-    //       forbidClick: true,
-    //     });
-    //     console.log(payMap);
-    //     executePayment(payMap)
-    //       .then((res) => {
-    //         this.$toast.clear();
-    //         let result = res.data;
-    //         if (result.code == 200) {
-    //           let payment = result.data;
-    //           if (payment.status === "succeeded") {
-    //             this.scanCodePay(payment);
-    //           } else if (payment.status == "failed") {
-    //             this.browserStatus = false;
-    //             this.errorText = payment.error_msg;
-    //             document.title = "ERROR";
-    //           } else if (payment.status == "pending") {
-    //             this.$dialog.alert({
-    //               title: "提示",
-    //               message: "订单处理中...",
-    //               confirmButtonColor: "#269a93",
-    //             });
-    //           }
-    //         } else {
-    //           this.$dialog.alert({
-    //             title: "提示",
-    //             message: result.msg,
-    //             confirmButtonColor: "#269a93",
-    //           });
-    //         }
-    //       })
-    //       .catch((err) => {
-    //         this.$toast.clear();
-    //         this.$dialog.alert({
-    //           title: "提示",
-    //           message: JSON.stringify(err),
-    //           confirmButtonColor: "#269a93",
-    //         });
-    //       });
-    //   } catch (error) {
-    //     this.$dialog.alert({
-    //       title: "提示",
-    //       message: "网络异常,请检查网络连接",
-    //       confirmButtonColor: "#269a93",
-    //     });
-    //   }
-    // }, 500),
-    // scanCodePay(data) {
-    //   // 判断支付方式 如果是 test 模式 支付用测试url 否则用生产url
-    //   if (this.payType == "alipay_qr") {
-    //     let url =
-    //       data.prod_mode === "false"
-    //         ? data.expend.qrcode_url +
-    //           "?payment_id=" +
-    //           data.id +
-    //           "&pay_channel=" +
-    //           data.pay_channel
-    //         : data.expend.qrcode_url;
-    //     window.location.href = url;
-    //   } else if (this.payType == "wx_pub") {
-    //     let tempPayInfo = JSON.parse(data.expend.pay_info);
-    //     this.payInfo = tempPayInfo;
-    //     if (typeof WeixinJSBridge == "undefined") {
-    //       if (document.addEventListener) {
-    //         document.addEventListener(
-    //           "WeixinJSBridgeReady",
-    //           this.onBridgeReady,
-    //           false
-    //         );
-    //       } else if (document.attachEvent) {
-    //         document.attachEvent("WeixinJSBridgeReady", this.onBridgeReady);
-    //         document.attachEvent("onWeixinJSBridgeReady", this.onBridgeReady);
-    //       }
-    //     } else {
-    //       this.onBridgeReady();
-    //     }
-    //   }
-    // },
+    const goAuth = () => {
+      // 用户授权
+      const urlNow = encodeURIComponent(window.location.href)
+      const scope = 'snsapi_base' //snsapi_userinfo   //静默授权 用户无感知
+      const appid = state.wxAppId || 'wx8654c671631cfade'
+      const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
+      window.location.replace(url)
+    }
 
-    onMounted(() => {
-      if (window.location.href.indexOf('?#') < 0) {
-        window.location.href = window.location.href.replace('#', '?#')
-      }
-      // 判断当前浏览器
+    const init = () => {
       const pay_channel = state.pay_channel
       if (browser().weixin) {
         if (pay_channel === 'wx_pub') {
           //授权
           const code = getUrlCode()
+          console.log(code)
           if (code) {
             state.code = code // 赋值code码
+          } else {
+            goAuth()
           }
           state.browserStatus = true
           document.title = '微信支付'
@@ -263,6 +156,11 @@ export default defineComponent({
         state.errorText = '请在微信或支付宝客户端打开'
       }
       state.errorText && (document.title = 'ERROR')
+    }
+
+    onMounted(() => {
+      console.log(state)
+      init()
     })
     return () => (
       <div class={styles.paydefine}>

+ 119 - 152
src/views/adapay/pay-result/index.tsx

@@ -1,5 +1,15 @@
-import { browser, getUrlCode } from '@/helpers/utils'
-import { Cell, CellGroup, closeToast, Icon, Loading, showConfirmDialog, showDialog } from 'vant'
+import request from '@/helpers/request'
+import { browser, getUrlCode, moneyFormat } from '@/helpers/utils'
+import {
+  Cell,
+  CellGroup,
+  closeToast,
+  Icon,
+  Loading,
+  showConfirmDialog,
+  showDialog,
+  showToast
+} from 'vant'
 import { defineComponent, onMounted, reactive } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import styles from './index.module.less'
@@ -12,21 +22,28 @@ export default defineComponent({
     const state = reactive({
       errorText: '',
       browserStatus: false,
-      payType: '',
-      payMap: {} as any,
-      code: ''
+      code: null as any,
+      pay_channel: route.query.pay_channel as any,
+      wxAppId: route.query.wxAppId as any,
+      body: route.query.body as any,
+      price: route.query.price as any,
+      orderNo: route.query.orderNo as any,
+      userId: route.query.userId as any,
+      payInfo: {} as any
     })
 
     const init = () => {
+      const query = route.query
+      console.log(query)
       // 判断是否有支付对象
-      if (!state.payMap || !state.payType) {
+      if (!query.orderNo || !query.pay_channel) {
         showConfirmDialog({
-          message: '支付订单信息错误请重新支付'
+          message: '支付订单信息错误请重新支付',
+          showCancelButton: false
         }).then(() => {
           router.back()
         })
       } else {
-        // state.amount = changeTwoDecimal(state.payMap.amount)
         // 判断当前浏览器
         if (browser().weixin) {
           state.browserStatus = true
@@ -41,155 +58,105 @@ export default defineComponent({
       }
     }
 
-    const getPayment = () => {
+    const getPayment = async () => {
       try {
-        // if (!(parseFloat(this.amount) > 0)) {
-        //   this.$toast('支付金额异常')
-        //   return
-        // }
-        // let { orderNo, sign, amount, orderBody, orderSubject, tenantId, returnUrl, notifyUrl } =
-        //   this.payMap
-        // returnUrl = returnUrl.replace(/\^\^/gi, '&')
-        // // 处理老师支付问题
-        // const tempPlatform = this.platform == 'teacher' ? 'student' : this.platform
-        // let that = this,
-        //   payMap = {
-        //     orderNo: orderNo,
-        //     sign: sign,
-        //     amount: numeral(amount).format('0.00'),
-        //     orderBody: orderBody,
-        //     orderSubject: orderSubject,
-        //     payChannel: this.payType, // 支付渠道
-        //     platform: tempPlatform,
-        //     tenantId: tenantId,
-        //     returnUrl: returnUrl,
-        //     notifyUrl: notifyUrl
-        //   }
-        // // 判断是否是微信公众号支付
-        // if (this.payType == 'wx_pub') {
-        //   payMap.code = this.code
-        // }
-        // this.$toast.loading({
-        //   duration: 0,
-        //   message: '加载中...',
-        //   forbidClick: true
-        // })
-        // executePayment(payMap)
-        //   .then((res) => {
-        //     this.$toast.clear()
-        //     let result = res.data
-        //     if (result.code == 200) {
-        //       let payment = result.data
-        //       if (payment.status === 'succeeded') {
-        //         this.scanCodePay(payment)
-        //       } else if (payment.status == 'failed') {
-        //         this.browserStatus = false
-        //         this.errorText = payment.error_msg
-        //         document.title = 'ERROR'
-        //       } else if (payment.status == 'pending') {
-        //         this.$dialog.alert({
-        //           title: '提示',
-        //           message: '订单处理中...',
-        //           confirmButtonColor: '#269a93'
-        //         })
-        //       }
-        //     } else {
-        //       showDialog({
-        //         title: '提示',
-        //         message: result.msg,
-        //         confirmButtonColor: '#269a93'
-        //       })
-        //     }
-        //   })
-        //   .catch((err) => {
-        //     closeToast()
-        //     showDialog({
-        //       title: '提示',
-        //       message: JSON.stringify(err),
-        //       confirmButtonColor: '#269a93'
-        //     })
-        //   })
+        try {
+          if (parseFloat(state.price) <= 0) {
+            showToast('支付金额异常')
+            return
+          }
+          const payMap: any = {
+            merOrderNo: state.orderNo,
+            paymentChannel: state.pay_channel, // 支付渠道
+            userId: state.userId
+          }
+          //     // 判断是否是微信公众号支付
+          if (state.pay_channel == 'wx_pub') {
+            payMap.code = state.code
+          }
+
+          const { data } = await request.post('/api-student/open/userOrder/executePayment', {
+            data: {
+              ...payMap
+            }
+          })
+
+          console.log(data, 'payment')
+          scanCodePay(data.reqParams)
+        } catch (e) {
+          //
+          console.log(e)
+        }
       } catch {
         //
       }
     }
+
     const scanCodePay = (data: any) => {
       // 判断支付方式 如果是 test 模式 支付用测试url 否则用生产url
-      // if (state.payType == 'alipay_wap') {
-      //   window.location.href = data.expend.pay_info
-      // } else if (state.payType == 'wx_pub') {
-      //   const tempPayInfo = JSON.parse(data.expend.pay_info)
-      //   state.payInfo = tempPayInfo
-      //   if (typeof WeixinJSBridge == 'undefined') {
-      //     if (document.addEventListener) {
-      //       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false)
-      //     } else if (document.attachEvent) {
-      //       document.attachEvent('WeixinJSBridgeReady', onBridgeReady)
-      //       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady)
-      //     }
-      //   } else {
-      //     state.onBridgeReady()
-      //   }
-      // }
+      if (state.pay_channel == 'alipay_qr') {
+        const url =
+          data.prod_mode === 'false'
+            ? data.expend.qrcode_url + '?payment_id=' + data.id + '&pay_channel=' + data.pay_channel
+            : data.expend.qrcode_url
+        window.location.href = url
+      } else if (state.pay_channel == 'wx_pub') {
+        const tempPayInfo = JSON.parse(data.expend.pay_info)
+        state.payInfo = tempPayInfo
+        if (typeof (window as any).WeixinJSBridge == 'undefined') {
+          if (document.addEventListener) {
+            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false)
+          } else if ((document as any).attachEvent) {
+            ;(document as any)
+              .attachEvent(
+                'WeixinJSBridgeReady',
+                onBridgeReady
+              )(document as any)
+              .attachEvent('onWeixinJSBridgeReady', onBridgeReady)
+          }
+        } else {
+          onBridgeReady()
+        }
+      }
     }
+
     const onBridgeReady = () => {
-      // let payInfo = this.payInfo
-      // WeixinJSBridge.invoke(
-      //   'getBrandWCPayRequest',
-      //   {
-      //     appId: payInfo.appId, //公众号名称,由商户传入
-      //     timeStamp: payInfo.timeStamp, //时间戳,自1970年以来的秒数
-      //     nonceStr: payInfo.nonceStr, //随机串
-      //     package: payInfo.package,
-      //     signType: payInfo.signType, //微信签名方式:
-      //     paySign: payInfo.paySign //微信签名
-      //   },
-      //   (res) => {
-      //     // if(res.err_msg == "get_brand_wcpay_request:ok" ){
-      //     // 使用以上方式判断前端返回,微信团队郑重提示:
-      //     //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
-      //     // } else
-      //     // 支付取消或支付失败
-      //     let { orderNo } = this.payMap
-      //     if (
-      //       res.err_msg == 'get_brand_wcpay_request:cancel' ||
-      //       res.err_msg == 'get_brand_wcpay_request:fail'
-      //     ) {
-      //       // 用户取消支付
-      //       if (this.platform == 'manager') {
-      //         // 管理端
-      //         window.location.replace(
-      //           validManageUrl() + '/#/paymentResult?orderNo=' + orderNo + '&isBack=off'
-      //         )
-      //       } else if (this.platform == 'teacher') {
-      //         // 老师端
-      //         window.location.replace(
-      //           validTeacherUrl() + '/#/paymentResult?orderNo=' + orderNo + '&isBack=off'
-      //         )
-      //       } else {
-      //         this.$router.replace({
-      //           path: '/paymentResult',
-      //           query: {
-      //             type: 'error',
-      //             orderNo: orderNo,
-      //             isBack: 'off'
-      //           }
-      //         })
-      //       }
-      //     } else {
-      //       // 使用以上方式判断前端返回,微信团队郑重提示:
-      //       //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
-      //       // this.$router.replace({
-      //       //   path: "/paymentResult",
-      //       //   query: {
-      //       //     orderNo: orderNo,
-      //       //     isBack: "off",
-      //       //   },
-      //       // });
-      //     }
-      //   }
-      // )
+      const payInfo = state.payInfo
+      // let orderNo = state.orderNo
+      ;(window as any).WeixinJSBridge.invoke(
+        'getBrandWCPayRequest',
+        {
+          appId: payInfo.appId, //公众号名称,由商户传入
+          timeStamp: payInfo.timeStamp, //时间戳,自1970年以来的秒数
+          nonceStr: payInfo.nonceStr, //随机串
+          package: payInfo.package,
+          signType: payInfo.signType, //微信签名方式:
+          paySign: payInfo.paySign //微信签名
+        },
+        (res: any) => {
+          // if(res.err_msg == "get_brand_wcpay_request:ok" ){
+          // 使用以上方式判断前端返回,微信团队郑重提示:
+          //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+          // } else
+          if (
+            res.err_msg == 'get_brand_wcpay_request:cancel' ||
+            res.err_msg == 'get_brand_wcpay_request:fail'
+          ) {
+            window.location.replace(
+              location.origin + '/orchestra-student/#/payment-result?orderNo=' + state.orderNo
+            )
+          } else {
+            // 使用以上方式判断前端返回,微信团队郑重提示:
+            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+            // alert('支付成功')
+            window.location.replace(
+              location.origin + '/orchestra-student/#/payment-result?orderNo=' + state.orderNo
+            )
+          }
+        }
+      )
     }
+
     const getWxPay = () => {
       // 微信公众号支付
       //授权
@@ -197,7 +164,7 @@ export default defineComponent({
       if (!code) {
         goAuth()
       } else {
-        // state.code = code
+        state.code = code
         getPayment()
       }
     }
@@ -205,7 +172,7 @@ export default defineComponent({
       // 用户授权
       const urlNow = encodeURIComponent(window.location.href)
       const scope = 'snsapi_base' //snsapi_userinfo   //静默授权 用户无感知
-      const appid = state.payMap.wxAppId || 'wx751141096e75a4ee'
+      const appid = state.wxAppId || 'wx8654c671631cfade'
       const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
       window.location.replace(url)
     }
@@ -220,13 +187,13 @@ export default defineComponent({
           <>
             <div class={styles.container}>
               <CellGroup border={false}>
-                <Cell title={'订单金额'} value={'¥' + 0}></Cell>
-                <Cell title={'订单信息'} value={'121212'}></Cell>
+                <Cell title={'订单金额'} value={'¥' + moneyFormat(state.price)}></Cell>
+                <Cell title={'订单信息'} value={state.body}></Cell>
               </CellGroup>
             </div>
 
             <div class={styles['order-loading']}>
-              <p>{state.payType == 'wx_pub' ? '微信支付' : '支付宝支付'}</p>
+              <p>{state.pay_channel == 'wx_pub' ? '微信支付' : '支付宝支付'}</p>
               <Loading type="spinner" color="#01C1B5" />
             </div>
           </>