diff --git a/jiuyi/node_modules/.vue-global-types/vue_99_0_0_0.d.ts b/jiuyi/node_modules/.vue-global-types/vue_99_0_0_0.d.ts new file mode 100644 index 00000000..72f1004c --- /dev/null +++ b/jiuyi/node_modules/.vue-global-types/vue_99_0_0_0.d.ts @@ -0,0 +1,121 @@ +// @ts-nocheck +export {}; + +; declare global { + const __VLS_intrinsicElements: __VLS_IntrinsicElements; + const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any }; + const __VLS_unref: typeof import('vue').unref; + const __VLS_placeholder: any; + + type __VLS_NativeElements = __VLS_SpreadMerge<SVGElementTagNameMap, HTMLElementTagNameMap>; + type __VLS_IntrinsicElements = import('vue/jsx-runtime').JSX.IntrinsicElements; + type __VLS_Element = import('vue/jsx-runtime').JSX.Element; + type __VLS_GlobalComponents = import('vue').GlobalComponents; + type __VLS_GlobalDirectives = import('vue').GlobalDirectives; + type __VLS_IsAny<T> = 0 extends 1 & T ? true : false; + type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A; + type __VLS_SpreadMerge<A, B> = Omit<A, keyof B> & B; + type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> = + N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } : + N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } : + N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N3] } : + Self extends object ? { [K in N0]: Self } : + N1 extends keyof __VLS_GlobalComponents ? N1 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N1] } : + N2 extends keyof __VLS_GlobalComponents ? N2 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N2] } : + N3 extends keyof __VLS_GlobalComponents ? N3 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : { [K in N0]: __VLS_GlobalComponents[N3] } : + { [K in N0]: unknown }; + type __VLS_FunctionalComponentProps<T, K> = + '__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never + : T extends (props: infer P, ...args: any) => any ? P : + {}; + type __VLS_IsFunction<T, K> = K extends keyof T + ? __VLS_IsAny<T[K]> extends false + ? unknown extends T[K] + ? false + : true + : false + : false; + type __VLS_NormalizeComponentEvent<Props, Events, onEvent extends keyof Props, Event extends keyof Events, CamelizedEvent extends keyof Events> = ( + __VLS_IsFunction<Props, onEvent> extends true + ? Props + : __VLS_IsFunction<Events, Event> extends true + ? { [K in onEvent]?: Events[Event] } + : __VLS_IsFunction<Events, CamelizedEvent> extends true + ? { [K in onEvent]?: Events[CamelizedEvent] } + : Props + ) & Record<string, unknown>; + // fix https://github.com/vuejs/language-tools/issues/926 + type __VLS_UnionToIntersection<U> = (U extends unknown ? (arg: U) => unknown : never) extends ((arg: infer P) => unknown) ? P : never; + type __VLS_OverloadUnionInner<T, U = unknown> = U & T extends (...args: infer A) => infer R + ? U extends T + ? never + : __VLS_OverloadUnionInner<T, Pick<T, keyof T> & U & ((...args: A) => R)> | ((...args: A) => R) + : never; + type __VLS_OverloadUnion<T> = Exclude< + __VLS_OverloadUnionInner<(() => never) & T>, + T extends () => never ? never : () => never + >; + type __VLS_ConstructorOverloads<T> = __VLS_OverloadUnion<T> extends infer F + ? F extends (event: infer E, ...args: infer A) => any + ? { [K in E & string]: (...args: A) => void; } + : never + : never; + type __VLS_NormalizeEmits<T> = __VLS_PrettifyGlobal< + __VLS_UnionToIntersection< + __VLS_ConstructorOverloads<T> & { + [K in keyof T]: T[K] extends any[] ? { (...args: T[K]): void } : never + } + > + >; + type __VLS_PrettifyGlobal<T> = { [K in keyof T]: T[K]; } & {}; + type __VLS_PickFunctionalComponentCtx<T, K> = NonNullable<__VLS_PickNotAny< + '__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends { __ctx?: infer Ctx } ? Ctx : never : any + , T extends (props: any, ctx: infer Ctx) => any ? Ctx : any + >>; + type __VLS_OmitStringIndex<T> = { + [K in keyof T as string extends K ? never : K]: T[K]; + }; + type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>; + + function __VLS_getVForSourceType<T extends number | string | any[] | Iterable<any>>(source: T): [ + item: T extends number ? number + : T extends string ? string + : T extends any[] ? T[number] + : T extends Iterable<infer T1> ? T1 + : any, + index: number, + ][]; + function __VLS_getVForSourceType<T>(source: T): [ + item: T[keyof T], + key: keyof T, + index: number, + ][]; + // @ts-ignore + function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>; + // @ts-ignore + function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0]; + function __VLS_asFunctionalDirective<T>(dir: T): T extends import('vue').ObjectDirective + ? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']> + : T extends (...args: any) => any + ? T + : (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; + function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] }; + function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K): + T extends new (...args: any) => any + ? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & { + __ctx?: { + attrs?: any; + slots?: K extends { $slots: infer Slots } ? Slots : any; + emit?: K extends { $emit: infer Emit } ? Emit : any; + expose?(exposed: K): void; + props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>; + } + } + : T extends () => any ? (props: {}, ctx?: any) => ReturnType<T> + : T extends (...args: any) => any ? T + : (_: {} & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {} & Record<string, unknown> } }; + function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : []; + function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (attrs: T & Record<string, unknown>) => void; + function __VLS_asFunctionalSlot<S>(slot: S): (props: NonNullable<S> extends (props: infer P) => any ? P : {}) => void; + function __VLS_tryAsConstant<const T>(t: T): T; +} diff --git a/jiuyi2/api/mine.js b/jiuyi2/api/mine.js index 57b3fca2..6eac9571 100644 --- a/jiuyi2/api/mine.js +++ b/jiuyi2/api/mine.js @@ -354,9 +354,9 @@ const mine = { }, /** - * 查看已绑定的银行卡列表 - * @param {Object} param - */ + * 查看已绑定的银行卡列表 + * @param {Object} param + */ getBankCards(param) { return util.request({ url: '/user/bank-cards/getBankCards', @@ -366,9 +366,8 @@ const mine = { load: true, }) }, - /** - * 添加银行卡 + * 添加银行卡 * @param {Object} param */ addBankCard(param) { @@ -393,6 +392,30 @@ const mine = { load: true, }) }, + + /** + * 拉黑 + * @param {Object} param + */ + blockUser(param) { + return util.request({ + url: `/video/statistics/block`, + data: param, + method: 'POST', + }) + }, + + /** + * 解锁他人评论 + * @param {Object} param + */ + unlockComment(param) { + return util.request({ + url: `/video/comment/unlockOthersComment`, + data: param, + method: 'POST', + }) + }, } export default mine \ No newline at end of file diff --git a/jiuyi2/api/video.js b/jiuyi2/api/video.js index 0ee5c6a3..3ed33e3c 100644 --- a/jiuyi2/api/video.js +++ b/jiuyi2/api/video.js @@ -426,7 +426,7 @@ const video = { */ reportVideo(param) { return util.request({ - url: `/report/reportVideo`, + url: `/video/videoReport`, data: param.data, method: 'POST', }) diff --git a/jiuyi2/components/index/videoMenu.vue b/jiuyi2/components/index/videoMenu.vue index b8f010ef..d38660b5 100644 --- a/jiuyi2/components/index/videoMenu.vue +++ b/jiuyi2/components/index/videoMenu.vue @@ -1,138 +1,138 @@ <script setup> - /** - * 视频菜单组件 - * - */ +/** + * 视频菜单组件 + * + */ - import { - ref, - reactive, - onMounted - } from 'vue' - import video from '../../api/video'; - import util from '../../common/js/util'; +import { + ref, + reactive, + onMounted +} from 'vue' +import video from '../../api/video'; +import util from '../../common/js/util'; - // 传参 - const props = defineProps({ - // 列表数据 - list: { - type: Array, - }, - // 模式 list列表展示 点击播放视频 menu菜单模式 点击触发回调事件 checkbox多选 - mode: { - type: String, - default: 'list', - }, - // 多选模式下的 选择数量限制 0为不限制 - limit: { - type: Number, - default: 0, - }, - // 是否我自己 0不是 1是 - isMine: { - type: [String, Number], - default: 0, - }, - // 是否显示统计 0不显示 1显示 - statistic: { - type: [String, Number], - default: 0, - }, - }) - // 子触发父 - const emit = defineEmits(['item']) - // 已选择的视频id - const ids = defineModel('ids') - // 视频上下文对象 - const videoContext = ref(null) - // 视频播放路径 - const videoUrl = ref('') +// 传参 +const props = defineProps({ + // 列表数据 + list: { + type: Array, + }, + // 模式 list列表展示 点击播放视频 menu菜单模式 点击触发回调事件 checkbox多选 + mode: { + type: String, + default: 'list', + }, + // 多选模式下的 选择数量限制 0为不限制 + limit: { + type: Number, + default: 0, + }, + // 是否我自己 0不是 1是 + isMine: { + type: [String, Number], + default: 0, + }, + // 是否显示统计 0不显示 1显示 + statistic: { + type: [String, Number], + default: 0, + }, +}) +// 子触发父 +const emit = defineEmits(['item']) +// 已选择的视频id +const videoInfo = reactive({ + videoId: '', + coverUrl: '', +}) +// 视频上下文对象 +const videoContext = ref(null) +// 视频播放路径 +const videoUrl = ref('') - onMounted(() => { - // 创建视频上下文对象 - videoContext.value = uni.createVideoContext('video') - }) +onMounted(() => { + // 创建视频上下文对象 + videoContext.value = uni.createVideoContext('video') +}) - // 进入全屏 - function requestFullScreen() { - videoContext.value.requestFullScreen() - } +// 进入全屏 +function requestFullScreen() { + videoContext.value.requestFullScreen() +} - // 暂停 - function pause() { - // 暂停当前视频 - videoContext.value.pause() - } +// 暂停 +function pause() { + // 暂停当前视频 + videoContext.value.pause() +} - /** - * 点击视频播放 - * @param {Object} item - */ - function handleVideo(item) { - // 列表模式 - if (props.mode == 'list') { - uni.navigateTo({ - url: util.setUrl('/pages/index/videoDetail', { - videoId: item.id, - isMine: props.isMine, - statistic: props.statistic, - }) +/** + * 点击视频播放 + * @param {Object} item + */ +function handleVideo(item) { + // 列表模式 + if (props.mode == 'list') { + uni.navigateTo({ + url: util.setUrl('/pages/index/videoDetail', { + videoId: item.id, + isMine: props.isMine, + statistic: props.statistic, }) - // videoUrl.value = item.format_videoUrl - // 进入全屏 - // requestFullScreen() - } - // 菜单模式 - else if (props.mode == 'menu') { - emit('item', item) - } - // 多选模式 - else if (props.mode == 'checkbox') { - const findIndex = ids.value.findIndex(node => node == item.videoId) - if (findIndex >= 0) ids.value.splice(findIndex, 1) - else { - // 如果有限制 且 数量到达上限 - if (props.limit != 0 && props.limit <= ids.value.length) return - ids.value.push(item.videoId) - } - } + }) + // videoUrl.value = item.format_videoUrl + // 进入全屏 + // requestFullScreen() } - - /** - * 视频进入退出全屏 - * @param {Object} ev - */ - function videoFullscreenchange(ev) { - // 根据全屏状态决定是否播放盒暂停 - if (ev.detail.fullScreen) videoContext.value.play() - else pause() + // 菜单模式 + else if (props.mode == 'menu') { + emit('item', item) } + // 单选模式 + else if (props.mode == 'checkbox') { + videoInfo.videoId = item.id + videoInfo.coverUrl = item.coverUrl + videoUrl.value = item.videoUrl + emit('videoInfo', videoInfo) + } +} - defineExpose({ - videoContext, - pause, - requestFullScreen, - }) +/** + * 视频进入退出全屏 + * @param {Object} ev + */ +function videoFullscreenchange(ev) { + // 根据全屏状态决定是否播放盒暂停 + if (ev.detail.fullScreen) videoContext.value.play() + else pause() +} + +defineExpose({ + videoContext, + pause, + requestFullScreen, +}) </script> <template> <view> <!-- 视频菜单 --> <view class="list"> - <view class="item pr" v-for="(item,index) in list" :key="index" @click="handleVideo(item)"> + <view class="item pr" v-for="(item, index) in list" :key="index" @click="handleVideo(item)"> <image :src="item.coverUrl" mode="aspectFill" /> <view class="window pfull"></view> <!-- 选项 --> <view class="amount pa r0 t0 df ptb10 plr10" v-if="mode == 'checkbox'"> - <uni-icons type="circle-filled" size="50rpx" color="#20D200" v-if="ids.includes(item.videoId)" /> + <uni-icons type="circle-filled" size="50rpx" color="#20D200" v-if="videoInfo.videoId == item.id" /> <uni-icons type="circle" color="#fff" size="50rpx" v-else /> </view> <view class="amount pa l0 r0 b0 df ptb10 plr10" v-if="item.play"> <image class="wh24" src="/static/amount.png" mode="aspectFit" /> - <view class="txt f1 ml10 cfff f20">{{item.play}}</view> + <view class="txt f1 ml10 cfff f20">{{ item.play }}</view> </view> </view> </view> @@ -145,37 +145,37 @@ </template> <style lang="scss" scoped> - // - .list { - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-gap: 5rpx; +// +.list { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 5rpx; - .item { - height: 360rpx; + .item { + height: 360rpx; - image { - width: 100%; - height: 100%; - } - } - - .window { - background-color: rgba(0, 0, 0, .1); - } - - // 播放量 - .amount { - .txt { - opacity: .5; - } + image { + width: 100%; + height: 100%; } } - // 视频上下文对象 - .videoContext { - position: absolute; - width: 0; - height: 0; + .window { + background-color: rgba(0, 0, 0, .1); } + + // 播放量 + .amount { + .txt { + opacity: .5; + } + } +} + +// 视频上下文对象 +.videoContext { + position: absolute; + width: 0; + height: 0; +} </style> \ No newline at end of file diff --git a/jiuyi2/components/mine/noAuth.vue b/jiuyi2/components/mine/noAuth.vue new file mode 100644 index 00000000..7e877c1d --- /dev/null +++ b/jiuyi2/components/mine/noAuth.vue @@ -0,0 +1,21 @@ +<script setup> +/** + * 未实名认证组件 + */ +</script> + +<template> + <view class="nologin pr fmid fdc"> + <view class="title f40 b">请先实名认证</view> + <navigator url="/pages/mine/realname" class="button btn pro bar black mt60">去实名认证</navigator> + </view> +</template> + +<style lang="scss" scoped> +// +.nologin { + .button { + width: 80%; + } +} +</style> \ No newline at end of file diff --git a/jiuyi2/node_modules/.vue-global-types/vue_99_0_0_0.d.ts b/jiuyi2/node_modules/.vue-global-types/vue_99_0_0_0.d.ts index 130f5375..72f1004c 100644 --- a/jiuyi2/node_modules/.vue-global-types/vue_99_0_0_0.d.ts +++ b/jiuyi2/node_modules/.vue-global-types/vue_99_0_0_0.d.ts @@ -7,18 +7,14 @@ export {}; const __VLS_unref: typeof import('vue').unref; const __VLS_placeholder: any; - const __VLS_nativeElements = { - ...{} as SVGElementTagNameMap, - ...{} as HTMLElementTagNameMap, - }; - + type __VLS_NativeElements = __VLS_SpreadMerge<SVGElementTagNameMap, HTMLElementTagNameMap>; type __VLS_IntrinsicElements = import('vue/jsx-runtime').JSX.IntrinsicElements; type __VLS_Element = import('vue/jsx-runtime').JSX.Element; type __VLS_GlobalComponents = import('vue').GlobalComponents; type __VLS_GlobalDirectives = import('vue').GlobalDirectives; type __VLS_IsAny<T> = 0 extends 1 & T ? true : false; type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A; - type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; + type __VLS_SpreadMerge<A, B> = Omit<A, keyof B> & B; type __VLS_WithComponent<N0 extends string, LocalComponents, Self, N1 extends string, N2 extends string, N3 extends string> = N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } : N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } : @@ -81,19 +77,12 @@ export {}; }; type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>; - function __VLS_getVForSourceType(source: number): [number, number][]; - function __VLS_getVForSourceType(source: string): [string, number][]; - function __VLS_getVForSourceType<T extends any[]>(source: T): [ - item: T[number], - index: number, - ][]; - function __VLS_getVForSourceType<T extends { [Symbol.iterator](): Iterator<any> }>(source: T): [ - item: T extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never, - index: number, - ][]; - // #3845 - function __VLS_getVForSourceType<T extends number | { [Symbol.iterator](): Iterator<any> }>(source: T): [ - item: number | (Exclude<T, number> extends { [Symbol.iterator](): Iterator<infer T1> } ? T1 : never), + function __VLS_getVForSourceType<T extends number | string | any[] | Iterable<any>>(source: T): [ + item: T extends number ? number + : T extends string ? string + : T extends any[] ? T[number] + : T extends Iterable<infer T1> ? T1 + : any, index: number, ][]; function __VLS_getVForSourceType<T>(source: T): [ @@ -109,21 +98,24 @@ export {}; ? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']> : T extends (...args: any) => any ? T - : __VLS_unknownDirective; - function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K; + : (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void; function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] }; function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K): T extends new (...args: any) => any - ? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & { __ctx?: { - attrs?: any, - slots?: K extends { $slots: infer Slots } ? Slots : any, - emit?: K extends { $emit: infer Emit } ? Emit : any - } & { props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>; expose?(exposed: K): void; } } + ? (props: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & { + __ctx?: { + attrs?: any; + slots?: K extends { $slots: infer Slots } ? Slots : any; + emit?: K extends { $emit: infer Emit } ? Emit : any; + expose?(exposed: K): void; + props?: (K extends { $props: infer Props } ? Props : any) & Record<string, unknown>; + } + } : T extends () => any ? (props: {}, ctx?: any) => ReturnType<T> : T extends (...args: any) => any ? T : (_: {} & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {} & Record<string, unknown> } }; - function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (_: T & Record<string, unknown>) => void; function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : []; - function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S; + function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (attrs: T & Record<string, unknown>) => void; + function __VLS_asFunctionalSlot<S>(slot: S): (props: NonNullable<S> extends (props: infer P) => any ? P : {}) => void; function __VLS_tryAsConstant<const T>(t: T): T; } diff --git a/jiuyi2/pages/index/report.vue b/jiuyi2/pages/index/report.vue index 9d151bf2..fe57a43f 100644 --- a/jiuyi2/pages/index/report.vue +++ b/jiuyi2/pages/index/report.vue @@ -1,203 +1,204 @@ <script setup> - /** - * 视频举报 - */ - import { - ref, - reactive, - computed, - getCurrentInstance - } from 'vue' - import { - onLoad, - } from '@dcloudio/uni-app' - // 工具库 - import util from '@/common/js/util'; - // api - import api from '@/api/index.js' - // 视频菜单 - import videoMenu from '@/components/index/videoMenu.vue'; +/** + * 视频举报 + */ +import { + ref, + reactive, + computed, + getCurrentInstance +} from 'vue' +import { + onLoad, +} from '@dcloudio/uni-app' +// 工具库 +import util from '@/common/js/util'; +// api +import api from '@/api/index.js' +// 视频菜单 +import videoMenu from '@/components/index/videoMenu.vue'; - const { - proxy - } = getCurrentInstance() - // 举报列表 - const reportList = reactive([{ - name: '发布不正当的内容或信息', - }, - { - name: '传播涩情资源', - }, - { - name: '冒充他人', - }, - { - name: '涉嫌诈骗', - }, - { - name: '侵犯权益', - }, - { - name: '其他', - } - ]) - // 举报下标 - const reportIndex = ref('') - // 表单 - const form = reactive({ - userId: '', - videoId: [], - reason: '', - context: '', - pic: [], - }) - // 列表数据 - const list = reactive({ - data: [], - pageSize: 10, - pageNum: 1, - total: 0, - }) - // 已选择的视频列表 - const videos = computed(() => { - let result = form.videoId.map(item => { - return list.data.find(node => node.videoId == item) || {} - }) - return result +const { + proxy +} = getCurrentInstance() +// 举报列表 +const reportList = reactive([{ + name: '发布不正当的内容或信息', +}, +{ + name: '传播涩情资源', +}, +{ + name: '冒充他人', +}, +{ + name: '涉嫌诈骗', +}, +{ + name: '侵犯权益', +}, +{ + name: '其他', +} +]) +// 举报下标 +const reportIndex = ref('') +// 表单 +const form = reactive({ + userId: '', + videoId: '', + reasonForReporting: '', + particulars: '', + videoPictureUrl: '', + coverUrl: '' +}) +// 列表数据 +const list = reactive({ + data: [], + pageSize: 10, + pageNum: 1, + total: 0, +}) +// 已选择的视频列表 +const videos = computed(() => { + let result = form.videoId.map(item => { + return list.data.find(node => node.videoId == item) || {} }) + return result +}) - onLoad((option) => { - // 被举报的用户id - if (option.userId) form.userId = option.userId - // 获取列表 - getList() - }) - - /** - * 选择举报列表 - * @param {Object} ev 携带参数 - */ - function handleReportList(ev) { - const index = ev.detail.value - if (reportIndex.value === index) return - reportIndex.value = index - } - - // 刷新列表 - function refreshList() { - list.pageNum = 1 - list.total = 0 - getList() - } - - // 获取更多列表 - function getMoreList() { - if (list.data.length >= list.rows) return - list.pageNum++ - getList() - } - +onLoad((option) => { + // 被举报的用户id + if (option.userId) form.userId = option.userId // 获取列表 - function getList() { - // - api.video.myVideoList({ - query: { - isDraft: 0, - userId: form.userId, - pageSize: list.pageSize, - pageNum: list.pageNum, - } - }).then(rs => { - if (rs.code == 200) { - if (list.pageNum == 1) list.data.length = [] - list.data.push(...rs.rows.map(item => { - item.format_videoUrl = util.format_url(item.videoUrl, 'video') - item.format_imageUrl = util.format_url(item.imageUrl, 'img') - return item - })) - list.total = rs.total - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } + getList() +}) - // 上传图片 - function uploadImg() { - util.upload_image({ - value: form.pic, - }) - } +/** + * 选择举报列表 + * @param {Object} ev 携带参数 + */ +function handleReportList(ev) { + const index = ev.detail.value + if (reportIndex.value === index) return + reportIndex.value = index +} - /** - * 删除多媒体 - * @param {Number} index 列表下标 - * @param {String} key 操作的键 - */ - function removeMedia(index, key) { +// 刷新列表 +function refreshList() { + list.pageNum = 1 + list.total = 0 + getList() +} + +// 获取列表 +function getList() { + // + api.video.myWorks({ + query: { + userId: form.userId, + pageSize: list.pageSize, + pageNum: list.pageNum, + } + }).then(rs => { + if (rs.code == 200) { + if (list.pageNum == 1) list.data.length = [] + list.data.push(...rs.rows.map(item => { + item.format_videoUrl = util.format_url(item.videoUrl, 'video') + item.format_imageUrl = util.format_url(item.imageUrl, 'img') + return item + })) + list.total = rs.total + return + } util.alert({ - content: '确认要删除吗?', - }).then(rs => { - if (rs.confirm) form[key].splice(index, 1) + content: rs.msg, + showCancel: false, }) + }) +} + +// 上传图片 +function uploadImg() { + util.upload_image({ + type: 1, + success: rs => { + form.videoPictureUrl = rs.value + } + }) +} + +/** + * 删除多媒体 + * @param {Number} index 列表下标 + * @param {String} key 操作的键 + */ +function removeMedia(key) { + util.alert({ + content: '确认要删除吗?', + }).then(rs => { + if (key == 'videoId') { + form.videoId = null + form.coverUrl = null + } + if (key == 'videoPictureUrl') form.videoPictureUrl = null + }) +} + +// 视频举报 +function handleSubmit() { + // + const data = { + ...form } - // 视频举报 - function handleSubmit() { - // - const data = { - ...form - } - - // 验证必填项 - if (reportIndex == '') { - util.alert('请选择举报理由') - return - } - if (!data.context) { - util.alert('详细描述不能为空') - return - } - if (data.context.length > 100) { - util.alert('详细描述自述超过100') - return - } - if (!data.pic[0]) { - util.alert('请上传举报图片') - return - } - if (!data.videoId[0]) { - util.alert('请选择举报视频') - return - } - - // - data.reason = reportList[reportIndex.value].name - data.pic = data.pic.map(node => { - node = util.replace_url('node') - return node - }).join(',') - data.videoId = data.videoId.join(',') - - api.video.reportVideo({ - data: data, - }).then(rs => { - if (rs.code == 200) { - util.alert('举报成功,请等待后台审核') - setTimeout(() => { - uni.navigateBack() - }, 500) - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) + // 验证必填项 + if (reportIndex == '') { + util.alert('请选择举报理由') + return } + if (!data.particulars) { + util.alert('详细描述不能为空') + return + } + if (data.particulars.length > 100) { + util.alert('详细描述自述超过100') + return + } + if (!data.videoPictureUrl) { + util.alert('请上传举报图片') + return + } + if (!data.videoId) { + util.alert('请选择举报视频') + return + } + + data.reasonForReporting = reportList[reportIndex.value].name + + api.video.reportVideo({ + data: data, + }).then(rs => { + if (rs.code == 200) { + util.alert('举报成功,请等待后台审核') + setTimeout(() => { + uni.navigateBack() + }, 500) + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }) +} + +// 选中视频信息 +function videoInfo(param) { + console.log('选中视频信息', param); + form.videoId = param.videoId; + form.coverUrl = param.coverUrl; +} </script> <template> @@ -208,7 +209,7 @@ <view class="key mr20">举报理由</view> <picker class="f1" :range="reportList" rangeKey="name" @change="handleReportList"> <view class="inputBox ptb10 plr10"> - <text v-if="reportList[reportIndex]">{{reportList[reportIndex].name}}</text> + <text v-if="reportList[reportIndex]">{{ reportList[reportIndex].name }}</text> <text v-else class="placeholderStyle">请选择举报理由</text> </view> </picker> @@ -218,10 +219,10 @@ <view class="key">详细描述</view> <view class="inputBox mt20 ptb15 plr15"> - <textarea v-model="form.context" placeholder="请详细填写,以提高举报成功率。" /> + <textarea v-model="form.particulars" placeholder="请详细填写,以提高举报成功率。" /> </view> - <view class="hint mt10 tar f20">{{form.context.length}}/100</view> + <view class="hint mt10 tar f20">{{ form.particulars.length }}/100</view> </view> <view class="line mtb50 uploadBox"> @@ -233,14 +234,15 @@ </view> <view class="imgList images mt20"> - <view class="item upload fmid pr mr20 br10" @click="uploadImg"> + <view v-if="!form.videoPictureUrl" class="item upload fmid pr mr20 br10" @click="uploadImg"> <uni-icons type="plusempty" color="#D8D8D8" size="100rpx" /> </view> - <view class="imgs item mr20 br10" v-for="(item,index) in form.pic" :key="index"> - <image class="br10" :src="item" mode="aspectFill" /> + <view v-else class="imgs item mr20 br10"> + <image class="br10" :src="form.videoPictureUrl" mode="aspectFill" /> <view class="close"> - <uni-icons type="clear" size="30rpx" color="red" @click="removeMedia(index,'pic')" /> + <uni-icons type="clear" size="30rpx" color="red" + @click="removeMedia('videoPictureUrl')" /> </view> </view> </view> @@ -251,15 +253,15 @@ <view class="key">选择视频</view> <view class="list pr mt20"> - <view class="item fmid oh br10" @click="$refs.select.open()"> + <view v-if="!form.coverUrl" class="item fmid oh br10" @click="$refs.select.open()"> <uni-icons type="plusempty" color="#D8D8D8" size="100rpx" /> </view> - <view class="item pr br10" v-for="(item,index) in videos" :key="index"> - <image :src="item.format_imageUrl" mode="aspectFill" /> + <view v-else class="item pr br10"> + <image :src="form.coverUrl" mode="aspectFill" /> <view class="close"> - <uni-icons type="clear" size="30rpx" color="red" @click="removeMedia(index,'videoId')" /> + <uni-icons type="clear" size="30rpx" color="red" @click="removeMedia('videoId')" /> </view> </view> </view> @@ -279,7 +281,7 @@ <view class="header rows ptb20 plr20"> <view class="title plr30 c333 f34"> <text>作品</text> - <text class="ml10">{{list.total}}</text> + <text class="ml10">{{ list.total }}</text> </view> <view class="fmid c999 f28" @click="refreshList"> @@ -290,7 +292,7 @@ <!-- 视频菜单 --> <scroll-view scroll-y="true" class="scroll"> - <videoMenu :list="list.data" v-model:ids="form.videoId" mode="checkbox" /> + <videoMenu :list="list.data" @videoInfo="videoInfo" mode="checkbox" /> </scroll-view> </view> </view> @@ -300,66 +302,66 @@ </template> <style lang="scss"> - image { - width: 100%; - height: 100%; +image { + width: 100%; + height: 100%; +} + +// 表单 +.form { + + .hint { + color: #a7a7a7; } +} - // 表单 - .form { +// 上传图片 +.uploadBox { - .hint { - color: #a7a7a7; + // + .uploads { + .cartoon { + top: 0; + right: -100rpx; + width: 530rpx; + height: 249rpx; } } // 上传图片 - .uploadBox { + .images .item { + width: 150rpx; + height: 150rpx; + background-color: #F3F3F5; + } - // - .uploads { - .cartoon { - top: 0; - right: -100rpx; - width: 530rpx; - height: 249rpx; - } - } - - // 上传图片 - .images .item { - width: 150rpx; - height: 150rpx; - background-color: #F3F3F5; - } + // 列表 + .list { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 20rpx; // 列表 - .list { - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-gap: 20rpx; + .item { + height: 290rpx; + background-color: #F1F1F1; - // 列表 - .item { - height: 290rpx; - background-color: #F1F1F1; - - // 关闭 - .close { - position: absolute; - top: 0; - right: 0; - transform: translate(50%, -50%); - z-index: 1; - } + // 关闭 + .close { + position: absolute; + top: 0; + right: 0; + transform: translate(50%, -50%); + z-index: 1; } } } +} - // 作品数量 - .product { - .scroll { - height: 80vh; - } +// 作品数量 +.product { + .scroll { + height: 80vh; } +} </style> \ No newline at end of file diff --git a/jiuyi2/pages/index/videoHome.vue b/jiuyi2/pages/index/videoHome.vue index c3fdbf33..7cce3588 100644 --- a/jiuyi2/pages/index/videoHome.vue +++ b/jiuyi2/pages/index/videoHome.vue @@ -1,233 +1,289 @@ <script setup> - /** - * 他人用户视频主页 - */ - import { - ref, - reactive, - getCurrentInstance, - computed, - } from 'vue'; - import { - onLoad, - onPageScroll, - onReachBottom, - onHide - } from '@dcloudio/uni-app' - import { - useStore - } from 'vuex' - // 工具库 - import util from '@/common/js/util'; - // api - import api from '@/api/index.js' - // 顶部状态栏 - import statusBar from '@/components/header/statusBar.vue' - // 顶部 - import apex from '@/components/header/apex.vue' - // 视频菜单 - import videoMenu from '@/components/index/videoMenu.vue' +/** + * 他人用户视频主页 + */ +import { + ref, + reactive, + getCurrentInstance, + computed, +} from 'vue'; +import { + onLoad, + onPageScroll, + onReachBottom, + onHide +} from '@dcloudio/uni-app' +import { + useStore +} from 'vuex' +// 工具库 +import util from '@/common/js/util'; +// api +import api from '@/api/index.js' +// 顶部状态栏 +import statusBar from '@/components/header/statusBar.vue' +// 顶部 +import apex from '@/components/header/apex.vue' +// 视频菜单 +import videoMenu from '@/components/index/videoMenu.vue' - // 代理 - const { - proxy - } = getCurrentInstance() - // - const store = useStore() - // 滚动头部 - const scrollTop = ref(false) +// 代理 +const { + proxy +} = getCurrentInstance() +// +const store = useStore() +// 滚动头部 +const scrollTop = ref(false) +// 用户id +const userId = ref('') +// 详情 +const detail = reactive({}) +// 列表对象 +const listProperty = reactive({ + data: [], + pageSize: 9, + pageNum: 1, + total: 0, +}) +// 用户信息 +let userinfo = computed(() => { + let result = store.state.userinfo + return result +}) + +// +onLoad((option) => { // 用户id - const userId = ref('') - // 详情 - const detail = reactive({}) - // 列表对象 - const listProperty = reactive({ - data: [], - pageSize: 9, - pageNum: 1, - total: 0, - }) - // 用户信息 - let userinfo = computed(() => { - let result = store.state.userinfo - return result - }) + if (option.userId) userId.value = option.userId + // 他人用户主页 + getUserinfo() + // 获取列表 + getList() +}) - // - onLoad((option) => { - // 用户id - if (option.userId) userId.value = option.userId - // 他人用户主页 - getUserinfo() - // 获取列表 - getList() - }) +onHide(() => { + // 暂停当前视频 + proxy.$refs.videoMenuRef.pause() +}) - onHide(() => { - // 暂停当前视频 - proxy.$refs.videoMenuRef.pause() - }) - - // 滚动 - onPageScroll((ev) => { - scrollTop.value = ev.scrollTop > 44 ? true : false - }) - - onReachBottom(() => { - // 获取更多列表 - getMoreList() - }) - - // 获取用户信息 - function getUserinfo() { - api.video.getUserInfo({ - query: { - userId: userId.value, - myId: userinfo.value.id, - } - }).then(rs => { - if (rs.code == 200) { - console.log('userinfo', rs) - const result = rs.data - Object.assign(detail, result) - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } +// 滚动 +onPageScroll((ev) => { + scrollTop.value = ev.scrollTop > 44 ? true : false +}) +onReachBottom(() => { // 获取更多列表 - function getMoreList() { - if (listProperty.total <= listProperty.data.length) return - listProperty.pageNum++ - getList() - } + getMoreList() +}) - // 获取用户作品 - function getList() { - // - api.video.myWorks({ - query: { - // 人员id - userId: userId.value, - pageSize: listProperty.pageSize, - pageNum: listProperty.pageNum, - } - }).then(rs => { - if (rs.code == 200) { - if (listProperty.pageNum == 1) listProperty.data.length = 0 - listProperty.data.push(...rs.rows) - listProperty.total = rs.total - return - } - util.alert({ - content: rs.msg, - showCancel: false, +// 获取用户信息 +function getUserinfo() { + api.video.getUserInfo({ + query: { + userId: userId.value, + myId: userinfo.value.id, + } + }).then(rs => { + if (rs.code == 200) { + console.log('userinfo', rs) + const result = rs.data + Object.assign(detail, result) + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }) +} + +// 获取更多列表 +function getMoreList() { + if (listProperty.total <= listProperty.data.length) return + listProperty.pageNum++ + getList() +} + +// 获取用户作品 +function getList() { + // + api.video.myWorks({ + query: { + // 人员id + userId: userId.value, + pageSize: listProperty.pageSize, + pageNum: listProperty.pageNum, + } + }).then(rs => { + if (rs.code == 200) { + if (listProperty.pageNum == 1) listProperty.data.length = 0 + listProperty.data.push(...rs.rows) + listProperty.total = rs.total + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }) +} + +// 举报 +function handleReport() { + // 关闭弹窗 + proxy.$refs.menuRef.close() + + // 打开模态弹窗 + uni.showActionSheet({ + itemList: ['举报'], + }).then(rs => { + const index = rs.tapIndex + if (index == 0) { + uni.navigateTo({ + url: util.setUrl('/pages/index/report', { + userId: userId.value, + }), }) + } + }) +} + +// 拉黑 +function handleBlack() { + // let text = detail.isBlock ? '取消拉黑' : '拉黑' + // util.alert({ + // content: `确认要${text}用户${detail.userNickname}吗?`, + // }).then(rs => { + // let obj = { + // blockUserId: detail.id, + // status: detail.isBlock ? 1 : 0 + // } + // api.mine.blockUser(obj).then(res => { + // if (res.code == 200) { + // util.alert('操作成功!') + // getUserinfo() + + // // 关闭弹窗 + // proxy.$refs.menuRef.close() + // } + // }) + // }) +} + +// 复制账号 +function handleCopyAccount() { + // 复制用户账号 + uni.setClipboardData({ + data: detail.account, + showToast: false, + success: rs => { + util.alert('复制成功') + } + }) +} + +// 关注用户 +function handleAttention() { + let targetAtt = detail.isAttention == 0 ? 1 : 0 + api.video.attention({ + data: { + // 当前用户id + userId: userinfo.value.id, + // 被关注id + attentionId: detail.id, + // + isAttention: targetAtt, + } + }).then(rs => { + if (rs.code == 200) { + // 关注状态切换 + detail.isAttention = targetAtt + + // 他人用户主页 + getUserinfo() + // 修改了他人关注状态 + uni.$emit('focusUser', { + userId: detail.id, + result: detail.isAttention, + }) + // 重载关注列表 + uni.$emit('updateFocusList') + return + } + util.alert({ + content: rs.msg, + showCancel: false, }) - } + }) +} - // 举报 - function handleReport() { - // 关闭弹窗 - proxy.$refs.menuRef.close() +// 操作不让看 +function handleBlock() { + // // 反选状态 + // detail.isBlock = !detail.isBlock - // 打开模态弹窗 - uni.showActionSheet({ - itemList: ['举报'], + // api.video.videoBlock({ + // query: { + // type: detail.isBlock ? 0 : 1, + // userId: detail.id, + // } + // }).then(rs => { + // if (rs.code == 200) { + // return + // } + + // detail.isBlock = !detail.isBlock + // util.alert({ + // content: rs.msg, + // showCancel: false, + // }) + // }) +} + +// 私信 +function handleMessage() { + util.toChat({ + name: detail.userNickname, + msgId: detail.id, + type: 'C2C', + }) + return +} +// 评论 +function userComments() { + if (detail.isLock) { + toCommentsList() + } else { + // 解锁提示 + util.alert({ + content: `确认消耗${detail.consumeFruit}个榴莲果解锁评论吗?`, }).then(rs => { - const index = rs.tapIndex - if (index == 0) { - uni.navigateTo({ - url: '/pages/index/report', - }) - } + unlockComments() }) } - - // 复制账号 - function handleCopyAccount() { - // 复制用户账号 - uni.setClipboardData({ - data: detail.account, - showToast: false, - success: rs => { - util.alert('复制成功') - } - }) - } - - // 关注用户 - function handleAttention() { - let targetAtt = detail.isAttention == 0 ? 1 : 0 - api.video.attention({ - data: { - // 当前用户id - userId: userinfo.value.id, - // 被关注id - attentionId: detail.id, - // - isAttention: targetAtt, - } - }).then(rs => { - if (rs.code == 200) { - // 关注状态切换 - detail.isAttention = targetAtt - - // 他人用户主页 +} +// 解锁评论列表 +function unlockComments() { + api.mine.unlockComment({ userId: detail.id }).then(res => { + if (res.code == 200) { + util.alert('解锁成功!') + if (res.data.isLock) { + toCommentsList() getUserinfo() - // 修改了他人关注状态 - uni.$emit('focusUser', { - userId: detail.userId, - result: detail.isAttention, - }) - // 重载关注列表 - uni.$emit('updateFocusList') - return } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } - - // 操作不让看 - function handleBlock() { - // 反选状态 - detail.isBlock = !detail.isBlock - - // - api.video.videoBlock({ - query: { - type: detail.isBlock ? 0 : 1, - userId: detail.userId, - } - }).then(rs => { - if (rs.code == 200) { - return - } - - detail.isBlock = !detail.isBlock - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } - - // 私信 - function handleMessage() { - util.toChat({ - name: detail.userNickname, - msgId: detail.userId, - type: 'C2C', - }) - return - } + } + }) +} +// 跳转到评论列表 +function toCommentsList() { + uni.navigateTo({ + url: util.setUrl('/pages/mine/myComment', { + userId: detail.id, + }), + }) +} </script> <template> @@ -239,9 +295,9 @@ <view class="window pfull"></view> </view> - <apex :bgColor="scrollTop?'#fff':'#fff0'" :color="scrollTop ? '#333' : '#fff'"> + <apex :bgColor="scrollTop ? '#fff' : '#fff0'" :color="scrollTop ? '#333' : '#fff'"> <template #content v-if="scrollTop"> - <view class="">{{detail.userNickname}}</view> + <view class="">{{ detail.userNickname }}</view> </template> <template #right> @@ -258,8 +314,8 @@ </view> <view class="user f1 ml20 cfff"> - <view class="f36 b">{{detail.userNickname}}</view> - <view class="f24">账号:{{detail.account}}</view> + <view class="f36 b">{{ detail.userNickname }}</view> + <view class="f24">账号:{{ detail.account }}</view> </view> </view> </view> @@ -270,25 +326,25 @@ <view class="number df"> <view class="option mr40" v-if="0"> - <text class="value f36">{{detail.userPraised}}</text> + <text class="value f36">{{ detail.userPraised }}</text> <text class="key ml10 c666 f24">获赞</text> </view> <view class="option mr40"> - <text class="value f36">{{detail.userFans}}</text> + <text class="value f36">{{ detail.userFans }}</text> <text class="key ml10 c666 f24">粉丝</text> </view> <view class="option mr40"> - <text class="value f36">{{detail.userAttention}}</text> + <text class="value f36">{{ detail.userAttention }}</text> <text class="key ml10 c666 f24">关注</text> </view> </view> - <view class="">他的评论</view> + <view class="" @click="userComments">他的评论</view> </view> <!-- 个人介绍 --> - <view class="desc mtb20 c333 f28">{{detail.userBrief}}</view> + <view class="desc mtb20 c333 f28">{{ detail.userBrief }}</view> <!-- 橱窗 --> <view class="shopwindow df aic mtb30" v-if="detail.isShop == 1 && 0"> @@ -312,7 +368,7 @@ <view class="product mt30"> <view class="title plr30 c333 f32"> <text>作品</text> - <text class="ml10">{{listProperty.total}}</text> + <text class="ml10">{{ listProperty.total }}</text> </view> <view class="list mt20"> @@ -326,9 +382,9 @@ <view class="menuAlt ptb50 plr40 "> <view class="header df"> <view class="user f1 c111"> - <view class="nickname f28">{{detail.userNickname}}</view> + <view class="nickname f28">{{ detail.userNickname }}</view> <view class="df aic mt10"> - <text class="f20">账号:{{detail.account}}</text> + <text class="f20">账号:{{ detail.account }}</text> <image class="wh30 ml10" src="/static/copy.png" mode="aspectFit" @click="handleCopyAccount" /> <view class="f1"></view> </view> @@ -345,7 +401,7 @@ <view class="txt mt20 c111 f20">分享主页</view> </view> --> - <view class="option ver jcc bfff br10"> + <view class="option ver jcc bfff br10" @click="handleMessage"> <image class="wh50" src="/static/email.png" mode="aspectFit" /> <view class="txt mt20 c111 f20">私信Ta</view> </view> @@ -358,14 +414,14 @@ <view class="option ver jcc bfff br10" @click="handleBlack"> <image class="wh50" src="/static/blackList.png" mode="aspectFit" /> <view class="txt mt20 c111 f20"> - <text>拉黑</text> + <text>{{ detail.isBlock ? '取消拉黑' : '拉黑' }}</text> </view> </view> </view> <!-- 列表 --> - <view class="list mtb20 plr20 c111 f24 bfff br10"> - <view class="item rows ptb25" v-if="0"> + <view class="list mtb20 plr20 c111 f24 bfff br10" v-if="0"> + <view class="item rows ptb25"> <view class="key">设置备注</view> <view class="inputBox tac"> <input class="c111 f24" type="text" placeholder="请输入备注" /> @@ -385,47 +441,47 @@ </template> <style lang="scss"> - // 头部 - .apex { +// 头部 +.apex { - // 用户信息 - .userinfo { - .avatar { - padding: 5rpx; - background-color: #fff; - } + // 用户信息 + .userinfo { + .avatar { + padding: 5rpx; + background-color: #fff; + } + } +} + +// 内容 +.container { + margin-top: -30rpx; + border-radius: 15rpx 15rpx 0 0; + background-color: #fff; +} + +// 菜单弹窗 +.menuAlt { + border-radius: 24rpx 24rpx 0 0; + background: #F2F2F2; + + // 选择菜单 + .select { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 20rpx; + + // 选项 + .option { + height: 160rpx; } } - // 内容 - .container { - margin-top: -30rpx; - border-radius: 15rpx 15rpx 0 0; - background-color: #fff; - } - - // 菜单弹窗 - .menuAlt { - border-radius: 24rpx 24rpx 0 0; - background: #F2F2F2; - - // 选择菜单 - .select { - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-gap: 20rpx; - - // 选项 - .option { - height: 160rpx; - } - } - - // 列表 - .list { - .inputBox { - width: 220rpx; - } + // 列表 + .list { + .inputBox { + width: 220rpx; } } +} </style> \ No newline at end of file diff --git a/jiuyi2/pages/mine/myComment.vue b/jiuyi2/pages/mine/myComment.vue index 0fb32c93..358a370a 100644 --- a/jiuyi2/pages/mine/myComment.vue +++ b/jiuyi2/pages/mine/myComment.vue @@ -1,97 +1,144 @@ <script setup> - // 我的评论 - import { - ref, - reactive, - computed, - getCurrentInstance, - } from 'vue'; - import { - onLoad, - onReady, - onUnload, - onPageScroll, - onReachBottom, - } from '@dcloudio/uni-app' - import { - useStore, - } from 'vuex' - import api from '@/api/index.js' - // 工具库 - import util from '@/common/js/util'; +// 我的评论 +import { + ref, + reactive, + computed, + getCurrentInstance, +} from 'vue'; +import { + onLoad, + onReady, + onUnload, + onPageScroll, + onReachBottom, + onPullDownRefresh +} from '@dcloudio/uni-app' +import { + useStore, +} from 'vuex' +import api from '@/api/index.js' +// 工具库 +import util from '@/common/js/util'; - // 仓库 - const store = useStore() - // 数据列表 - const list = reactive({ - data: [], - pageSize: 20, - pageNum: 1, - total: 0, - }) - // 用户信息 - const userinfo = computed(() => { - let result = store.state.userinfo - return result - }) +// 仓库 +const store = useStore() +// 数据列表 +const list = reactive({ + data: [], + pageSize: 20, + pageNum: 1, + total: 0, +}) +// 用户信息 +const userinfo = computed(() => { + return store.state.userinfo +}) - onLoad(() => { - getLst() - }) - - // 重载视频列表 - function refreshVideoList() { - list.pageNum = 1 - list.total = 0 - getLst() - } - - // 获取更多视频列表 - function getMoreVideoList() { - if (list.data.length >= list.total) return - list.pageNum++ - getLst() - } - - // 获取我的评论 - function getLst() { - api.mine.myComment({ - query: { - userId: userinfo.value.id, - pageNum: list.pageNum, - pageSize: list.pageSize, - } - }).then(rs => { - if (rs.code == 200) { - if (list.pageNum) list.data.length = 0 - // 追加视频列表 - list.data.push(...rs.rows.map(item => { - return item - })) - // 视频列表 - list.total = rs.total - console.log('list', list.data) - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }).finally(() => { - uni.stopPullDownRefresh() +onLoad((option) => { + if (option.userId) { + uni.setNavigationBarTitle({ + title: '他的评论' }) + getList(option.userId) + } else { + getList() } +}) + +onReachBottom(() => { + // 获取更多列表 + getMoreVideoList() +}) + +onPullDownRefresh(() => { + // 刷新 + refreshVideoList() +}) + +// 重载视频列表 +function refreshVideoList() { + list.pageNum = 1 + list.total = 0 + getLst() +} + +// 获取更多视频列表 +function getMoreVideoList() { + if (list.data.length >= list.total) return + list.pageNum++ + getLst() +} + +// 获取我的评论 +function getLst() { + api.mine.myComment({ + query: { + userId: userinfo.value.id, + pageNum: list.pageNum, + pageSize: list.pageSize, + } + }).then(rs => { + if (rs.code == 200) { + if (list.pageNum) list.data.length = 0 + // 追加视频列表 + list.data.push(...rs.rows.map(item => { + return item + })) + // 视频列表 + list.total = rs.total + console.log('list', list.data) + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }).finally(() => { + uni.stopPullDownRefresh() + }) +} + +// 获取我的评论 +function getList(id) { + api.mine.myComment({ + query: { + userId: id ? id : userinfo.value.id, + pageNum: list.pageNum, + pageSize: list.pageSize, + } + }).then(rs => { + if (rs.code == 200) { + if (list.pageNum) list.data.length = 0 + // 追加视频列表 + list.data.push(...rs.data[0].CommentVo.map(item => { + return item + })) + // 视频列表 + list.total = rs.total + console.log('list', list.data) + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }).finally(() => { + uni.stopPullDownRefresh() + }) + +} </script> <template> <view class="appbw"> <view class="listBox plr30 "> - <view class="list ptb30 plr10" v-for="(item,index) in list.data" :key="index"> + <view class="list ptb30 plr10" v-for="(item, index) in list.data" :key="index"> <view class="rows"> <view class="message"> - <view class="title f32 c333">评论了 视频</view> - <view class="content t2hd mtb15 c333 f32">{{item.content}}</view> - <view class="time mt15 f28 c999">{{item.createTime}}</view> + <view class="title f32 c333">评论了{{ item.commentType }}</view> + <view class="content t2hd mtb15 c333 f32">{{ item.content }}</view> + <view class="time mt15 f28 c999">{{ item.createTime }}</view> </view> <view class="image ml20" v-if="item.imageUrl"> <image class="wh120 br10" :src="item.imageUrl" mode="aspectFill" /> @@ -106,12 +153,12 @@ </template> <style scoped lang="scss"> - // - .listBox { +// +.listBox { - // 列表 - .list+.list { - border-top: 2rpx solid #eee; - } + // 列表 + .list+.list { + border-top: 2rpx solid #eee; } +} </style> \ No newline at end of file diff --git a/jiuyi2/pages/news/chat/chat.vue b/jiuyi2/pages/news/chat/chat.vue index 8f168652..21bb310e 100644 --- a/jiuyi2/pages/news/chat/chat.vue +++ b/jiuyi2/pages/news/chat/chat.vue @@ -1,458 +1,456 @@ <script setup> - /** - * 聊天页面 - */ - // 腾讯云聊天 - import TencentCloudChat from '@tencentcloud/chat'; - import { - ref, - reactive, - nextTick, - onUnmounted, - onMounted, - computed, - getCurrentInstance, - watch, - } from 'vue' - // api - import api from '@/api/index.js' - // 工具库 - import util from '@/common/js/util.js' - import { - onLoad, - onReady, - onPageScroll, - onUnload - } from "@dcloudio/uni-app" +/** + * 聊天页面 + */ +// 腾讯云聊天 +import TencentCloudChat from '@tencentcloud/chat'; +import { + ref, + reactive, + nextTick, + onUnmounted, + onMounted, + computed, + getCurrentInstance, + watch, +} from 'vue' +// api +import api from '@/api/index.js' +// 工具库 +import util from '@/common/js/util.js' +import { + onLoad, + onReady, + onPageScroll, + onUnload +} from "@dcloudio/uni-app" - // 单条消息 - import newsTemplate from './components/news-temp' - // 表情 - import emoji from './emoji.vue' - // 语音条 - import JyVoice from './jy-voice.vue' - // 加号菜单 - import JyPlus from './jy-plus.vue' +// 单条消息 +import newsTemplate from './components/news-temp' +// 表情 +import emoji from './emoji.vue' +// 语音条 +import JyVoice from './jy-voice.vue' +// 加号菜单 +import JyPlus from './jy-plus.vue' - import { - useStore - } from 'vuex' - const { - proxy - } = getCurrentInstance() - const store = useStore() +import { + useStore +} from 'vuex' +const { + proxy +} = getCurrentInstance() +const store = useStore() +// 聊天对象 +const msg = reactive({ // 聊天对象 - const msg = reactive({ - // 聊天对象 - id: '', - // 聊天类型 C2C单聊 GROUP群聊 - type: '', - // 群人数 - num: '', - // 是否客服聊天 - isCustomer: false, - }) - // 输入的内容 - const content = ref('') - // 加载 - const loading = ref(false) - // 用户信息 - const userinfo = computed(() => { - let result = store.state.userinfo - return result - }) - // 列表数据 - const list = reactive({ - // 列表条数 - limit: 20, - //显示的数据 - data: [], - // - total: 0, - }) - // 滚动条位置 - const top = ref(0) - // 工具条的高度 - const toolHeight = ref(0) - // 当前操作的元素 - const messageItem = ref({}) - // 工具栏状态 voice录音 input输入框 emoji表情 plus加号菜单 - const toolStatus = ref('input') - // video路径 - const videoUrl = ref('') - // 视频上下文 - const videoContext = ref(null) - // 红包对象 - const redPacket = reactive({}) + id: '', + // 聊天类型 C2C单聊 GROUP群聊 + type: '', + // 群人数 + num: '', + // 是否客服聊天 + isCustomer: false, +}) +// 输入的内容 +const content = ref('') +// 加载 +const loading = ref(false) +// 用户信息 +const userinfo = computed(() => { + let result = store.state.userinfo + return result +}) +// 列表数据 +const list = reactive({ + // 列表条数 + limit: 20, + //显示的数据 + data: [], + // + total: 0, +}) +// 滚动条位置 +const top = ref(0) +// 工具条的高度 +const toolHeight = ref(0) +// 当前操作的元素 +const messageItem = ref({}) +// 工具栏状态 voice录音 input输入框 emoji表情 plus加号菜单 +const toolStatus = ref('input') +// video路径 +const videoUrl = ref('') +// 视频上下文 +const videoContext = ref(null) +// 红包对象 +const redPacket = reactive({}) - onLoad(option => { - // 标题 - let title = '' - // 聊天类型 - if (option.type) msg.type = option.type - // 标题 - if (option.name) title = option.name - // 用户id - if (option.msgId) msg.id = option.msgId - // 如果是群组 - if (option.type == 'GROUP') { - msg.num = option.num - title = `(${option.num})${option.name}` +onLoad(option => { + // 标题 + let title = '' + // 聊天类型 + if (option.type) msg.type = option.type + // 标题 + if (option.name) title = option.name + // 用户id + if (option.msgId) msg.id = option.msgId + // 如果是群组 + if (option.type == 'GROUP') { + msg.num = option.num + title = `(${option.num})${option.name}` + } + // 标题 + if (title) uni.setNavigationBarTitle({ + title, + }) + // 是否客服 + if (option.isCustomer) msg.isCustomer = option.isCustomer + + // 开启消息监听 + addListener() + // 获取历史消息 + getHistory({ + callback: scrollToBottom + }) + // #ifdef APP + uni.onKeyboardHeightChange((rs) => { + ghostBox.value.height = rs.height + 'px' + nextTick(() => { + scrollToBottom() + }) + }) + // #endif +}) + +onReady(() => { + uni.createSelectorQuery().in(proxy).select('#tool').boundingClientRect((rect) => { + toolHeight.value = rect.height + }).exec(); + // + videoContext.value = uni.createVideoContext('video') +}) + +onPageScroll((ev) => { + onContentScroll(ev) +}) + +onUnload(() => { + // #ifdef APP + uni.offKeyboardHeightChange(() => { }) + // #endif + videoContext.value.stop() +}) + +// 开启监听消息 +function addListener() { + let onMessageReceived = function (event) { + console.log('TencentCloudChat.EVENT.MESSAGE_RECEIVED', event) + setTimeout(() => { + // 获取历史记录 + getHistory({ + msgId: '', + limit: 1, + }) + }, 200) + } + + // #ifdef APP + uni.$chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived); + // #endif +} + +// 监听内容滚动 +function onContentScroll(ev) { + if (ev.scrollTop == 50) getMoreHistroy() + debounce(() => { + top.value = ev.detail.scrollTop + }) +} + +// 点击发送 +function handleSend() { + // 发送消息 + sendMsg({ + query: { + formId: userinfo.value.id, + toUserId: msg.id, + msgType: TencentCloudChat.TYPES.MSG_TEXT, + }, + data: { + text: content.value + }, + success: () => { + // 清空已发送的消息 + content.value = '' } - // 标题 - if (title) uni.setNavigationBarTitle({ - title, - }) - // 是否客服 - if (option.isCustomer) msg.isCustomer = option.isCustomer - - // 开启消息监听 - addListener() - // 获取历史消息 - getHistory({ - callback: scrollToBottom - }) - // #ifdef APP - uni.onKeyboardHeightChange((rs) => { - ghostBox.value.height = rs.height + 'px' - nextTick(() => { - scrollToBottom() - }) - }) - // #endif }) +} - onReady(() => { - uni.createSelectorQuery().in(proxy).select('#tool').boundingClientRect((rect) => { - toolHeight.value = rect.height - }).exec(); - // - videoContext.value = uni.createVideoContext('video') - }) +/** + * 加号菜单发送 + * @param {Object} message 消息对象 + */ +function handlePlusSend(message) { + sendMsg(message) +} - onPageScroll((ev) => { - onContentScroll(ev) - }) +/** + * 发送消息 + * @param {Object} param + */ +function sendMsg(param) { + // + let request = api.news.sendUserMsg + // + if (msg.type == 'GROUP') request = api.news.sendGroupMsg + // if (msg.isCustomer) request = api.news.sendCusomterService - onUnload(() => { - // #ifdef APP - uni.offKeyboardHeightChange(() => {}) - // #endif - videoContext.value.stop() - }) - - // 开启监听消息 - function addListener() { - let onMessageReceived = function(event) { - console.log('TencentCloudChat.EVENT.MESSAGE_RECEIVED', event) - setTimeout(() => { - // 获取历史记录 - getHistory({ - msgId: '', - limit: 1, - }) - }, 200) - } - - // #ifdef APP - uni.$chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived); - // #endif - } - - // 监听内容滚动 - function onContentScroll(ev) { - if (ev.scrollTop == 50) getMoreHistroy() - debounce(() => { - top.value = ev.detail.scrollTop - }) - } - - // 点击发送 - function handleSend() { - // 发送消息 - sendMsg({ - query: { - formId: userinfo.value.id, - toUserId: msg.id, - msgType: TencentCloudChat.TYPES.MSG_TEXT, - }, - data: { - text: content.value - }, - success: () => { - // 清空已发送的消息 - content.value = '' - } - }) - } - - /** - * 加号菜单发送 - * @param {Object} message 消息对象 - */ - function handlePlusSend(message) { - sendMsg(message) - } - - /** - * 发送消息 - * @param {Object} param - */ - function sendMsg(param) { - // - let request = api.news.sendUserMsg - // - if (msg.type == 'GROUP') request = api.news.sendGroupMsg - // if (msg.isCustomer) request = api.news.sendCusomterService - - // 发送消息 - request({ - query: param.query, - data: param.data, - }).then((rs) => { - if (rs.code == 200) { - getHistory({ - msgId: '', - limit: 1, - }) - param.success ? param.success() : '' - return - } - util.alert({ - content: rs.msg, - showCancel: false, + // 发送消息 + request({ + query: param.query, + data: param.data, + }).then((rs) => { + if (rs.code == 200) { + getHistory({ + msgId: '', + limit: 1, }) - }).catch((rs) => { - console.log('sendMsg error:', rs); - }) - } - - /** - * 打开红包详情 - * @param {Object} ev - */ - function handleRedPacket(ev) { - messageItem.value = ev - api.news.getRedPacketInfo({ - query: { - // 红包id - redPacketId: ev.callbackData.callback_json[0].businessId - } - }).then(rs => { - if (rs.code == 200) { - proxy.$refs.RedPacketRef.open() - Object.assign(redPacket, rs.data) - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } - - // 领取红包 - function handleOpenReadPacket() { - // 如果不能领取 - if (redPacket.redStatus == false) return - // 红包过期 - // if (redPacket.isStale == 1) return - - - // 抢红包 - api.news.getRedPacket({ - query: { - // 红包id - redPacketId: redPacket.id, - // 领取人id - userId: userinfo.value.id, - // 群聊类型 - sendType: { - 'C2C': '1', - 'GROUP': '2', - } [msg.type], - } - }).then(rs => { - if (rs.code == 200) { - // 修改领取状态 - redPacket.redStatus = false - // 获取金额 - redPacket.amount = rs.data - return - } - util.alert({ - content: rs.msg, - showCancel: false, - }) - }) - } - - // 选择的emoji - function emojiTap(val) { - content.value = content.value + val - } - - // 点击工具栏 - function handleTool(val) { - if (toolStatus.value === val) toolStatus.value = 'input' - else toolStatus.value = val - } - - // 获取更多消息记录 - function getMoreHistroy() { - // 获取第一条消息记录 - if (list.total <= list.data.length) return - getHistory({ - msgId: list.data[0].id - }) - } - - /** - * 获取历史记录 - * @param {Object} param - */ - function getHistory(param = {}) { - // 验证sdk是否准备完毕 - // #ifdef APP - let isReady = uni.$chat.isReady(); - if (!isReady && userinfo.value.id) { - setTimeout(function() { - getHistory() - }, 200); + param.success ? param.success() : '' return } - // #endif - loading.value = true - - // 获取单聊聊天记录 - let request = api.news.getUserMsgHistory - // 如果是群聊 获取群聊聊天记录 - if (msg.type == 'GROUP') request = api.news.getGroupMsgHistory - - // 获取历史记录 - request({ - query: { - msgId: param.msgId || '', - fromId: userinfo.value.id, - toId: msg.id, - groupId: msg.id, - limit: param.limit || list.limit, - }, - }).then(res => { - if (res.code === 200) { - // 结果 - const result = res.data - // 头像路径 - list.faceUrl = result.faceUrl - - // 如果是最新消息 - if (param.limit == 1) { - list.data.push(...result.list.map(item => { - item.callbackData = JSON.parse(item.callbackJson) - return item - })) - } else { - // 追加 - list.data.unshift(...result.list.map(item => { - item.callbackData = JSON.parse(item.callbackJson) - return item - })) - } - console.log('getHostory', list.data) - // 总数 - list.total = result.total - nextTick(() => { - param.callback && param.callback() - }) - return - } - util.alert({ - content: res.msg, - showCancel: false, - }) - }).catch(rs => { - console.log('err', rs) - }).finally(() => { - loading.value = false + util.alert({ + content: rs.msg, + showCancel: false, }) - } - - // 滚动至底部 - function scrollToBottom() { - uni.createSelectorQuery().in(proxy).select('#scroll-content').boundingClientRect((res) => { - top.value = res.height - - uni.pageScrollTo({ - scrollTop: top.value, - duration: 0 - }) - // console.log('top.value', top.value) - }).exec(); - } - - // 防抖 - function debounce(func, wait = 500) { - let timeout = null; - return function(...args) { - clearTimeout(timeout) - timeout = setTimeout(() => { - func.apply(this, args) - }, wait); - } - } - - // 输入框聚焦 - function onFocus() { - handleTool('input') - } - - // 输入语音 - function voiceSend(message) { - console.log('handlePlusSend', message) - sendMsg({ - message, - }) - } - - // 监听滚动 - const handleScroll = (e) => { - if (e.detail.scrollTop === 0) { - getHistory() - } - } - - // 撑起键盘的高度 打开该元素 - const showGhost = ref(false) - // 给元素加高度 - const ghostBox = ref({ - height: '0px', - duration: '0.25s' + }).catch((rs) => { + console.log('sendMsg error:', rs); }) +} - // 监听键盘高度变化 - function keyboardheightchange(res) { - ghostBox.value = res.detail - nextTick(() => { - showGhost.value = res.detail.height > 0 ? true : false +/** + * 打开红包详情 + * @param {Object} ev + */ +function handleRedPacket(ev) { + messageItem.value = ev + api.news.getRedPacketInfo({ + query: { + // 红包id + redPacketId: ev.callbackData.callback_json[0].businessId + } + }).then(rs => { + if (rs.code == 200) { + proxy.$refs.RedPacketRef.open() + Object.assign(redPacket, rs.data) + return + } + util.alert({ + content: rs.msg, + showCancel: false, }) - } + }) +} - /** - * 看视频 - * @param {Object} item 聊天消息对象 - */ - function handleViewVideo(item) { - videoUrl.value = item.payload.videoUrl - // 进入全屏 - videoContext.value.requestFullScreen() - } +// 领取红包 +function handleOpenReadPacket() { + // 如果不能领取 + if (redPacket.redStatus == false) return + // 红包过期 + // if (redPacket.isStale == 1) return - // 监听视频是否全屏 - function onScreenChange(ev) { - console.log('onScreenChange', ev) - if (!ev.fullScreen) videoContext.value.pause() + + // 抢红包 + api.news.getRedPacket({ + query: { + // 红包id + redPacketId: redPacket.id, + // 领取人id + userId: userinfo.value.id, + // 群聊类型 + sendType: { + 'C2C': '1', + 'GROUP': '2', + }[msg.type], + } + }).then(rs => { + if (rs.code == 200) { + // 修改领取状态 + redPacket.redStatus = false + // 获取金额 + redPacket.amount = rs.data + return + } + util.alert({ + content: rs.msg, + showCancel: false, + }) + }) +} + +// 选择的emoji +function emojiTap(val) { + content.value = content.value + val +} + +// 点击工具栏 +function handleTool(val) { + if (toolStatus.value === val) toolStatus.value = 'input' + else toolStatus.value = val +} + +// 获取更多消息记录 +function getMoreHistroy() { + // 获取第一条消息记录 + if (list.total <= list.data.length) return + getHistory({ + msgId: list.data[0].id + }) +} + +/** + * 获取历史记录 + * @param {Object} param + */ +function getHistory(param = {}) { + // 验证sdk是否准备完毕 + // #ifdef APP + let isReady = uni.$chat.isReady(); + if (!isReady && userinfo.value.id) { + setTimeout(function () { + getHistory() + }, 200); + return } + // #endif + loading.value = true + + // 获取单聊聊天记录 + let request = api.news.getUserMsgHistory + // 如果是群聊 获取群聊聊天记录 + if (msg.type == 'GROUP') request = api.news.getGroupMsgHistory + + // 获取历史记录 + request({ + query: { + msgId: param.msgId || '', + fromId: userinfo.value.id, + toId: msg.id, + groupId: msg.id, + limit: param.limit || list.limit, + }, + }).then(res => { + if (res.code === 200) { + // 结果 + const result = res.data + // 头像路径 + list.faceUrl = result.faceUrl + + // 如果是最新消息 + if (param.limit == 1) { + list.data.push(...result.list.map(item => { + item.callbackData = JSON.parse(item.callbackJson) + return item + })) + } else { + // 追加 + list.data.unshift(...result.list.map(item => { + item.callbackData = JSON.parse(item.callbackJson) + return item + })) + } + console.log('getHostory', list.data) + // 总数 + list.total = result.total + nextTick(() => { + param.callback && param.callback() + }) + return + } + util.alert({ + content: res.msg, + showCancel: false, + }) + }).catch(rs => { + console.log('err', rs) + }).finally(() => { + loading.value = false + }) +} + +// 滚动至底部 +function scrollToBottom() { + uni.createSelectorQuery().in(proxy).select('#scroll-content').boundingClientRect((res) => { + top.value = res.height + + uni.pageScrollTo({ + scrollTop: top.value, + duration: 0 + }) + // console.log('top.value', top.value) + }).exec(); +} + +// 防抖 +function debounce(func, wait = 500) { + let timeout = null; + return function (...args) { + clearTimeout(timeout) + timeout = setTimeout(() => { + func.apply(this, args) + }, wait); + } +} + +// 输入框聚焦 +function onFocus() { + handleTool('input') +} + +// 输入语音 +function voiceSend(message) { + console.log('handlePlusSend', message) + sendMsg(message) +} + +// 监听滚动 +const handleScroll = (e) => { + if (e.detail.scrollTop === 0) { + getHistory() + } +} + +// 撑起键盘的高度 打开该元素 +const showGhost = ref(false) +// 给元素加高度 +const ghostBox = ref({ + height: '0px', + duration: '0.25s' +}) + +// 监听键盘高度变化 +function keyboardheightchange(res) { + ghostBox.value = res.detail + nextTick(() => { + showGhost.value = res.detail.height > 0 ? true : false + }) +} + +/** + * 看视频 + * @param {Object} item 聊天消息对象 + */ +function handleViewVideo(item) { + videoUrl.value = item.payload.videoUrl + // 进入全屏 + videoContext.value.requestFullScreen() +} + +// 监听视频是否全屏 +function onScreenChange(ev) { + console.log('onScreenChange', ev) + if (!ev.fullScreen) videoContext.value.pause() +} </script> <template> @@ -572,147 +570,147 @@ <style lang="scss" scoped> - @import './index.scss'; +@import './index.scss'; - // - #video { - position: fixed; - top: 100%; - left: 0; +// +#video { + position: fixed; + top: 100%; + left: 0; +} + +// +.red-bag { + position: relative; + width: 528rpx; + height: 60vh; + color: #ECCD97; + background-color: #e0534a; + box-shadow: 0 0 20rpx #00000033; + + .rbag_top { + padding-top: 60rpx; + height: 70%; + background-color: #e0534a; + border-radius: 0 0 500rpx 500rpx / 0 0 200rpx 200rpx; + box-shadow: 0 5rpx 5rpx rgba(0, 0, 0, 0.2); + + .amount { + margin-top: 120rpx; + text-align: center; + letter-spacing: 1rpx; + + .value { + font-size: 60rpx; + font-weight: bold; + } + } } - // - .red-bag { - position: relative; - width: 528rpx; - height: 60vh; - color: #ECCD97; - background-color: #e0534a; - box-shadow: 0 0 20rpx #00000033; + .open_rbag_btn { + width: 180rpx; + height: 180rpx; + margin: -90rpx auto 0; + color: #fef5e8; + font-size: 74rpx; + font-weight: bold; + background-color: #ffd287; + box-shadow: 2rpx 2rpx 6rpx rgba(0, 0, 0, 0.2); + border-radius: 50%; + z-index: 1; + } - .rbag_top { - padding-top: 60rpx; - height: 70%; - background-color: #e0534a; - border-radius: 0 0 500rpx 500rpx / 0 0 200rpx 200rpx; - box-shadow: 0 5rpx 5rpx rgba(0, 0, 0, 0.2); + // 打开红包 + .open_rbag_model { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background-color: rgba(0, 0, 0, 0.3); + z-index: 1000; - .amount { - margin-top: 120rpx; - text-align: center; - letter-spacing: 1rpx; - - .value { - font-size: 60rpx; - font-weight: bold; - } - } - } - - .open_rbag_btn { - width: 180rpx; - height: 180rpx; - margin: -90rpx auto 0; - color: #fef5e8; - font-size: 74rpx; - font-weight: bold; - background-color: #ffd287; - box-shadow: 2rpx 2rpx 6rpx rgba(0, 0, 0, 0.2); - border-radius: 50%; - z-index: 1; - } - - // 打开红包 - .open_rbag_model { - position: fixed; + .rbag_conbg { + position: absolute; top: 0; left: 0; - width: 100%; - height: 100vh; - background-color: rgba(0, 0, 0, 0.3); - z-index: 1000; + right: 0; + bottom: 0; + width: 80%; + height: 840rpx; + margin: auto; + z-index: 1001; + } - .rbag_conbg { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 80%; - height: 840rpx; - margin: auto; - z-index: 1001; + .open_rbag_con { + z-index: 1002; + + .open_title { + height: 120rpx; + line-height: 120rpx; + text-align: center; + font-size: 38rpx; + letter-spacing: 2rpx; + color: #e46965; } - .open_rbag_con { - z-index: 1002; + .rbag_detail { + margin-top: 90rpx; - .open_title { - height: 120rpx; - line-height: 120rpx; + .open_money { text-align: center; - font-size: 38rpx; - letter-spacing: 2rpx; - color: #e46965; - } - - .rbag_detail { - margin-top: 90rpx; - - .open_money { - text-align: center; - font-size: 80rpx; - color: #c95948; - font-weight: bold; - display: flex; - justify-content: center; - - .danwei { - font-size: 30rpx; - margin-left: 16rpx; - margin-top: 24rpx; - } - } - - .open_tips { - text-align: center; - font-size: 30rpx; - color: #d26762; - margin-top: 30rpx; - } - } - - .lookbag_box { - margin-top: 300rpx; + font-size: 80rpx; + color: #c95948; + font-weight: bold; display: flex; justify-content: center; - .lookbag_btn { - width: 70%; - height: 90rpx; - line-height: 90rpx; - text-align: center; - font-size: 32rpx; - color: #c95948; - letter-spacing: 2rpx; - background-color: #ffd356; - border-radius: 50rpx; - box-shadow: 0rpx 0rpx 4rpx rgba(0, 0, 0, 0.2); + .danwei { + font-size: 30rpx; + margin-left: 16rpx; + margin-top: 24rpx; } } - .hide_btn { - position: absolute; - bottom: -110rpx; - left: 0; - right: 0; - width: 80rpx; - height: 80rpx; - line-height: 80rpx; + .open_tips { text-align: center; - margin: 0 auto; + font-size: 30rpx; + color: #d26762; + margin-top: 30rpx; } } + + .lookbag_box { + margin-top: 300rpx; + display: flex; + justify-content: center; + + .lookbag_btn { + width: 70%; + height: 90rpx; + line-height: 90rpx; + text-align: center; + font-size: 32rpx; + color: #c95948; + letter-spacing: 2rpx; + background-color: #ffd356; + border-radius: 50rpx; + box-shadow: 0rpx 0rpx 4rpx rgba(0, 0, 0, 0.2); + } + } + + .hide_btn { + position: absolute; + bottom: -110rpx; + left: 0; + right: 0; + width: 80rpx; + height: 80rpx; + line-height: 80rpx; + text-align: center; + margin: 0 auto; + } } } +} </style> \ No newline at end of file diff --git a/jiuyi2/pages/news/chat/jy-voice.vue b/jiuyi2/pages/news/chat/jy-voice.vue index cc2dbedf..3f56827d 100644 --- a/jiuyi2/pages/news/chat/jy-voice.vue +++ b/jiuyi2/pages/news/chat/jy-voice.vue @@ -16,265 +16,274 @@ </template> <script setup> - import { - ref, - defineEmits - } from 'vue' - // 腾讯云聊天 - import TencentCloudChat from '@tencentcloud/chat'; - const props = defineProps({ - msg: { - type: Object - }, - }) - const emit = defineEmits(['send']) - //录音 - // #ifdef APP-PLUS - const recorderManager = uni.getRecorderManager(); - // #endif - // 录音时长 - const voiceLength = ref(0); - // 录音定时器 - const voiceTimer = ref(null); - // 录音文本 - const voiceText = ref('按住 说话'); - // 录音提示 - const voiceTis = ref('手指上滑 取消发送'); - // 录音图标显示 - const voiceFlg = ref(false); - // 录音开始Y坐标 - const voicePageY = ref(0); - // 录音结束 - const voiceStop = ref(false); - const str = ''; - // 录音相关 - const sv = { - // 按下触发 - touchstartVoice: (e) => { - voicePageY.value = (e.changedTouches[0].pageY).toFixed(2); - recorderManager.start({ - duration: 60000, // 录音的时长,单位 ms,最大值 600000(10 分钟) - sampleRate: 44100, // 采样率 - numberOfChannels: 1, // 录音通道数 - encodeBitRate: 192000, // 编码码率 - format: "mp3" - }); - voiceLength.value = 0; - voiceFlg.value = true - console.log('recorder start success'); - //录音开始, - voiceTimer.value = setInterval(() => { - voiceLength.value += 0.1; - }, 100); +import { + ref, + defineEmits +} from 'vue' +// 腾讯云聊天 +import TencentCloudChat from '@tencentcloud/chat'; +const props = defineProps({ + msg: { + type: Object + }, +}) +const emit = defineEmits(['send']) +//录音 +// #ifdef APP-PLUS +const recorderManager = uni.getRecorderManager(); +// #endif +// 录音时长 +const voiceLength = ref(0); +// 录音定时器 +const voiceTimer = ref(null); +// 录音文本 +const voiceText = ref('按住 说话'); +// 录音提示 +const voiceTis = ref('手指上滑 取消发送'); +// 录音图标显示 +const voiceFlg = ref(false); +// 录音开始Y坐标 +const voicePageY = ref(0); +// 录音结束 +const voiceStop = ref(false); +const str = ''; +// 录音相关 +const sv = { + // 按下触发 + touchstartVoice: (e) => { + voicePageY.value = (e.changedTouches[0].pageY).toFixed(2); + recorderManager.start({ + duration: 60000, // 录音的时长,单位 ms,最大值 600000(10 分钟) + sampleRate: 44100, // 采样率 + numberOfChannels: 1, // 录音通道数 + encodeBitRate: 192000, // 编码码率 + format: "mp3" + }); + voiceLength.value = 0; + voiceFlg.value = true + console.log('recorder start success'); + //录音开始, + voiceTimer.value = setInterval(() => { + voiceLength.value += 0.1; + }, 100); - console.log('touchstartVoice', voicePageY.value); - }, - // 滑动触发 - touchmoveVoice: (e) => { - // 没有展示UI不触发 - if (!voiceFlg.value) { - return; - } - let numTemp = voicePageY.value - ((e.changedTouches[0].pageY).toFixed(2)); - if (numTemp >= 60) { - console.log('取消发送'); - voiceStop.value = true - voiceTis.value = '松开手指 取消发送' - } else { - console.log('继续发送'); - voiceStop.value = false - voiceTis.value = '手指上滑 取消发送' - } - }, - // 松开触发 - touchendVoice: () => { - // 没有展示UI不触发 - if (!voiceFlg.value) { - return; - } - clearInterval(voiceTimer.value); - voiceText.value = '按住 说话' - voiceTis.value = "手指上滑 取消发送" - console.log('touchendVoice'); - sv.stop(); - }, - // 打断触发 - touchcancelVoice: () => { - clearInterval(voiceTimer.value); - // 关闭UI - voiceText.value = '按住 说话' - voiceTis.value = "手指上滑 取消发送" - // 不发送语音 + console.log('touchstartVoice', voicePageY.value); + }, + // 滑动触发 + touchmoveVoice: (e) => { + // 没有展示UI不触发 + if (!voiceFlg.value) { + return; + } + let numTemp = voicePageY.value - ((e.changedTouches[0].pageY).toFixed(2)); + if (numTemp >= 60) { + console.log('取消发送'); voiceStop.value = true - console.log('touchcancelVoice'); - sv.stop(); - }, - stop: () => { - voiceTimer.value = null; - voiceFlg.value = false - recorderManager.stop(); // 录音结束 - console.log('录音结束'); + voiceTis.value = '松开手指 取消发送' + } else { + console.log('继续发送'); + voiceStop.value = false + voiceTis.value = '手指上滑 取消发送' } - }; - // #ifdef APP-PLUS - // 监听录音停止事件 - recorderManager.onStop((res) => { - // 被打断等情况不发送 - if (voiceStop.value) { - return + }, + // 松开触发 + touchendVoice: () => { + // 没有展示UI不触发 + if (!voiceFlg.value) { + return; } - // 正常情况 - if (voiceStop.value) { - uni.showToast({ - icon: "none", - title: "取消发送", - duration: 2000 - }) - return - } - if (voiceLength.value < 1) { - uni.showToast({ - icon: "none", - title: "语音时长过短", - duration: 2000 - }) - return - } - if (voiceLength.value > 60) { - uni.showToast({ - icon: "none", - title: "语音时长过长", - duration: 2000 - }) - return - } - console.log('file', res) + clearInterval(voiceTimer.value); + voiceText.value = '按住 说话' + voiceTis.value = "手指上滑 取消发送" + console.log('touchendVoice'); + sv.stop(); + }, + // 打断触发 + touchcancelVoice: () => { + clearInterval(voiceTimer.value); + // 关闭UI + voiceText.value = '按住 说话' + voiceTis.value = "手指上滑 取消发送" + // 不发送语音 + voiceStop.value = true + console.log('touchcancelVoice'); + sv.stop(); + }, + stop: () => { + voiceTimer.value = null; + voiceFlg.value = false + recorderManager.stop(); // 录音结束 + console.log('录音结束'); + } +}; +// #ifdef APP-PLUS +// 监听录音停止事件 +recorderManager.onStop((res) => { + // 被打断等情况不发送 + if (voiceStop.value) { + return + } + // 正常情况 + if (voiceStop.value) { + uni.showToast({ + icon: "none", + title: "取消发送", + duration: 2000 + }) + return + } + if (voiceLength.value < 1) { + uni.showToast({ + icon: "none", + title: "语音时长过短", + duration: 2000 + }) + return + } + if (voiceLength.value > 60) { + uni.showToast({ + icon: "none", + title: "语音时长过长", + duration: 2000 + }) + return + } + console.log('file', res) - try { - let message = uni.$chat.createAudioMessage({ - to: props.msg.id, - conversationType: props.msg.type, - payload: { - file: res - }, - // 音频上传进度回调 - onProgress: function(event) { - console.log('file uploading:', event) - } - }) - emit('send', message) - } catch (e) { - console.log('message catch', e) - } - // + try { + let message = uni.$chat.createAudioMessage({ + to: props.msg.id, + conversationType: props.msg.type, + payload: { + file: res + }, + // 音频上传进度回调 + onProgress: function (event) { + console.log('file uploading:', event) + } + }) - }) - // #endif + let obj = { + query: { + toUserId: message.to, + formId: message.from, + msgType: message.type, + }, + data: message + } + emit('send', obj) + } catch (e) { + console.log('message catch', e) + } + // + +}) +// #endif </script> <style scoped lang="scss"> - .voice_box { - padding: 20rpx 0; - margin: 0 20rpx; - border-radius: 50rpx; - background: #fff; - flex: 1; +.voice_box { + padding: 20rpx 0; + margin: 0 20rpx; + border-radius: 50rpx; + background: #fff; + flex: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.hidden { + display: none !important; +} + +.record { + width: 40vw; + height: 40vw; + position: fixed; + top: 55%; + left: 30%; + background-color: rgba(0, 0, 0, .6); + border-radius: 20rpx; + + .ing { + width: 100%; + height: 30vw; display: flex; - align-items: center; justify-content: center; - } + align-items: center; - .hidden { - display: none !important; - } - - .record { - width: 40vw; - height: 40vw; - position: fixed; - top: 55%; - left: 30%; - background-color: rgba(0, 0, 0, .6); - border-radius: 20rpx; - - .ing { - width: 100%; - height: 30vw; - display: flex; - justify-content: center; - align-items: center; - - // 模拟录音音效动画 - @keyframes volatility { - 0% { - background-position: 0% 130%; - } - - 20% { - background-position: 0% 150%; - } - - 30% { - background-position: 0% 155%; - } - - 40% { - background-position: 0% 150%; - } - - 50% { - background-position: 0% 145%; - } - - 70% { - background-position: 0% 150%; - } - - 80% { - background-position: 0% 155%; - } - - 90% { - background-position: 0% 140%; - } - - 100% { - background-position: 0% 135%; - } + // 模拟录音音效动画 + @keyframes volatility { + 0% { + background-position: 0% 130%; } - background-image: linear-gradient(to bottom, #f09b37, #fff 50%); - background-size: 100% 200%; - animation: volatility 1.5s ease-in-out -1.5s infinite alternate; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - font-size: 150rpx; + 20% { + background-position: 0% 150%; + } + + 30% { + background-position: 0% 155%; + } + + 40% { + background-position: 0% 150%; + } + + 50% { + background-position: 0% 145%; + } + + 70% { + background-position: 0% 150%; + } + + 80% { + background-position: 0% 155%; + } + + 90% { + background-position: 0% 140%; + } + + 100% { + background-position: 0% 135%; + } + } + + background-image: linear-gradient(to bottom, #f09b37, #fff 50%); + background-size: 100% 200%; + animation: volatility 1.5s ease-in-out -1.5s infinite alternate; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-size: 150rpx; + color: #f09b37; + + } + + .cancel { + width: 100%; + height: 30vw; + display: flex; + justify-content: center; + align-items: center; + + color: #fff; + font-size: 150rpx; + + } + + .tis { + width: 100%; + height: 10vw; + display: flex; + justify-content: center; + font-size: 28rpx; + color: #fff; + + &.change { color: #f09b37; - - } - - .cancel { - width: 100%; - height: 30vw; - display: flex; - justify-content: center; - align-items: center; - - color: #fff; - font-size: 150rpx; - - } - - .tis { - width: 100%; - height: 10vw; - display: flex; - justify-content: center; - font-size: 28rpx; - color: #fff; - - &.change { - color: #f09b37; - } } } +} </style> \ No newline at end of file diff --git a/jiuyi2/pages/news/myQr.vue b/jiuyi2/pages/news/myQr.vue index 4c5be626..20dfb6cb 100644 --- a/jiuyi2/pages/news/myQr.vue +++ b/jiuyi2/pages/news/myQr.vue @@ -2,6 +2,8 @@ // 我的二维码 import uQRCode from '@/common/js/uqrcode.js' +// 未实名认证 +import noAuth from '@/components/mine/noAuth.vue' import { ref, reactive, @@ -60,7 +62,11 @@ function init() { </script> <template> - <view class="app"> + <view class="page" v-if="!userinfo.isRealName"> + <noAuth class="f1" /> + </view> + + <view class="app" v-else> <!-- --> <view class="container ver mtb30 mlr30 tac"> <!-- 二维码插件 width height设置宽高 --> diff --git a/jiuyi2/pages/news/news.vue b/jiuyi2/pages/news/news.vue index 29316378..5577c3db 100644 --- a/jiuyi2/pages/news/news.vue +++ b/jiuyi2/pages/news/news.vue @@ -20,6 +20,8 @@ import TencentCloudChat from '@tencentcloud/chat'; import apex from '@/components/header/apex' // 未登录 import noLogin from '@/components/login/noLogin.vue' +// 未实名认证 +import noAuth from '@/components/mine/noAuth.vue' // 通讯录 import book from '@/components/news/book' // 群聊列表 @@ -107,7 +109,7 @@ function imLoading() { // 移除监听 function removeListener() { // #ifdef APP - uni.$chat.off(TencentCloudChat.EVENT.SDK_READY,()=>{}); + uni.$chat.off(TencentCloudChat.EVENT.SDK_READY, () => { }); // #endif } @@ -178,6 +180,10 @@ function getUserInfos(userRecommend) { <noLogin class="f1" /> </view> + <view class="page" v-else-if="!userinfo.isRealName"> + <noAuth class="f1" /> + </view> + <view class="page" v-else> <apex> <template #left>