|  | @@ -0,0 +1,331 @@
 | 
	
		
			
				|  |  | +import request from '@/helpers/request'
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  Button,
 | 
	
		
			
				|  |  | +  closeToast,
 | 
	
		
			
				|  |  | +  Icon,
 | 
	
		
			
				|  |  | +  Image,
 | 
	
		
			
				|  |  | +  showFailToast,
 | 
	
		
			
				|  |  | +  showLoadingToast,
 | 
	
		
			
				|  |  | +  showSuccessToast,
 | 
	
		
			
				|  |  | +  showToast
 | 
	
		
			
				|  |  | +} from 'vant'
 | 
	
		
			
				|  |  | +import { defineComponent, onMounted, reactive } from 'vue'
 | 
	
		
			
				|  |  | +import { useRoute } from 'vue-router'
 | 
	
		
			
				|  |  | +import styles from './index.module.less'
 | 
	
		
			
				|  |  | +import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'
 | 
	
		
			
				|  |  | +import html2canvas from 'html2canvas'
 | 
	
		
			
				|  |  | +import { state as baseState } from '@/state'
 | 
	
		
			
				|  |  | +import OQrcode from '@/components/o-qrcode'
 | 
	
		
			
				|  |  | +import iconImage from './images/icon-image.png'
 | 
	
		
			
				|  |  | +import iconWeichat from './images/icon-weichat.png'
 | 
	
		
			
				|  |  | +import teacherTopBg from './images/teacher-top_bg.png'
 | 
	
		
			
				|  |  | +import manageTopBg from './images/manage-top_bg.png'
 | 
	
		
			
				|  |  | +import orchestraTopBg from './images/orchestra-top_bg.png'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'save-share-image',
 | 
	
		
			
				|  |  | +  setup() {
 | 
	
		
			
				|  |  | +    const route = useRoute()
 | 
	
		
			
				|  |  | +    const state = reactive({
 | 
	
		
			
				|  |  | +      type: route.query.type as any,
 | 
	
		
			
				|  |  | +      paramValue: 2,
 | 
	
		
			
				|  |  | +      schoolName: '',
 | 
	
		
			
				|  |  | +      schoolId: '',
 | 
	
		
			
				|  |  | +      url: null as any,
 | 
	
		
			
				|  |  | +      schoolLogo: '',
 | 
	
		
			
				|  |  | +      loading: false
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const imgs = reactive({
 | 
	
		
			
				|  |  | +      saveLoading: false,
 | 
	
		
			
				|  |  | +      image: null as any,
 | 
	
		
			
				|  |  | +      shareLoading: false
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +    const onSaveImg = async () => {
 | 
	
		
			
				|  |  | +      // 判断是否在保存中...
 | 
	
		
			
				|  |  | +      if (imgs.saveLoading) {
 | 
	
		
			
				|  |  | +        return
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      imgs.saveLoading = true
 | 
	
		
			
				|  |  | +      // 判断是否已经生成图片
 | 
	
		
			
				|  |  | +      if (imgs.image) {
 | 
	
		
			
				|  |  | +        saveImg()
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        const container: any = document.getElementById(`preview-container`)
 | 
	
		
			
				|  |  | +        html2canvas(container, {
 | 
	
		
			
				|  |  | +          allowTaint: true,
 | 
	
		
			
				|  |  | +          useCORS: true,
 | 
	
		
			
				|  |  | +          backgroundColor: null
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +          .then(async (canvas) => {
 | 
	
		
			
				|  |  | +            const url = canvas.toDataURL('image/png')
 | 
	
		
			
				|  |  | +            imgs.image = url
 | 
	
		
			
				|  |  | +            saveImg()
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +          .catch(() => {
 | 
	
		
			
				|  |  | +            closeToast()
 | 
	
		
			
				|  |  | +            imgs.saveLoading = false
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const onShare = () => {
 | 
	
		
			
				|  |  | +      if (imgs.shareLoading) {
 | 
	
		
			
				|  |  | +        return
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      imgs.shareLoading = true
 | 
	
		
			
				|  |  | +      if (imgs.image) {
 | 
	
		
			
				|  |  | +        openShare()
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        const container: any = document.getElementById(`preview-container`)
 | 
	
		
			
				|  |  | +        html2canvas(container, {
 | 
	
		
			
				|  |  | +          allowTaint: true,
 | 
	
		
			
				|  |  | +          useCORS: true,
 | 
	
		
			
				|  |  | +          backgroundColor: null
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +          .then(async (canvas) => {
 | 
	
		
			
				|  |  | +            const url = canvas.toDataURL('image/png')
 | 
	
		
			
				|  |  | +            imgs.image = url
 | 
	
		
			
				|  |  | +            openShare()
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +          .catch(() => {
 | 
	
		
			
				|  |  | +            closeToast()
 | 
	
		
			
				|  |  | +            imgs.shareLoading = false
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const openShare = () => {
 | 
	
		
			
				|  |  | +      const image = imgs.image
 | 
	
		
			
				|  |  | +      setTimeout(() => {
 | 
	
		
			
				|  |  | +        imgs.shareLoading = false
 | 
	
		
			
				|  |  | +      }, 100)
 | 
	
		
			
				|  |  | +      if (image) {
 | 
	
		
			
				|  |  | +        postMessage(
 | 
	
		
			
				|  |  | +          {
 | 
	
		
			
				|  |  | +            api: 'shareTripartite',
 | 
	
		
			
				|  |  | +            content: {
 | 
	
		
			
				|  |  | +              title: '',
 | 
	
		
			
				|  |  | +              desc: '',
 | 
	
		
			
				|  |  | +              image,
 | 
	
		
			
				|  |  | +              video: '',
 | 
	
		
			
				|  |  | +              type: 'image',
 | 
	
		
			
				|  |  | +              // button: ['copy']
 | 
	
		
			
				|  |  | +              shareType: 'wechat'
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          },
 | 
	
		
			
				|  |  | +          (res: any) => {
 | 
	
		
			
				|  |  | +            if (res && res.content) {
 | 
	
		
			
				|  |  | +              showToast(res.content.message || (res.content.status ? '分享成功' : '分享失败'))
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const saveImg = async () => {
 | 
	
		
			
				|  |  | +      showLoadingToast({ message: '图片生成中...', forbidClick: true })
 | 
	
		
			
				|  |  | +      setTimeout(() => {
 | 
	
		
			
				|  |  | +        imgs.saveLoading = false
 | 
	
		
			
				|  |  | +      }, 100)
 | 
	
		
			
				|  |  | +      const res = await promisefiyPostMessage({
 | 
	
		
			
				|  |  | +        api: 'savePicture',
 | 
	
		
			
				|  |  | +        content: {
 | 
	
		
			
				|  |  | +          base64: imgs.image
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +      if (res?.content?.status === 'success') {
 | 
	
		
			
				|  |  | +        showSuccessToast('保存成功')
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        showFailToast('保存失败')
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 获取当前用户所在的学校
 | 
	
		
			
				|  |  | +    const getDetail = async () => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const schoolId = (baseState.user.data.schoolInfos || [])
 | 
	
		
			
				|  |  | +          .map((item) => {
 | 
	
		
			
				|  |  | +            return item.id
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +          .join(',')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const res = await request.get(`/api-school/school/detail/${schoolId}`, {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        state.schoolName = res.data.name
 | 
	
		
			
				|  |  | +        state.schoolId = res.data.id
 | 
	
		
			
				|  |  | +        state.schoolLogo = res.data.logo + '@base@tag=imgScale&w=570?t=' + +new Date()
 | 
	
		
			
				|  |  | +        // 生成二维码
 | 
	
		
			
				|  |  | +        if (state.type === 'teacher') {
 | 
	
		
			
				|  |  | +          state.url =
 | 
	
		
			
				|  |  | +            location.origin +
 | 
	
		
			
				|  |  | +            '/orchestra-school/#/companion-teacher-register?id=' +
 | 
	
		
			
				|  |  | +            res.data.id +
 | 
	
		
			
				|  |  | +            '&name=' +
 | 
	
		
			
				|  |  | +            res.data.name +
 | 
	
		
			
				|  |  | +            '&t=' +
 | 
	
		
			
				|  |  | +            +new Date()
 | 
	
		
			
				|  |  | +        } else if (state.type === 'manage') {
 | 
	
		
			
				|  |  | +          state.url =
 | 
	
		
			
				|  |  | +            location.origin +
 | 
	
		
			
				|  |  | +            '/orchestra-school/#/manage-teacher-register?id=' +
 | 
	
		
			
				|  |  | +            res.data.id +
 | 
	
		
			
				|  |  | +            '&name=' +
 | 
	
		
			
				|  |  | +            res.data.name +
 | 
	
		
			
				|  |  | +            '&t=' +
 | 
	
		
			
				|  |  | +            +new Date()
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 获取当前用户所在的学校
 | 
	
		
			
				|  |  | +    const getOrchestraDetail = async () => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res = await request.get('/api-school/orchestra/detail/' + route.query.id)
 | 
	
		
			
				|  |  | +        state.schoolName = res.data.name
 | 
	
		
			
				|  |  | +        state.schoolId = res.data.id
 | 
	
		
			
				|  |  | +        state.schoolLogo = res.data.schoolLogo + '@base@tag=imgScale&w=570?t=' + +new Date()
 | 
	
		
			
				|  |  | +        // 生成二维码
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        state.url = window.location.origin + '/orchestra-student/#/preApply?id=' + route.query.id
 | 
	
		
			
				|  |  | +      } catch {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    onMounted(async () => {
 | 
	
		
			
				|  |  | +      if (state.type === 'teacher') {
 | 
	
		
			
				|  |  | +        document.title = '乐团伴学指导注册'
 | 
	
		
			
				|  |  | +      } else if (state.type === 'manage') {
 | 
	
		
			
				|  |  | +        document.title = '乐团管理老师注册'
 | 
	
		
			
				|  |  | +      } else if (state.type === 'orchestra') {
 | 
	
		
			
				|  |  | +        document.title = '乐团报名'
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const { data } = await request.get('/api-school/open/paramConfig/queryByParamName', {
 | 
	
		
			
				|  |  | +          requestType: 'form',
 | 
	
		
			
				|  |  | +          params: {
 | 
	
		
			
				|  |  | +            paramName: 'qr_code_expire_hours'
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        state.paramValue = data.paramValue
 | 
	
		
			
				|  |  | +      } catch {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (state.type === 'orchestra') {
 | 
	
		
			
				|  |  | +        getOrchestraDetail()
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        getDetail()
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <div class={[styles.saveShareImage]}>
 | 
	
		
			
				|  |  | +        {state.type === 'teacher' && <Image src={teacherTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +        {state.type === 'manage' && <Image src={manageTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +        {state.type === 'orchestra' && <Image src={orchestraTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +        <div
 | 
	
		
			
				|  |  | +          class={[styles.shareContaienr, state.type === 'orchestra' && styles.orchestraContainer]}
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +          {state.type !== 'orchestra' ? (
 | 
	
		
			
				|  |  | +            <>
 | 
	
		
			
				|  |  | +              <img
 | 
	
		
			
				|  |  | +                class={[styles.schoolLogo]}
 | 
	
		
			
				|  |  | +                src={state.schoolLogo}
 | 
	
		
			
				|  |  | +                crossorigin="anonymous"
 | 
	
		
			
				|  |  | +                style={{
 | 
	
		
			
				|  |  | +                  objectFit: 'cover'
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +              />
 | 
	
		
			
				|  |  | +              <div class={styles.schoolName}>{state.schoolName}</div>
 | 
	
		
			
				|  |  | +              <div class={styles.shareType}>
 | 
	
		
			
				|  |  | +                邀请您成为
 | 
	
		
			
				|  |  | +                <span>
 | 
	
		
			
				|  |  | +                  {state.type === 'teacher' && '乐团伴学指导'}
 | 
	
		
			
				|  |  | +                  {state.type === 'manage' && '乐团管理老师'}
 | 
	
		
			
				|  |  | +                </span>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </>
 | 
	
		
			
				|  |  | +          ) : (
 | 
	
		
			
				|  |  | +            <>
 | 
	
		
			
				|  |  | +              <div class={styles.schoolName}>乐团报名</div>
 | 
	
		
			
				|  |  | +              <div class={styles.shareType}>{state.schoolName}</div>
 | 
	
		
			
				|  |  | +            </>
 | 
	
		
			
				|  |  | +          )}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.qrcodeSection}>
 | 
	
		
			
				|  |  | +            <OQrcode text={state.url} logoSize={'small'} size={'100%'} />
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.memo}>扫描上方二维码完成资料填写</div>
 | 
	
		
			
				|  |  | +          {state.type !== 'orchestra' && (
 | 
	
		
			
				|  |  | +            <div class={styles.endTime}>
 | 
	
		
			
				|  |  | +              二维码将在<span>{state.paramValue}小时后</span>失效,请及时登记
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          )}
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <div class={styles.btnGroup}>
 | 
	
		
			
				|  |  | +          <Button class={styles.btn} round block onClick={onSaveImg}>
 | 
	
		
			
				|  |  | +            <Icon name={iconImage} class={styles.icon} />
 | 
	
		
			
				|  |  | +            保存图片
 | 
	
		
			
				|  |  | +          </Button>
 | 
	
		
			
				|  |  | +          <Button class={styles.btn} round block onClick={onShare}>
 | 
	
		
			
				|  |  | +            <Icon name={iconWeichat} class={styles.icon} />
 | 
	
		
			
				|  |  | +            分享到微信
 | 
	
		
			
				|  |  | +          </Button>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {!state.loading && (
 | 
	
		
			
				|  |  | +          <div class={[styles.saveShareImage, styles.previewSection]} id="preview-container">
 | 
	
		
			
				|  |  | +            {state.type === 'teacher' && <Image src={teacherTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +            {state.type === 'manage' && <Image src={manageTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +            {state.type === 'orchestra' && <Image src={orchestraTopBg} class={styles.topImage} />}
 | 
	
		
			
				|  |  | +            <div
 | 
	
		
			
				|  |  | +              class={[
 | 
	
		
			
				|  |  | +                styles.shareContaienr,
 | 
	
		
			
				|  |  | +                state.type === 'orchestra' && styles.orchestraContainer
 | 
	
		
			
				|  |  | +              ]}
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +              {state.type !== 'orchestra' ? (
 | 
	
		
			
				|  |  | +                <>
 | 
	
		
			
				|  |  | +                  <img
 | 
	
		
			
				|  |  | +                    class={[styles.schoolLogo]}
 | 
	
		
			
				|  |  | +                    src={state.schoolLogo}
 | 
	
		
			
				|  |  | +                    crossorigin="anonymous"
 | 
	
		
			
				|  |  | +                    style={{
 | 
	
		
			
				|  |  | +                      objectFit: 'cover'
 | 
	
		
			
				|  |  | +                    }}
 | 
	
		
			
				|  |  | +                  />
 | 
	
		
			
				|  |  | +                  <div class={styles.schoolName}>{state.schoolName}</div>
 | 
	
		
			
				|  |  | +                  <div class={styles.shareType}>
 | 
	
		
			
				|  |  | +                    邀请您成为
 | 
	
		
			
				|  |  | +                    <span>
 | 
	
		
			
				|  |  | +                      {state.type === 'teacher' && '乐团伴学指导'}
 | 
	
		
			
				|  |  | +                      {state.type === 'manage' && '乐团管理老师'}
 | 
	
		
			
				|  |  | +                    </span>
 | 
	
		
			
				|  |  | +                  </div>
 | 
	
		
			
				|  |  | +                </>
 | 
	
		
			
				|  |  | +              ) : (
 | 
	
		
			
				|  |  | +                <>
 | 
	
		
			
				|  |  | +                  <div class={styles.schoolName}>乐团报名</div>
 | 
	
		
			
				|  |  | +                  <div class={styles.shareType}>{state.schoolName}</div>
 | 
	
		
			
				|  |  | +                </>
 | 
	
		
			
				|  |  | +              )}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              <div class={styles.qrcodeSection}>
 | 
	
		
			
				|  |  | +                <OQrcode text={state.url} logoSize={'small'} size={'100%'} />
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              <div class={styles.memo}>扫描上方二维码完成资料填写</div>
 | 
	
		
			
				|  |  | +              {state.type !== 'orchestra' && (
 | 
	
		
			
				|  |  | +                <div class={styles.endTime}>
 | 
	
		
			
				|  |  | +                  二维码将在<span>{state.paramValue}小时后</span>失效,请及时登记
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              )}
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        )}
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +})
 |