Browse Source

添加首页功能

lex 2 years ago
parent
commit
195818bebd

+ 13 - 2
src/components/col-sticky/index.tsx

@@ -29,8 +29,16 @@ export default defineComponent({
     } else {
       this.divStyle.bottom = '0px'
     }
-    const { height } = useRect((this as any).$refs.div)
-    this.sectionStyle.height = `${height}px`
+    // const { height } = useRect((this as any).$refs.div)
+    // this.sectionStyle.height = `${height}px`
+
+    this.$nextTick(() => {
+      setTimeout(() => {
+        const { height } = useRect((this as any).$refs.div)
+        this.sectionStyle.height = `${height}px`
+        this.$emit('getHeight', height)
+      }, 100)
+    })
   },
   render() {
     return (
@@ -46,3 +54,6 @@ export default defineComponent({
     )
   }
 })
+function nextTick(arg0: () => void) {
+  throw new Error('Function not implemented.')
+}

+ 11 - 4
src/helpers/native-message.ts

@@ -27,7 +27,7 @@ window.postMessage = (message: IPostMessage) => {
 type CallBack = (evt?: IPostMessage) => void
 
 // eslint-disable-next-line @typescript-eslint/no-empty-function
-const loop = () => {}
+const loop = () => { }
 
 const calls: { [key: string]: CallBack | CallBack[] } = {}
 
@@ -76,8 +76,15 @@ if (browserInfo.isApp) {
   })
 }
 
-const instance: any =
-  (window as any).COLEXIU || (window as any).webkit?.messageHandlers?.COLEXIU
+// 判断是否是管乐团学生端的app
+console.log(browserInfo.isOrchestraStudent)
+let instance: any
+if (browserInfo.isOrchestraStudent) {
+  instance = (window as any).ORCHESTRA || (window as any).webkit?.messageHandlers?.ORCHESTRA
+} else {
+  instance = (window as any).COLEXIU || (window as any).webkit?.messageHandlers?.COLEXIU
+}
+
 
 export const postMessage = (data: IPostMessage, callback?: CallBack) => {
   if (browserInfo.isApp) {
@@ -111,7 +118,7 @@ export const removeListenerMessage = (api: string, callback: CallBack) => {
     const uuid = api
     if (Array.isArray(calls[uuid])) {
       const indexOf = (calls[uuid] as CallBack[]).indexOf(callback)
-      ;(calls[uuid] as CallBack[]).splice(indexOf, 1)
+        ; (calls[uuid] as CallBack[]).splice(indexOf, 1)
     }
   }
 }

+ 2 - 0
src/helpers/utils.ts

@@ -19,9 +19,11 @@ export const browser = () => {
     isApp:
       u.indexOf('COLEXIUAPPI') > -1 ||
       u.indexOf('COLEXIUAPPA') > -1 ||
+      u.indexOf('ORCHESTRASTUDENT') > -1 ||
       u.indexOf('Adr') > -1,
     isTeacher: u.indexOf('COLEXIUTEACHER') > -1,
     isStudent: u.indexOf('COLEXIUSTUDENT') > -1,
+    isOrchestraStudent: u.indexOf('ORCHESTRASTUDENT') > -1, // 判断是否是管乐团学生端
     iPad: u.indexOf('iPad') > -1, //是否iPad
     webApp: u.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
     weixin: u.indexOf('MicroMessenger') > -1, //是否微信 (2015-01-22新增)

+ 31 - 6
src/router/routes-student.ts

@@ -1,4 +1,5 @@
 import Auth from '@/student/layout/auth'
+import HomeAuth from '@/student/home-layout-orchestra/auth'
 import { router, rootRouter } from './routes-common'
 
 type metaType = {
@@ -21,7 +22,8 @@ const noLoginRouter = [
       title: '曲目挑战排行榜'
       // isExternal: true // 是否外部浏览器可以打开
     }
-  }
+  },
+
 ]
 
 export default [
@@ -38,11 +40,7 @@ export default [
           isRegister: false
         } as metaType
       },
-      {
-        path: '/home',
-        name: 'home',
-        component: () => import('@/student/home/index')
-      },
+
       {
         path: '/practiceClass',
         name: 'practiceClass',
@@ -141,6 +139,33 @@ export default [
       }
     ]
   },
