single.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import SectionDetail from '@/business-components/section-detail'
  2. import ColVideo from '@/components/col-video'
  3. import request from '@/helpers/request'
  4. import { Button, Cell, Icon, Image, Popup } from 'vant'
  5. import { defineComponent } from 'vue'
  6. import styles from './single.module.less'
  7. import { postMessage } from '@/helpers/native-message'
  8. import JoinChat from '../model/join-chat'
  9. import iconUploadPoster from '@common/images/icon_upload_poster.png'
  10. import { browser } from '@/helpers/utils'
  11. export const getAssetsHomeFile = (fileName: string) => {
  12. const path = `../images/${fileName}`
  13. const modules = import.meta.globEager('../images/*')
  14. return modules[path].default
  15. }
  16. export default defineComponent({
  17. name: 'single',
  18. props: {
  19. userInfo: {
  20. type: Object,
  21. default: {}
  22. }
  23. },
  24. data() {
  25. const query = this.$route.query
  26. return {
  27. videoStatus: false,
  28. chatStatus: false,
  29. teacherId: query.teacherId,
  30. fansList: [],
  31. chatItem: {},
  32. videoItem: {} as any,
  33. isAddBrowse: false
  34. }
  35. },
  36. async mounted() {
  37. try {
  38. const res = await request.post('/api-student/imGroup/queryTeacherGroup', {
  39. data: {
  40. type: 'FAN',
  41. createUserId: this.teacherId
  42. }
  43. })
  44. this.fansList = res.data || []
  45. } catch {}
  46. },
  47. methods: {
  48. async onDetail(item: any) {
  49. // 申请入群
  50. if (!item.hasWaitAuditFlag && !item.existFlag) {
  51. this.chatStatus = true
  52. this.chatItem = item
  53. return
  54. }
  55. // 进入群聊天
  56. if (item.existFlag) {
  57. postMessage({
  58. api: 'joinChatGroup',
  59. content: {
  60. type: 'multi', // single 单人 multi 多人
  61. id: item.id
  62. }
  63. })
  64. }
  65. },
  66. async onPlay() {
  67. try {
  68. if (!this.isAddBrowse) {
  69. return
  70. }
  71. await request.get('/api-student/teacher/addVideoBrowse', {
  72. hideLoading: true,
  73. params: {
  74. videoId: this.videoItem.id
  75. }
  76. })
  77. this.isAddBrowse = false
  78. } catch {}
  79. }
  80. },
  81. render() {
  82. const userInfo = this.userInfo
  83. return (
  84. <div class={styles.single}>
  85. {userInfo.introduction && (
  86. <SectionDetail
  87. icon="personal"
  88. title="个人介绍"
  89. size={24}
  90. border={false}
  91. >
  92. <p class={styles.introduction}>{userInfo.introduction}</p>
  93. </SectionDetail>
  94. )}
  95. {userInfo.styleVideo && userInfo.styleVideo.length > 0 && (
  96. <SectionDetail
  97. icon="elegant"
  98. title="老师风采"
  99. size={24}
  100. border={false}
  101. >
  102. <div class={styles.videoList}>
  103. {userInfo.styleVideo.map((item: any) => (
  104. <div class={styles.videoItem}>
  105. <div
  106. class={styles.itemBg}
  107. onClick={() => {
  108. this.videoStatus = true
  109. this.isAddBrowse = true
  110. this.videoItem = item
  111. }}
  112. ></div>
  113. <Icon
  114. class={styles['icon-upload']}
  115. name={getAssetsHomeFile('icon_video.png')}
  116. size={26}
  117. />
  118. {/* <video width="100%" class={styles.video}>
  119. <source src={item.videoUrl} type="video/mp4" />
  120. </video> */}
  121. <Image src={item.cover || iconUploadPoster} fit="cover" />
  122. </div>
  123. ))}
  124. </div>
  125. </SectionDetail>
  126. )}
  127. {this.fansList && this.fansList.length > 0 && (
  128. <SectionDetail icon="fans" title="粉丝群" size={24} border={false}>
  129. {this.fansList.map((item: any) => (
  130. <Cell
  131. center
  132. class={styles.fansGroup}
  133. border={false}
  134. v-slots={{
  135. icon: () => (
  136. <Image
  137. src={item.img || getAssetsHomeFile('icon_fans.png')}
  138. fit="cover"
  139. class={styles.fansImage}
  140. />
  141. ),
  142. title: () => (
  143. <div class={styles.fansTitle}>
  144. <div class={[styles.title, 'van-ellipsis']}>
  145. {item.name}
  146. </div>
  147. <p class="van-ellipsis">{item.introduce}</p>
  148. </div>
  149. ),
  150. default: () => (
  151. <Button
  152. type="primary"
  153. size="small"
  154. round
  155. disabled={item.hasWaitAuditFlag}
  156. onClick={() => this.onDetail(item)}
  157. >
  158. {item.existFlag ? '去聊天' : ''}
  159. {item.hasWaitAuditFlag ? '审核中' : ''}
  160. {!item.hasWaitAuditFlag && !item.existFlag
  161. ? '申请入群'
  162. : ''}
  163. </Button>
  164. )
  165. }}
  166. />
  167. ))}
  168. </SectionDetail>
  169. )}
  170. <Popup
  171. show={this.chatStatus}
  172. position="bottom"
  173. round
  174. closeable
  175. safe-area-inset-bottom
  176. onClose={() => (this.chatStatus = false)}
  177. >
  178. <JoinChat
  179. item={this.chatItem}
  180. onClose={(id: number) => {
  181. this.fansList.forEach((item: any) => {
  182. item.id === id && (item.hasWaitAuditFlag = true)
  183. })
  184. this.chatStatus = false
  185. }}
  186. />
  187. </Popup>
  188. <Popup
  189. show={this.videoStatus}
  190. round
  191. class={styles.videoGroup}
  192. closeable
  193. onClose={() => {
  194. this.videoStatus = false
  195. this.isAddBrowse = false
  196. }}
  197. >
  198. {this.videoStatus && (
  199. <ColVideo
  200. playsinline
  201. onPlay={this.onPlay}
  202. src={this.videoItem?.videoUrl + '#t=0.1'}
  203. />
  204. )}
  205. {/* <video
  206. style={{ height: '210px', width: '100%' }}
  207. controls
  208. class={styles.video}
  209. >
  210. <source
  211. src={this.videoItem?.videoUrl + '#t=1,4'}
  212. type="video/mp4"
  213. />
  214. </video> */}
  215. </Popup>
  216. </div>
  217. )
  218. }
  219. })