+  {
+    path: '/home-layout',
+    component: HomeAuth,
+    children: [
+      {
+        path: '/home-auth',
+        name: 'home-auth',
+        component: () => import('@/student/home-layout-orchestra/auth-login'),
+        meta: {
+          title: '登录酷乐秀'
+        }
+      },
+      {
+        path: '/home-login',
+        name: 'home-login',
+        component: () => import('@/student/home-layout-orchestra/login'),
+        meta: {
+          title: '登录酷乐秀'
+        }
+      },
+      {
+        path: '/home',
+        name: 'home',
+        component: () => import('@/student/home/index')
+      },
+    ]
+  },
   ...noLoginRouter,
   ...rootRouter,
   {

+ 7 - 1
src/state.ts

@@ -9,6 +9,13 @@ export const state = reactive({
     status: 'init' as status,
     data: {} as any
   },
+  orchestraInfo: {
+    token: '' as any, phone: '' as any,
+    installStatus: 0 as any,
+    nickname: '',
+    avatar: '',
+    unionId: 0 // 是否已关联账号
+  } as any, // 管乐团信息
   platformType: '' as 'STUDENT' | 'TEACHER',
   platformApi: '/api-student' as '/api-student' | '/api-teacher',
   version: '', // 版本号 例如: 1.0.0
@@ -57,5 +64,4 @@ export const openDefaultWebView = (url?: string, callBack?: any) => {
   } else {
     callBack && callBack()
   }
-
 }

+ 94 - 0
src/student/home-layout-orchestra/auth-login.tsx

@@ -0,0 +1,94 @@
+import { defineComponent } from 'vue'
+import { Button, Image, Toast } from 'vant'
+import { removeAuth, setAuth } from './utils'
+import styles from './index.module.less'
+import { postMessage } from '@/helpers/native-message'
+import iconStudent from '@common/images/icon_student.png'
+import logo from '@common/images/logo.png'
+import ColPopup from '@/components/col-popup'
+import InviteCode from './invite-code'
+import { state } from '@/state'
+
+export default defineComponent({
+  name: 'login-music',
+  data() {
+    return {
+      username: '',
+      imgCodeStatus: false
+    }
+  },
+  mounted() {
+    this.username = state.orchestraInfo.phone
+    removeAuth()
+  },
+  methods: {
+    onLoginSuccess() {
+      // console.log('1111111---1-1-')
+      // 调用原生api去关联账号
+      postMessage({ api: 'bindUserAccount', content: { phone: this.username } })
+      // 登录成功
+      setTimeout(() => {
+        Toast('授权成功')
+      }, 100)
+      setTimeout(() => {
+        // this.$router.push('/home')
+        window.location.href = location.origin + location.pathname + '#/home'
+        // setTimeout(() => {
+        window.location.reload()
+        // }, 100)
+      }, 1000)
+    }
+  },
+  render() {
+    return (
+      <div class={styles.login}>
+        <div class={styles.container}>
+          <div class={[styles.userInfo, styles.loginCenter]}>
+            <Image src={iconStudent} class={styles.img} />
+
+            <p class={styles.name}>{state.orchestraInfo.name}</p>
+          </div>
+
+          <div class={[styles.tips, styles.loginCenter]}>
+            <Image src={logo} class={styles.logo} fit="contain" />
+
+            <p class={styles.text}>同意酷乐秀获取您的管乐团信息并登录</p>
+
+            <p class={styles.phone}>{this.username}</p>
+          </div>
+        </div>
+
+        <div class={styles.btnGroup}>
+          <Button
+            round
+            color="#FF8057"
+            class={styles.btn}
+            onClick={() => {
+              this.imgCodeStatus = true
+            }}
+          >
+            登录
+          </Button>
+
+          <span
+            class={styles.moreBtn}
+            onClick={() => {
+              this.$router.push('/home-login')
+            }}
+          >
+            其他手机号登录
+          </span>
+        </div>
+
+        <ColPopup v-model={this.imgCodeStatus}>
+          {this.imgCodeStatus && (
+            <InviteCode
+              phone={this.username}
+              onLoginSuccess={this.onLoginSuccess}
+            />
+          )}
+        </ColPopup>
+      </div>
+    )
+  }
+})

+ 110 - 0
src/student/home-layout-orchestra/auth.tsx

@@ -0,0 +1,110 @@
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+import { state, setLogin, setLogout, setLoginError } from './state-orchestra'
+import { browser } from '@/helpers/utils'
+import { setAuth } from './utils'
+import { RouterView } from 'vue-router'
+
+import request from './request-home'
+import ColResult from '@/components/col-result'
+
+const browserInfo = browser()
+export default defineComponent({
+  name: 'Auth-loayout',
+  data() {
+    return {
+      loading: false as boolean
+    }
+  },
+  computed: {
+    isExternal() {
+      // 该路由在外部连接打开是否需要登录
+      // 只判断是否在学生端打开
+      return (this.$route.meta.isExternal && !browserInfo.isStudent) || false
+    },
+    isNeedView() {
+      return (
+        state.user.status === 'login' ||
+        this.$route.path === '/home-auth' ||
+        this.$route.path === '/home-login' ||
+        (this as any).isExternal
+      )
+    }
+  },
+  mounted() {
+    !this.isExternal && this.setAuth()
+  },
+  methods: {
+    async setAuth() {
+      const { query } = this.$route
+      const token = query.userInfo || query.Authorization
+      if (token) {
+        setAuth(token)
+      }
+      if (this.loading) {
+        return
+      }
+      console.log('state.user', state.user)
+      if (state.user.status === 'init' || state.user.status === 'error') {
+        this.loading = true
+        try {
+          const res = await request.get('/api-student/student/queryUserInfo', {
+            initRequest: true, // 初始化接口
+            requestType: 'form'
+          })
+          setLogin(res.data)
+        } catch (e: any) {
+          // console.log(e, 'e')
+          const message = e.message
+          if (
+            message.indexOf('5000') === -1 &&
+            message.indexOf('authentication') === -1
+          ) {
+            setLoginError()
+          } else {
+            setLogout()
+          }
+        }
+        this.loading = false
+      }
+      if (state.user.status === 'logout') {
+        try {
+          const route = this.$route
+          const query = {
+            returnUrl: this.$route.path,
+            ...this.$route.query
+          } as any
+          if (route.meta.isRegister) {
+            query.isRegister = route.meta.isRegister
+          }
+          this.$router.replace({
+            path: '/home-auth',
+            query: query
+          })
+        } catch (error) {
+          //
+        }
+      }
+    }
+  },
+  render() {
+    return (
+      <>
+        {state.user.status === 'error' ? (
+          <div class={styles.error}>
+            <ColResult
+              type="notFond"
+              classImgSize="CERT"
+              tips="加载失败,请稍后重试"
+              buttonText="重新加载"
+              plain={true}
+              onClick={this.setAuth}
+            />
+          </div>
+        ) : this.isNeedView ? (
+          <RouterView></RouterView>
+        ) : null}
+      </>
+    )
+  }
+})

+ 103 - 0
src/student/home-layout-orchestra/index.module.less

@@ -0,0 +1,103 @@
+.error {
+  background-color: #fff;
+  display: flex;
+  // padding-top: 20px;
+  flex-direction: column;
+  min-height: calc(100vh);
+  align-items: center;
+  justify-content: center;
+  .info {
+    display: flex;
+    align-items: center;
+    margin-bottom: 30px;
+
+    span {
+      display: inline-block;
+      margin-left: 10px;
+      color: #58727e;
+      font-size: 18px;
+    }
+  }
+
+  :global {
+    .col-result-container,
+    .van-empty {
+      padding-top: 0;
+    }
+
+    .van-button {
+      width: 50%;
+    }
+  }
+}
+.login {
+  min-height: 100vh;
+  background-color: #f6f6f6;
+  background-size: 100%;
+  position: relative;
+  overflow: hidden;
+
+  .loginCenter {
+    margin: 0 auto;
+    text-align: center;
+  }
+  .userInfo {
+    margin-top: 72px;
+    .img {
+      width: 104px;
+      height: 104px;
+      border-radius: 50%;
+      overflow: hidden;
+    }
+    .name {
+      padding-top: 12px;
+      font-size: 20px;
+      font-weight: 500;
+      color: #333333;
+      line-height: 28px;
+    }
+  }
+
+  .tips {
+    padding-top: 50px;
+    .logo {
+      height: 28px;
+    }
+    .text {
+      padding-top: 12px;
+      font-size: 14px;
+      color: #777777;
+      line-height: 20px;
+    }
+    .phone {
+      padding-top: 24px;
+      font-size: 20px;
+      font-weight: 500;
+      color: #333333;
+      line-height: 28px;
+    }
+  }
+
+  .btnGroup {
+    position: absolute;
+    bottom: 70px;
+    width: 100%;
+    text-align: center;
+    display: flex;
+    align-items: center;
+    flex-direction: column;
+
+    .btn {
+      font-size: 16px;
+      font-weight: 500;
+      width: 204px;
+    }
+
+    .moreBtn {
+      padding-top: 24px;
+      font-size: 16px;
+      color: #333333;
+      line-height: 22px;
+    }
+  }
+}

+ 46 - 0
src/student/home-layout-orchestra/invite-code/index.module.less

@@ -0,0 +1,46 @@
+.loginCode {
+  min-height: 100vh;
+  background: url('../../layout/images/top_bg.png') no-repeat top center,
+    url('../../layout/images/bottom_bg.png') no-repeat bottom center;
+  background-color: #fff;
+  background-size: 100%;
+
+  :global {
+    .van-password-input {
+      margin: 0 42px;
+    }
+    .van-password-input__security li {
+      background-color: #f3f3f3;
+      width: 38px;
+      height: 40px;
+      border-radius: 6px;
+    }
+    .van-button {
+      padding: 14px 32px;
+    }
+    .van-count-down {
+      display: inline;
+      color: #fff;
+    }
+  }
+}
+
+.codeTips {
+  padding: 85px 35px 40px;
+  font-size: 26px;
+  font-weight: 500;
+
+  .codeTxt {
+    padding-top: 20px;
+    font-size: 16px;
+    line-height: 22px;
+    span {
+      color: #999999;
+    }
+  }
+}
+
+.btnWrap {
+  padding-top: 50px;
+  text-align: center;
+}

+ 145 - 0
src/student/home-layout-orchestra/invite-code/index.tsx

@@ -0,0 +1,145 @@
+import ColHeader from '@/components/col-header'
+import { promisefiyPostMessage } from '@/helpers/native-message'
+import request from '@/student/home-layout-orchestra/request-home'
+import { setAuth } from '@/helpers/utils'
+import { Button, NumberKeyboard, PasswordInput, Toast } from 'vant'
+import { defineComponent } from 'vue'
+import styles from './index.module.less'
+
+export default defineComponent({
+  name: 'invteCode',
+  props: {
+    phone: String,
+    onLoginSuccess: {
+      type: Function,
+      default: () => {}
+    }
+  },
+  data() {
+    return {
+      smsCode: '',
+      showKeyboard: true,
+      countDownStatus: true,
+      countDownTime: 120, // 倒计时时间
+      countTimer: null as any
+    }
+  },
+  watch: {
+    smsCode(val: any) {
+      if (val && val.length === 6) {
+        this.onLogin()
+      }
+    }
+  },
+  async mounted() {
+    this.$nextTick(async () => {
+      await this.onSendSms()
+    })
+  },
+  unmounted() {
+    clearInterval(this.countTimer)
+  },
+  methods: {
+    async onSendSms() {
+      try {
+        console.log(this.phone, 'this.phone')
+        await request.post('/api-student/code/sendSmsCode', {
+          requestType: 'form',
+          data: {
+            mobile: this.phone,
+            type: 'LOGIN'
+          }
+        })
+        this.onCountDown()
+        setTimeout(() => {
+          Toast('验证码已发送')
+        }, 100)
+      } catch {
+        this.countDownStatus = true
+      }
+    },
+    onCountDown() {
+      this.countDownStatus = false
+      this.countTimer = setInterval(() => {
+        if (this.countDownTime > 0) {
+          this.countDownTime--
+        } else {
+          this.countDownStatus = true
+          clearInterval(this.countTimer)
+        }
+      }, 1000)
+    },
+    async onLogin() {
+      try {
+        const res = await request.post('/api-auth/smsLogin', {
+          requestType: 'form',
+          data: {
+            clientId: 'student',
+            clientSecret: 'student',
+            phone: this.phone,
+            smsCode: this.smsCode,
+            isSurportRegister: true
+          }
+        })
+
+        const { authentication } = res.data
+        setAuth(authentication.token_type + ' ' + authentication.access_token)
+        this.onLoginSuccess()
+        // await promisefiyPostMessage({
+        //   api: 'setCache',
+        //   content: {
+        //     key: 'h5-colexiu-token',
+        //     value: authentication.access_token
+        //   }
+        // })
+      } catch {
+        //
+      }
+    }
+  },
+  render() {
+    return (
+      <>
+        <div class={styles.loginCode}>
+          <ColHeader border={false} background="transparent" title=" " isBack />
+
+          <div class={styles.codeTips}>
+            <p class={styles.txt}>输入验证码</p>
+            <p class={styles.codeTxt}>
+              已发送6位验证码至 <span>{this.phone}</span>
+            </p>
+          </div>
+
+          <PasswordInput
+            value={this.smsCode}
+            focused={this.showKeyboard}
+            length={6}
+            onFocus={() => {
+              this.showKeyboard = true
+            }}
+            gutter={10}
+          ></PasswordInput>
+          <NumberKeyboard
+            v-model={this.smsCode}
+            show={this.showKeyboard}
+            maxlength={6}
+            onBlur={() => {
+              this.showKeyboard = false
+            }}
+          ></NumberKeyboard>
+
+          <div class={styles.btnWrap}>
+            <Button
+              type="primary"
+              round
+              onClick={this.onSendSms}
+              disabled={!this.countDownStatus}
+            >
+              重新发送 {!this.countDownStatus && <>({this.countDownTime})</>}
+            </Button>
+          </div>
+        </div>
+      </>
+    )
+  }
+})

+ 44 - 0
src/student/home-layout-orchestra/login.module.less

@@ -0,0 +1,44 @@
+.login {
+  min-height: 100vh;
+  background: url('../layout/images/top_bg.png') no-repeat top center,
+    url('../layout/images/bottom_bg.png') no-repeat bottom center;
+  background-color: #fff;
+  background-size: 100%;
+
+  .loginTitle {
+    padding-top: 100px;
+    font-size: 26px;
+    padding-left: 35px;
+    padding-bottom: 70px;
+    line-height: 37px;
+    font-weight: 500;
+  }
+
+  .codeText {
+    color: var(--van-primary);
+  }
+
+  .margin34 {
+    margin: 0 34px;
+  }
+
+  .formTitle {
+    font-size: 18px;
+    color: #000;
+    font-weight: 500;
+  }
+
+  :global {
+    .van-cell-group {
+      margin-bottom: 35px;
+    }
+    .van-field {
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .van-button + .van-button {
+      margin-top: 20px;
+      color: #000 !important;
+    }
+  }
+}

+ 178 - 0
src/student/home-layout-orchestra/login.tsx

@@ -0,0 +1,178 @@
+import { defineComponent } from 'vue'
+import { CellGroup, Field, Button, CountDown, Row, Col, Toast } from 'vant'
+import ImgCode from '@/components/col-img-code'
+import { checkPhone } from '@/helpers/validate'
+import request from '@/student/home-layout-orchestra/request-home'
+import { setLogin, state } from '@/state'
+import { removeAuth, setAuth } from '@/helpers/utils'
+import styles from './login.module.less'
+import ColHeader from '@/components/col-header'
+
+export default defineComponent({
+  name: 'login',
+  data() {
+    return {
+      username: '',
+      password: '',
+      smsCode: '',
+      countDownStatus: true, // 是否发送验证码
+      countDownTime: 1000 * 120, // 倒计时时间
+      countDownRef: null as any, // 倒计时实例
+      imgCodeStatus: false
+    }
+  },
+  computed: {
+    codeDisable() {
+      let status = true
+
+      this.username && this.smsCode && (status = false)
+      return status
+    }
+  },
+  mounted() {
+    removeAuth()
+    this.directNext()
+  },
+  methods: {
+    directNext() {
+      if (state.user.status === 'login' || state.user.status === 'error') {
+        const { returnUrl, isRegister, ...rest } = this.$route.query
+        this.$router.replace({
+          path: '/home',
+          query: {
+            ...rest
+          }
+        })
+      }
+    },
+    async onLogin() {
+      try {
+        const res = await request.post('/api-auth/smsLogin', {
+          requestType: 'form',
+          data: {
+            clientId: 'student',
+            clientSecret: 'student',
+            phone: this.username,
+            smsCode: this.smsCode,
+            isSurportRegister: true
+          }
+        })
+
+        const { authentication } = res.data
+        setAuth(authentication.token_type + ' ' + authentication.access_token)
+
+        const userCash = await request.get(
+          '/api-student/student/queryUserInfo',
+          {
+            initRequest: true // 初始化接口
+          }
+        )
+        setLogin(userCash.data)
+        // 调用原生api去关联账号
+        postMessage({
+          api: 'bindUserAccount',
+          content: { phone: this.username }
+        })
+
+        this.directNext()
+      } catch {
+        //
+      }
+    },
+    async onSendCode() {
+      // 发送验证码
+      if (!checkPhone(this.username)) {
+        return Toast('请输入正确的手机号码')
+      }
+      this.imgCodeStatus = true
+    },
+    onCodeSend() {
+      this.countDownStatus = false
+      this.countDownRef.start()
+    },
+    onFinished() {
+      this.countDownStatus = true
+      this.countDownRef.reset()
+    }
+  },
+  render() {
+    return (
+      <div class={styles.login}>
+        <ColHeader border={false} background="transparent" title=" " isBack />
+        <div class={styles.loginTitle}>
+          您好,
+          <br /> 欢迎使用酷乐秀
+        </div>
+        <CellGroup class={styles.margin34} border={false}>
+          <Row style={{ marginBottom: '16px' }}>
+            <Col span={24} class={styles.formTitle}>
+              手机号
+            </Col>
+            <Col span={24} class="van-hairline--bottom">
+              <Field
+                v-model={this.username}
+                name="手机号"
+                placeholder="请输入您的手机号"
+                type="tel"
+                maxlength={11}
+              />
+            </Col>
+          </Row>
+
+          <Row>
+            <Col span={24} class={styles.formTitle}>
+              验证码
+            </Col>
+            <Col span={24} class="van-hairline--bottom">
+              <Field
+                v-model={this.smsCode}
+                name="验证码"
+                placeholder="请输入验证码"
+                type="tel"
+                maxlength={6}
+                v-slots={{
+                  button: () =>
+                    this.countDownStatus ? (
+                      <span class={styles.codeText} onClick={this.onSendCode}>
+                        获取验证码
+                      </span>
+                    ) : (
+                      <CountDown
+                        ref={this.countDownRef}
+                        auto-start={false}
+                        time={this.countDownTime}
+                        onFinish={this.onFinished}
+                        format="ss秒"
+                      />
+                    )
+                }}
+              />
+            </Col>
+          </Row>
+        </CellGroup>
+        <div class={styles.margin34}>
+          <Button
+            round
+            block
+            type="primary"
+            disabled={this.codeDisable}
+            onClick={this.onLogin}
+          >
+            登录
+          </Button>
+        </div>
+
+        {this.imgCodeStatus ? (
+          <ImgCode
+            v-model:value={this.imgCodeStatus}
+            phone={this.username}
+            onClose={() => {
+              this.imgCodeStatus = false
+            }}
+            onSendCode={this.onCodeSend}
+          />
+        ) : null}
+      </div>
+    )
+  }
+})

+ 119 - 0
src/student/home-layout-orchestra/request-home.ts

@@ -0,0 +1,119 @@
+import { extend } from 'umi-request'
+import cleanDeep from 'clean-deep'
+import { browser, openLoading, closeLoading } from '@/helpers/utils'
+import { setLogout, setLoginError } from './state-orchestra'
+import { postMessage } from '@/helpers/native-message'
+import { Toast } from 'vant'
+
+export interface SearchInitParams {
+  rows?: string | number
+  page?: string | number
+}
+
+const request = extend({
+  // requestType: 'form',
+  timeout: 20000,
+  timeoutMessage: '请求超时'
+})
+
+// request.use(async (ctx, next) => {
+//   const { url, options } = ctx.req
+//   const prefix = options.prefix || '';
+//   const baseUrl: string = url.replace(prefix, '') || '';
+//   const linkUrl: string = (ApiRouter as any)[baseUrl];
+//   if (linkUrl) {
+//     ctx.req.url = prefix + linkUrl;
+//   }
+//   await next();
+// })
+
+// 是否是初始化接口
+let initRequest = false
+let toast: ReturnType<typeof setTimeout>
+
+request.interceptors.request.use(
+  (url, options: any) => {
+    // openLoading();
+    if (!options.hideLoading) {
+      clearTimeout(toast)
+      Toast.loading({
+        message: '加载中...',
+        forbidClick: true,
+        loadingType: 'spinner',
+        duration: 0
+      })
+    }
+
+    initRequest = options.initRequest || false
+    const Authorization = sessionStorage.getItem('Authorization') || ''
+    const authHeaders: any = {}
+    if (
+      Authorization &&
+      ![
+        '/api-auth/usernameLogin',
+        '/api-auth/smsLogin',
+        '/api-auth/code/sendSms'
+      ].includes(url)
+    ) {
+      authHeaders.Authorization = Authorization
+    }
+    return {
+      url,
+      options: {
+        ...options,
+        params: cleanDeep(options.params),
+        headers: {
+          ...options.headers,
+          ...authHeaders
+        }
+      }
+    }
+  },
+  { global: false }
+)
+
+request.interceptors.response.use(
+  async res => {
+    toast = setTimeout(() => {
+      Toast.clear()
+    }, 100)
+
+    if (res.status > 299 || res.status < 200) {
+      clearTimeout(toast)
+      const msg = '服务器错误,状态码' + res.status
+      Toast(msg)
+      throw new Error(msg)
+    }
+    const data = await res.clone().json()
+    if (data.code !== 200 && data.errCode !== 0) {
+      let msg = data.msg || data.message || '处理失败,请重试'
+      if (initRequest) {
+        if (data.code === 403 || data.code === 401) {
+          setLogout()
+        } else {
+          setLoginError()
+        }
+      }
+      if (!(data.code === 403 || data.code === 401)) {
+        clearTimeout(toast)
+        Toast(msg)
+      }
+      const browserInfo = browser()
+      if (data.code === 403) {
+        msg += '403'
+        // if (browserInfo.isApp) {
+        //   postMessage({
+        //     api: 'login'
+        //   })
+        // } else {
+        //   setLogout()
+        // }
+      }
+      throw new Error(msg)
+    }
+    return res
+  },
+  { global: false }
+)
+
+export default request

+ 54 - 0
src/student/home-layout-orchestra/state-orchestra.ts

@@ -0,0 +1,54 @@
+import { browser } from '@/helpers/utils'
+import { reactive } from 'vue'
+
+type status = 'init' | 'login' | 'logout' | 'error'
+
+export const state = reactive({
+  user: {
+    status: 'init' as status,
+    data: {} as any
+  }
+})
+
+// 预览上传到oss的地址
+export const getOssUploadUrl = (bucket: string) => {
+  const tmpBucket = bucket || 'daya'
+  return `https://${tmpBucket}.ks3-cn-beijing.ksyuncs.com/`
+}
+
+export const setLoginInit = () => {
+  state.user.status = 'init'
+  state.user.data = null
+}
+
+export const setLogin = (data: any) => {
+  state.user.status = 'login'
+  state.user.data = data
+}
+
+export const setLogout = () => {
+  state.user.status = 'logout'
+  state.user.data = null
+}
+
+export const setLoginError = () => {
+  state.user.status = 'error'
+  state.user.data = null
+}
+
+
+// 用于处理跳转地址,如果是在app内,则打开一个新的webview, 否则跳转连接
+export const openDefaultWebView = (url?: string, callBack?: any) => {
+  if (browser().isApp) {
+    postMessage({
+      api: 'openWebView',
+      content: {
+        url,
+        orientation: 1,
+        isHideTitle: false
+      }
+    })
+  } else {
+    callBack && callBack()
+  }
+}

+ 22 - 0
src/student/home-layout-orchestra/utils.tsx

@@ -0,0 +1,22 @@
+/**
+ * 删除token
+ */
+export const removeAuth = () => {
+  sessionStorage.removeItem('Authorization')
+}
+
+/**
+ * 设置token
+ * @param token
+ * @returns {void}
+ */
+export const setAuth = (token: any) => {
+  sessionStorage.setItem('Authorization', token)
+}
+
+/**
+ * 获取token
+ */
+export const getAuth = () => {
+  sessionStorage.getItem('Authorization')
+}

+ 1 - 1
src/student/home/components/hot-album/index.tsx

@@ -4,7 +4,7 @@ import { defineComponent } from 'vue'
 import IconXin from '@/common/images/icon-xin.png'
 import IconXinActive from '@/common/images/icon-xin-active.png'
 import TheTitle from '../the-title'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { useRouter } from 'vue-router'
 
 export default defineComponent({

+ 2 - 2
src/student/home/components/info-list/index.tsx

@@ -1,8 +1,8 @@
 import ColResult from '@/components/col-result'
-import request from '@/helpers/request'
+import request from '@/student/home-layout-orchestra/request-home'
 import { verifyUrl } from '@/helpers/toolsValidate'
 import { dateFormat } from '@/helpers/utils'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { Cell, CellGroup, Image, List } from 'vant'
 import { defineComponent, reactive } from 'vue'
 import { useRouter } from 'vue-router'

+ 1 - 1
src/student/home/components/menu-list/index.tsx

@@ -1,5 +1,5 @@
 import { verifyUrl } from '@/helpers/toolsValidate'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { Swipe, SwipeItem, Image } from 'vant'
 import { defineComponent } from 'vue'
 import styles from './index.module.less'

+ 1 - 1
src/student/home/components/music/index.tsx

@@ -4,7 +4,7 @@ import { defineComponent, onMounted, ref } from 'vue'
 import { useRouter } from 'vue-router'
 import TheSong from '../TheSong'
 import TheTitle from '../the-title'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import item from '@/views/coupons/item'
 
 export default defineComponent({

+ 2 - 2
src/student/home/components/recommend-sage/index.tsx

@@ -1,11 +1,11 @@
 import { Button, Cell, Icon, Image, Toast } from 'vant'
 import styles from './index.module.less'
 import { defineComponent } from 'vue'
-import request from '@/helpers/request'
+import request from '@/student/home-layout-orchestra/request-home'
 import bars from '../../images/bars.svg'
 import TheTitle from '../the-title'
 import { useRouter } from 'vue-router'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 
 export default defineComponent({
   name: 'recommend-sage',

+ 2 - 2
src/student/home/components/talent-style/index.tsx

@@ -1,11 +1,11 @@
 import ColResult from '@/components/col-result'
-import request from '@/helpers/request'
+import request from '@/student/home-layout-orchestra/request-home'
 import { Image, List } from 'vant'
 import { defineComponent, reactive } from 'vue'
 import styles from './index.module.less'
 import bars from '../../images/bars2.svg'
 import iconVideoPlay from '../../images/icon_video_play.png'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { useRouter } from 'vue-router'
 
 export default defineComponent({

+ 1 - 1
src/student/home/components/video-class/index.tsx

@@ -1,4 +1,4 @@
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { Image } from 'vant'
 import { defineComponent } from 'vue'
 import { useRouter } from 'vue-router'

+ 2 - 2
src/student/home/index.tsx

@@ -1,6 +1,6 @@
-import request from '@/helpers/request'
+import request from '@/student/home-layout-orchestra/request-home'
 import { verifyUrl } from '@/helpers/toolsValidate'
-import { openDefaultWebView } from '@/state'
+import { openDefaultWebView } from '@/student/home-layout-orchestra/state-orchestra'
 import { PullRefresh, Swipe, SwipeItem, Image, Tabs, Tab } from 'vant'
 import { defineComponent } from 'vue'
 import HotAlbum from './components/hot-album'

+ 37 - 3
src/student/main.ts

@@ -4,13 +4,13 @@ import dayjs from 'dayjs'
 import 'dayjs/locale/zh-cn'
 import router from '../router/index-student'
 import vueFilter from '@/helpers/vueFilter'
-import { postMessage } from '@/helpers/native-message'
+import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'
 
 import 'normalize.css'
 
 import '../styles/index.less'
 import { state } from '@/state'
-import { browser } from '@/helpers/utils'
+import { browser, setAuth } from '@/helpers/utils'
 
 const app = createApp(App)
 
@@ -22,10 +22,44 @@ postMessage(
   },
   (res: any) => {
     state.version = res.content.version
-    console.log(res, 'version')
   }
 )
 
+// 判断是否是管乐团学生端,用来获取基础数据
+if (browser().isOrchestraStudent) {
+  // await promisefiyPostMessage({
+  //   api: 'setCache',
+  //   content: {
+  //     key: 'h5-colexiu-token',
+  //     value: ''
+  //   }
+  // })
+
+  // 获取管乐团token
+  promisefiyPostMessage({ api: 'getUserAccount' }).then((res: any) => {
+    const content = res.content
+    state.orchestraInfo.token = content.token
+    state.orchestraInfo.phone = content.phone
+    state.orchestraInfo.nickname = content.nickname
+    state.orchestraInfo.avatar = content.avatar
+    state.orchestraInfo.unionId = content.unionId || 0
+  })
+
+  // 管乐团里面,获取是否已安装酷乐秀
+  promisefiyPostMessage({ api: 'isInstall' }).then((res: any) => {
+    const content = res.content
+    state.orchestraInfo.isInstall = content.installStatus
+  })
+
+  // 从缓存里面获取token
+  promisefiyPostMessage({ api: 'getCache', content: { key: 'h5-colexiu-token' } }).then((res: any) => {
+    const content = res.content
+    if (content.value) {
+      setAuth('bearer ' + content.value)
+    }
+  })
+}
+
 if (browser().isTeacher) {
   state.platformType = 'TEACHER'
 } else if (browser().isStudent) {

+ 2 - 2
vite.config.ts

@@ -11,8 +11,8 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-const proxyUrl = 'https://online.colexiu.com/';
-// const proxyUrl = 'https://dev.colexiu.com/'
+// const proxyUrl = 'https://online.colexiu.com/';
+const proxyUrl = 'https://dev.colexiu.com/'
 // const proxyUrl = 'http://192.168.3.143:8000/'
 export default defineConfig({
   base: './',