shop
This commit is contained in:
commit
f1d1f5cc5c
543
App.vue
543
App.vue
@ -1,273 +1,270 @@
|
||||
<script>
|
||||
/**
|
||||
* vuex管理登录状态,具体可以参考官方登录模板示例
|
||||
*/
|
||||
import { mapMutations } from "vuex";
|
||||
import APPUpdate from "@/plugins/APPUpdate";
|
||||
import { getClipboardData } from "@/js_sdk/h5-copy/h5-copy.js";
|
||||
import config from "@/config/config";
|
||||
// 区域code
|
||||
import provinceList from "./json/area_province.js";
|
||||
import cityList from "./json/area_city.js";
|
||||
import districtList from "./json/area_district.js";
|
||||
import storage from "@/utils/storage.js"; //缓存
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听返回
|
||||
*/
|
||||
onBackPress(e) {
|
||||
if (e.from == "backbutton") {
|
||||
let routes = getCurrentPages();
|
||||
let curRoute = routes[routes.length - 1].options;
|
||||
routes.forEach((item) => {
|
||||
if (
|
||||
item.route == "pages/tabbar/cart/cartList" ||
|
||||
item.route.indexOf("pages/product/goods") != -1
|
||||
) {
|
||||
uni.redirectTo({
|
||||
url: item.route,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (curRoute.addId) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/tabbar/cart/cartList",
|
||||
});
|
||||
} else {
|
||||
uni.navigateBack();
|
||||
}
|
||||
return true; //阻止默认返回行为
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["login"]),
|
||||
},
|
||||
onLaunch: function () {
|
||||
// #ifdef APP-PLUS
|
||||
this.checkArguments(); // 检测启动参数
|
||||
APPUpdate();
|
||||
this.hanleTabCenter();
|
||||
// 重点是以下: 一定要监听后台恢复 !一定要
|
||||
plus.globalEvent.addEventListener("newintent", (e) => {
|
||||
this.checkArguments(); // 检测启动参数
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
this.applyUpdateWeChat();
|
||||
// #endif
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// #ifndef H5
|
||||
this.getClipboard();
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
//
|
||||
hanleTabCenter() {
|
||||
// 点击中间的➕
|
||||
uni.onTabBarMidButtonTap(() => {
|
||||
console.log("center");
|
||||
// 未登录不能发布视频
|
||||
let myUserInfo = storage.getVlogUserInfo() || null;
|
||||
if (myUserInfo == null) {
|
||||
uni.navigateTo({
|
||||
// url: "../loginRegist/loginRegist",
|
||||
url: "/pages/passport/login",
|
||||
animationType: "slide-in-bottom",
|
||||
success() {
|
||||
this.loginWords = "请登录";
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.chooseVideo({
|
||||
sourceType: ["album"],
|
||||
compressed: false,
|
||||
success(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/publish/publish?fileObjectEvent=" + JSON.stringify(e),
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 微信小程序版本提交更新版本 解决缓存问题
|
||||
*/
|
||||
applyUpdateWeChat() {
|
||||
const updateManager = uni.getUpdateManager();
|
||||
|
||||
updateManager.onCheckForUpdate(function (res) {
|
||||
// 请求完新版本信息的回调
|
||||
});
|
||||
|
||||
updateManager.onUpdateReady(function (res) {
|
||||
uni.showModal({
|
||||
title: "更新提示",
|
||||
content: "发现新版本,是否重启应用?",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||
updateManager.applyUpdate();
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
updateManager.onUpdateFailed(function (res) {
|
||||
// 新的版本下载失败
|
||||
});
|
||||
},
|
||||
|
||||
// TODO 开屏广告 后续优化添加
|
||||
launch() {
|
||||
try {
|
||||
// 获取本地存储中launchFlag标识 开屏广告
|
||||
const value = uni.getStorageSync("launchFlag");
|
||||
if (!value) {
|
||||
// this.$u.route("/pages/index/agreement");
|
||||
} else {
|
||||
//app启动时打开启动广告页
|
||||
var w = plus.webview.open(
|
||||
"/hybrid/html/advertise/advertise.html",
|
||||
"本地地址",
|
||||
{
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
zindex: 999,
|
||||
},
|
||||
"fade-in",
|
||||
500
|
||||
);
|
||||
//设置定时器,4s后关闭启动广告页
|
||||
setTimeout(function () {
|
||||
plus.webview.close(w);
|
||||
APPUpdate();
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
// error
|
||||
uni.setStorage({
|
||||
key: "launchFlag",
|
||||
data: true,
|
||||
success: function () {
|
||||
console.log("error时存储launchFlag");
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取粘贴板数据
|
||||
*/
|
||||
async getClipboard() {
|
||||
let res = await getClipboardData();
|
||||
/**
|
||||
* 解析粘贴板数据
|
||||
*/
|
||||
if (res.indexOf(config.shareLink) != -1) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "检测到一个分享链接是否跳转?",
|
||||
confirmText: "跳转",
|
||||
success: function (callback) {
|
||||
if (callback.confirm) {
|
||||
const path = res.split(config.shareLink)[1];
|
||||
if (path.indexOf("tabbar") != -1) {
|
||||
uni.switchTab({
|
||||
url: path,
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* h5中打开app获取跳转app的链接并跳转
|
||||
*/
|
||||
checkArguments() {
|
||||
// #ifdef APP-PLUS
|
||||
setTimeout(() => {
|
||||
const args = plus.runtime.arguments;
|
||||
if (args) {
|
||||
const argsStr = decodeURIComponent(args);
|
||||
const path = argsStr.split("//")[1];
|
||||
if (path.indexOf("tabbar") != -1) {
|
||||
uni.switchTab({
|
||||
url: `/${path}`,
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/${path}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* #ifndef APP-NVUE */
|
||||
@import "uview-ui/index.scss";
|
||||
/* #endif */
|
||||
|
||||
// -------适配底部安全区 苹果x系列刘海屏
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
.mp-iphonex-bottom {
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-sizing: content-box;
|
||||
height: auto !important;
|
||||
padding-top: 10rpx;
|
||||
}
|
||||
// #endif
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
body {
|
||||
background-color: $bg-color;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/************************ */
|
||||
.w200 {
|
||||
width: 200rpx !important;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1; //必须父级设置flex
|
||||
}
|
||||
.activate-line {
|
||||
background-color: #ffffff;
|
||||
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
// uni-page-body,
|
||||
// html,
|
||||
// body,
|
||||
// page {
|
||||
// width: 100% ;
|
||||
// height: 100% ;
|
||||
// overflow: hidden;
|
||||
// }
|
||||
</style>
|
||||
<script>
|
||||
/**
|
||||
* vuex管理登录状态,具体可以参考官方登录模板示例
|
||||
*/
|
||||
import { mapMutations } from 'vuex';
|
||||
import APPUpdate from '@/plugins/APPUpdate';
|
||||
import { getClipboardData } from '@/js_sdk/h5-copy/h5-copy.js';
|
||||
import config from '@/config/config';
|
||||
// 区域code
|
||||
import provinceList from './json/area_province.js';
|
||||
import cityList from './json/area_city.js';
|
||||
import districtList from './json/area_district.js';
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听返回
|
||||
*/
|
||||
onBackPress(e) {
|
||||
if (e.from == 'backbutton') {
|
||||
let routes = getCurrentPages();
|
||||
let curRoute = routes[routes.length - 1].options;
|
||||
routes.forEach((item) => {
|
||||
if (item.route == 'pages/tabbar/cart/cartList' || item.route.indexOf('pages/product/goods') != -1) {
|
||||
uni.redirectTo({
|
||||
url: item.route
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (curRoute.addId) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabbar/cart/cartList'
|
||||
});
|
||||
} else {
|
||||
uni.navigateBack();
|
||||
}
|
||||
return true; //阻止默认返回行为
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['login'])
|
||||
},
|
||||
onLaunch: function () {
|
||||
// #ifdef APP-PLUS
|
||||
this.checkArguments(); // 检测启动参数
|
||||
APPUpdate();
|
||||
this.hanleTabCenter();
|
||||
// 重点是以下: 一定要监听后台恢复 !一定要
|
||||
plus.globalEvent.addEventListener('newintent', (e) => {
|
||||
this.checkArguments(); // 检测启动参数
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
this.applyUpdateWeChat();
|
||||
// #endif
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// #ifndef H5
|
||||
this.getClipboard();
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
//
|
||||
hanleTabCenter() {
|
||||
// 点击中间的➕
|
||||
uni.onTabBarMidButtonTap(() => {
|
||||
console.log('center');
|
||||
// 未登录不能发布视频
|
||||
let myUserInfo = storage.getVlogUserInfo();
|
||||
if (myUserInfo == null) {
|
||||
uni.navigateTo({
|
||||
// url: "../loginRegist/loginRegist",
|
||||
url: '/pages/passport/login',
|
||||
animationType: 'slide-in-bottom',
|
||||
success() {
|
||||
this.loginWords = '请登录';
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album'],
|
||||
compressed: false,
|
||||
success(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
uni.navigateTo({
|
||||
url: '/pages/publish/publish?fileObjectEvent=' + JSON.stringify(e)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 微信小程序版本提交更新版本 解决缓存问题
|
||||
*/
|
||||
applyUpdateWeChat() {
|
||||
const updateManager = uni.getUpdateManager();
|
||||
|
||||
updateManager.onCheckForUpdate(function (res) {
|
||||
// 请求完新版本信息的回调
|
||||
});
|
||||
|
||||
updateManager.onUpdateReady(function (res) {
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '发现新版本,是否重启应用?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||
updateManager.applyUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
updateManager.onUpdateFailed(function (res) {
|
||||
// 新的版本下载失败
|
||||
});
|
||||
},
|
||||
|
||||
// TODO 开屏广告 后续优化添加
|
||||
launch() {
|
||||
try {
|
||||
// 获取本地存储中launchFlag标识 开屏广告
|
||||
const value = uni.getStorageSync('launchFlag');
|
||||
if (!value) {
|
||||
// this.$u.route("/pages/index/agreement");
|
||||
} else {
|
||||
//app启动时打开启动广告页
|
||||
var w = plus.webview.open(
|
||||
'/hybrid/html/advertise/advertise.html',
|
||||
'本地地址',
|
||||
{
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
zindex: 999
|
||||
},
|
||||
'fade-in',
|
||||
500
|
||||
);
|
||||
//设置定时器,4s后关闭启动广告页
|
||||
setTimeout(function () {
|
||||
plus.webview.close(w);
|
||||
APPUpdate();
|
||||
}, 3000);
|
||||
}
|
||||
} catch (e) {
|
||||
// error
|
||||
uni.setStorage({
|
||||
key: 'launchFlag',
|
||||
data: true,
|
||||
success: function () {
|
||||
console.log('error时存储launchFlag');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取粘贴板数据
|
||||
*/
|
||||
async getClipboard() {
|
||||
let res = await getClipboardData();
|
||||
/**
|
||||
* 解析粘贴板数据
|
||||
*/
|
||||
if (res.indexOf(config.shareLink) != -1) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '检测到一个分享链接是否跳转?',
|
||||
confirmText: '跳转',
|
||||
success: function (callback) {
|
||||
if (callback.confirm) {
|
||||
const path = res.split(config.shareLink)[1];
|
||||
if (path.indexOf('tabbar') != -1) {
|
||||
uni.switchTab({
|
||||
url: path
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: path
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* h5中打开app获取跳转app的链接并跳转
|
||||
*/
|
||||
checkArguments() {
|
||||
// #ifdef APP-PLUS
|
||||
setTimeout(() => {
|
||||
const args = plus.runtime.arguments;
|
||||
if (args) {
|
||||
const argsStr = decodeURIComponent(args);
|
||||
const path = argsStr.split('//')[1];
|
||||
if (path.indexOf('tabbar') != -1) {
|
||||
uni.switchTab({
|
||||
url: `/${path}`
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/${path}`
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* #ifndef APP-NVUE */
|
||||
@import 'uview-ui/index.scss';
|
||||
/* #endif */
|
||||
|
||||
// -------适配底部安全区 苹果x系列刘海屏
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
.mp-iphonex-bottom {
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-sizing: content-box;
|
||||
height: auto !important;
|
||||
padding-top: 10rpx;
|
||||
}
|
||||
// #endif
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
body {
|
||||
background-color: $bg-color;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/************************ */
|
||||
.w200 {
|
||||
width: 200rpx !important;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1; //必须父级设置flex
|
||||
}
|
||||
.activate-line {
|
||||
background-color: #ffffff;
|
||||
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
// uni-page-body,
|
||||
// html,
|
||||
// body,
|
||||
// page {
|
||||
// width: 100% ;
|
||||
// height: 100% ;
|
||||
// overflow: hidden;
|
||||
// }
|
||||
</style>
|
||||
|
@ -1,60 +1,60 @@
|
||||
body, div, ul, ol, dt, dd, li, dl, h1, h2, h3, h4, p {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-style:normal;
|
||||
|
||||
/* font:12px/22px"\5B8B\4F53",Arial,Helvetica,sans-serif; */
|
||||
}
|
||||
|
||||
ol, ul, li {
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
img {
|
||||
border:0;
|
||||
vertical-align:middle;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
body{
|
||||
height: 100% important;
|
||||
color:#000;
|
||||
background:#FFF;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear:both;
|
||||
height:1px;
|
||||
width:100%;
|
||||
overflow:hidden;
|
||||
margin-top:-1px;
|
||||
}
|
||||
|
||||
a {
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
input:focus, input:active, textarea:focus, textarea:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.chat-aside {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
width: 360px !important;
|
||||
border-radius: 8px 0 0 8px;
|
||||
z-index: 9999;
|
||||
max-height: calc(100% - 50px);
|
||||
}
|
||||
body, div, ul, ol, dt, dd, li, dl, h1, h2, h3, h4, p {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-style:normal;
|
||||
|
||||
/* font:12px/22px"\5B8B\4F53",Arial,Helvetica,sans-serif; */
|
||||
}
|
||||
|
||||
ol, ul, li {
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
img {
|
||||
border:0;
|
||||
vertical-align:middle;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
body{
|
||||
height: 100% important;
|
||||
color:#000;
|
||||
background:#FFF;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear:both;
|
||||
height:1px;
|
||||
width:100%;
|
||||
overflow:hidden;
|
||||
margin-top:-1px;
|
||||
}
|
||||
|
||||
a {
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
input:focus, input:active, textarea:focus, textarea:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.chat-aside {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
width: 360px !important;
|
||||
border-radius: 8px 0 0 8px;
|
||||
z-index: 9999;
|
||||
max-height: calc(100% - 50px);
|
||||
}
|
||||
|
@ -1,243 +1,243 @@
|
||||
<template>
|
||||
<div :class="['message-input', !isPC && 'message-input-h5']">
|
||||
<div class="audio-main-content-line">
|
||||
<MessageInputAudio
|
||||
v-if="(isWeChat || isApp) && isRenderVoice"
|
||||
:class="{
|
||||
'message-input-wx-audio-open': displayType === 'audio',
|
||||
}"
|
||||
:isEnableAudio="displayType === 'audio'"
|
||||
@changeDisplayType="changeDisplayType"
|
||||
/>
|
||||
<MessageInputEditor
|
||||
v-show="displayType === 'editor'"
|
||||
ref="editor"
|
||||
class="message-input-editor"
|
||||
:placeholder="props.placeholder"
|
||||
:isMuted="props.isMuted"
|
||||
:muteText="props.muteText"
|
||||
:enableInput="props.enableInput"
|
||||
:enableAt="props.enableAt"
|
||||
:enableTyping="props.enableTyping"
|
||||
:isGroup="isGroup"
|
||||
@onTyping="onTyping"
|
||||
@onAt="onAt"
|
||||
@onFocus="onFocus"
|
||||
/>
|
||||
<MessageInputAt
|
||||
v-if="props.enableAt"
|
||||
ref="messageInputAtRef"
|
||||
@insertAt="insertAt"
|
||||
@onAtListOpen="onAtListOpen"
|
||||
/>
|
||||
<Icon
|
||||
v-if="isRenderEmojiPicker"
|
||||
class="icon icon-face"
|
||||
:file="faceIcon"
|
||||
:size="'23px'"
|
||||
:hotAreaSize="'3px'"
|
||||
@onClick="changeToolbarDisplayType('emojiPicker')"
|
||||
/>
|
||||
<Icon
|
||||
v-if="isRenderMore"
|
||||
class="icon icon-more"
|
||||
:file="moreIcon"
|
||||
:size="'23px'"
|
||||
:hotAreaSize="'3px'"
|
||||
@onClick="changeToolbarDisplayType('tools')"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<MessageQuote
|
||||
:style="{minWidth: 0}"
|
||||
:displayType="displayType"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
IMessageModel,
|
||||
IConversationModel,
|
||||
} from '@tencentcloud/chat-uikit-engine';
|
||||
import { ref, watch, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import MessageInputEditor from './message-input-editor.vue';
|
||||
import MessageInputAt from './message-input-at/index.vue';
|
||||
import MessageInputAudio from './message-input-audio.vue';
|
||||
import MessageQuote from './message-input-quote/index.vue';
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import faceIcon from '../../../assets/icon/face-uni.png';
|
||||
import moreIcon from '../../../assets/icon/more-uni.png';
|
||||
import { isPC, isH5, isWeChat, isApp } from '../../../utils/env';
|
||||
import { sendTyping } from '../utils/sendMessage';
|
||||
import { ToolbarDisplayType, InputDisplayType } from '../../../interface';
|
||||
import TUIChatConfig from '../config';
|
||||
|
||||
interface IProps {
|
||||
placeholder: string;
|
||||
isMuted?: boolean;
|
||||
muteText?: string;
|
||||
enableInput?: boolean;
|
||||
enableAt?: boolean;
|
||||
enableTyping?: boolean;
|
||||
replyOrReference?: Record<string, any>;
|
||||
inputToolbarDisplayType: ToolbarDisplayType;
|
||||
}
|
||||
interface IEmits {
|
||||
(e: 'changeToolbarDisplayType', displayType: ToolbarDisplayType): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>();
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
placeholder: 'this is placeholder',
|
||||
replyOrReference: () => ({}),
|
||||
isMuted: true,
|
||||
muteText: '',
|
||||
enableInput: true,
|
||||
enableAt: true,
|
||||
enableTyping: true,
|
||||
inputToolbarDisplayType: 'none',
|
||||
});
|
||||
|
||||
const editor = ref();
|
||||
const messageInputAtRef = ref();
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const isGroup = ref<boolean>(false);
|
||||
const displayType = ref<InputDisplayType>('editor');
|
||||
const featureConfig = TUIChatConfig.getFeatureConfig();
|
||||
const isRenderVoice = ref<boolean>(featureConfig.InputVoice);
|
||||
const isRenderEmojiPicker = ref<boolean>(featureConfig.InputEmoji || featureConfig.InputStickers);
|
||||
const isRenderMore = ref<boolean>(featureConfig.InputImage || featureConfig.InputVideo || featureConfig.InputEvaluation || featureConfig.InputQuickReplies);
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
watch(() => props.inputToolbarDisplayType, (newVal: ToolbarDisplayType) => {
|
||||
if (newVal !== 'none') {
|
||||
changeDisplayType('editor');
|
||||
}
|
||||
});
|
||||
|
||||
function changeDisplayType(display: InputDisplayType) {
|
||||
displayType.value = display;
|
||||
if (display === 'audio') {
|
||||
emits('changeToolbarDisplayType', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
function changeToolbarDisplayType(displayType: ToolbarDisplayType) {
|
||||
emits('changeToolbarDisplayType', displayType);
|
||||
}
|
||||
|
||||
const onTyping = (inputContentEmpty: boolean, inputBlur: boolean) => {
|
||||
sendTyping(inputContentEmpty, inputBlur);
|
||||
};
|
||||
|
||||
const onAt = (show: boolean) => {
|
||||
messageInputAtRef?.value?.toggleAtList(show);
|
||||
};
|
||||
|
||||
const onFocus = () => {
|
||||
// if (isH5) {
|
||||
emits('changeToolbarDisplayType', 'none');
|
||||
// }
|
||||
// 新增隐藏加号控制显示内容的逻辑
|
||||
// emits('changeToolbarDisplayType', 'none');
|
||||
};
|
||||
|
||||
const insertEmoji = (emoji: any) => {
|
||||
editor?.value?.addEmoji && editor?.value?.addEmoji(emoji);
|
||||
};
|
||||
|
||||
const insertAt = (atInfo: any) => {
|
||||
editor?.value?.insertAt && editor?.value?.insertAt(atInfo);
|
||||
};
|
||||
|
||||
const onAtListOpen = () => {
|
||||
editor?.value?.blur && editor?.value?.blur();
|
||||
};
|
||||
|
||||
const reEdit = (content: any) => {
|
||||
editor?.value?.resetEditor();
|
||||
editor?.value?.setEditorContent(content);
|
||||
};
|
||||
|
||||
function onCurrentConversationUpdated(conversation: IConversationModel) {
|
||||
currentConversation.value = conversation;
|
||||
isGroup.value = currentConversation.value?.type === TUIChatEngine.TYPES.CONV_GROUP;
|
||||
}
|
||||
|
||||
function onQuoteMessageUpdated(options?: { message: IMessageModel; type: string }) {
|
||||
// switch text input mode when there is a quote message
|
||||
if (options?.message && options?.type === 'quote') {
|
||||
changeDisplayType('editor');
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
insertEmoji,
|
||||
reEdit,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../../../assets/styles/common";
|
||||
|
||||
:not(not) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
background: #ebf0f6;
|
||||
|
||||
&-h5 {
|
||||
padding: 10px 10px 15px;
|
||||
}
|
||||
|
||||
&-editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
&-wx-audio-open {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.audio-main-content-line {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div :class="['message-input', !isPC && 'message-input-h5']">
|
||||
<div class="audio-main-content-line">
|
||||
<MessageInputAudio
|
||||
v-if="(isWeChat || isApp) && isRenderVoice"
|
||||
:class="{
|
||||
'message-input-wx-audio-open': displayType === 'audio',
|
||||
}"
|
||||
:isEnableAudio="displayType === 'audio'"
|
||||
@changeDisplayType="changeDisplayType"
|
||||
/>
|
||||
<MessageInputEditor
|
||||
v-show="displayType === 'editor'"
|
||||
ref="editor"
|
||||
class="message-input-editor"
|
||||
:placeholder="props.placeholder"
|
||||
:isMuted="props.isMuted"
|
||||
:muteText="props.muteText"
|
||||
:enableInput="props.enableInput"
|
||||
:enableAt="props.enableAt"
|
||||
:enableTyping="props.enableTyping"
|
||||
:isGroup="isGroup"
|
||||
@onTyping="onTyping"
|
||||
@onAt="onAt"
|
||||
@onFocus="onFocus"
|
||||
/>
|
||||
<MessageInputAt
|
||||
v-if="props.enableAt"
|
||||
ref="messageInputAtRef"
|
||||
@insertAt="insertAt"
|
||||
@onAtListOpen="onAtListOpen"
|
||||
/>
|
||||
<Icon
|
||||
v-if="isRenderEmojiPicker"
|
||||
class="icon icon-face"
|
||||
:file="faceIcon"
|
||||
:size="'23px'"
|
||||
:hotAreaSize="'3px'"
|
||||
@onClick="changeToolbarDisplayType('emojiPicker')"
|
||||
/>
|
||||
<Icon
|
||||
v-if="isRenderMore"
|
||||
class="icon icon-more"
|
||||
:file="moreIcon"
|
||||
:size="'23px'"
|
||||
:hotAreaSize="'3px'"
|
||||
@onClick="changeToolbarDisplayType('tools')"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<MessageQuote
|
||||
:style="{minWidth: 0}"
|
||||
:displayType="displayType"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
IMessageModel,
|
||||
IConversationModel,
|
||||
} from '@tencentcloud/chat-uikit-engine';
|
||||
import { ref, watch, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import MessageInputEditor from './message-input-editor.vue';
|
||||
import MessageInputAt from './message-input-at/index.vue';
|
||||
import MessageInputAudio from './message-input-audio.vue';
|
||||
import MessageQuote from './message-input-quote/index.vue';
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import faceIcon from '../../../assets/icon/face-uni.png';
|
||||
import moreIcon from '../../../assets/icon/more-uni.png';
|
||||
import { isPC, isH5, isWeChat, isApp } from '../../../utils/env';
|
||||
import { sendTyping } from '../utils/sendMessage';
|
||||
import { ToolbarDisplayType, InputDisplayType } from '../../../interface';
|
||||
import TUIChatConfig from '../config';
|
||||
|
||||
interface IProps {
|
||||
placeholder: string;
|
||||
isMuted?: boolean;
|
||||
muteText?: string;
|
||||
enableInput?: boolean;
|
||||
enableAt?: boolean;
|
||||
enableTyping?: boolean;
|
||||
replyOrReference?: Record<string, any>;
|
||||
inputToolbarDisplayType: ToolbarDisplayType;
|
||||
}
|
||||
interface IEmits {
|
||||
(e: 'changeToolbarDisplayType', displayType: ToolbarDisplayType): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>();
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
placeholder: 'this is placeholder',
|
||||
replyOrReference: () => ({}),
|
||||
isMuted: true,
|
||||
muteText: '',
|
||||
enableInput: true,
|
||||
enableAt: true,
|
||||
enableTyping: true,
|
||||
inputToolbarDisplayType: 'none',
|
||||
});
|
||||
|
||||
const editor = ref();
|
||||
const messageInputAtRef = ref();
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const isGroup = ref<boolean>(false);
|
||||
const displayType = ref<InputDisplayType>('editor');
|
||||
const featureConfig = TUIChatConfig.getFeatureConfig();
|
||||
const isRenderVoice = ref<boolean>(featureConfig.InputVoice);
|
||||
const isRenderEmojiPicker = ref<boolean>(featureConfig.InputEmoji || featureConfig.InputStickers);
|
||||
const isRenderMore = ref<boolean>(featureConfig.InputImage || featureConfig.InputVideo || featureConfig.InputEvaluation || featureConfig.InputQuickReplies);
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
watch(() => props.inputToolbarDisplayType, (newVal: ToolbarDisplayType) => {
|
||||
if (newVal !== 'none') {
|
||||
changeDisplayType('editor');
|
||||
}
|
||||
});
|
||||
|
||||
function changeDisplayType(display: InputDisplayType) {
|
||||
displayType.value = display;
|
||||
if (display === 'audio') {
|
||||
emits('changeToolbarDisplayType', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
function changeToolbarDisplayType(displayType: ToolbarDisplayType) {
|
||||
emits('changeToolbarDisplayType', displayType);
|
||||
}
|
||||
|
||||
const onTyping = (inputContentEmpty: boolean, inputBlur: boolean) => {
|
||||
sendTyping(inputContentEmpty, inputBlur);
|
||||
};
|
||||
|
||||
const onAt = (show: boolean) => {
|
||||
messageInputAtRef?.value?.toggleAtList(show);
|
||||
};
|
||||
|
||||
const onFocus = () => {
|
||||
// if (isH5) {
|
||||
emits('changeToolbarDisplayType', 'none');
|
||||
// }
|
||||
// 新增隐藏加号控制显示内容的逻辑
|
||||
// emits('changeToolbarDisplayType', 'none');
|
||||
};
|
||||
|
||||
const insertEmoji = (emoji: any) => {
|
||||
editor?.value?.addEmoji && editor?.value?.addEmoji(emoji);
|
||||
};
|
||||
|
||||
const insertAt = (atInfo: any) => {
|
||||
editor?.value?.insertAt && editor?.value?.insertAt(atInfo);
|
||||
};
|
||||
|
||||
const onAtListOpen = () => {
|
||||
editor?.value?.blur && editor?.value?.blur();
|
||||
};
|
||||
|
||||
const reEdit = (content: any) => {
|
||||
editor?.value?.resetEditor();
|
||||
editor?.value?.setEditorContent(content);
|
||||
};
|
||||
|
||||
function onCurrentConversationUpdated(conversation: IConversationModel) {
|
||||
currentConversation.value = conversation;
|
||||
isGroup.value = currentConversation.value?.type === TUIChatEngine.TYPES.CONV_GROUP;
|
||||
}
|
||||
|
||||
function onQuoteMessageUpdated(options?: { message: IMessageModel; type: string }) {
|
||||
// switch text input mode when there is a quote message
|
||||
if (options?.message && options?.type === 'quote') {
|
||||
changeDisplayType('editor');
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
insertEmoji,
|
||||
reEdit,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../../../assets/styles/common";
|
||||
|
||||
:not(not) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
background: #ebf0f6;
|
||||
|
||||
&-h5 {
|
||||
padding: 10px 10px 15px;
|
||||
}
|
||||
|
||||
&-editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
&-wx-audio-open {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.audio-main-content-line {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,285 +1,285 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'message-input-container': true,
|
||||
'message-input-container-h5': !isPC,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="props.isMuted"
|
||||
class="message-input-mute"
|
||||
>
|
||||
{{ props.muteText }}
|
||||
</div>
|
||||
<input
|
||||
id="editor"
|
||||
ref="inputRef"
|
||||
v-model="inputText"
|
||||
:adjust-position="true"
|
||||
cursor-spacing="20"
|
||||
confirm-type="send"
|
||||
:confirm-hold="true"
|
||||
maxlength="140"
|
||||
type="text"
|
||||
placeholder-class="input-placeholder"
|
||||
class="message-input-area"
|
||||
:placeholder="props.placeholder"
|
||||
auto-blur
|
||||
@confirm="handleSendMessage"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@focus="onFocus"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import { TUIStore, StoreName, IConversationModel, IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import DraftManager from '../utils/conversationDraft';
|
||||
import { transformTextWithEmojiNamesToKeys } from '../emoji-config';
|
||||
import { isPC } from '../../../utils/env';
|
||||
import { sendMessages } from '../utils/sendMessage';
|
||||
import { ISendMessagePayload } from '../../../interface';
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: 'this is placeholder',
|
||||
},
|
||||
replayOrReferenceMessage: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
required: false,
|
||||
},
|
||||
isMuted: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
muteText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
enableInput: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
enableAt: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
enableTyping: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['onTyping', 'onFocus', 'onAt']);
|
||||
const inputText = ref('');
|
||||
const inputRef = ref();
|
||||
const inputBlur = ref(true);
|
||||
const inputContentEmpty = ref(true);
|
||||
const allInsertedAtInfo = new Map();
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const currentConversationID = ref<string>('');
|
||||
const currentQuoteMessage = ref<{ message: IMessageModel; type: string }>();
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
|
||||
uni.$on('insert-emoji', (data) => {
|
||||
inputText.value += data?.emoji?.name;
|
||||
});
|
||||
|
||||
uni.$on('send-message-in-emoji-picker', () => {
|
||||
handleSendMessage();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (currentConversationID.value) {
|
||||
DraftManager.setStore(currentConversationID.value, inputText.value, inputText.value, currentQuoteMessage.value);
|
||||
}
|
||||
|
||||
uni.$off('insertEmoji');
|
||||
uni.$off('send-message-in-emoji-picker');
|
||||
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
|
||||
reset();
|
||||
});
|
||||
|
||||
const handleSendMessage = () => {
|
||||
const messageList = getEditorContent();
|
||||
resetEditor();
|
||||
sendMessages(messageList as any, currentConversation.value!);
|
||||
};
|
||||
|
||||
const insertAt = (atInfo: any) => {
|
||||
if (!allInsertedAtInfo?.has(atInfo?.id)) {
|
||||
allInsertedAtInfo?.set(atInfo?.id, atInfo?.label);
|
||||
}
|
||||
inputText.value += atInfo?.label;
|
||||
};
|
||||
|
||||
const getEditorContent = () => {
|
||||
let text = inputText.value;
|
||||
text = transformTextWithEmojiNamesToKeys(text);
|
||||
const atUserList: string[] = [];
|
||||
allInsertedAtInfo?.forEach((value: string, key: string) => {
|
||||
if (text?.includes('@' + value)) {
|
||||
atUserList.push(key);
|
||||
}
|
||||
});
|
||||
const payload: ISendMessagePayload = {
|
||||
text,
|
||||
};
|
||||
if (atUserList?.length) {
|
||||
payload.atUserList = atUserList;
|
||||
}
|
||||
return [
|
||||
{
|
||||
type: 'text',
|
||||
payload,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const resetEditor = () => {
|
||||
inputText.value = '';
|
||||
inputContentEmpty.value = true;
|
||||
allInsertedAtInfo?.clear();
|
||||
};
|
||||
|
||||
const setEditorContent = (content: any) => {
|
||||
inputText.value = content;
|
||||
};
|
||||
|
||||
const onBlur = () => {
|
||||
inputBlur.value = true;
|
||||
};
|
||||
|
||||
const onFocus = (e: any) => {
|
||||
inputBlur.value = false;
|
||||
emits('onFocus', e?.detail?.height);
|
||||
};
|
||||
|
||||
const isEditorContentEmpty = () => {
|
||||
inputContentEmpty.value = inputText?.value?.length ? false : true;
|
||||
};
|
||||
|
||||
const onInput = (e: any) => {
|
||||
// uni-app recognizes mention messages
|
||||
const text = e?.detail?.value;
|
||||
isEditorContentEmpty();
|
||||
if (props.isGroup && (text.endsWith('@') || text.endsWith('@\n'))) {
|
||||
// TUIGlobal?.hideKeyboard();
|
||||
emits('onAt', true);
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [inputContentEmpty.value, inputBlur.value],
|
||||
(newVal: any, oldVal: any) => {
|
||||
if (newVal !== oldVal) {
|
||||
emits('onTyping', inputContentEmpty.value, inputBlur.value);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
function onCurrentConversationUpdated(conversation: IConversationModel) {
|
||||
const prevConversationID = currentConversationID.value;
|
||||
currentConversation.value = conversation;
|
||||
currentConversationID.value = conversation?.conversationID;
|
||||
if (prevConversationID !== currentConversationID.value) {
|
||||
if (prevConversationID) {
|
||||
DraftManager.setStore(
|
||||
prevConversationID,
|
||||
inputText.value,
|
||||
inputText.value,
|
||||
currentQuoteMessage.value,
|
||||
);
|
||||
}
|
||||
resetEditor();
|
||||
if (currentConversationID.value) {
|
||||
DraftManager.getStore(currentConversationID.value, setEditorContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onQuoteMessageUpdated(options?: { message: IMessageModel; type: string }) {
|
||||
currentQuoteMessage.value = options;
|
||||
}
|
||||
|
||||
function reset() {
|
||||
inputBlur.value = true;
|
||||
currentConversation.value = null;
|
||||
currentConversationID.value = '';
|
||||
currentQuoteMessage.value = null;
|
||||
resetEditor();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
insertAt,
|
||||
resetEditor,
|
||||
setEditorContent,
|
||||
getEditorContent,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../../assets/styles/common";
|
||||
|
||||
.message-input-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 3px 10px 10px;
|
||||
overflow: hidden;
|
||||
|
||||
&-h5 {
|
||||
flex: 1;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 7px 0 7px 10px;
|
||||
font-size: 16px !important;
|
||||
max-height: 86px;
|
||||
}
|
||||
|
||||
.message-input-mute {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message-input-area {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
min-height: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'message-input-container': true,
|
||||
'message-input-container-h5': !isPC,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="props.isMuted"
|
||||
class="message-input-mute"
|
||||
>
|
||||
{{ props.muteText }}
|
||||
</div>
|
||||
<input
|
||||
id="editor"
|
||||
ref="inputRef"
|
||||
v-model="inputText"
|
||||
:adjust-position="true"
|
||||
cursor-spacing="20"
|
||||
confirm-type="send"
|
||||
:confirm-hold="true"
|
||||
maxlength="140"
|
||||
type="text"
|
||||
placeholder-class="input-placeholder"
|
||||
class="message-input-area"
|
||||
:placeholder="props.placeholder"
|
||||
auto-blur
|
||||
@confirm="handleSendMessage"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@focus="onFocus"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import { TUIStore, StoreName, IConversationModel, IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import DraftManager from '../utils/conversationDraft';
|
||||
import { transformTextWithEmojiNamesToKeys } from '../emoji-config';
|
||||
import { isPC } from '../../../utils/env';
|
||||
import { sendMessages } from '../utils/sendMessage';
|
||||
import { ISendMessagePayload } from '../../../interface';
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: 'this is placeholder',
|
||||
},
|
||||
replayOrReferenceMessage: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
required: false,
|
||||
},
|
||||
isMuted: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
muteText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
enableInput: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
enableAt: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
enableTyping: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['onTyping', 'onFocus', 'onAt']);
|
||||
const inputText = ref('');
|
||||
const inputRef = ref();
|
||||
const inputBlur = ref(true);
|
||||
const inputContentEmpty = ref(true);
|
||||
const allInsertedAtInfo = new Map();
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const currentConversationID = ref<string>('');
|
||||
const currentQuoteMessage = ref<{ message: IMessageModel; type: string }>();
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
|
||||
uni.$on('insert-emoji', (data) => {
|
||||
inputText.value += data?.emoji?.name;
|
||||
});
|
||||
|
||||
uni.$on('send-message-in-emoji-picker', () => {
|
||||
handleSendMessage();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (currentConversationID.value) {
|
||||
DraftManager.setStore(currentConversationID.value, inputText.value, inputText.value, currentQuoteMessage.value);
|
||||
}
|
||||
|
||||
uni.$off('insertEmoji');
|
||||
uni.$off('send-message-in-emoji-picker');
|
||||
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
quoteMessage: onQuoteMessageUpdated,
|
||||
});
|
||||
|
||||
reset();
|
||||
});
|
||||
|
||||
const handleSendMessage = () => {
|
||||
const messageList = getEditorContent();
|
||||
resetEditor();
|
||||
sendMessages(messageList as any, currentConversation.value!);
|
||||
};
|
||||
|
||||
const insertAt = (atInfo: any) => {
|
||||
if (!allInsertedAtInfo?.has(atInfo?.id)) {
|
||||
allInsertedAtInfo?.set(atInfo?.id, atInfo?.label);
|
||||
}
|
||||
inputText.value += atInfo?.label;
|
||||
};
|
||||
|
||||
const getEditorContent = () => {
|
||||
let text = inputText.value;
|
||||
text = transformTextWithEmojiNamesToKeys(text);
|
||||
const atUserList: string[] = [];
|
||||
allInsertedAtInfo?.forEach((value: string, key: string) => {
|
||||
if (text?.includes('@' + value)) {
|
||||
atUserList.push(key);
|
||||
}
|
||||
});
|
||||
const payload: ISendMessagePayload = {
|
||||
text,
|
||||
};
|
||||
if (atUserList?.length) {
|
||||
payload.atUserList = atUserList;
|
||||
}
|
||||
return [
|
||||
{
|
||||
type: 'text',
|
||||
payload,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const resetEditor = () => {
|
||||
inputText.value = '';
|
||||
inputContentEmpty.value = true;
|
||||
allInsertedAtInfo?.clear();
|
||||
};
|
||||
|
||||
const setEditorContent = (content: any) => {
|
||||
inputText.value = content;
|
||||
};
|
||||
|
||||
const onBlur = () => {
|
||||
inputBlur.value = true;
|
||||
};
|
||||
|
||||
const onFocus = (e: any) => {
|
||||
inputBlur.value = false;
|
||||
emits('onFocus', e?.detail?.height);
|
||||
};
|
||||
|
||||
const isEditorContentEmpty = () => {
|
||||
inputContentEmpty.value = inputText?.value?.length ? false : true;
|
||||
};
|
||||
|
||||
const onInput = (e: any) => {
|
||||
// uni-app recognizes mention messages
|
||||
const text = e?.detail?.value;
|
||||
isEditorContentEmpty();
|
||||
if (props.isGroup && (text.endsWith('@') || text.endsWith('@\n'))) {
|
||||
// TUIGlobal?.hideKeyboard();
|
||||
emits('onAt', true);
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [inputContentEmpty.value, inputBlur.value],
|
||||
(newVal: any, oldVal: any) => {
|
||||
if (newVal !== oldVal) {
|
||||
emits('onTyping', inputContentEmpty.value, inputBlur.value);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
function onCurrentConversationUpdated(conversation: IConversationModel) {
|
||||
const prevConversationID = currentConversationID.value;
|
||||
currentConversation.value = conversation;
|
||||
currentConversationID.value = conversation?.conversationID;
|
||||
if (prevConversationID !== currentConversationID.value) {
|
||||
if (prevConversationID) {
|
||||
DraftManager.setStore(
|
||||
prevConversationID,
|
||||
inputText.value,
|
||||
inputText.value,
|
||||
currentQuoteMessage.value,
|
||||
);
|
||||
}
|
||||
resetEditor();
|
||||
if (currentConversationID.value) {
|
||||
DraftManager.getStore(currentConversationID.value, setEditorContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onQuoteMessageUpdated(options?: { message: IMessageModel; type: string }) {
|
||||
currentQuoteMessage.value = options;
|
||||
}
|
||||
|
||||
function reset() {
|
||||
inputBlur.value = true;
|
||||
currentConversation.value = null;
|
||||
currentConversationID.value = '';
|
||||
currentQuoteMessage.value = null;
|
||||
resetEditor();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
insertAt,
|
||||
resetEditor,
|
||||
setEditorContent,
|
||||
getEditorContent,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../../assets/styles/common";
|
||||
|
||||
.message-input-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 3px 10px 10px;
|
||||
overflow: hidden;
|
||||
|
||||
&-h5 {
|
||||
flex: 1;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 7px 0 7px 10px;
|
||||
font-size: 16px !important;
|
||||
max-height: 86px;
|
||||
}
|
||||
|
||||
.message-input-mute {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message-input-area {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
min-height: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,430 +1,430 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{height: '100%'}"
|
||||
v-if="typeof contactInfoData === 'object' && Object.keys(contactInfoData).length"
|
||||
:class="['tui-contact-info', !isPC && 'tui-contact-info-h5']"
|
||||
>
|
||||
<div
|
||||
v-if="!isPC"
|
||||
:class="[
|
||||
'tui-contact-info-header',
|
||||
!isPC && 'tui-contact-info-h5-header',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-header-icon',
|
||||
!isPC && 'tui-contact-info-h5-header-icon',
|
||||
]"
|
||||
@click="resetContactSearchingUIData"
|
||||
>
|
||||
<Icon :file="backSVG" />
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-header-title',
|
||||
!isPC && 'tui-contact-info-h5-header-title',
|
||||
]"
|
||||
>
|
||||
{{ TUITranslateService.t("TUIContact.添加好友/群聊") }}
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['tui-contact-info-basic', !isPC && 'tui-contact-info-h5-basic']">
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-basic-text',
|
||||
!isPC && 'tui-contact-info-h5-basic-text',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-basic-text-name',
|
||||
!isPC && 'tui-contact-info-h5-basic-text-name',
|
||||
]"
|
||||
>
|
||||
{{ generateContactInfoName(contactInfoData) }}
|
||||
</div>
|
||||
<div
|
||||
v-for="item in contactInfoBasicList"
|
||||
:key="item.label"
|
||||
:class="[
|
||||
'tui-contact-info-basic-text-other',
|
||||
!isPC && 'tui-contact-info-h5-basic-text-other',
|
||||
]"
|
||||
>
|
||||
{{
|
||||
`${TUITranslateService.t(`TUIContact.${item.label}`)}:
|
||||
${item.data}`
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
:class="[
|
||||
'tui-contact-info-basic-avatar',
|
||||
!isPC && 'tui-contact-info-h5-basic-avatar',
|
||||
]"
|
||||
:src="generateAvatar(contactInfoData)"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
v-if="contactInfoMoreList[0]"
|
||||
:class="['tui-contact-info-more', !isPC && 'tui-contact-info-h5-more']"
|
||||
>
|
||||
<div
|
||||
v-for="item in contactInfoMoreList"
|
||||
:key="item.key"
|
||||
:class="[
|
||||
'tui-contact-info-more-item',
|
||||
!isPC && 'tui-contact-info-h5-more-item',
|
||||
item.labelPosition === CONTACT_INFO_LABEL_POSITION.TOP
|
||||
? 'tui-contact-info-more-item-top'
|
||||
: 'tui-contact-info-more-item-left',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-label',
|
||||
!isPC && 'tui-contact-info-h5-more-item-label',
|
||||
]"
|
||||
>
|
||||
{{ `${TUITranslateService.t(`TUIContact.${item.label}`)}` }}
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
v-if="!item.editing"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text-data',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text-data',
|
||||
]"
|
||||
>
|
||||
{{ item.data }}
|
||||
</div>
|
||||
<div
|
||||
v-if="item.editable"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text-icon',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text-icon',
|
||||
]"
|
||||
@click="setEditing(item)"
|
||||
>
|
||||
<Icon
|
||||
:file="editSVG"
|
||||
width="14px"
|
||||
height="14px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.INPUT"
|
||||
v-model="item.data"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-input',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-input',
|
||||
]"
|
||||
type="text"
|
||||
@confirm="onContactInfoEmitSubmit(item)"
|
||||
@keyup.enter="onContactInfoEmitSubmit(item)"
|
||||
>
|
||||
<textarea
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.TEXTAREA"
|
||||
v-model="item.data"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-textarea',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-textarea',
|
||||
]"
|
||||
confirm-type="done"
|
||||
/>
|
||||
<div
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.SWITCH"
|
||||
@click="onContactInfoEmitSubmit(item)"
|
||||
>
|
||||
<SwitchBar :value="item.data" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-button',
|
||||
!isPC && 'tui-contact-info-h5-button',
|
||||
]"
|
||||
>
|
||||
<button
|
||||
v-for="item in contactInfoButtonList"
|
||||
:key="item.key"
|
||||
:class="[
|
||||
'tui-contact-info-button-item',
|
||||
!isPC && 'tui-contact-info-h5-button-item',
|
||||
item.type === CONTACT_INFO_BUTTON_TYPE.CANCEL
|
||||
? `tui-contact-info-button-item-cancel`
|
||||
: `tui-contact-info-button-item-submit`,
|
||||
]"
|
||||
@click="onContactInfoButtonClicked(item)"
|
||||
>
|
||||
{{ TUITranslateService.t(`TUIContact.${item.label}`) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
TUITranslateService,
|
||||
IGroupModel,
|
||||
Friend,
|
||||
FriendApplication,
|
||||
} from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, computed, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import { isPC } from '../../../utils/env';
|
||||
|
||||
import {
|
||||
generateAvatar,
|
||||
generateContactInfoName,
|
||||
generateContactInfoBasic,
|
||||
isFriend,
|
||||
isApplicationType,
|
||||
} from '../utils/index';
|
||||
import {
|
||||
contactMoreInfoConfig,
|
||||
contactButtonConfig,
|
||||
} from './contact-info-config';
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import editSVG from '../../../assets/icon/edit.svg';
|
||||
import backSVG from '../../../assets/icon/back.svg';
|
||||
import SwitchBar from '../../common/SwitchBar/index.vue';
|
||||
import {
|
||||
IBlackListUserItem,
|
||||
IContactInfoMoreItem,
|
||||
IContactInfoButton,
|
||||
} from '../../../interface';
|
||||
import {
|
||||
CONTACT_INFO_LABEL_POSITION,
|
||||
CONTACT_INFO_MORE_EDIT_TYPE,
|
||||
CONTACT_INFO_BUTTON_TYPE,
|
||||
} from '../../../constant';
|
||||
import { deepCopy } from '../../TUIChat/utils/utils';
|
||||
|
||||
type IContactInfoType = IGroupModel | Friend | FriendApplication | IBlackListUserItem;
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
|
||||
const contactInfoData = ref<IContactInfoType>({} as IContactInfoType);
|
||||
const contactInfoBasicList = ref<Array<{ label: string; data: string }>>([]);
|
||||
const contactInfoMoreList = ref<IContactInfoMoreItem[]>([]);
|
||||
const contactInfoButtonList = ref<IContactInfoButton[]>([]);
|
||||
|
||||
const setEditing = (item: any) => {
|
||||
item.editing = true;
|
||||
};
|
||||
|
||||
const isGroup = computed((): boolean =>
|
||||
(contactInfoData.value as IGroupModel)?.groupID ? true : false,
|
||||
);
|
||||
|
||||
const isApplication = computed((): boolean => {
|
||||
return isApplicationType(contactInfoData?.value);
|
||||
});
|
||||
|
||||
// is both friend, if is group type always false
|
||||
const isBothFriend = ref<boolean>(false);
|
||||
|
||||
// is group member, including ordinary member, admin, group owner
|
||||
const isGroupMember = computed((): boolean => {
|
||||
return (contactInfoData.value as IGroupModel)?.selfInfo?.userID ? true : false;
|
||||
});
|
||||
|
||||
// is in black list, if is group type always false
|
||||
const isInBlackList = computed((): boolean => {
|
||||
return (
|
||||
!isGroup.value
|
||||
&& blackList.value?.findIndex(
|
||||
(item: IBlackListUserItem) =>
|
||||
item?.userID === (contactInfoData.value as IBlackListUserItem)?.userID,
|
||||
) >= 0
|
||||
);
|
||||
});
|
||||
|
||||
const blackList = ref<IBlackListUserItem[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
currentContactInfo: onCurrentContactInfoUpdated,
|
||||
});
|
||||
TUIStore.watch(StoreName.USER, {
|
||||
userBlacklist: onUserBlacklistUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CUSTOM, {
|
||||
currentContactInfo: onCurrentContactInfoUpdated,
|
||||
});
|
||||
TUIStore.unwatch(StoreName.USER, {
|
||||
userBlacklist: onUserBlacklistUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
const resetContactInfoUIData = () => {
|
||||
contactInfoData.value = {} as IContactInfoType;
|
||||
contactInfoBasicList.value = [];
|
||||
contactInfoMoreList.value = [];
|
||||
contactInfoButtonList.value = [];
|
||||
};
|
||||
|
||||
const resetContactSearchingUIData = () => {
|
||||
TUIStore.update(StoreName.CUSTOM, 'currentContactInfo', {});
|
||||
TUIStore.update(StoreName.CUSTOM, 'currentContactSearchingStatus', false);
|
||||
TUIGlobal?.closeSearching && TUIGlobal?.closeSearching();
|
||||
};
|
||||
|
||||
const onContactInfoEmitSubmit = (item: any) => {
|
||||
item.editSubmitHandler
|
||||
&& item.editSubmitHandler({
|
||||
item,
|
||||
contactInfoData: contactInfoData.value,
|
||||
isBothFriend: isBothFriend.value,
|
||||
isInBlackList: isInBlackList.value,
|
||||
});
|
||||
};
|
||||
|
||||
const onContactInfoButtonClicked = (item: any) => {
|
||||
item.onClick
|
||||
&& item.onClick({
|
||||
contactInfoData: contactInfoData.value,
|
||||
contactInfoMoreList: contactInfoMoreList.value,
|
||||
});
|
||||
if (
|
||||
item.key === 'enterGroupConversation'
|
||||
|| item.key === 'enterC2CConversation'
|
||||
) {
|
||||
emits('switchConversation', contactInfoData.value);
|
||||
resetContactSearchingUIData();
|
||||
}
|
||||
};
|
||||
|
||||
const generateMoreInfo = async () => {
|
||||
if (!isApplication.value) {
|
||||
if (
|
||||
(!isGroup.value && !isBothFriend.value && !isInBlackList.value)
|
||||
|| (isGroup.value
|
||||
&& !isGroupMember.value
|
||||
&& (contactInfoData.value as IGroupModel)?.type !== TUIChatEngine?.TYPES?.GRP_AVCHATROOM)
|
||||
) {
|
||||
contactMoreInfoConfig.setWords.data = '';
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.setWords);
|
||||
}
|
||||
if (!isGroup.value && !isInBlackList.value) {
|
||||
contactMoreInfoConfig.setRemark.data
|
||||
= (contactInfoData.value as Friend)?.remark || '';
|
||||
contactMoreInfoConfig.setRemark.editing = false;
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.setRemark);
|
||||
}
|
||||
if (!isGroup.value && (isBothFriend.value || isInBlackList.value)) {
|
||||
contactMoreInfoConfig.blackList.data = isInBlackList.value || false;
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.blackList);
|
||||
}
|
||||
} else {
|
||||
contactMoreInfoConfig.displayWords.data
|
||||
= (contactInfoData.value as FriendApplication)?.wording || '';
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.displayWords);
|
||||
}
|
||||
};
|
||||
|
||||
const generateButton = () => {
|
||||
if (isInBlackList.value) {
|
||||
return;
|
||||
}
|
||||
if (isApplication.value) {
|
||||
if (
|
||||
(contactInfoData.value as FriendApplication)?.type
|
||||
=== TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_TO_ME
|
||||
) {
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.refuseFriendApplication,
|
||||
);
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.acceptFriendApplication,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (isGroup.value && isGroupMember.value) {
|
||||
switch ((contactInfoData.value as IGroupModel)?.selfInfo?.role) {
|
||||
case 'Owner':
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.dismissGroup);
|
||||
break;
|
||||
default:
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.quitGroup);
|
||||
break;
|
||||
}
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.enterGroupConversation,
|
||||
);
|
||||
} else if (!isGroup.value && isBothFriend.value) {
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.deleteFriend);
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.enterC2CConversation,
|
||||
);
|
||||
} else {
|
||||
if (isGroup.value) {
|
||||
contactInfoButtonList?.value?.push(
|
||||
(contactInfoData.value as IGroupModel)?.type === TUIChatEngine?.TYPES?.GRP_AVCHATROOM
|
||||
? contactButtonConfig.joinAVChatGroup
|
||||
: contactButtonConfig.joinGroup,
|
||||
);
|
||||
} else {
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.addFriend);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onUserBlacklistUpdated(userBlacklist: IBlackListUserItem[]) {
|
||||
blackList.value = userBlacklist;
|
||||
}
|
||||
|
||||
async function onCurrentContactInfoUpdated(contactInfo: IContactInfoType) {
|
||||
if (
|
||||
contactInfoData.value
|
||||
&& contactInfo
|
||||
&& JSON.stringify(contactInfoData.value) === JSON.stringify(contactInfo)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
resetContactInfoUIData();
|
||||
// deep clone
|
||||
contactInfoData.value = deepCopy(contactInfo) || {};
|
||||
if (!contactInfoData.value || Object.keys(contactInfoData.value)?.length === 0) {
|
||||
return;
|
||||
}
|
||||
contactInfoBasicList.value = generateContactInfoBasic(
|
||||
contactInfoData.value,
|
||||
);
|
||||
isBothFriend.value = await isFriend(contactInfoData.value);
|
||||
generateMoreInfo();
|
||||
generateButton();
|
||||
if (contactInfo.infoKeyList) {
|
||||
contactInfoMoreList.value = contactInfo.infoKeyList.map((key: string) => {
|
||||
return (contactMoreInfoConfig as any)[key];
|
||||
});
|
||||
}
|
||||
if (contactInfo.btnKeyList) {
|
||||
contactInfoButtonList.value = contactInfo.btnKeyList.map((key: string) => {
|
||||
return (contactButtonConfig as any)[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped src="./style/index.scss"></style>
|
||||
<template>
|
||||
<div
|
||||
:style="{height: '100%'}"
|
||||
v-if="typeof contactInfoData === 'object' && Object.keys(contactInfoData).length"
|
||||
:class="['tui-contact-info', !isPC && 'tui-contact-info-h5']"
|
||||
>
|
||||
<div
|
||||
v-if="!isPC"
|
||||
:class="[
|
||||
'tui-contact-info-header',
|
||||
!isPC && 'tui-contact-info-h5-header',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-header-icon',
|
||||
!isPC && 'tui-contact-info-h5-header-icon',
|
||||
]"
|
||||
@click="resetContactSearchingUIData"
|
||||
>
|
||||
<Icon :file="backSVG" />
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-header-title',
|
||||
!isPC && 'tui-contact-info-h5-header-title',
|
||||
]"
|
||||
>
|
||||
{{ TUITranslateService.t("TUIContact.添加好友/群聊") }}
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['tui-contact-info-basic', !isPC && 'tui-contact-info-h5-basic']">
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-basic-text',
|
||||
!isPC && 'tui-contact-info-h5-basic-text',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-basic-text-name',
|
||||
!isPC && 'tui-contact-info-h5-basic-text-name',
|
||||
]"
|
||||
>
|
||||
{{ generateContactInfoName(contactInfoData) }}
|
||||
</div>
|
||||
<div
|
||||
v-for="item in contactInfoBasicList"
|
||||
:key="item.label"
|
||||
:class="[
|
||||
'tui-contact-info-basic-text-other',
|
||||
!isPC && 'tui-contact-info-h5-basic-text-other',
|
||||
]"
|
||||
>
|
||||
{{
|
||||
`${TUITranslateService.t(`TUIContact.${item.label}`)}:
|
||||
${item.data}`
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
:class="[
|
||||
'tui-contact-info-basic-avatar',
|
||||
!isPC && 'tui-contact-info-h5-basic-avatar',
|
||||
]"
|
||||
:src="generateAvatar(contactInfoData)"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
v-if="contactInfoMoreList[0]"
|
||||
:class="['tui-contact-info-more', !isPC && 'tui-contact-info-h5-more']"
|
||||
>
|
||||
<div
|
||||
v-for="item in contactInfoMoreList"
|
||||
:key="item.key"
|
||||
:class="[
|
||||
'tui-contact-info-more-item',
|
||||
!isPC && 'tui-contact-info-h5-more-item',
|
||||
item.labelPosition === CONTACT_INFO_LABEL_POSITION.TOP
|
||||
? 'tui-contact-info-more-item-top'
|
||||
: 'tui-contact-info-more-item-left',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-label',
|
||||
!isPC && 'tui-contact-info-h5-more-item-label',
|
||||
]"
|
||||
>
|
||||
{{ `${TUITranslateService.t(`TUIContact.${item.label}`)}` }}
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
v-if="!item.editing"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text-data',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text-data',
|
||||
]"
|
||||
>
|
||||
{{ item.data }}
|
||||
</div>
|
||||
<div
|
||||
v-if="item.editable"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-text-icon',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-text-icon',
|
||||
]"
|
||||
@click="setEditing(item)"
|
||||
>
|
||||
<Icon
|
||||
:file="editSVG"
|
||||
width="14px"
|
||||
height="14px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.INPUT"
|
||||
v-model="item.data"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-input',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-input',
|
||||
]"
|
||||
type="text"
|
||||
@confirm="onContactInfoEmitSubmit(item)"
|
||||
@keyup.enter="onContactInfoEmitSubmit(item)"
|
||||
>
|
||||
<textarea
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.TEXTAREA"
|
||||
v-model="item.data"
|
||||
:class="[
|
||||
'tui-contact-info-more-item-content-textarea',
|
||||
!isPC && 'tui-contact-info-h5-more-item-content-textarea',
|
||||
]"
|
||||
confirm-type="done"
|
||||
/>
|
||||
<div
|
||||
v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.SWITCH"
|
||||
@click="onContactInfoEmitSubmit(item)"
|
||||
>
|
||||
<SwitchBar :value="item.data" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="[
|
||||
'tui-contact-info-button',
|
||||
!isPC && 'tui-contact-info-h5-button',
|
||||
]"
|
||||
>
|
||||
<button
|
||||
v-for="item in contactInfoButtonList"
|
||||
:key="item.key"
|
||||
:class="[
|
||||
'tui-contact-info-button-item',
|
||||
!isPC && 'tui-contact-info-h5-button-item',
|
||||
item.type === CONTACT_INFO_BUTTON_TYPE.CANCEL
|
||||
? `tui-contact-info-button-item-cancel`
|
||||
: `tui-contact-info-button-item-submit`,
|
||||
]"
|
||||
@click="onContactInfoButtonClicked(item)"
|
||||
>
|
||||
{{ TUITranslateService.t(`TUIContact.${item.label}`) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
TUITranslateService,
|
||||
IGroupModel,
|
||||
Friend,
|
||||
FriendApplication,
|
||||
} from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, computed, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import { isPC } from '../../../utils/env';
|
||||
|
||||
import {
|
||||
generateAvatar,
|
||||
generateContactInfoName,
|
||||
generateContactInfoBasic,
|
||||
isFriend,
|
||||
isApplicationType,
|
||||
} from '../utils/index';
|
||||
import {
|
||||
contactMoreInfoConfig,
|
||||
contactButtonConfig,
|
||||
} from './contact-info-config';
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import editSVG from '../../../assets/icon/edit.svg';
|
||||
import backSVG from '../../../assets/icon/back.svg';
|
||||
import SwitchBar from '../../common/SwitchBar/index.vue';
|
||||
import {
|
||||
IBlackListUserItem,
|
||||
IContactInfoMoreItem,
|
||||
IContactInfoButton,
|
||||
} from '../../../interface';
|
||||
import {
|
||||
CONTACT_INFO_LABEL_POSITION,
|
||||
CONTACT_INFO_MORE_EDIT_TYPE,
|
||||
CONTACT_INFO_BUTTON_TYPE,
|
||||
} from '../../../constant';
|
||||
import { deepCopy } from '../../TUIChat/utils/utils';
|
||||
|
||||
type IContactInfoType = IGroupModel | Friend | FriendApplication | IBlackListUserItem;
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
|
||||
const contactInfoData = ref<IContactInfoType>({} as IContactInfoType);
|
||||
const contactInfoBasicList = ref<Array<{ label: string; data: string }>>([]);
|
||||
const contactInfoMoreList = ref<IContactInfoMoreItem[]>([]);
|
||||
const contactInfoButtonList = ref<IContactInfoButton[]>([]);
|
||||
|
||||
const setEditing = (item: any) => {
|
||||
item.editing = true;
|
||||
};
|
||||
|
||||
const isGroup = computed((): boolean =>
|
||||
(contactInfoData.value as IGroupModel)?.groupID ? true : false,
|
||||
);
|
||||
|
||||
const isApplication = computed((): boolean => {
|
||||
return isApplicationType(contactInfoData?.value);
|
||||
});
|
||||
|
||||
// is both friend, if is group type always false
|
||||
const isBothFriend = ref<boolean>(false);
|
||||
|
||||
// is group member, including ordinary member, admin, group owner
|
||||
const isGroupMember = computed((): boolean => {
|
||||
return (contactInfoData.value as IGroupModel)?.selfInfo?.userID ? true : false;
|
||||
});
|
||||
|
||||
// is in black list, if is group type always false
|
||||
const isInBlackList = computed((): boolean => {
|
||||
return (
|
||||
!isGroup.value
|
||||
&& blackList.value?.findIndex(
|
||||
(item: IBlackListUserItem) =>
|
||||
item?.userID === (contactInfoData.value as IBlackListUserItem)?.userID,
|
||||
) >= 0
|
||||
);
|
||||
});
|
||||
|
||||
const blackList = ref<IBlackListUserItem[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
currentContactInfo: onCurrentContactInfoUpdated,
|
||||
});
|
||||
TUIStore.watch(StoreName.USER, {
|
||||
userBlacklist: onUserBlacklistUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CUSTOM, {
|
||||
currentContactInfo: onCurrentContactInfoUpdated,
|
||||
});
|
||||
TUIStore.unwatch(StoreName.USER, {
|
||||
userBlacklist: onUserBlacklistUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
const resetContactInfoUIData = () => {
|
||||
contactInfoData.value = {} as IContactInfoType;
|
||||
contactInfoBasicList.value = [];
|
||||
contactInfoMoreList.value = [];
|
||||
contactInfoButtonList.value = [];
|
||||
};
|
||||
|
||||
const resetContactSearchingUIData = () => {
|
||||
TUIStore.update(StoreName.CUSTOM, 'currentContactInfo', {});
|
||||
TUIStore.update(StoreName.CUSTOM, 'currentContactSearchingStatus', false);
|
||||
TUIGlobal?.closeSearching && TUIGlobal?.closeSearching();
|
||||
};
|
||||
|
||||
const onContactInfoEmitSubmit = (item: any) => {
|
||||
item.editSubmitHandler
|
||||
&& item.editSubmitHandler({
|
||||
item,
|
||||
contactInfoData: contactInfoData.value,
|
||||
isBothFriend: isBothFriend.value,
|
||||
isInBlackList: isInBlackList.value,
|
||||
});
|
||||
};
|
||||
|
||||
const onContactInfoButtonClicked = (item: any) => {
|
||||
item.onClick
|
||||
&& item.onClick({
|
||||
contactInfoData: contactInfoData.value,
|
||||
contactInfoMoreList: contactInfoMoreList.value,
|
||||
});
|
||||
if (
|
||||
item.key === 'enterGroupConversation'
|
||||
|| item.key === 'enterC2CConversation'
|
||||
) {
|
||||
emits('switchConversation', contactInfoData.value);
|
||||
resetContactSearchingUIData();
|
||||
}
|
||||
};
|
||||
|
||||
const generateMoreInfo = async () => {
|
||||
if (!isApplication.value) {
|
||||
if (
|
||||
(!isGroup.value && !isBothFriend.value && !isInBlackList.value)
|
||||
|| (isGroup.value
|
||||
&& !isGroupMember.value
|
||||
&& (contactInfoData.value as IGroupModel)?.type !== TUIChatEngine?.TYPES?.GRP_AVCHATROOM)
|
||||
) {
|
||||
contactMoreInfoConfig.setWords.data = '';
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.setWords);
|
||||
}
|
||||
if (!isGroup.value && !isInBlackList.value) {
|
||||
contactMoreInfoConfig.setRemark.data
|
||||
= (contactInfoData.value as Friend)?.remark || '';
|
||||
contactMoreInfoConfig.setRemark.editing = false;
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.setRemark);
|
||||
}
|
||||
if (!isGroup.value && (isBothFriend.value || isInBlackList.value)) {
|
||||
contactMoreInfoConfig.blackList.data = isInBlackList.value || false;
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.blackList);
|
||||
}
|
||||
} else {
|
||||
contactMoreInfoConfig.displayWords.data
|
||||
= (contactInfoData.value as FriendApplication)?.wording || '';
|
||||
contactInfoMoreList.value.push(contactMoreInfoConfig.displayWords);
|
||||
}
|
||||
};
|
||||
|
||||
const generateButton = () => {
|
||||
if (isInBlackList.value) {
|
||||
return;
|
||||
}
|
||||
if (isApplication.value) {
|
||||
if (
|
||||
(contactInfoData.value as FriendApplication)?.type
|
||||
=== TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_TO_ME
|
||||
) {
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.refuseFriendApplication,
|
||||
);
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.acceptFriendApplication,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (isGroup.value && isGroupMember.value) {
|
||||
switch ((contactInfoData.value as IGroupModel)?.selfInfo?.role) {
|
||||
case 'Owner':
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.dismissGroup);
|
||||
break;
|
||||
default:
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.quitGroup);
|
||||
break;
|
||||
}
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.enterGroupConversation,
|
||||
);
|
||||
} else if (!isGroup.value && isBothFriend.value) {
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.deleteFriend);
|
||||
contactInfoButtonList?.value?.push(
|
||||
contactButtonConfig.enterC2CConversation,
|
||||
);
|
||||
} else {
|
||||
if (isGroup.value) {
|
||||
contactInfoButtonList?.value?.push(
|
||||
(contactInfoData.value as IGroupModel)?.type === TUIChatEngine?.TYPES?.GRP_AVCHATROOM
|
||||
? contactButtonConfig.joinAVChatGroup
|
||||
: contactButtonConfig.joinGroup,
|
||||
);
|
||||
} else {
|
||||
contactInfoButtonList?.value?.push(contactButtonConfig.addFriend);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onUserBlacklistUpdated(userBlacklist: IBlackListUserItem[]) {
|
||||
blackList.value = userBlacklist;
|
||||
}
|
||||
|
||||
async function onCurrentContactInfoUpdated(contactInfo: IContactInfoType) {
|
||||
if (
|
||||
contactInfoData.value
|
||||
&& contactInfo
|
||||
&& JSON.stringify(contactInfoData.value) === JSON.stringify(contactInfo)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
resetContactInfoUIData();
|
||||
// deep clone
|
||||
contactInfoData.value = deepCopy(contactInfo) || {};
|
||||
if (!contactInfoData.value || Object.keys(contactInfoData.value)?.length === 0) {
|
||||
return;
|
||||
}
|
||||
contactInfoBasicList.value = generateContactInfoBasic(
|
||||
contactInfoData.value,
|
||||
);
|
||||
isBothFriend.value = await isFriend(contactInfoData.value);
|
||||
generateMoreInfo();
|
||||
generateButton();
|
||||
if (contactInfo.infoKeyList) {
|
||||
contactInfoMoreList.value = contactInfo.infoKeyList.map((key: string) => {
|
||||
return (contactMoreInfoConfig as any)[key];
|
||||
});
|
||||
}
|
||||
if (contactInfo.btnKeyList) {
|
||||
contactInfoButtonList.value = contactInfo.btnKeyList.map((key: string) => {
|
||||
return (contactButtonConfig as any)[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped src="./style/index.scss"></style>
|
||||
|
@ -1,138 +1,138 @@
|
||||
<template>
|
||||
<SelectFriend v-if="isShowSelectFriend" />
|
||||
<div
|
||||
v-else-if="isShowContactList"
|
||||
:class="['tui-contact', !isPC && 'tui-contact-h5']"
|
||||
>
|
||||
<div :class="['tui-contact-left', !isPC && 'tui-contact-h5-left']" :style="{height:ht+'px'}">
|
||||
<!-- <ContactSearch /> -->
|
||||
<ContactList :class="['tui-contact-left-list', !isPC && 'tui-contact-h5-left-list']" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isShowContactInfo"
|
||||
:class="['tui-contact-right', !isPC && 'tui-contact-h5-right']"
|
||||
:style="{height:ht+'px'}"
|
||||
>
|
||||
<ContactInfo @switchConversation="switchConversation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, watchEffect,defineProps } from '../../adapter-vue';
|
||||
import { isPC, isUniFrameWork } from '../../utils/env';
|
||||
const ht = uni.getSystemInfoSync().windowHeight
|
||||
import SelectFriend from './select-friend/index.vue';
|
||||
import ContactSearch from './contact-search/index.vue';
|
||||
import ContactList from './contact-list/index.vue';
|
||||
import ContactInfo from './contact-info/index.vue';
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
|
||||
const props = defineProps({
|
||||
// web/h5 single page application display format, uniapp please ignore
|
||||
displayType: {
|
||||
type: String,
|
||||
default: 'contactList', // "contactList" / "selectFriend"
|
||||
require: false,
|
||||
|
||||
},
|
||||
stu: {
|
||||
type: Number, // 这里可以根据实际类型修改,如 String, Number, Object 等
|
||||
require: true,
|
||||
}
|
||||
});
|
||||
|
||||
const displayTypeRef = ref<string>(props.displayType || 'contactList');
|
||||
const isShowSelectFriend = ref(false);
|
||||
const isShowContactList = ref(true);
|
||||
const isShowContactInfo = ref(true);
|
||||
const isstu=ref(props.stu);
|
||||
|
||||
watchEffect(() => {
|
||||
isShowContactList.value = props?.displayType !== 'selectFriend';
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
isShowSelectFriendComponent: (data: any) => {
|
||||
if (!isUniFrameWork && props?.displayType === 'selectFriend') {
|
||||
isShowSelectFriend.value = data;
|
||||
isShowContactList.value = false;
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
isShowSelectFriend.value = true;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = 'selectFriend';
|
||||
TUIGlobal?.hideTabBar();
|
||||
}
|
||||
} else {
|
||||
isShowSelectFriend.value = false;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = props.displayType;
|
||||
TUIGlobal?.showTabBar()?.catch(() => { /* ignore */ });
|
||||
}
|
||||
}
|
||||
},
|
||||
currentContactInfo: (contactInfo: any) => {
|
||||
isShowContactInfo.value = isPC || (contactInfo && typeof contactInfo === 'object' && Object.keys(contactInfo)?.length > 0);
|
||||
},
|
||||
});
|
||||
|
||||
const switchConversation = (data: any) => {
|
||||
isUniFrameWork
|
||||
&& TUIGlobal?.navigateTo({
|
||||
url: '/TUIKit/components/TUIChat/index',
|
||||
});
|
||||
emits('switchConversation', data);
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/styles/common";
|
||||
|
||||
.tui-contact {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&-left {
|
||||
min-width: 285px;
|
||||
flex: 0 0 24%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-right {
|
||||
border-left: 1px solid #f4f5f9;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.tui-contact-h5 {
|
||||
position: relative;
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-right {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
&-left {
|
||||
&-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<SelectFriend v-if="isShowSelectFriend" />
|
||||
<div
|
||||
v-else-if="isShowContactList"
|
||||
:class="['tui-contact', !isPC && 'tui-contact-h5']"
|
||||
>
|
||||
<div :class="['tui-contact-left', !isPC && 'tui-contact-h5-left']" :style="{height:ht+'px'}">
|
||||
<!-- <ContactSearch /> -->
|
||||
<ContactList :class="['tui-contact-left-list', !isPC && 'tui-contact-h5-left-list']" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isShowContactInfo"
|
||||
:class="['tui-contact-right', !isPC && 'tui-contact-h5-right']"
|
||||
:style="{height:ht+'px'}"
|
||||
>
|
||||
<ContactInfo @switchConversation="switchConversation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, watchEffect,defineProps } from '../../adapter-vue';
|
||||
import { isPC, isUniFrameWork } from '../../utils/env';
|
||||
const ht = uni.getSystemInfoSync().windowHeight
|
||||
import SelectFriend from './select-friend/index.vue';
|
||||
import ContactSearch from './contact-search/index.vue';
|
||||
import ContactList from './contact-list/index.vue';
|
||||
import ContactInfo from './contact-info/index.vue';
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
|
||||
const props = defineProps({
|
||||
// web/h5 single page application display format, uniapp please ignore
|
||||
displayType: {
|
||||
type: String,
|
||||
default: 'contactList', // "contactList" / "selectFriend"
|
||||
require: false,
|
||||
|
||||
},
|
||||
stu: {
|
||||
type: Number, // 这里可以根据实际类型修改,如 String, Number, Object 等
|
||||
require: true,
|
||||
}
|
||||
});
|
||||
|
||||
const displayTypeRef = ref<string>(props.displayType || 'contactList');
|
||||
const isShowSelectFriend = ref(false);
|
||||
const isShowContactList = ref(true);
|
||||
const isShowContactInfo = ref(true);
|
||||
const isstu=ref(props.stu);
|
||||
|
||||
watchEffect(() => {
|
||||
isShowContactList.value = props?.displayType !== 'selectFriend';
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
isShowSelectFriendComponent: (data: any) => {
|
||||
if (!isUniFrameWork && props?.displayType === 'selectFriend') {
|
||||
isShowSelectFriend.value = data;
|
||||
isShowContactList.value = false;
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
isShowSelectFriend.value = true;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = 'selectFriend';
|
||||
TUIGlobal?.hideTabBar();
|
||||
}
|
||||
} else {
|
||||
isShowSelectFriend.value = false;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = props.displayType;
|
||||
TUIGlobal?.showTabBar()?.catch(() => { /* ignore */ });
|
||||
}
|
||||
}
|
||||
},
|
||||
currentContactInfo: (contactInfo: any) => {
|
||||
isShowContactInfo.value = isPC || (contactInfo && typeof contactInfo === 'object' && Object.keys(contactInfo)?.length > 0);
|
||||
},
|
||||
});
|
||||
|
||||
const switchConversation = (data: any) => {
|
||||
isUniFrameWork
|
||||
&& TUIGlobal?.navigateTo({
|
||||
url: '/TUIKit/components/TUIChat/index',
|
||||
});
|
||||
emits('switchConversation', data);
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/styles/common";
|
||||
|
||||
.tui-contact {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&-left {
|
||||
min-width: 285px;
|
||||
flex: 0 0 24%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-right {
|
||||
border-left: 1px solid #f4f5f9;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.tui-contact-h5 {
|
||||
position: relative;
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-right {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
&-left {
|
||||
&-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,141 +1,141 @@
|
||||
<template>
|
||||
<SelectFriend v-if="isShowSelectFriend" />
|
||||
<div
|
||||
v-else-if="isShowContactList"
|
||||
:class="['tui-contact', !isPC && 'tui-contact-h5']"
|
||||
>
|
||||
<div :class="['tui-contact-left', !isPC && 'tui-contact-h5-left']" :style="{height:ht+'px'}" >
|
||||
<ContactSearch @cancel="cancel" />
|
||||
<ContactList :class="['tui-contact-left-list', !isPC && 'tui-contact-h5-left-list']" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isShowContactInfo"
|
||||
:class="['tui-contact-right', !isPC && 'tui-contact-h5-right']"
|
||||
:style="{height:ht+'px'}"
|
||||
>
|
||||
<ContactInfo @switchConversation="switchConversation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, watchEffect,defineProps } from '../../adapter-vue';
|
||||
import { isPC, isUniFrameWork } from '../../utils/env';
|
||||
|
||||
import SelectFriend from './select-friend/index.vue';
|
||||
import ContactSearch from './contact-search/index.vue';
|
||||
import ContactList from './contact-list/indexsea.vue';
|
||||
import ContactInfo from './contact-info/index.vue';
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
const ht = uni.getSystemInfoSync().windowHeight
|
||||
const props = defineProps({
|
||||
// web/h5 single page application display format, uniapp please ignore
|
||||
displayType: {
|
||||
type: String,
|
||||
default: 'contactList', // "contactList" / "selectFriend"
|
||||
require: false,
|
||||
|
||||
},
|
||||
stu: {
|
||||
type: Number, // 这里可以根据实际类型修改,如 String, Number, Object 等
|
||||
require: true,
|
||||
}
|
||||
});
|
||||
const cancel=(item)=>{
|
||||
emits('switchConversation', item);
|
||||
}
|
||||
const displayTypeRef = ref<string>(props.displayType || 'contactList');
|
||||
const isShowSelectFriend = ref(false);
|
||||
const isShowContactList = ref(true);
|
||||
const isShowContactInfo = ref(true);
|
||||
const isstu=ref(props.stu);
|
||||
|
||||
watchEffect(() => {
|
||||
isShowContactList.value = props?.displayType !== 'selectFriend';
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
isShowSelectFriendComponent: (data: any) => {
|
||||
if (!isUniFrameWork && props?.displayType === 'selectFriend') {
|
||||
isShowSelectFriend.value = data;
|
||||
isShowContactList.value = false;
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
isShowSelectFriend.value = true;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = 'selectFriend';
|
||||
TUIGlobal?.hideTabBar();
|
||||
}
|
||||
} else {
|
||||
isShowSelectFriend.value = false;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = props.displayType;
|
||||
TUIGlobal?.showTabBar()?.catch(() => { /* ignore */ });
|
||||
}
|
||||
}
|
||||
},
|
||||
currentContactInfo: (contactInfo: any) => {
|
||||
isShowContactInfo.value = isPC || (contactInfo && typeof contactInfo === 'object' && Object.keys(contactInfo)?.length > 0);
|
||||
},
|
||||
});
|
||||
|
||||
const switchConversation = (data: any) => {
|
||||
isUniFrameWork
|
||||
&& TUIGlobal?.navigateTo({
|
||||
url: '/TUIKit/components/TUIChat/index',
|
||||
});
|
||||
emits('switchConversation', data);
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/styles/common";
|
||||
|
||||
.tui-contact {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&-left {
|
||||
min-width: 285px;
|
||||
flex: 0 0 24%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-right {
|
||||
border-left: 1px solid #f4f5f9;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.tui-contact-h5 {
|
||||
position: relative;
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-right {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
&-left {
|
||||
&-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<SelectFriend v-if="isShowSelectFriend" />
|
||||
<div
|
||||
v-else-if="isShowContactList"
|
||||
:class="['tui-contact', !isPC && 'tui-contact-h5']"
|
||||
>
|
||||
<div :class="['tui-contact-left', !isPC && 'tui-contact-h5-left']" :style="{height:ht+'px'}" >
|
||||
<ContactSearch @cancel="cancel" />
|
||||
<ContactList :class="['tui-contact-left-list', !isPC && 'tui-contact-h5-left-list']" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isShowContactInfo"
|
||||
:class="['tui-contact-right', !isPC && 'tui-contact-h5-right']"
|
||||
:style="{height:ht+'px'}"
|
||||
>
|
||||
<ContactInfo @switchConversation="switchConversation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { ref, watchEffect,defineProps } from '../../adapter-vue';
|
||||
import { isPC, isUniFrameWork } from '../../utils/env';
|
||||
|
||||
import SelectFriend from './select-friend/index.vue';
|
||||
import ContactSearch from './contact-search/index.vue';
|
||||
import ContactList from './contact-list/indexsea.vue';
|
||||
import ContactInfo from './contact-info/index.vue';
|
||||
|
||||
const emits = defineEmits(['switchConversation']);
|
||||
const ht = uni.getSystemInfoSync().windowHeight
|
||||
const props = defineProps({
|
||||
// web/h5 single page application display format, uniapp please ignore
|
||||
displayType: {
|
||||
type: String,
|
||||
default: 'contactList', // "contactList" / "selectFriend"
|
||||
require: false,
|
||||
|
||||
},
|
||||
stu: {
|
||||
type: Number, // 这里可以根据实际类型修改,如 String, Number, Object 等
|
||||
require: true,
|
||||
}
|
||||
});
|
||||
const cancel=(item)=>{
|
||||
emits('switchConversation', item);
|
||||
}
|
||||
const displayTypeRef = ref<string>(props.displayType || 'contactList');
|
||||
const isShowSelectFriend = ref(false);
|
||||
const isShowContactList = ref(true);
|
||||
const isShowContactInfo = ref(true);
|
||||
const isstu=ref(props.stu);
|
||||
|
||||
watchEffect(() => {
|
||||
isShowContactList.value = props?.displayType !== 'selectFriend';
|
||||
});
|
||||
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
isShowSelectFriendComponent: (data: any) => {
|
||||
if (!isUniFrameWork && props?.displayType === 'selectFriend') {
|
||||
isShowSelectFriend.value = data;
|
||||
isShowContactList.value = false;
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
isShowSelectFriend.value = true;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = 'selectFriend';
|
||||
TUIGlobal?.hideTabBar();
|
||||
}
|
||||
} else {
|
||||
isShowSelectFriend.value = false;
|
||||
if (isUniFrameWork) {
|
||||
displayTypeRef.value = props.displayType;
|
||||
TUIGlobal?.showTabBar()?.catch(() => { /* ignore */ });
|
||||
}
|
||||
}
|
||||
},
|
||||
currentContactInfo: (contactInfo: any) => {
|
||||
isShowContactInfo.value = isPC || (contactInfo && typeof contactInfo === 'object' && Object.keys(contactInfo)?.length > 0);
|
||||
},
|
||||
});
|
||||
|
||||
const switchConversation = (data: any) => {
|
||||
isUniFrameWork
|
||||
&& TUIGlobal?.navigateTo({
|
||||
url: '/TUIKit/components/TUIChat/index',
|
||||
});
|
||||
emits('switchConversation', data);
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/styles/common";
|
||||
|
||||
.tui-contact {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&-left {
|
||||
min-width: 285px;
|
||||
flex: 0 0 24%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-right {
|
||||
border-left: 1px solid #f4f5f9;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.tui-contact-h5 {
|
||||
position: relative;
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-right {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
&-left {
|
||||
&-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
817
api/vlog.js
817
api/vlog.js
@ -1,340 +1,477 @@
|
||||
/**
|
||||
* 短视频相关API
|
||||
*/
|
||||
|
||||
import { http, Method } from "@/utils/request.js";
|
||||
|
||||
import api from "@/config/api.js";
|
||||
|
||||
|
||||
/**
|
||||
* 短视频关注列表
|
||||
*/
|
||||
export function vlogDetail(vlogId,userId) {
|
||||
let data = {
|
||||
vlogId,
|
||||
userId
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/detail",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频关注列表
|
||||
*/
|
||||
export function vlogFollowList(page, pageSize,myId) {
|
||||
let data = {
|
||||
page,
|
||||
pageSize,
|
||||
myId
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/followList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频列表-true
|
||||
*/
|
||||
export function vlogList(page, pageSize,userId='',search='') {
|
||||
let data = {
|
||||
page,
|
||||
pageSize,
|
||||
userId,
|
||||
search
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/indexList",
|
||||
method: Method.GET,
|
||||
needToken: false,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频喜欢
|
||||
*/
|
||||
export function vlogLike({userId,vlogId,vlogerId}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/like",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {userId,vlogId,vlogerId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频不喜欢
|
||||
*/
|
||||
export function vlogUnLike({userId,vlogId,vlogerId}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/unlike",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {userId,vlogId,vlogerId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频评论数量统计
|
||||
*/
|
||||
export function vlogComment(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/counts",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { vlogId },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 短视频关注博主
|
||||
*/
|
||||
export function vlogFollow(myId,vlogerId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/follow",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {myId,vlogerId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频查询当前点赞数
|
||||
*/
|
||||
export function vlogTotalLikedCounts(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/totalLikedCounts",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {vlogId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户信息
|
||||
*/
|
||||
export function vlogUserInfo(userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/userInfo/query",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我的公开视频
|
||||
*/
|
||||
export function vlogMyPublicList(page,pageSize,userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myPublicList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { page,pageSize,userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我的私密视频
|
||||
*/
|
||||
export function vlogMyPrivateList(page,pageSize,userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myPrivateList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { page,pageSize,userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我喜欢的视频
|
||||
*/
|
||||
export function vlogMyLikedList(page,pageSize,userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myLikedList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { page,pageSize,userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我喜欢的视频
|
||||
*/
|
||||
export function vlogMeTag(path,page,pageSize,userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/"+path,
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { page,pageSize,userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论数量
|
||||
*/
|
||||
export function vlogCommentCounts(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/counts",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { vlogId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论不喜欢
|
||||
*/
|
||||
export function vlogCommentUnLike(userId,commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/unlike",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {userId,commentId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论喜欢
|
||||
*/
|
||||
export function vlogCommentLike(userId,commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/like",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {userId,commentId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论删除
|
||||
*/
|
||||
export function vlogCommentDelete(vlogId,commentUserId,commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/delete",
|
||||
method: Method.DELETE,
|
||||
needToken: true,
|
||||
params: {vlogId,commentUserId,commentId}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询视频评论内容
|
||||
*/
|
||||
export function vlogCommentList(page,pageSize,vlogId,userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/list",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: { page,pageSize,vlogId,userId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发表评论
|
||||
*/
|
||||
export function vlogCommentCreate(data) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/create",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将视频转为公开
|
||||
*/
|
||||
export function vlogChangeToPublic(userId,vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/changeToPublic",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params:{userId,vlogId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将视频转为私密
|
||||
*/
|
||||
export function vlogChangeToPrivate(userId,vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/changeToPrivate",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params:{userId,vlogId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改信息
|
||||
*/
|
||||
export function vlogModifyUserInfo(data,type) {
|
||||
return http.request({
|
||||
url: api.vlog + "/userInfo/modifyUserInfo?type="+type,
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取关
|
||||
*/
|
||||
export function vlogFansCancel({myId,vlogerId}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/cancel",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params:{myId,vlogerId}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 关注
|
||||
*/
|
||||
export function vlogFansFollow({myId,vlogerId}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/follow",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params:{myId,vlogerId}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的粉丝
|
||||
*/
|
||||
export function vlogQueryMyFans({myId,page,pageSize}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/queryMyFans",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params:{myId,page,pageSize}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的关注
|
||||
*/
|
||||
export function vlogQueryMyFollows({myId,page,pageSize}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/queryMyFollows",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params:{myId,page,pageSize}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 短视频相关API
|
||||
*/
|
||||
|
||||
import {
|
||||
http,
|
||||
Method
|
||||
} from "@/utils/request.js";
|
||||
|
||||
import api from "@/config/api.js";
|
||||
|
||||
|
||||
/**
|
||||
* 根据昵称搜索用户
|
||||
*/
|
||||
export function vlogSearchUser({
|
||||
id,
|
||||
nickname,
|
||||
page,
|
||||
pageSize
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/userInfo/searchByNickname",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
id,
|
||||
nickname,
|
||||
page,
|
||||
pageSize
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 短视频详情
|
||||
*/
|
||||
export function vlogDetail(vlogId, userId) {
|
||||
let data = {
|
||||
vlogId,
|
||||
userId
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/detail",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频关注列表
|
||||
*/
|
||||
export function vlogFollowList(page, pageSize, myId) {
|
||||
let data = {
|
||||
page,
|
||||
pageSize,
|
||||
myId
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/followList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频列表-true
|
||||
*/
|
||||
export function vlogList(page, pageSize, userId = '', cityCode = '', search = '') {
|
||||
let data = {
|
||||
page,
|
||||
pageSize,
|
||||
userId,
|
||||
cityCode,
|
||||
search
|
||||
}
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/indexList",
|
||||
method: Method.GET,
|
||||
needToken: false,
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频喜欢
|
||||
*/
|
||||
export function vlogLike({
|
||||
userId,
|
||||
vlogId,
|
||||
vlogerId
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/like",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
vlogId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频不喜欢
|
||||
*/
|
||||
export function vlogUnLike({
|
||||
userId,
|
||||
vlogId,
|
||||
vlogerId
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/unlike",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
vlogId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频评论数量统计
|
||||
*/
|
||||
export function vlogComment(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/counts",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
vlogId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 短视频关注博主
|
||||
*/
|
||||
export function vlogFollow(myId, vlogerId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/follow",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 短视频查询当前点赞数
|
||||
*/
|
||||
export function vlogTotalLikedCounts(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/totalLikedCounts",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
vlogId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户信息
|
||||
*/
|
||||
export function vlogUserInfo(userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/userInfo/query",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我的公开视频
|
||||
*/
|
||||
export function vlogMyPublicList(page, pageSize, userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myPublicList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我的私密视频
|
||||
*/
|
||||
export function vlogMyPrivateList(page, pageSize, userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myPrivateList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我喜欢的视频
|
||||
*/
|
||||
export function vlogMyLikedList(page, pageSize, userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/myLikedList",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我喜欢的视频
|
||||
*/
|
||||
export function vlogMeTag(path, page, pageSize, userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/" + path,
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论数量
|
||||
*/
|
||||
export function vlogCommentCounts(vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/counts",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
vlogId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论不喜欢
|
||||
*/
|
||||
export function vlogCommentUnLike(userId, commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/unlike",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
commentId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论喜欢
|
||||
*/
|
||||
export function vlogCommentLike(userId, commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/like",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
commentId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频评论删除
|
||||
*/
|
||||
export function vlogCommentDelete(vlogId, commentUserId, commentId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/delete",
|
||||
method: Method.DELETE,
|
||||
needToken: true,
|
||||
params: {
|
||||
vlogId,
|
||||
commentUserId,
|
||||
commentId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询视频评论内容
|
||||
*/
|
||||
export function vlogCommentList(page, pageSize, vlogId, userId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/list",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
vlogId,
|
||||
userId
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发表评论
|
||||
*/
|
||||
export function vlogCommentCreate(data) {
|
||||
return http.request({
|
||||
url: api.vlog + "/comment/create",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将视频转为公开
|
||||
*/
|
||||
export function vlogChangeToPublic(userId, vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/changeToPublic",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
vlogId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将视频转为私密
|
||||
*/
|
||||
export function vlogChangeToPrivate(userId, vlogId) {
|
||||
return http.request({
|
||||
url: api.vlog + "/vlog/changeToPrivate",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
userId,
|
||||
vlogId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改信息
|
||||
*/
|
||||
export function vlogModifyUserInfo(data, type) {
|
||||
return http.request({
|
||||
url: api.vlog + "/userInfo/modifyUserInfo?type=" + type,
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取关
|
||||
*/
|
||||
export function vlogFansCancel({
|
||||
myId,
|
||||
vlogerId
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/cancel",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 关注
|
||||
*/
|
||||
export function vlogFansFollow({
|
||||
myId,
|
||||
vlogerId
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/follow",
|
||||
method: Method.POST,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的粉丝
|
||||
*/
|
||||
export function vlogQueryMyFans({
|
||||
myId,
|
||||
page,
|
||||
pageSize
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/queryMyFans",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
page,
|
||||
pageSize
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的关注
|
||||
*/
|
||||
export function vlogQueryMyFollows({
|
||||
myId,
|
||||
page,
|
||||
pageSize
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/queryMyFollows",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
page,
|
||||
pageSize
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的关注
|
||||
*/
|
||||
export function vlogQueryDoIFollowVloger({
|
||||
myId,
|
||||
vlogerId
|
||||
}) {
|
||||
return http.request({
|
||||
url: api.vlog + "/fans/queryDoIFollowVloger",
|
||||
method: Method.GET,
|
||||
needToken: true,
|
||||
params: {
|
||||
myId,
|
||||
vlogerId
|
||||
}
|
||||
});
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1017
components/vlog/videoLocal.vue
Normal file
1017
components/vlog/videoLocal.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,12 +6,10 @@
|
||||
const dev = {
|
||||
// common: "https://common-api.pickmall.cn",
|
||||
// buyer: "https://buyer-api.pickmall.cn",
|
||||
|
||||
common: "http://192.168.1.211:8890",
|
||||
buyer: "http://192.168.1.211:8888",
|
||||
vlog: "http://192.168.1.211:8099",
|
||||
web: "http://192.168.1.211:8099",
|
||||
|
||||
};
|
||||
// 生产环境
|
||||
const prod = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "wzj4",
|
||||
"appid" : "__UNI__1F0975C",
|
||||
"appid" : "__UNI__6DB512D",
|
||||
"description" : "admin",
|
||||
"versionName" : "4.0.0",
|
||||
"versionCode" : 4000049,
|
||||
@ -9,8 +9,8 @@
|
||||
"compatible" : {
|
||||
"ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
|
||||
},
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
/* 5+App特有相关 */
|
||||
"usingComponents" : true,
|
||||
"splashscreen" : {
|
||||
@ -19,18 +19,17 @@
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"screenOrientation" : [ "portrait-primary" ],
|
||||
"screenOrientation" : [ "portrait-primary" ],
|
||||
"modules" : {
|
||||
"Payment" : {},
|
||||
"Share" : {},
|
||||
"Fingerprint" : {},
|
||||
"FaceID" : {},
|
||||
"Geolocation" : {},
|
||||
"Maps" : {},
|
||||
"OAuth" : {},
|
||||
"Camera" : {},
|
||||
"Barcode" : {},
|
||||
"VideoPlayer" : {}
|
||||
"VideoPlayer" : {},
|
||||
"Push" : {}
|
||||
},
|
||||
"error" : {
|
||||
/* 404错误页面*/
|
||||
@ -90,7 +89,7 @@
|
||||
"payment" : {
|
||||
"weixin" : {
|
||||
"__platform__" : [ "ios", "android" ],
|
||||
"appid" : "wx32788b91bdb614c0",
|
||||
"appid" : "wxebcdaea31881caab",
|
||||
"UniversalLinks" : "https://m-b2b2c.pickmall.cn/app/"
|
||||
},
|
||||
"alipay" : {
|
||||
@ -100,14 +99,14 @@
|
||||
"ad" : {},
|
||||
"share" : {
|
||||
"weixin" : {
|
||||
"appid" : "wx32788b91bdb614c0",
|
||||
"appid" : "wxebcdaea31881caab",
|
||||
"UniversalLinks" : "https://m-b2b2c.pickmall.cn/app/"
|
||||
}
|
||||
},
|
||||
"oauth" : {
|
||||
"weixin" : {
|
||||
"appid" : "wx32788b91bdb614c0",
|
||||
"appsecret" : "230233cef7520ee935bbecad372a370e",
|
||||
"appid" : "wxebcdaea31881caab",
|
||||
"appsecret" : "71826d76bad096ec5407897c6ed1391f",
|
||||
"UniversalLinks" : "https://m-b2b2c.pickmall.cn/app/"
|
||||
},
|
||||
"apple" : {},
|
||||
@ -120,6 +119,9 @@
|
||||
"__platform__" : [ "ios", "android" ],
|
||||
"appkey_ios" : "f463d3350efe63f8be5d9a62f24d0aab",
|
||||
"appkey_android" : "fb3f1ccb34616c70f068aa950f3e27df"
|
||||
},
|
||||
"system" : {
|
||||
"__platform__" : [ "ios", "android" ]
|
||||
}
|
||||
},
|
||||
"maps" : {
|
||||
@ -174,7 +176,8 @@
|
||||
"xxhdpi" : "CustomStartPage/start-page.9.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"nativePlugins" : {}
|
||||
},
|
||||
"permission" : {
|
||||
"scope.userLocation" : {
|
||||
|
1
nativeResources/android/assets/agconnect-services.json
Normal file
1
nativeResources/android/assets/agconnect-services.json
Normal file
@ -0,0 +1 @@
|
||||
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"30086000741655511","product_id":"388421841221950710","client_id":"1346412471476315840","client_secret":"F4B8602C5E2D5642872ED211C7478DB199EA3882FF02AD64113FCFD85CAE0E39","project_id":"388421841221950710","app_id":"110231111","api_key":"DQEDAKxxD0khNfIg6UkOoL08FvJ7BHkKnRi926D1isiHr1coC0avMtrtUxZSJOgu8nUoEWou+q/cZEY+O+5p40IarYKa/PD/JPoYMQ==","package_name":"cn.net.wzj.mall"},"oauth_client":{"client_id":"110231111","client_type":1},"app_info":{"app_id":"110231111","package_name":"cn.net.wzj.mall"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"cn.net.wzj.mall","client":{"app_id":"110231111"},"app_info":{"package_name":"cn.net.wzj.mall","app_id":"110231111"},"oauth_client":{"client_type":1,"client_id":"110231111"}}]}
|
1
nativeResources/android/assets/timpush-configs.json
Normal file
1
nativeResources/android/assets/timpush-configs.json
Normal file
@ -0,0 +1 @@
|
||||
{"version":"1.0.1","cn.net.wzj.mall":{"manifestPlaceholders":{"VIVO_APPKEY":"ebe0d2ef18e69264e8ddfb48472cb3ec","VIVO_APPID":"105722088","HONOR_APPID":"104443878"},"xiaomiPushBussinessId":"41169","xiaomiPushAppId":"2882303761520283584","xiaomiPushAppKey":"5242028361584","oppoPushBussinessId":"41170","oppoPushAppKey":"d64af1f3a4c54c0dae37d556fde086af","oppoPushAppSecret":"f6458a874f9b432aaa7a4e4a7b782fd0","huaweiPushBussinessId":"41171","huaweiBadgeClassName":"","meizuPushBussinessId":"41176","meizuPushAppId":"153237","meizuPushAppKey":"e6cdd35fcd6b47679ccd9f5bba117578","vivoPushBussinessId":"41177","honorPushBussinessId":"41178"}}
|
5
nativeResources/android/manifestPlaceholders.json
Normal file
5
nativeResources/android/manifestPlaceholders.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"VIVO_APPKEY": "ebe0d2ef18e69264e8ddfb48472cb3ec",
|
||||
"VIVO_APPID": "105722088",
|
||||
"HONOR_APPID": "104443878"
|
||||
}
|
6
nativeResources/android/mcs-services.json
Normal file
6
nativeResources/android/mcs-services.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"developer_id":"109999867274",
|
||||
"app_id":"104443878",
|
||||
"package_name":"cn.net.wzj.mall",
|
||||
"version":"1.0"
|
||||
}
|
3
nativeResources/ios/Resources/timpush-configs.json
Normal file
3
nativeResources/ios/Resources/timpush-configs.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"businessID": "45148"
|
||||
}
|
BIN
nativeplugins/JG-JPush/android/HiPushSDK-8.0.12.307.aar
Normal file
BIN
nativeplugins/JG-JPush/android/HiPushSDK-8.0.12.307.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/agconnect-core-1.7.3.302.aar
Normal file
BIN
nativeplugins/JG-JPush/android/agconnect-core-1.7.3.302.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/availableupdate-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/availableupdate-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/base-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/base-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/baselegacyapi-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/baselegacyapi-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/com.heytap.msp_3.5.3.aar
Normal file
BIN
nativeplugins/JG-JPush/android/com.heytap.msp_3.5.3.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/device-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/device-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-common-20.3.1.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-common-20.3.1.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-components-17.1.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-components-17.1.0.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-datatransport-18.1.7.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-datatransport-18.1.7.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-encoders-json-18.0.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-encoders-json-18.0.0.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-iid-interop-17.1.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-iid-interop-17.1.0.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-installations-17.1.3.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-installations-17.1.3.aar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/firebase-messaging-23.1.2.aar
Normal file
BIN
nativeplugins/JG-JPush/android/firebase-messaging-23.1.2.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/hatool-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/hatool-6.9.0.300.aar
Normal file
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/libs/commons-codec-1.6.jar
Normal file
BIN
nativeplugins/JG-JPush/android/libs/commons-codec-1.6.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/libs/firebase-encoders-17.0.0.jar
Normal file
BIN
nativeplugins/JG-JPush/android/libs/firebase-encoders-17.0.0.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/libs/javax.inject-1.jar
Executable file
BIN
nativeplugins/JG-JPush/android/libs/javax.inject-1.jar
Executable file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/libs/jpush-android-5.6.0.jar
Normal file
BIN
nativeplugins/JG-JPush/android/libs/jpush-android-5.6.0.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/libs/tasks-1.5.2.206.jar
Normal file
BIN
nativeplugins/JG-JPush/android/libs/tasks-1.5.2.206.jar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/log-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/log-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/network-common-6.0.2.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/network-common-6.0.2.300.aar
Normal file
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/network-grs-6.0.2.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/network-grs-6.0.2.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/niopush-sdk-v1.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/niopush-sdk-v1.0.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/opendevice-6.11.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/opendevice-6.11.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/play-services-base-18.0.1.aar
Normal file
BIN
nativeplugins/JG-JPush/android/play-services-base-18.0.1.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/play-services-basement-18.1.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/play-services-basement-18.1.0.aar
Normal file
Binary file not shown.
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/play-services-stats-17.0.2.aar
Normal file
BIN
nativeplugins/JG-JPush/android/play-services-stats-17.0.2.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/play-services-tasks-18.0.2.aar
Normal file
BIN
nativeplugins/JG-JPush/android/play-services-tasks-18.0.2.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/push-6.11.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/push-6.11.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/push-internal-5.0.3.aar
Normal file
BIN
nativeplugins/JG-JPush/android/push-internal-5.0.3.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/security-base-1.2.0.307.aar
Normal file
BIN
nativeplugins/JG-JPush/android/security-base-1.2.0.307.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/security-encrypt-1.2.0.307.aar
Normal file
BIN
nativeplugins/JG-JPush/android/security-encrypt-1.2.0.307.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/security-ssl-1.2.0.307.aar
Normal file
BIN
nativeplugins/JG-JPush/android/security-ssl-1.2.0.307.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/stats-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/stats-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/transport-api-3.0.0.aar
Normal file
BIN
nativeplugins/JG-JPush/android/transport-api-3.0.0.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/transport-backend-cct-3.1.8.aar
Normal file
BIN
nativeplugins/JG-JPush/android/transport-backend-cct-3.1.8.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/transport-runtime-3.1.8.aar
Normal file
BIN
nativeplugins/JG-JPush/android/transport-runtime-3.1.8.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/ui-6.9.0.300.aar
Normal file
BIN
nativeplugins/JG-JPush/android/ui-6.9.0.300.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/uniplugin_jpush-release.aar
Normal file
BIN
nativeplugins/JG-JPush/android/uniplugin_jpush-release.aar
Normal file
Binary file not shown.
BIN
nativeplugins/JG-JPush/android/vivo_pushSDK_v4.0.6.0_506.aar
Normal file
BIN
nativeplugins/JG-JPush/android/vivo_pushSDK_v4.0.6.0_506.aar
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
//
|
||||
// JPushModule.h
|
||||
// UniPluginJPush
|
||||
//
|
||||
// Created by huangshuni on 2021/1/12.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DCUniModule.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface JPushModule : DCUniModule
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
BIN
nativeplugins/JG-JPush/ios/UniPluginJPush.framework/Info.plist
Normal file
BIN
nativeplugins/JG-JPush/ios/UniPluginJPush.framework/Info.plist
Normal file
Binary file not shown.
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
169
nativeplugins/JG-JPush/package.json
Executable file
169
nativeplugins/JG-JPush/package.json
Executable file
@ -0,0 +1,169 @@
|
||||
{
|
||||
"name": "JG-JPush",
|
||||
"id": "JG-JPush",
|
||||
"version": "1.2.5",
|
||||
"description": "极光推送Hbuilder插件",
|
||||
"_dp_type":"nativeplugin",
|
||||
"_dp_nativeplugin":{
|
||||
"ios": {
|
||||
"deploymentTarget": "11.0",
|
||||
"validArchitectures": [
|
||||
"arm64"
|
||||
],
|
||||
"plugins": [{
|
||||
"type": "module",
|
||||
"name": "JG-JPush",
|
||||
"class": "JPushModule"
|
||||
}],
|
||||
"hooksClass": "JPushProxy",
|
||||
"integrateType": "framework",
|
||||
"frameworks": [
|
||||
"CFNetwork.framework",
|
||||
"CoreFoundation.framework",
|
||||
"CoreTelephony.framework",
|
||||
"SystemConfiguration.framework",
|
||||
"CoreGraphics.framework",
|
||||
"Foundation.framework",
|
||||
"UIKit.framework",
|
||||
"Security.framework",
|
||||
"libz.tbd",
|
||||
"AdSupport.framework",
|
||||
"UserNotifications.framework",
|
||||
"libresolv.tbd",
|
||||
"WebKit.framework",
|
||||
"AppTrackingTransparency.framework",
|
||||
"StoreKit.framework"
|
||||
],
|
||||
"resources": [
|
||||
|
||||
],
|
||||
"capabilities": {
|
||||
"entitlements": {
|
||||
"aps-environment":"development"
|
||||
}
|
||||
},
|
||||
"privacies": [
|
||||
"NSLocationAlwaysAndWhenInUseUsageDescription",
|
||||
"NSLocationAlwaysUsageDescription",
|
||||
"NSLocationWhenInUseUsageDescription"
|
||||
],
|
||||
"parameters": {
|
||||
"JPUSH_ISPRODUCTION_IOS": {
|
||||
"des": "[iOS]是否是生产环境,是填true,不是填false或者不填",
|
||||
"key": "JPush:ISPRODUCTION"
|
||||
},
|
||||
"JPUSH_ADVERTISINGID_IOS": {
|
||||
"des": "[iOS]广告标识符(IDFA)如果不需要使用IDFA,可不填",
|
||||
"key": "JPush:ADVERTISINGID"
|
||||
},
|
||||
"JPUSH_DEFAULTINITJPUSH_IOS": {
|
||||
"des": "[iOS]是否默认初始化,是填true,不是填false或者不填",
|
||||
"key": "JPush:DEFAULTINITJPUSH"
|
||||
}
|
||||
}
|
||||
},
|
||||
"android": {
|
||||
"plugins": [
|
||||
{
|
||||
"type": "module",
|
||||
"name": "JG-JPush",
|
||||
"class": "cn.jiguang.uniplugin_jpush.JPushModule"
|
||||
}
|
||||
],
|
||||
"integrateType": "aar",
|
||||
"minSdkVersion": "19",
|
||||
"permissions": [
|
||||
"${applicationId}.permission.JPUSH_MESSAGE",
|
||||
"android.permission.INTERNET",
|
||||
"android.permission.ACCESS_NETWORK_STATE",
|
||||
"android.permission.POST_NOTIFICATIONS",
|
||||
"com.huawei.android.launcher.permission.CHANGE_BADGE",
|
||||
"com.vivo.notification.permission.BADGE_ICON",
|
||||
"com.hihonor.android.launcher.permission.CHANGE_BADGE",
|
||||
"android.permission.VIBRATE",
|
||||
"android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android.permission.ACCESS_FINE_LOCATION",
|
||||
"android.permission.ACCESS_BACKGROUND_LOCATION",
|
||||
"android.permission.READ_PHONE_STATE",
|
||||
"android.permission.QUERY_ALL_PACKAGES",
|
||||
"android.permission.GET_TASKS",
|
||||
"android.permission.ACCESS_WIFI_STATE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"${applicationId}.permission.MIPUSH_RECEIVE",
|
||||
"com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE",
|
||||
"com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE"
|
||||
],
|
||||
"parameters": {
|
||||
"JPUSH_OPPO_APPKEY": {
|
||||
"des": "厂商OPPO-appkey,示例:OP-12345678",
|
||||
"key": "OPPO_APPKEY"
|
||||
},
|
||||
"JPUSH_OPPO_APPID":{
|
||||
"des": "厂商OPPO-appId,示例:OP-12345678",
|
||||
"key": "OPPO_APPID"
|
||||
},
|
||||
"JPUSH_OPPO_APPSECRET":{
|
||||
"des": "厂商OPPO-appSecret,示例:OP-12345678",
|
||||
"key": "OPPO_APPSECRET"
|
||||
},
|
||||
"JPUSH_VIVO_APPKEY":{
|
||||
"des": "厂商VIVO-appkey,示例:12345678",
|
||||
"key": "com.vivo.push.api_key"
|
||||
},
|
||||
"JPUSH_VIVO_APPID":{
|
||||
"des": "厂商VIVO-appId,示例:12345678",
|
||||
"key": "com.vivo.push.app_id"
|
||||
},
|
||||
"JPUSH_MEIZU_APPKEY":{
|
||||
"des": "厂商MEIZU-appKey,示例:MZ-12345678",
|
||||
"key": "MEIZU_APPKEY"
|
||||
},
|
||||
"JPUSH_MEIZU_APPID":{
|
||||
"des": "厂商MEIZU-appId,示例:MZ-12345678",
|
||||
"key": "MEIZU_APPID"
|
||||
},
|
||||
"JPUSH_XIAOMI_APPKEY":{
|
||||
"des": "厂商XIAOMI-appKey,示例:MI-12345678",
|
||||
"key": "XIAOMI_APPKEY"
|
||||
},
|
||||
"JPUSH_XIAOMI_APPID":{
|
||||
"des": "厂商XIAOMI-appId,示例:MI-12345678",
|
||||
"key": "XIAOMI_APPID"
|
||||
},
|
||||
"JPUSH_HUAWEI_APPID":{
|
||||
"des": "厂商HUAWEI-appId,示例:appid=12346578",
|
||||
"key": "com.huawei.hms.client.appid"
|
||||
},
|
||||
"JPUSH_HONOR_APPID" : {
|
||||
"des" : "厂商HONOR-appId,示例:12346578",
|
||||
"key" : "com.hihonor.push.app_id"
|
||||
},
|
||||
"JPUSH_NIO_APPID" : {
|
||||
"des" : "厂商nio-appId,示例:12346578",
|
||||
"key" : "nio_push_app_id"
|
||||
},
|
||||
"JPUSH_GOOGLE_API_KEY" : {
|
||||
"des" : "厂商google api_key,示例:g-12346578",
|
||||
"key" : "google_api_key"
|
||||
},
|
||||
"JPUSH_GOOGLE_APP_ID" : {
|
||||
"des" : "厂商google mobilesdk_app_id,示例:g-12346578",
|
||||
"key" : "google_app_id"
|
||||
},
|
||||
"JPUSH_GOOGLE_PROJECT_NUMBER" : {
|
||||
"des" : "厂商google project_number,示例:g-12346578",
|
||||
"key" : "gcm_defaultSenderId"
|
||||
},
|
||||
"JPUSH_GOOGLE_PROJECT_ID" : {
|
||||
"des" : "厂商google project_id ,示例:g-12346578",
|
||||
"key" : "project_id"
|
||||
},
|
||||
"JPUSH_GOOGLE_STORAGE_BUCKET" : {
|
||||
"des" : "厂商google storage_bucket,示例:g-12346578",
|
||||
"key" : "google_storage_bucket"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4096
package-lock.json
generated
4096
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -1,10 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "^2.0.2-4050720250324001",
|
||||
"@tencentcloud/chat-uikit-uniapp": "^2.4.3",
|
||||
"@vue/runtime-core": "^3.5.13",
|
||||
"unplugin-vue2-script-setup": "^0.11.4",
|
||||
"vue": "^3.2.0",
|
||||
"ws": "^8.18.1"
|
||||
}
|
||||
}
|
||||
{
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "^2.0.2-4050720250324001",
|
||||
"@tencentcloud/chat-uikit-uniapp": "^2.4.3",
|
||||
"@vue/runtime-core": "^3.5.13",
|
||||
"unplugin-vue2-script-setup": "^0.11.4",
|
||||
"vue": "^3.2.0",
|
||||
"ws": "^8.18.1"
|
||||
}
|
||||
}
|
67
pages.json
67
pages.json
@ -489,14 +489,14 @@
|
||||
"navigationBarBackgroundColor": "#181b27"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "path" : "pages/me/settings",
|
||||
// "style" : {
|
||||
// "navigationBarTitleText" : "设置",
|
||||
// "navigationBarTextStyle" : "white",
|
||||
// "navigationBarBackgroundColor" : "#181b27"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
"path": "pages/me/settings",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置",
|
||||
"navigationBarTextStyle": "white",
|
||||
"navigationBarBackgroundColor": "#181b27"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/me/myFans",
|
||||
"style": {
|
||||
@ -543,7 +543,22 @@
|
||||
"navigationBarTitleText": "消息详情",
|
||||
"navigationBarTextStyle": "white",
|
||||
"navigationBarBackgroundColor": "#181b27"
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/search/search",
|
||||
"style": {
|
||||
"app-plus": {
|
||||
"titleNView": false //禁用原生导航栏
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/search/searchList",
|
||||
"style": {
|
||||
"app-plus": {
|
||||
"titleNView": false //禁用原生导航栏
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -1267,27 +1282,25 @@
|
||||
{
|
||||
"path": "components/TUIChat/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "腾讯云 IM",
|
||||
"app-plus": {
|
||||
"softinputMode": "adjustResize",
|
||||
"titleNView": {
|
||||
"buttons": [
|
||||
{
|
||||
"type": "menu"
|
||||
// "click": "handleMenuClick" // 绑定点击事件
|
||||
"navigationBarTitleText": "腾讯云 IM",
|
||||
"app-plus": {
|
||||
"softinputMode": "adjustResize",
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"type": "menu"
|
||||
// "click": "handleMenuClick" // 绑定点击事件
|
||||
}]
|
||||
}
|
||||
},
|
||||
"h5": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"type": "menu"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"h5": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"type": "menu"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
// 集成 chat 组件,必须配置该路径: 视频播放
|
||||
{
|
||||
"path": "components/TUIChat/video-play",
|
||||
|
@ -121,7 +121,7 @@
|
||||
|
||||
<view class="vlog-list">
|
||||
<block v-for="(vlog, index) in vlogList" :key="index">
|
||||
<image class="vlog-cover" :src="vlog.cover" @click="goToVlog(vlog)" mode="aspectFill"></image>
|
||||
<image class="vlog-cover" :src="vlog.cover||vlog.firstFrameImg" @click="goToVlog(vlog)" mode="aspectFill"></image>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
@ -230,8 +230,9 @@
|
||||
if (result.data.status == 200) {
|
||||
this.pageUserInfo = result.data.data;
|
||||
storage.setVlogUserInfo(this.pageUserInfo)
|
||||
// 查询用户信息
|
||||
this.myList(0, 'myPublicList', true);
|
||||
// 查询用户信息
|
||||
this.switchTab(0)
|
||||
// this.myList(0, 'myPublicList', true);
|
||||
this.setBasicUserInfo(this.pageUserInfo);
|
||||
}
|
||||
},
|
||||
@ -355,14 +356,14 @@
|
||||
goMyFans(userId) {
|
||||
uni.navigateTo({
|
||||
animationType: "fade-in",
|
||||
url: "myFans?userId=" + userId,
|
||||
url: "myFans",
|
||||
});
|
||||
},
|
||||
// 关注列表
|
||||
goMyFollows(userId) {
|
||||
uni.navigateTo({
|
||||
animationType: "fade-in",
|
||||
url: "myFollows?userId=" + userId,
|
||||
url: "myFollows",
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
<view class="mpage">
|
||||
<view class="line"></view>
|
||||
<scroll-view scroll-y="true" @scrolltolower="pagingFansList()">
|
||||
<view class="user-wrapper" v-for="(f, index) in fansList" :key="index">
|
||||
<view class="user-wrapper" v-for="(f, index) in fansList" :key="f.fanId">
|
||||
<view class="user-info" @click="goTovlogerInfo(f.fanId)">
|
||||
<image class="face" :src="f.face" />
|
||||
<text class="user-name">
|
||||
@ -10,29 +10,19 @@
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view v-if="isLogin && f.me" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff">你</text>
|
||||
</view>
|
||||
<view v-else-if="!isLogin || isLogin && !f.follow && !f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff" @click="followMe(f.fanId)">
|
||||
关注
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="isLogin && !f.follow && f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff" @click="followMe(f.fanId)">
|
||||
回粉
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="isLogin && f.follow && !f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="cancelFollow(f.fanId)">
|
||||
已关注
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="isLogin && f.follow && f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="cancelFollow(f.fanId)">
|
||||
互关
|
||||
</text>
|
||||
<view v-if="!from">
|
||||
<view v-if="f.bothFriend==0" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="followMe(f.fanId)">
|
||||
回粉
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="f.bothFriend==1" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff" @click="cancelFollow(f.fanId)">
|
||||
互粉
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
@ -53,28 +43,28 @@
|
||||
data() {
|
||||
return {
|
||||
userId: "",
|
||||
currentUserId: "",
|
||||
isLogin: false,
|
||||
screenHeight: 0,
|
||||
page: 0,
|
||||
totalPage: 0,
|
||||
fansList: [],
|
||||
fansList: [],
|
||||
from:false
|
||||
};
|
||||
},
|
||||
onLoad(param) {
|
||||
var uinfo = storage.getVlogUserInfo()
|
||||
if (uinfo == null) {
|
||||
return
|
||||
if(!isStrEmpty(param.userId)){
|
||||
this.from = true
|
||||
this.userId = param.userId
|
||||
}else{
|
||||
var uinfo = storage.getVlogUserInfo()
|
||||
this.userId = uinfo.id;
|
||||
}
|
||||
this.isLogin = true;
|
||||
this.currentUserId = uinfo.id
|
||||
this.userId = param.userId;
|
||||
this.queryMyFansList(0);
|
||||
},
|
||||
methods: {
|
||||
goTovlogerInfo(vlogerId) {
|
||||
goTovlogerInfo(vlogerId) {
|
||||
var id = storage.getVlogUserInfo().id
|
||||
// 是否是当前登录的用户
|
||||
if (this.currentUserId == vlogerId) {
|
||||
if (id == vlogerId) {
|
||||
uni.switchTab({
|
||||
url: "me",
|
||||
});
|
||||
@ -91,15 +81,15 @@
|
||||
for (let i = 0; i < fansList.length; i++) {
|
||||
let fan = fansList[i];
|
||||
if (fan.fanId == vlogerId) {
|
||||
fan.follow = status;
|
||||
fansList.splice(i, 1, fan);
|
||||
fan.bothFriend = status;
|
||||
// fansList.splice(i, 1);
|
||||
}
|
||||
}
|
||||
me.fansList = fansList;
|
||||
},
|
||||
async cancelFollow(vlogerId) {
|
||||
let me = this;
|
||||
let userId = storage.getVlogUserInfo().id
|
||||
let userId = me.userId
|
||||
let data = {
|
||||
myId: userId,
|
||||
vlogerId
|
||||
@ -107,7 +97,7 @@
|
||||
var result = await vlogFansCancel(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, false);
|
||||
me.reFreshList(vlogerId, 0);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
@ -118,7 +108,7 @@
|
||||
},
|
||||
async followMe(vlogerId) {
|
||||
let me = this;
|
||||
let userId = this.currentUserId;
|
||||
let userId = me.userId;
|
||||
let data = {
|
||||
myId: userId,
|
||||
vlogerId
|
||||
@ -126,7 +116,7 @@
|
||||
var result = await vlogFansFollow(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, true);
|
||||
me.reFreshList(vlogerId, 1);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
@ -147,7 +137,8 @@
|
||||
page: page,
|
||||
pageSize: 10
|
||||
}
|
||||
var result = await vlogQueryMyFans(data)
|
||||
var result = await vlogQueryMyFans(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
let fansList = result.data.data.rows;
|
||||
let totalPage = result.data.data.total;
|
||||
@ -217,7 +208,8 @@
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
@ -231,8 +223,8 @@
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
background-color: #ef274d;
|
||||
border-radius: 20rpx;
|
||||
align-self: center;
|
||||
border-radius: 20rpx;
|
||||
align-items: center;
|
||||
border-width: 2rpx;
|
||||
border-color: #ef274d;
|
||||
background-color: #181b27;
|
||||
|
@ -2,7 +2,7 @@
|
||||
<view class="mpage">
|
||||
<view class="line"></view>
|
||||
<scroll-view scroll-y="true" @scrolltolower="pagingFollowsList">
|
||||
<view class="user-wrapper" v-for="(f, index) in followsList" :key="index">
|
||||
<view class="user-wrapper" v-for="(f, index) in followsList" :key="f.vlogerId">
|
||||
<view class="user-info" @click="goTovlogerInfo(f.vlogerId)">
|
||||
<image class="face" :src="f.face" />
|
||||
<text class="user-name">
|
||||
@ -10,64 +10,59 @@
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view v-if="f.me" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff">你</text>
|
||||
</view>
|
||||
<view v-else-if="!f.follow" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff" @click="followMe(f.vlogerId)">
|
||||
关注
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="f.follow && !f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="cancelFollow(f.vlogerId)">
|
||||
已关注
|
||||
</text>
|
||||
</view>
|
||||
<view v-else-if="f.follow && f.fan" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="cancelFollow(f.vlogerId)">
|
||||
互关
|
||||
</text>
|
||||
<view v-if="!from">
|
||||
<view v-if="f.bothFriend==0" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ef274d" @click="cancelFollow(f.vlogerId)">
|
||||
已关注
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="f.bothFriend==1" class="operator-wrapper">
|
||||
<text class="operator-words" style="color: #ffffff" @click="cancelFollow(f.vlogerId)">
|
||||
互关
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js"; //缓存
|
||||
import {
|
||||
vlogFansCancel,
|
||||
vlogFansFollow,
|
||||
vlogQueryMyFollows
|
||||
} from "@/api/vlog"
|
||||
import {
|
||||
isStrEmpty
|
||||
<script>
|
||||
import storage from "@/utils/storage.js"; //缓存
|
||||
import {
|
||||
vlogFansCancel,
|
||||
vlogFansFollow,
|
||||
vlogQueryMyFollows
|
||||
} from "@/api/vlog"
|
||||
import {
|
||||
isStrEmpty
|
||||
} from '@/utils/tools.js'
|
||||
let system = uni.getSystemInfoSync();
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userId: "",
|
||||
currentUserId: "",
|
||||
screenHeight: 0,
|
||||
page: 0,
|
||||
totalPage: 0,
|
||||
followsList: [],
|
||||
from: false
|
||||
};
|
||||
},
|
||||
onLoad(param) {
|
||||
var uinfo = storage.getVlogUserInfo()
|
||||
if (uinfo==null) {
|
||||
return
|
||||
}
|
||||
this.currentUserId = uinfo.id
|
||||
this.userId = param.userId;
|
||||
onLoad(param) {
|
||||
if (!isStrEmpty(param.userId)) {
|
||||
this.from = true
|
||||
this.userId = param.userId
|
||||
} else {
|
||||
var uinfo = storage.getVlogUserInfo()
|
||||
this.userId = uinfo.id;
|
||||
}
|
||||
this.queryMyFollowList(0);
|
||||
},
|
||||
methods: {
|
||||
goTovlogerInfo(vlogerId) {
|
||||
// 是否是当前登录的用户
|
||||
if (this.currentUserId == vlogerId) {
|
||||
var id = storage.getVlogUserInfo().id
|
||||
if (id == vlogerId) {
|
||||
uni.switchTab({
|
||||
url: "me",
|
||||
});
|
||||
@ -84,69 +79,67 @@
|
||||
for (let i = 0; i < followsList.length; i++) {
|
||||
let vloger = followsList[i];
|
||||
if (vloger.vlogerId == vlogerId) {
|
||||
vloger.follow = status;
|
||||
followsList.splice(i, 1, vloger);
|
||||
vloger.bothFriend = status;
|
||||
followsList.splice(i, 1);
|
||||
}
|
||||
}
|
||||
me.followsList = followsList;
|
||||
},
|
||||
async cancelFollow(vlogerId) {
|
||||
let me = this;
|
||||
let userId = this.currentUserId;
|
||||
var data ={
|
||||
myId: userId,
|
||||
vlogerId
|
||||
}
|
||||
var result = await vlogFansCancel(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, false);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
let userId = this.userId;
|
||||
var data = {
|
||||
myId: userId,
|
||||
vlogerId
|
||||
}
|
||||
var result = await vlogFansCancel(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, 0);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
async followMe(vlogerId) {
|
||||
let me = this;
|
||||
let userId = this.currentUserId;
|
||||
let data = {
|
||||
myId: userId,
|
||||
vlogerId
|
||||
}
|
||||
var result = await vlogFansFollow(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, true);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
let userId = this.userId;
|
||||
let data = {
|
||||
myId: userId,
|
||||
vlogerId
|
||||
}
|
||||
var result = await vlogFansFollow(data)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.reFreshList(vlogerId, true);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
async queryMyFollowList(page) {
|
||||
let me = this;
|
||||
page = page + 1;
|
||||
let userId = me.userId;
|
||||
let currentUserId = this.currentUserId;
|
||||
var data = {
|
||||
myId:userId,
|
||||
// vlogerId: userId,
|
||||
// currentUserId: currentUserId,
|
||||
page: page,
|
||||
pageSize: 10
|
||||
}
|
||||
var result = await vlogQueryMyFollows(data)
|
||||
if (result.data.status == 200) {
|
||||
let followsList = result.data.data.rows;
|
||||
let totalPage = result.data.data.total;
|
||||
me.followsList = me.followsList.concat(followsList);
|
||||
me.page = page;
|
||||
me.totalPage = totalPage;
|
||||
var data = {
|
||||
myId: userId,
|
||||
page: page,
|
||||
pageSize: 10
|
||||
}
|
||||
var result = await vlogQueryMyFollows(data)
|
||||
if (result.data.status == 200) {
|
||||
let followsList = result.data.data.rows;
|
||||
let totalPage = result.data.data.total;
|
||||
me.followsList = me.followsList.concat(followsList);
|
||||
console.log(me.followsList)
|
||||
me.page = page;
|
||||
me.totalPage = totalPage;
|
||||
}
|
||||
},
|
||||
|
||||
@ -157,8 +150,8 @@
|
||||
}
|
||||
this.queryMyFollowList(this.page);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -206,7 +199,7 @@
|
||||
justify-content: space-between;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
align-items: center;
|
||||
|
||||
|
||||
}
|
||||
|
227
pages/me/settings.vue
Executable file
227
pages/me/settings.vue
Executable file
@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- <view class="line"></view> -->
|
||||
|
||||
<scroll-view scroll-y="true">
|
||||
<view
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx;
|
||||
">
|
||||
<view
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
">
|
||||
<image
|
||||
src="/static/imooc/lee.jpeg"
|
||||
mode="widthFix"
|
||||
class="fengjianyingyue"
|
||||
style="align-self: center"></image>
|
||||
<image
|
||||
src="/static/imooc/fengjianyingyue.png"
|
||||
mode="widthFix"
|
||||
class="fengjianyingyue-name"
|
||||
style="align-self: center"></image>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<text class="introduce">
|
||||
物流科技公司部门经理,近10年开发和技术管理经验。主要从事后端技术和架构领域,有丰富的电商平台与物流平台核心系统的架构设计和开发经验。
|
||||
拥有丰富的大型项目开发经验,授课风格诙谐幽默,讲解到位细致。
|
||||
</text>
|
||||
<text class="introduce">
|
||||
近20万的学生学习人数,学生入职公司有:
|
||||
百度云盘,阿里,腾讯云,字节跳动,金山,网易,OPPO,新浪微博,华为,货拉拉,58同城,海信,蘑菇街,金蝶
|
||||
等。
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-top: 20rpx;
|
||||
">
|
||||
<image
|
||||
src="/static/imooc/course-javaarchitect.png"
|
||||
mode="widthFix"
|
||||
class="course"
|
||||
style="width: 380rpx"></image>
|
||||
</view>
|
||||
|
||||
<view
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 20rpx;
|
||||
padding-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
">
|
||||
<image
|
||||
src="/static/imooc/course-pm.png"
|
||||
mode="widthFix"
|
||||
class="course"
|
||||
style=""></image>
|
||||
<image
|
||||
src="/static/imooc/course-springcloud.png"
|
||||
mode="widthFix"
|
||||
class="course"
|
||||
style=""></image>
|
||||
</view>
|
||||
|
||||
<view
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 20rpx;
|
||||
padding-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
">
|
||||
<image
|
||||
src="/static/imooc/course-netty.png"
|
||||
mode="widthFix"
|
||||
class="course"
|
||||
style=""></image>
|
||||
<image
|
||||
src="/static/imooc/course-zookeeper.png"
|
||||
mode="widthFix"
|
||||
class="course"
|
||||
style=""></image>
|
||||
</view>
|
||||
|
||||
<!-- <view style="display: flex;flex-direction: row;justify-content: center;margin-top: 20rpx;">
|
||||
<image src="/static/imooc/lee-qrcode.png" mode="widthFix" class="course" style="width: 380rpx;"></image>
|
||||
</view> -->
|
||||
|
||||
<view
|
||||
:class="{ logout: !logoutTouched, 'logout-touched': logoutTouched }"
|
||||
@touchstart="touchstartLogout"
|
||||
@touchend="touchendLogout"
|
||||
@click="logout"
|
||||
style="
|
||||
margin-top: 20rpx;
|
||||
padding-left: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
width: 750rpx;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
">
|
||||
<text style="color: #ffffff; align-self: center; font-size: 15px">
|
||||
退出登录
|
||||
</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
logoutTouched: false,
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
touchstartLogout() {
|
||||
this.logoutTouched = true;
|
||||
},
|
||||
touchendLogout() {
|
||||
this.logoutTouched = false;
|
||||
},
|
||||
logout() {
|
||||
// let userId = getApp().getUserInfoSession().id;
|
||||
// uni.request({
|
||||
// method: "GET",
|
||||
// url: serverUrl + "/passport/logout?userId=" + userId,
|
||||
// success(result) {
|
||||
// let status = result.data.status;
|
||||
// if (status == 211) {
|
||||
// app.clearUserInfo();
|
||||
// uni.showToast({
|
||||
// title: result.data.msg,
|
||||
// duration: 3000
|
||||
// })
|
||||
// // 在登录登出后,都需要重新刷新首页list,目的为了刷新关注点赞状态
|
||||
// // uni.setStorageSync("needRefreshIndexVlogList", "1");
|
||||
// // uni.switchTab({
|
||||
// // url: "../index/index"
|
||||
// // })
|
||||
// uni.reLaunch({
|
||||
// url: "../index/index",
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #181b27;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 1rpx;
|
||||
background-color: #393a41;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.place-box {
|
||||
background-color: #4a4c52;
|
||||
}
|
||||
.place-box-touched {
|
||||
background-color: #6d6b6b;
|
||||
}
|
||||
|
||||
.right-arrow {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.logout {
|
||||
background-color: #4a4c52;
|
||||
}
|
||||
.logout-touched {
|
||||
background-color: #6d6b6b;
|
||||
}
|
||||
.fengjianyingyue {
|
||||
width: 250rpx;
|
||||
border-width: 1rpx;
|
||||
border-color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.fengjianyingyue-name {
|
||||
width: 200rpx;
|
||||
margin-top: 26rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.introduce {
|
||||
color: #f1f1f1;
|
||||
font-size: 26rpx;
|
||||
font-weight: 300;
|
||||
width: 440rpx;
|
||||
}
|
||||
.course {
|
||||
width: 330rpx;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
687
pages/me/vlogerInfo.nvue
Executable file
687
pages/me/vlogerInfo.nvue
Executable file
@ -0,0 +1,687 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<scroll-view
|
||||
class="isLogin-info-wrapper"
|
||||
:style="{ height: screenHeight + 'px' }"
|
||||
scroll-y="true"
|
||||
@scrolltolower="loadMore">
|
||||
<image class="mybg" :src="pageUserInfo.bgImg" mode="aspectFill" />
|
||||
|
||||
|
||||
<view class="header" :style="{ marginTop: statusBarHeight + 'px' }">
|
||||
<image
|
||||
class="header-right-search"
|
||||
src="../../static/images/icon-back.png"
|
||||
@click="back()" />
|
||||
</view>
|
||||
<view class="my-info-wrapper">
|
||||
<view class="my-info">
|
||||
<image :src="pageUserInfo.face" mode="aspectFill" class="my-face" />
|
||||
<view class="info-wrapper">
|
||||
<text class="nickname">
|
||||
{{ pageUserInfo.nickname }}
|
||||
</text>
|
||||
<view class="tiktok-num-wrapper">
|
||||
<text class="tiktok-num">视频号:</text>
|
||||
<text class="tiktok-num">
|
||||
{{ pageUserInfo.imoocNum }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="location">
|
||||
<text class="location-text">所在地:</text>
|
||||
<text class="location-text">
|
||||
{{ pageUserInfo.city == "" ? "中国" : "" + pageUserInfo.city
|
||||
}}{{
|
||||
pageUserInfo.district == "" ? "" : "·" + pageUserInfo.district
|
||||
}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="sex-wrapper">
|
||||
<view class="constellation">
|
||||
<image
|
||||
class="sex-img"
|
||||
v-if="pageUserInfo.sex == 1"
|
||||
src="/static/images/icon-sex-boy.png" />
|
||||
<image
|
||||
class="sex-img"
|
||||
v-if="pageUserInfo.sex == 0"
|
||||
src="/static/images/icon-sex-girl.png" />
|
||||
<image
|
||||
class="sex-img"
|
||||
v-if="pageUserInfo.sex == 2"
|
||||
src="/static/images/icon-sex-secret.png" />
|
||||
<text class="astro">{{ astro }}座</text>
|
||||
</view>
|
||||
<view class="animal">
|
||||
<text class="animal-text">
|
||||
{{ animal }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="desc">
|
||||
{{ pageUserInfo.description }}
|
||||
</text>
|
||||
|
||||
<view class="bottom-wrapper">
|
||||
<view class="bottom">
|
||||
<view class="bottom-item" @click="goMyFollows(pageUserInfo.id)">
|
||||
<text class="item-num">
|
||||
{{ getGraceNumber(pageUserInfo.myFollowsCounts) }}
|
||||
</text>
|
||||
<text class="item-text">关注</text>
|
||||
</view>
|
||||
<view class="bottom-item" @click="goMyFans(pageUserInfo.id)">
|
||||
<text class="item-num">
|
||||
{{ getGraceNumber(pageUserInfo.myFansCounts) }}
|
||||
</text>
|
||||
<text class="item-text">粉丝</text>
|
||||
</view>
|
||||
<view class="bottom-item">
|
||||
<text class="item-num">
|
||||
{{ getGraceNumber(pageUserInfo.totalLikeMeCounts) }}
|
||||
</text>
|
||||
<text class="item-text">获赞</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="edit">
|
||||
<view
|
||||
v-if="isFollow && !isFan"
|
||||
@click="cancelFollow()"
|
||||
class="follow-btn">
|
||||
<text class="follow-text">已关注</text>
|
||||
</view>
|
||||
<view
|
||||
v-if="isFollow && isFan"
|
||||
@click="cancelFollow()"
|
||||
class="follow-btn">
|
||||
<text class="follow-text">相互关注</text>
|
||||
</view>
|
||||
<view
|
||||
v-if="!isFollow"
|
||||
@click="followMe()"
|
||||
class="follow-btn"
|
||||
style="background-color: #ef274d">
|
||||
<text class="follow-text">关注我</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tab-wrapper">
|
||||
<view class="tab-item" @click="switchTab(0)">
|
||||
<text class="tab-normal" :class="{ 'tab-selected': currentTab == 0 }">
|
||||
作品
|
||||
</text>
|
||||
<view v-if="currentTab == 0" class="selected-tab"></view>
|
||||
</view>
|
||||
<!-- <view class="tab-item" @click="switchTab(1)">
|
||||
<text class="tab-normal" :class="{ 'tab-selected': currentTab == 1 }">
|
||||
私密
|
||||
</text>
|
||||
<view v-if="currentTab == 1" class="selected-tab"></view>
|
||||
</view> -->
|
||||
<view class="tab-item" @click="switchTab(1)">
|
||||
<text class="tab-normal" :class="{ 'tab-selected': currentTab == 1 }">
|
||||
赞过
|
||||
</text>
|
||||
<view v-if="currentTab == 1" class="selected-tab"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="vlog-list">
|
||||
<block v-for="(vlog, index) in vlogList" :key="index">
|
||||
<image
|
||||
class="vlog-cover"
|
||||
:src="vlog.cover||vlog.firstFrameImg"
|
||||
@click="goToVlog(vlog)"
|
||||
mode="aspectFill"></image>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<view v-if="vlogList.length == 0" class="empty">
|
||||
<text class="empty-text">~ 空空如也 ~</text>
|
||||
</view>
|
||||
|
||||
<view v-if="vlogList.length > 0" class="not-empty">
|
||||
<text class="not-empty-text">~ 没有更多了 ~</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let system = uni.getSystemInfoSync();
|
||||
import * as filters from "@/utils/filters.js"
|
||||
import api from "@/config/api.js";
|
||||
import storage from "@/utils/storage.js"; //缓存
|
||||
import {
|
||||
vlogUserInfo,
|
||||
vlogQueryDoIFollowVloger,
|
||||
vlogMyPublicList,
|
||||
vlogMyPrivateList,
|
||||
vlogMyLikedList,
|
||||
vlogMeTag,
|
||||
vlogFansCancel,
|
||||
vlogFansFollow
|
||||
} from "@/api/vlog"
|
||||
|
||||
import {
|
||||
getAstro,
|
||||
getAnimal,
|
||||
dateFormat,
|
||||
graceNumber,
|
||||
isStrEmpty
|
||||
} from '@/utils/tools.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pageUserInfo: {
|
||||
id: "",
|
||||
mobile: "",
|
||||
nickname: "",
|
||||
imoocNum: "",
|
||||
face: "",
|
||||
birthday: "1998-12-31T16:00:00.000+0000",
|
||||
country: "",
|
||||
province: "",
|
||||
city: "",
|
||||
district: "",
|
||||
description: "",
|
||||
myFollowsCounts: 0,
|
||||
myFansCounts: 0,
|
||||
totalLikeMeCounts: 0
|
||||
},
|
||||
userPageId: "",
|
||||
astro: "",
|
||||
animal: "",
|
||||
loginWords: "请登录",
|
||||
|
||||
statusBarHeight: 0,
|
||||
screenHeight: 0,
|
||||
screenHeightUnLogin: 0,
|
||||
|
||||
currentTab: 0,
|
||||
isFollow: false,
|
||||
isFan: false,
|
||||
isAndroid: uni.getSystemInfoSync().platform == "android",
|
||||
|
||||
page: 0,
|
||||
totalpage: 0,
|
||||
vlogList: [],
|
||||
};
|
||||
},
|
||||
async onLoad(params) {
|
||||
this.statusBarHeight = system.statusBarHeight;
|
||||
let screenHeight = system.safeArea.bottom + 50;
|
||||
this.screenHeight = screenHeight;
|
||||
let screenHeightUnLogin = system.safeArea.bottom;
|
||||
this.screenHeightUnLogin = screenHeightUnLogin;
|
||||
let me = this;
|
||||
|
||||
// 从视频页面, 点击用户头像传递过来的id
|
||||
let userPageId = params.userPageId;
|
||||
if (isStrEmpty(userPageId)) {
|
||||
uni.showToast({
|
||||
title: "出错啦~",
|
||||
icon: " none",
|
||||
duration: 2000,
|
||||
});
|
||||
settimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
me.userPageId = userPageId;
|
||||
var result = await vlogUserInfo(userPageId)
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.pageUserInfo = result.data.data;
|
||||
me.setBasicUserInfo(me.pageUserInfo);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
// this.switchTab(0);
|
||||
this.myList(0, 'myPublicList', true);
|
||||
let myUserId = "";
|
||||
let info = storage.getVlogUserInfo()
|
||||
if (info!=null) {
|
||||
myUserId = info.id;
|
||||
}
|
||||
|
||||
if (!isStrEmpty(myUserId)) {
|
||||
// 查询我是否关注博主
|
||||
var result = await vlogQueryDoIFollowVloger({myId:myUserId,vlogerId:userPageId})
|
||||
console.log(result)
|
||||
if (result.data.status == 200) {
|
||||
me.isFollow = result.data.data;
|
||||
// me.isFan = result.data.data;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
// 查询博主是否关注我
|
||||
var result2 = await vlogQueryDoIFollowVloger({myId:userPageId,vlogerId:myUserId})
|
||||
if (result2.data.status == 200) {
|
||||
me.isFan = result2.data.data;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result2.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setBasicUserInfo(myUserInfo) {
|
||||
// 根据生日判断星座
|
||||
let birthday = myUserInfo.birthday;
|
||||
let birth = dateFormat("YYYY-mm-dd", new Date(birthday));
|
||||
let birthArr = birth.split("-");
|
||||
let year = birthArr[0];
|
||||
let month = birthArr[1];
|
||||
let day = birthArr[2];
|
||||
let astro = getAstro(month, day);
|
||||
this.astro = astro;
|
||||
|
||||
// 根据生日判断生肖
|
||||
let animal = getAnimal(year);
|
||||
this.animal = animal;
|
||||
},
|
||||
switchTab(index) {
|
||||
this.currentTab = index;
|
||||
if (index == 0) {
|
||||
this.page = 0;
|
||||
this.toalPage = 0;
|
||||
this.myList(0, 'myPublicList', true);
|
||||
} else if (index == 1) {
|
||||
this.page = 0;
|
||||
this.toalPage = 0;
|
||||
this.myList(0, 'myLikedList', true);
|
||||
}
|
||||
},
|
||||
loadMore() {
|
||||
if (this.page >= this.toalPage) {
|
||||
return;
|
||||
} else {
|
||||
this.myList(this.page);
|
||||
}
|
||||
},
|
||||
async myList(page, requrl, init = false) {
|
||||
let me = this;
|
||||
page = page + 1;
|
||||
me.page = page;
|
||||
let userId = me.userPageId;;
|
||||
var result = await vlogMeTag(requrl, page, 20, userId)
|
||||
if (result.data.status == 200) {
|
||||
let vlogList = result.data.data.rows;
|
||||
console.log(vlogList)
|
||||
let toalPage = result.data.data.total;
|
||||
if (init) {
|
||||
me.vlogList = vlogList
|
||||
} else {
|
||||
me.vlogList = me.vlogList.concat(vlogList);
|
||||
}
|
||||
me.page = page;
|
||||
me.toalPage = toalPage;
|
||||
}
|
||||
},
|
||||
back() {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
},
|
||||
async cancelFollow() {
|
||||
let me = this;
|
||||
let vlogerId = me.userPageId;
|
||||
let userId = storage.getVlogUserInfo().id;
|
||||
var result = await vlogFansCancel({myId:userId,vlogerId:vlogerId})
|
||||
if (result.data.status == 200) {
|
||||
me.isFollow = false;
|
||||
// uni.setStorageSync("justCancelVlogerId", vlogerId);
|
||||
// 刷新当前页的粉丝数
|
||||
let pendingInfo = me.pageUserInfo;
|
||||
me.pageUserInfo.myFansCounts = pendingInfo.myFansCounts - 1;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
async followMe() {
|
||||
let me = this;
|
||||
let myUserInfo = storage.getVlogUserInfo();
|
||||
|
||||
let vlogerId = me.userPageId;
|
||||
let userId = myUserInfo.id;
|
||||
var result = await vlogFansFollow({myId:userId,vlogerId:vlogerId})
|
||||
if (result.data.status == 200) {
|
||||
me.isFollow = true;
|
||||
// uni.setStorageSync("justFollowVlogerId", vlogerId);
|
||||
// 刷新当前页的粉丝数
|
||||
let pendingInfo = me.pageUserInfo;
|
||||
me.pageUserInfo.myFansCounts = pendingInfo.myFansCounts + 1;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 把超过1000或10000的数字调整, 比如1.3k/6.8w
|
||||
getGraceNumber(num) {
|
||||
return graceNumber(num);
|
||||
},
|
||||
|
||||
goToVlog(vlog) {
|
||||
let vlogId = vlog.id ? vlog.id : vlog.vlogId;
|
||||
// uni.navigateTo({
|
||||
// url: "../vlog/vlog?type=mine&isNeedPage=1&vlogId=" + vlogId,
|
||||
// });
|
||||
uni.navigateTo({
|
||||
url: "/pages/me/vlog?vlogId=" + vlogId,
|
||||
});
|
||||
},
|
||||
goMyFans(userId) {
|
||||
uni.navigateTo({
|
||||
animationType: "fade-in",
|
||||
url: "myFans?userId=" + userId,
|
||||
});
|
||||
},
|
||||
|
||||
goMyFollows(userId) {
|
||||
uni.navigateTo({
|
||||
animationType: "fade-in",
|
||||
url: "myFollows?userId=" + userId,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #000000;
|
||||
|
||||
.isLogin-info-wrapper {
|
||||
.header {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
flex-direction: row;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
align-items: center;
|
||||
padding-left: 40rpx;
|
||||
padding-right: 40rpx;
|
||||
.header-right-search {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.mybg {
|
||||
width: 750rpx;
|
||||
height: 750rpx;
|
||||
box-shadow: inset 0 -150px 180px #313030;
|
||||
}
|
||||
|
||||
.my-info-wrapper {
|
||||
position: relative;
|
||||
left: 30rpx;
|
||||
top: -560rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 1000rpx;
|
||||
.my-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.my-face {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 100rpx;
|
||||
border-width: 1px;
|
||||
border-color: #f1f1f1;
|
||||
}
|
||||
.info-wrapper {
|
||||
margin-left: 30rpx;
|
||||
padding-top: 20rpx;
|
||||
width: 500rpx;
|
||||
.nickname {
|
||||
font-size: 20px;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
.tiktok-num-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.tiktok-num {
|
||||
font-size: 10px;
|
||||
color: #ffffff;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
.location {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 20px;
|
||||
margin-top: 2px;
|
||||
font-size: 1px;
|
||||
.location-text {
|
||||
line-height: 20px;
|
||||
color: #ffffff;
|
||||
font-size: 10px;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
.sex-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 10rpx;
|
||||
.constellation {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
opacity: 0.5;
|
||||
width: 130rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 10px;
|
||||
.sex-img {
|
||||
width: 22rpx;
|
||||
height: 22rpx;
|
||||
align-self: center;
|
||||
}
|
||||
.astro {
|
||||
font-size: 10px;
|
||||
color: #ffffff;
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
margin-left: 6rpx;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
.animal {
|
||||
margin-left: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
opacity: 0.5;
|
||||
width: 60rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 10px;
|
||||
.animal-text {
|
||||
font-size: 10px;
|
||||
color: #ffffff;
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc {
|
||||
position: relative;
|
||||
top: -520rpx;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
|
||||
.bottom-wrapper {
|
||||
position: relative;
|
||||
top: -510rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
.bottom {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.bottom-item {
|
||||
margin-left: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.item-num {
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
align-self: center;
|
||||
}
|
||||
.item-text {
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.edit {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-right: 30rpx;
|
||||
.follow-btn {
|
||||
margin-right: 20rpx;
|
||||
border-width: 1px;
|
||||
border-color: #ffffff;
|
||||
width: 200rpx;
|
||||
height: 66rpx;
|
||||
background-color: #545456;
|
||||
opacity: 0.8;
|
||||
border-radius: 40rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-self: center;
|
||||
.follow-text {
|
||||
font-size: 13px;
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tab-wrapper {
|
||||
position: relative;
|
||||
top: -480rpx;
|
||||
height: 40px;
|
||||
background-color: #171825;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding-top: 3px;
|
||||
border-top-left-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
.tab-item {
|
||||
width: 250rpx;
|
||||
align-self: center;
|
||||
.tab-normal {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
align-self: center;
|
||||
color: #808080;
|
||||
}
|
||||
.tab-selected {
|
||||
color: #ffffff;
|
||||
}
|
||||
.selected-tab {
|
||||
margin-top: 5px;
|
||||
height: 5rpx;
|
||||
width: 250rpx;
|
||||
border-radius: 6rpx;
|
||||
background-color: #ef274d;
|
||||
}
|
||||
}
|
||||
}
|
||||
.vlog-list {
|
||||
position: relative;
|
||||
top: -480rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
background-color: #000000;
|
||||
.vlog-cover {
|
||||
align-self: center;
|
||||
width: 248rpx;
|
||||
height: 360rpx;
|
||||
border-width: 1rpx;
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
background-color: #000000;
|
||||
width: 750rpx;
|
||||
height: 300rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
top: -480rpx;
|
||||
.empty-text {
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
margin-top: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.not-empty {
|
||||
width: 750rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
top: -260rpx;
|
||||
.not-empty-text {
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -464,8 +464,13 @@ export default {
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
storage.setAccessToken(res.data.result.accessToken);
|
||||
storage.setRefreshToken(res.data.result.refreshToken);
|
||||
var infoData = res.data.result;
|
||||
storage.setAccessToken(infoData.accessToken);
|
||||
storage.setRefreshToken(infoData.refreshToken);
|
||||
const vlogInfo = JSON.parse(infoData.tikUser);
|
||||
// 将vlog的token和vlog用户信息放入缓存
|
||||
storage.setVlogToken(vlogInfo.userToken);
|
||||
storage.setVlogUserInfo(vlogInfo);
|
||||
// 登录成功
|
||||
uni.showToast({
|
||||
title: "第三方登录成功!",
|
||||
|
@ -1,375 +1,418 @@
|
||||
<template>
|
||||
<scroll-view class="prpage" scroll-y="true">
|
||||
<view class="line"></view>
|
||||
<!-- 进度条 -->
|
||||
<view class="progress" v-if="percentCompleted != 100">
|
||||
<progress :percent="percentCompleted" stroke-width="3" activeColor="#ef274d" backgroundColor="#F1F1F1" />
|
||||
<text class="progress-text">视频上传中,请耐心等待~~</text>
|
||||
<image class="progress-img" mode="aspectFit" src="/static/images/loading-4.gif" />
|
||||
</view>
|
||||
|
||||
<!-- 发布主体内容 -->
|
||||
<view class="main-body" v-if="percentCompleted == 100">
|
||||
<image class="main-body-img-m" v-if="tempCover" :src="tempCover" mode="widthFix" />
|
||||
<image class="main-body-img-m" v-if="!tempCover" src='/static/images/loading-4.gif' mode="aspectFit" />
|
||||
<view class="main-body-content">
|
||||
<view class="preplay-wrapper" @click="preview" @touchstart="touchstartPreplay"
|
||||
@touchend="touchendPreplay">
|
||||
<image class="preplay-icon" src="/static/images/btn-play.png" />
|
||||
<text class="preplay-text">预览视频</text>
|
||||
</view>
|
||||
<view class="choose-cover" @click="chooseCover">
|
||||
<text class="choose-cover-text">选择封面</text>
|
||||
</view>
|
||||
</view>
|
||||
<textarea class="vlog-content" placeholder-style="color: #9798a0;" placeholder="添加合适的描述内容~" :value="title"
|
||||
:model="title" maxlength="60" @input="typingContent" confirm-type="done"></textarea>
|
||||
<view class="mbtn" :class="{
|
||||
'btn-publish': !publishTouched,
|
||||
'btn-publish-touched': publishTouched,
|
||||
}" @touchstart="touchstartPublish" @touchend="touchendPublish" @click="doPublich">
|
||||
<text class="btn-text">发布视频</text>
|
||||
<template>
|
||||
<scroll-view
|
||||
class="prpage"
|
||||
scroll-y="true"
|
||||
>
|
||||
<view class="line"></view>
|
||||
<!-- 进度条 -->
|
||||
<view
|
||||
class="progress"
|
||||
v-if="percentCompleted != 100"
|
||||
>
|
||||
<progress
|
||||
:percent="percentCompleted"
|
||||
stroke-width="3"
|
||||
activeColor="#ef274d"
|
||||
backgroundColor="#F1F1F1"
|
||||
/>
|
||||
<text class="progress-text">视频上传中,请耐心等待~~</text>
|
||||
<image
|
||||
class="progress-img"
|
||||
mode="aspectFit"
|
||||
src="/static/images/loading-4.gif"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 发布主体内容 -->
|
||||
<view
|
||||
class="main-body"
|
||||
v-if="percentCompleted == 100"
|
||||
>
|
||||
<image
|
||||
class="main-body-img-m"
|
||||
v-if="tempCover"
|
||||
:src="tempCover"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image
|
||||
class="main-body-img-m"
|
||||
v-if="!tempCover"
|
||||
src="/static/images/loading-4.gif"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<view class="main-body-content">
|
||||
<view
|
||||
class="preplay-wrapper"
|
||||
@click="preview"
|
||||
@touchstart="touchstartPreplay"
|
||||
@touchend="touchendPreplay"
|
||||
>
|
||||
<image
|
||||
class="preplay-icon"
|
||||
src="/static/images/btn-play.png"
|
||||
/>
|
||||
<text class="preplay-text">预览视频</text>
|
||||
</view>
|
||||
<view
|
||||
class="choose-cover"
|
||||
@click="chooseCover"
|
||||
>
|
||||
<text class="choose-cover-text">选择封面</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js"; //缓存
|
||||
// import {
|
||||
// graceNumber
|
||||
// } from '@/utils/tools.js'
|
||||
import api from "@/config/api.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
publishTouched: false,
|
||||
preplayTouched: false,
|
||||
tempFilePath: "",
|
||||
videoUrl: "",
|
||||
tempCover: "", // 视频封面
|
||||
title: "",
|
||||
width: 0,
|
||||
height: 0,
|
||||
percentCompleted: 0, // 进度
|
||||
};
|
||||
},
|
||||
onLoad(params) {
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo()
|
||||
// 上个页面传过来的文件事件对象, 其中包含了相册中选择的视频内容
|
||||
let fileObjectEvent = JSON.parse(params.fileObjectEvent);
|
||||
let times = new Date().getTime();
|
||||
var userId = vlogInfo.id;
|
||||
let nickname = vlogInfo.nickname;
|
||||
|
||||
let serverUrl = api.vlog;
|
||||
const uploadTask = uni.uploadFile({
|
||||
filePath: fileObjectEvent.tempFilePath,
|
||||
url: serverUrl + "/upload",
|
||||
name: 'file',
|
||||
formData: {
|
||||
filetype: 'video'
|
||||
},
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken()
|
||||
},
|
||||
success: (f) => {
|
||||
console.log(f)
|
||||
let jsondata = f.data
|
||||
let data = JSON.parse(jsondata)
|
||||
let videoUrl = data.data;
|
||||
me.videoUrl = videoUrl;
|
||||
me.width = fileObjectEvent.width;
|
||||
me.height = fileObjectEvent.height;
|
||||
}
|
||||
})
|
||||
|
||||
uploadTask.onProgressUpdate((res) => {
|
||||
console.log('上传进度' + res.progress);
|
||||
// console.log('已经上传的数据长度' + res.totalBytesSent);
|
||||
// console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
|
||||
// 显示进度
|
||||
// let percentCompleted = Math.round(
|
||||
// (res.progress * 100) / res.total
|
||||
// );
|
||||
me.percentCompleted = res.progress
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
typingContent(e) {
|
||||
let event = e;
|
||||
this.title = e.detail.value;
|
||||
},
|
||||
doPublich() {
|
||||
if (this.title.length < 5) {
|
||||
uni.showToast({
|
||||
title: "请输入5个字以上的标题!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo()
|
||||
let userId = vlogInfo.id;
|
||||
let vlog = {
|
||||
vlogerId: userId,
|
||||
url: me.videoUrl,
|
||||
cover: me.tempCover || '',
|
||||
title: me.title,
|
||||
width: me.width,
|
||||
height: me.height,
|
||||
};
|
||||
|
||||
// 发布视频
|
||||
let serverUrl = api.vlog
|
||||
uni.request({
|
||||
method: "POST",
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken(),
|
||||
},
|
||||
url: serverUrl + "/vlog/publish",
|
||||
data: vlog,
|
||||
success(result) {
|
||||
if (result.data.status == 200) {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 2000,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
preview() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/publish/preview?videoUrl=" +
|
||||
this.videoUrl +
|
||||
"&width=" +
|
||||
this.width +
|
||||
"&height=" +
|
||||
this.height,
|
||||
animationType: "slide-in-bottom",
|
||||
animationDuration: 500,
|
||||
});
|
||||
},
|
||||
|
||||
touchstartPreplay() {
|
||||
this.preplayTouched = true;
|
||||
},
|
||||
|
||||
touchendPreplay() {
|
||||
this.preplayTouched = false;
|
||||
},
|
||||
|
||||
touchstartPublish() {
|
||||
this.publishTouched = true;
|
||||
},
|
||||
|
||||
touchendPublish() {
|
||||
this.publishTouched = false;
|
||||
},
|
||||
|
||||
chooseCover() {
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo()
|
||||
let userId = vlogInfo.id;
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: "original",
|
||||
sourceType: ["album"],
|
||||
success(e) {
|
||||
me.tempCover = e.tempFilePaths[0]; //先在本地回显
|
||||
// 上传封面
|
||||
let serverUrl = api.vlog;
|
||||
uni.uploadFile({
|
||||
filePath: e.tempFilePaths[0],
|
||||
url: serverUrl + "/upload",
|
||||
formData: {
|
||||
filetype: 'video'
|
||||
},
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken(),
|
||||
},
|
||||
name: "file",
|
||||
success(result) {
|
||||
let res = JSON.parse(result.data);
|
||||
console.log(res)
|
||||
if (res.status == 200) {
|
||||
let imageUrl = res.data;
|
||||
me.tempCover = imageUrl;
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 2000,
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.prpage {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #181b27;
|
||||
}
|
||||
|
||||
|
||||
.main-body-img-m {
|
||||
min-height: 400rpx;
|
||||
/* width: 750rpx; */
|
||||
border: 2rpx solid #545456;
|
||||
border-radius: 20rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.choose-cover-text {
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.choose-cover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin-left: 100rpx;
|
||||
margin-top: 10px;
|
||||
width: 200rpx;
|
||||
height: 100rpx;
|
||||
position: relative;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.preplay-icon {
|
||||
width: 22rpx;
|
||||
height: 22rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.preplay-text {
|
||||
color: #e6e6e6;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
|
||||
.preplay-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding: 6rpx 16rpx;
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
.main-body-content {
|
||||
/* display: flex; */
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
|
||||
}
|
||||
|
||||
.vlog-content {
|
||||
margin-top: 30rpx;
|
||||
height: 200rpx;
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
background-color: #ffffff;
|
||||
padding-left: 20rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: #e6e6e6;
|
||||
font-size: 36rpx;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mbtn {
|
||||
margin-top: 30rpx;
|
||||
height: 90rpx;
|
||||
/* display: flex; */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40rpx;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
.btn-publish {
|
||||
background-color: #ef274d;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-publish-touched {
|
||||
background-color: #de6981;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
.main-body {
|
||||
margin-top: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 1rpx;
|
||||
background-color: #393a41;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-top: 60rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
color: #f1f1f1;
|
||||
font-size: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.progress-img {
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<textarea
|
||||
class="vlog-content"
|
||||
placeholder-style="color: #9798a0;"
|
||||
placeholder="添加合适的描述内容~"
|
||||
:value="title"
|
||||
:model="title"
|
||||
maxlength="60"
|
||||
@input="typingContent"
|
||||
confirm-type="done"
|
||||
></textarea>
|
||||
<view
|
||||
class="mbtn"
|
||||
:class="{
|
||||
'btn-publish': !publishTouched,
|
||||
'btn-publish-touched': publishTouched
|
||||
}"
|
||||
@touchstart="touchstartPublish"
|
||||
@touchend="touchendPublish"
|
||||
@click="doPublich"
|
||||
>
|
||||
<text class="btn-text">发布视频</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
// import {
|
||||
// graceNumber
|
||||
// } from '@/utils/tools.js'
|
||||
import api from '@/config/api.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
publishTouched: false,
|
||||
preplayTouched: false,
|
||||
tempFilePath: '',
|
||||
videoUrl: '',
|
||||
tempCover: '', // 视频封面
|
||||
title: '',
|
||||
width: 0,
|
||||
height: 0,
|
||||
percentCompleted: 0 // 进度
|
||||
};
|
||||
},
|
||||
onLoad(params) {
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo();
|
||||
// 上个页面传过来的文件事件对象, 其中包含了相册中选择的视频内容
|
||||
let fileObjectEvent = JSON.parse(params.fileObjectEvent);
|
||||
let times = new Date().getTime();
|
||||
var userId = vlogInfo.id;
|
||||
let nickname = vlogInfo.nickname;
|
||||
|
||||
let serverUrl = api.vlog;
|
||||
const uploadTask = uni.uploadFile({
|
||||
filePath: fileObjectEvent.tempFilePath,
|
||||
url: serverUrl + '/upload',
|
||||
name: 'file',
|
||||
formData: {
|
||||
filetype: 'video'
|
||||
},
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken()
|
||||
},
|
||||
success: (f) => {
|
||||
console.log(f);
|
||||
let jsondata = f.data;
|
||||
let data = JSON.parse(jsondata);
|
||||
let videoUrl = data.data;
|
||||
me.videoUrl = videoUrl;
|
||||
me.width = fileObjectEvent.width;
|
||||
me.height = fileObjectEvent.height;
|
||||
}
|
||||
});
|
||||
|
||||
uploadTask.onProgressUpdate((res) => {
|
||||
console.log('上传进度' + res.progress);
|
||||
// console.log('已经上传的数据长度' + res.totalBytesSent);
|
||||
// console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
|
||||
// 显示进度
|
||||
// let percentCompleted = Math.round(
|
||||
// (res.progress * 100) / res.total
|
||||
// );
|
||||
me.percentCompleted = res.progress;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
typingContent(e) {
|
||||
let event = e;
|
||||
this.title = e.detail.value;
|
||||
},
|
||||
doPublich() {
|
||||
if (this.title.length < 5) {
|
||||
uni.showToast({
|
||||
title: '请输入5个字以上的标题!',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo();
|
||||
let userId = vlogInfo.id;
|
||||
let vlog = {
|
||||
vlogerId: userId,
|
||||
url: me.videoUrl,
|
||||
cover: me.tempCover || '',
|
||||
title: me.title,
|
||||
width: me.width,
|
||||
height: me.height,
|
||||
cityCode: storage.getCityCode()
|
||||
};
|
||||
|
||||
// 发布视频
|
||||
let serverUrl = api.vlog;
|
||||
uni.request({
|
||||
method: 'POST',
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken()
|
||||
},
|
||||
url: serverUrl + '/vlog/publish',
|
||||
data: vlog,
|
||||
success(result) {
|
||||
if (result.data.status == 200) {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/me/me'
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
preview() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/publish/preview?videoUrl=' + this.videoUrl + '&width=' + this.width + '&height=' + this.height,
|
||||
animationType: 'slide-in-bottom',
|
||||
animationDuration: 500
|
||||
});
|
||||
},
|
||||
|
||||
touchstartPreplay() {
|
||||
this.preplayTouched = true;
|
||||
},
|
||||
|
||||
touchendPreplay() {
|
||||
this.preplayTouched = false;
|
||||
},
|
||||
|
||||
touchstartPublish() {
|
||||
this.publishTouched = true;
|
||||
},
|
||||
|
||||
touchendPublish() {
|
||||
this.publishTouched = false;
|
||||
},
|
||||
|
||||
chooseCover() {
|
||||
let me = this;
|
||||
let vlogInfo = storage.getVlogUserInfo();
|
||||
let userId = vlogInfo.id;
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: 'original',
|
||||
sourceType: ['album'],
|
||||
success(e) {
|
||||
me.tempCover = e.tempFilePaths[0]; //先在本地回显
|
||||
// 上传封面
|
||||
let serverUrl = api.vlog;
|
||||
uni.uploadFile({
|
||||
filePath: e.tempFilePaths[0],
|
||||
url: serverUrl + '/upload',
|
||||
formData: {
|
||||
filetype: 'video'
|
||||
},
|
||||
header: {
|
||||
headerUserId: userId,
|
||||
headerUserToken: storage.getVlogToken()
|
||||
},
|
||||
name: 'file',
|
||||
success(result) {
|
||||
let res = JSON.parse(result.data);
|
||||
console.log(res);
|
||||
if (res.status == 200) {
|
||||
let imageUrl = res.data;
|
||||
me.tempCover = imageUrl;
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
duration: 2000
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.prpage {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #181b27;
|
||||
}
|
||||
|
||||
.main-body-img-m {
|
||||
min-height: 400rpx;
|
||||
/* width: 750rpx; */
|
||||
border: 2rpx solid #545456;
|
||||
border-radius: 20rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.choose-cover-text {
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.choose-cover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin-left: 100rpx;
|
||||
margin-top: 10px;
|
||||
width: 200rpx;
|
||||
height: 100rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.preplay-icon {
|
||||
width: 22rpx;
|
||||
height: 22rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.preplay-text {
|
||||
color: #e6e6e6;
|
||||
font-size: 28rpx;
|
||||
align-items: center;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
|
||||
.preplay-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding: 6rpx 16rpx;
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
.main-body-content {
|
||||
/* display: flex; */
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.vlog-content {
|
||||
margin-top: 30rpx;
|
||||
height: 200rpx;
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
background-color: #ffffff;
|
||||
padding-left: 20rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: #e6e6e6;
|
||||
font-size: 36rpx;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mbtn {
|
||||
margin-top: 30rpx;
|
||||
height: 90rpx;
|
||||
/* display: flex; */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40rpx;
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
.btn-publish {
|
||||
background-color: #ef274d;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-publish-touched {
|
||||
background-color: #de6981;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main-body {
|
||||
margin-top: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 1rpx;
|
||||
background-color: #393a41;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-top: 60rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
color: #f1f1f1;
|
||||
font-size: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.progress-img {
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
296
pages/search/search.vue
Executable file
296
pages/search/search.vue
Executable file
@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 这里是状态栏, 每个页面都需要有, 目的不让页面覆盖状态栏 -->
|
||||
<view :style="{ height: statusBarHeight + 'px' }"></view>
|
||||
<view class="big-search-wrapper">
|
||||
<image
|
||||
class="header-right-search icon-search"
|
||||
src="/static/images/icon-back.png"
|
||||
@click="back"
|
||||
/>
|
||||
<view class="search-box">
|
||||
<view class="search-box-left">
|
||||
<image
|
||||
class="header-right-search search-image"
|
||||
src="/static/images/icon-search.png"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
:model="searchContent"
|
||||
:value="searchContent"
|
||||
@input="typingContent"
|
||||
@confirm=""
|
||||
placeholder="请输入内容~"
|
||||
maxlength="10"
|
||||
class="search-input"
|
||||
/>
|
||||
|
||||
<!-- <view class="search-box-right">
|
||||
<image
|
||||
class="scan-image"
|
||||
src="/static/images/icon-scan-qrcode.png"
|
||||
@click="scan"
|
||||
/>
|
||||
</view> -->
|
||||
</view>
|
||||
<view
|
||||
class="sbtn"
|
||||
@click="doSearch"
|
||||
>
|
||||
搜索
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="history">
|
||||
<view
|
||||
v-for="(h, index) in historyList"
|
||||
:key="index"
|
||||
class="history-item-wrapper"
|
||||
>
|
||||
<view
|
||||
class="time-and-text"
|
||||
@click="searchByHistory(h)"
|
||||
>
|
||||
<image
|
||||
class="time-image"
|
||||
src="/static/images/icon-time.png"
|
||||
/>
|
||||
<text class="history-text">{{ h }}</text>
|
||||
</view>
|
||||
<image
|
||||
class="delete-image"
|
||||
src="/static/images/icon-delete.png"
|
||||
@click="removeHistoryItem(index)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-if="historyList.length == 0"
|
||||
class="clear-all-wrapper"
|
||||
@click="removeAllHistory"
|
||||
>
|
||||
<text class="clear-all"></text>
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="clear-all-wrapper"
|
||||
@click="removeAllHistory"
|
||||
>
|
||||
<text class="clear-all">清除所有搜索记录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let system = uni.getSystemInfoSync();
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
import { isStrEmpty } from '@/utils/tools.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchContent: '',
|
||||
historyList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.statusBarHeight = system.statusBarHeight;
|
||||
|
||||
// 从本地缓存获得搜索的历史记录
|
||||
let historyListJSON = uni.getStorageSync('historyList') || null;
|
||||
console.log(historyListJSON);
|
||||
if (historyListJSON != null && historyListJSON != undefined) {
|
||||
this.historyList = JSON.parse(historyListJSON);
|
||||
} else {
|
||||
this.historyList = [];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
},
|
||||
scan() {
|
||||
// 扫描二维码跳转视频详情,先不做
|
||||
// uni.scanCode({
|
||||
// success: (e) => {
|
||||
// let result = e.result;
|
||||
// let vlogId = JSON.parse(result).content;
|
||||
// uni.navigateTo({
|
||||
// url: '../vlog/vlog?vlogId=' + vlogId
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
},
|
||||
typingContent(e) {
|
||||
this.searchContent = e.detail.value;
|
||||
},
|
||||
searchByHistory(searchContent) {
|
||||
console.log(searchContent);
|
||||
this.searchContent = searchContent;
|
||||
this.doSearch();
|
||||
},
|
||||
doSearch() {
|
||||
var searchContent = this.searchContent;
|
||||
if (isStrEmpty(this.searchContent)) {
|
||||
uni.showToast({
|
||||
title: '搜索关键字为空!',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
this.searchContent = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let tempList = this.historyList;
|
||||
// 判断搜索内容是否已经存在, 如果存在, 则移除
|
||||
for (let i = 0; i < tempList.length; i++) {
|
||||
let old = tempList[i];
|
||||
if (this.searchContent === old) {
|
||||
tempList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tempList.unshift(searchContent);
|
||||
|
||||
// 如果超过10个, 则删除第一一项
|
||||
if (tempList.length > 10) {
|
||||
tempList.splice(0, 1);
|
||||
this.historyList = tempList;
|
||||
}
|
||||
|
||||
// 保存到本地缓存
|
||||
uni.setStorageSync('historyList', JSON.stringify(this.historyList));
|
||||
|
||||
// 跳转页面, 把搜索条件携带过去
|
||||
uni.navigateTo({
|
||||
url: 'searchList?search=' + searchContent
|
||||
});
|
||||
},
|
||||
|
||||
removeHistoryItem(index) {
|
||||
this.historyList.splice(index, 1);
|
||||
uni.setStorageSync('historyList', JSON.stringify(this.historyList));
|
||||
},
|
||||
|
||||
removeAllHistory() {
|
||||
this.historyList = [];
|
||||
uni.setStorageSync('historyList', JSON.stringify(this.historyList));
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scope>
|
||||
.page {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #181b27;
|
||||
|
||||
.big-search-wrapper {
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
.header-right-search {
|
||||
height: 100rpx;
|
||||
}
|
||||
.icon-search {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.search-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.search-box-left {
|
||||
padding: 0 10rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: #55565e;
|
||||
border-top-left-radius: 6rpx;
|
||||
border-bottom-left-radius: 6rpx;
|
||||
.search-image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-input {
|
||||
width: 410rpx;
|
||||
height: 50rpx;
|
||||
background-color: #55565e;
|
||||
font-size: 28rpx;
|
||||
color: #ffffff;
|
||||
border-top-right-radius: 6rpx;
|
||||
border-bottom-right-radius: 6rpx;
|
||||
}
|
||||
.search-box-right {
|
||||
padding: 0 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: #55565e;
|
||||
border-top-right-radius: 6rpx;
|
||||
border-bottom-right-radius: 6rpx;
|
||||
.scan-image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.sbtn {
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.history {
|
||||
.history-item-wrapper {
|
||||
padding: 16rpx 26rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
.time-and-text {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 500rpx;
|
||||
.time-image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
.history-text {
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
.delete-image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
.clear-all-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-top: 40rpx;
|
||||
.clear-all {
|
||||
color: #f1f1f1;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
399
pages/search/searchList.vue
Executable file
399
pages/search/searchList.vue
Executable file
@ -0,0 +1,399 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view :style="{ height: statusBarHeight + 'px' }">
|
||||
<!-- 这里是状态栏, 每个页面都需要有, 目的不让页面覆盖状态栏 -->
|
||||
</view>
|
||||
<view class="big-search-wrapper">
|
||||
<image
|
||||
class="header-right-search icon-search"
|
||||
src="/static/images/icon-back.png"
|
||||
@click="back"
|
||||
/>
|
||||
<view class="search-box">
|
||||
<view class="search-box-left">
|
||||
<image
|
||||
class="header-right-search search-image"
|
||||
src="/static/images/icon-search.png"
|
||||
/>
|
||||
</view>
|
||||
<input
|
||||
type="text"
|
||||
:model="searchContent"
|
||||
:value="searchContent"
|
||||
@input="typingContent"
|
||||
placeholder="请输入内容~"
|
||||
maxlength="10"
|
||||
class="search-input"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
class="sbtn"
|
||||
@click="doSearch"
|
||||
>
|
||||
搜索
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mainCont">
|
||||
<view
|
||||
class="wrap"
|
||||
:style="{ height: screenHeight - statusBarHeight - 50 + 'px' }"
|
||||
>
|
||||
<view class="u-tabs-box">
|
||||
<u-tabs-swiper
|
||||
bgColor=" #F5F5F5"
|
||||
activeColor="#FF3229"
|
||||
ref="tabs"
|
||||
:list="list"
|
||||
:current="current"
|
||||
@change="change"
|
||||
:is-scroll="false"
|
||||
swiperWidth="750"
|
||||
font-size="30rpx"
|
||||
barWidth="24"
|
||||
barHeight="8"
|
||||
></u-tabs-swiper>
|
||||
</view>
|
||||
<swiper
|
||||
class="swiper-box"
|
||||
:current="swiperCurrent"
|
||||
@transition="transition"
|
||||
@animationfinish="animationfinish"
|
||||
>
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="no-scrollbar"
|
||||
style="height: 100%; width: 100%"
|
||||
@scrolltolower="reachBottom"
|
||||
>
|
||||
<view class="page-box">
|
||||
<!--视频-->
|
||||
<search-vd
|
||||
ref="vd"
|
||||
:keywords="searchContent"
|
||||
></search-vd>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="no-scrollbar"
|
||||
style="height: 100%; width: 100%"
|
||||
@scrolltolower="reachBottom"
|
||||
>
|
||||
<view class="page-box">
|
||||
<!--商品-->
|
||||
<shop
|
||||
ref="shop"
|
||||
:keywords="searchContent"
|
||||
></shop>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="no-scrollbar"
|
||||
style="height: 100%; width: 100%"
|
||||
@scrolltolower="reachBottom"
|
||||
>
|
||||
<view class="page-box">
|
||||
<!--用户-->
|
||||
<user
|
||||
ref="user"
|
||||
:keywords="searchContent"
|
||||
></user>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="no-scrollbar"
|
||||
style="height: 100%; width: 100%"
|
||||
@scrolltolower="reachBottom"
|
||||
>
|
||||
<view class="page-box">
|
||||
<!--团购-->
|
||||
<tuangou
|
||||
ref="tuangou"
|
||||
:keywords="searchContent"
|
||||
></tuangou>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- <view class="page-footer">
|
||||
<view class="contract-button">
|
||||
自定义底部栏
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let system = uni.getSystemInfoSync();
|
||||
console.log(system);
|
||||
import { isStrEmpty } from '@/utils/tools.js';
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
import searchVd from './searchVd.vue';
|
||||
import shop from './shop';
|
||||
import user from './user';
|
||||
import tuangou from './tuangou';
|
||||
export default {
|
||||
components: {
|
||||
searchVd,
|
||||
shop,
|
||||
user,
|
||||
tuangou
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
screenHeight: 0,
|
||||
statusBarHeight: 0,
|
||||
search: '',
|
||||
searchContent: '',
|
||||
// tabs
|
||||
list: [
|
||||
{
|
||||
name: '视频'
|
||||
},
|
||||
{
|
||||
name: '商品'
|
||||
},
|
||||
{
|
||||
name: '用户'
|
||||
},
|
||||
{
|
||||
name: '团购'
|
||||
}
|
||||
],
|
||||
listValue: ['vd', 'shop', 'user', 'tuangou'],
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
dx: 0
|
||||
// tabs-end
|
||||
};
|
||||
},
|
||||
onLoad(params) {
|
||||
this.statusBarHeight = system.statusBarHeight;
|
||||
let screenHeight = system.safeArea.bottom;
|
||||
this.screenHeight = screenHeight;
|
||||
// 搜索的关键字
|
||||
let search = params.search || ''.trim();
|
||||
this.searchContent = params.search;
|
||||
},
|
||||
watch: {
|
||||
current(n) {
|
||||
this.initCurrentData();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 初始化数据
|
||||
initCurrentData() {
|
||||
console.log(this.current);
|
||||
var prop = this.listValue[this.current];
|
||||
var dom = this.$refs[prop];
|
||||
var child = dom.search; //子组件内部的关键字
|
||||
console.log('子关键字:' + child);
|
||||
var flag = dom.flag; // 子组件内部索引
|
||||
var parent = this.searchContent;
|
||||
console.log('fu关键字:' + parent);
|
||||
if (parent != child && this.swiperCurrent == flag && this.searchContent != '') {
|
||||
dom.initData();
|
||||
}
|
||||
},
|
||||
// tab栏切换
|
||||
change(index) {
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
transition({ detail: { dx } }) {
|
||||
this.$refs.tabs.setDx(dx);
|
||||
},
|
||||
animationfinish({ detail: { current } }) {
|
||||
this.$refs.tabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
},
|
||||
reachBottom() {
|
||||
console.log('触底' + this.current);
|
||||
var prop = this.listValue[this.current];
|
||||
var dom = this.$refs[prop];
|
||||
dom.getData();
|
||||
},
|
||||
doSearch() {
|
||||
let me = this;
|
||||
let searchContent = this.searchContent;
|
||||
if (isStrEmpty(searchContent)) {
|
||||
uni.showToast({
|
||||
title: '搜索为空!',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
this.searchContent = '';
|
||||
return;
|
||||
} else {
|
||||
this.initCurrentData();
|
||||
}
|
||||
},
|
||||
typingContent(e) {
|
||||
this.searchContent = e.detail.value || ''.trim();
|
||||
},
|
||||
back() {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page {
|
||||
// position: absolute;
|
||||
// left: 0;
|
||||
// right: 0;
|
||||
// top: 0;
|
||||
// bottom: 0;
|
||||
background-color: #181b27;
|
||||
|
||||
.big-search-wrapper {
|
||||
padding: 14px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
.header-right-search {
|
||||
height: 50px;
|
||||
}
|
||||
.icon-search {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.search-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.search-box-left {
|
||||
padding: 0 10rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: #55565e;
|
||||
border-top-left-radius: 6rpx;
|
||||
border-bottom-left-radius: 6rpx;
|
||||
.search-image {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-input {
|
||||
width: 410rpx;
|
||||
height: 25px;
|
||||
background-color: #55565e;
|
||||
font-size: 28rpx;
|
||||
color: #ffffff;
|
||||
border-top-right-radius: 6rpx;
|
||||
border-bottom-right-radius: 6rpx;
|
||||
}
|
||||
.search-box-right {
|
||||
padding: 0 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: #55565e;
|
||||
border-top-right-radius: 6rpx;
|
||||
border-bottom-right-radius: 6rpx;
|
||||
.scan-image {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.sbtn {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
// 隐藏ios端滚动条
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
//
|
||||
.mainCont {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.u-tabs-box {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.page-box {
|
||||
width: 710rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.swiper-item {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// footer config
|
||||
// .page-footer {
|
||||
// width: 750rpx;
|
||||
// height: 128rpx;
|
||||
// background: #ffffff;
|
||||
// box-shadow: 0rpx -4rpx 16rpx rgba(219, 208, 208, 0.61);
|
||||
// opacity: 1;
|
||||
// border-radius: 0rpx;
|
||||
|
||||
// .contract-button {
|
||||
// width: 686rpx;
|
||||
// height: 80rpx;
|
||||
|
||||
// margin-top: 24rpx;
|
||||
// margin-left: 32rpx;
|
||||
|
||||
// font-size: 34rpx;
|
||||
// font-family: PingFang SC;
|
||||
// font-weight: 500;
|
||||
|
||||
// text-align: center;
|
||||
|
||||
// line-height: 80rpx;
|
||||
// color: #ffffff;
|
||||
// letter-spacing: 5rpx;
|
||||
|
||||
// background: linear-gradient(137deg, #ff3229 0%, #ff7b59 100%);
|
||||
// opacity: 1;
|
||||
// border-radius: 40rpx;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
</style>
|
243
pages/search/searchVd.vue
Normal file
243
pages/search/searchVd.vue
Normal file
@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view v-if="flowList.length">
|
||||
<u-waterfall
|
||||
v-model="flowList"
|
||||
ref="uWaterfall"
|
||||
idKey="vlogId"
|
||||
>
|
||||
<template v-slot:left="{ leftList }">
|
||||
<view
|
||||
class="demo-warter"
|
||||
v-for="(item, index) in leftList"
|
||||
:key="index"
|
||||
@click="goToVlog(item.vlogId)"
|
||||
>
|
||||
<u-lazy-load
|
||||
border-radius="10"
|
||||
:image="item.cover || item.firstFrameImg"
|
||||
:index="index"
|
||||
></u-lazy-load>
|
||||
<view class="content">
|
||||
{{ item.content }}
|
||||
</view>
|
||||
<view class="flxbox">
|
||||
<view class="bottom-info">
|
||||
<u-image
|
||||
width="30rpx"
|
||||
height="30rpx"
|
||||
:src="item.vlogerFace"
|
||||
loading-icon="/static/missing-face.png"
|
||||
error-icon="/static/missing-face.png"
|
||||
shape="circle"
|
||||
style="display: flex; align-items: center"
|
||||
></u-image>
|
||||
<view class="showOne ml">{{ item.vlogerName }}</view>
|
||||
</view>
|
||||
<view class="bottom-info">
|
||||
<image
|
||||
style="width: 20rpx; height: 20rpx"
|
||||
src="/static/images/icon-comment-unlike.png"
|
||||
></image>
|
||||
<view class="ml">{{ getGraceNumber(item.likeCounts) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:right="{ rightList }">
|
||||
<view
|
||||
class="demo-warter"
|
||||
v-for="(item, index) in rightList"
|
||||
:key="index"
|
||||
@click="goToVlog(item.vlogId)"
|
||||
>
|
||||
<u-lazy-load
|
||||
border-radius="10"
|
||||
:image="item.cover || item.firstFrameImg"
|
||||
:index="index"
|
||||
></u-lazy-load>
|
||||
<view class="content">
|
||||
{{ item.content }}
|
||||
</view>
|
||||
<view class="flxbox">
|
||||
<view class="bottom-info">
|
||||
<u-image
|
||||
width="30rpx"
|
||||
height="30rpx"
|
||||
loading-icon="/static/missing-face.png"
|
||||
error-icon="/static/missing-face.png"
|
||||
:src="item.vlogerFace"
|
||||
shape="circle"
|
||||
style="display: flex; align-items: center"
|
||||
></u-image>
|
||||
<view class="showOne ml">{{ item.vlogerName }}</view>
|
||||
</view>
|
||||
<view class="bottom-info">
|
||||
<image
|
||||
style="width: 20rpx; height: 20rpx"
|
||||
src="/static/images/icon-comment-unlike.png"
|
||||
></image>
|
||||
<view class="ml">{{ getGraceNumber(item.likeCounts) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-waterfall>
|
||||
<u-loadmore
|
||||
style="padding: 10px 0"
|
||||
bg-color="#f8f8f8"
|
||||
:status="loadStatus"
|
||||
@loadmore="getData"
|
||||
></u-loadmore>
|
||||
</view>
|
||||
|
||||
<u-empty
|
||||
class="mt20"
|
||||
v-else
|
||||
text="暂无数据"
|
||||
mode="data"
|
||||
></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { vlogList } from '@/api/vlog';
|
||||
import { graceNumber, isStrEmpty } from '@/utils/tools.js';
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
export default {
|
||||
props: {
|
||||
keywords: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: 0, // 在tabs中的索引
|
||||
loadStatus: 'loadmore',
|
||||
flowList: [],
|
||||
page: 0,
|
||||
totalPage: 0,
|
||||
search: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
this.clear();
|
||||
this.search = this.keywords;
|
||||
this.page = 0;
|
||||
this.totalPage = 0;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
this.getData();
|
||||
},
|
||||
async getData() {
|
||||
try {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
let me = this;
|
||||
me.loadStatus = 'loading';
|
||||
let page = me.page + 1;
|
||||
let keywords = me.search;
|
||||
let userInfo = storage.getVlogUserInfo();
|
||||
let userId = '';
|
||||
if (userInfo != null) {
|
||||
userId = userInfo.id;
|
||||
}
|
||||
var result = await vlogList(page, 10, userId, '', keywords);
|
||||
console.log(result);
|
||||
if (result.data.status == 200) {
|
||||
let flowList = result.data.data.rows;
|
||||
let totalPage = result.data.data.total;
|
||||
me.flowList = me.flowList.concat(flowList);
|
||||
me.page = page;
|
||||
me.totalPage = totalPage;
|
||||
if (page >= totalPage) {
|
||||
me.loadStatus = 'nomore';
|
||||
} else {
|
||||
me.loadStatus = 'loadmore';
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.loadStatus = 'nomore';
|
||||
}
|
||||
},
|
||||
// 把超过1000或10000的数字调整,比如1.3k/6.8w
|
||||
getGraceNumber(num) {
|
||||
return graceNumber(num);
|
||||
},
|
||||
goToVlog(vlogId) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/vlog?vlogId=' + vlogId
|
||||
});
|
||||
},
|
||||
remove(id) {
|
||||
this.$refs.uWaterfall.remove(id);
|
||||
},
|
||||
clear() {
|
||||
var dom = this.$refs.uWaterfall;
|
||||
if (dom) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mt20 {
|
||||
margin-top: 20% !important;
|
||||
}
|
||||
.demo-warter {
|
||||
border-radius: 8px;
|
||||
margin: 5px;
|
||||
background-color: #ffffff;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
max-width: 329rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.u-close {
|
||||
position: absolute;
|
||||
top: 32rpx;
|
||||
right: 32rpx;
|
||||
}
|
||||
|
||||
.showOne {
|
||||
width: 200rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.content {
|
||||
// width: 329rpx;
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
margin-top: 5px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3; /* 最多显示三行 */
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.flxbox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.bottom-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 22rpx;
|
||||
color: $u-tips-color;
|
||||
}
|
||||
.ml {
|
||||
display: block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
</style>
|
818
pages/search/shop.vue
Normal file
818
pages/search/shop.vue
Normal file
@ -0,0 +1,818 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view v-if="flowList.length">
|
||||
<view class="goods-list">
|
||||
<view
|
||||
v-for="(item, index) in flowList"
|
||||
:key="index"
|
||||
class="goods-item"
|
||||
>
|
||||
<view
|
||||
class="image-wrapper"
|
||||
@click="navigateToDetailPage(item)"
|
||||
>
|
||||
<image
|
||||
:src="removeOssStyle(item.content.thumbnail)"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
</view>
|
||||
<view class="goods-detail">
|
||||
<div
|
||||
class="title"
|
||||
@click="navigateToDetailPage(item)"
|
||||
>
|
||||
{{ item.content.goodsName }}
|
||||
</div>
|
||||
<view
|
||||
class="price-box"
|
||||
@click="navigateToDetailPage(item)"
|
||||
>
|
||||
<div
|
||||
class="price"
|
||||
v-if="item.content.price != undefined"
|
||||
>
|
||||
¥
|
||||
<span>{{ formatPrice(item.content.price)[0] }}</span>
|
||||
.{{ formatPrice(item.content.price)[1] }}
|
||||
</div>
|
||||
</view>
|
||||
|
||||
<div
|
||||
class="promotion"
|
||||
@click="navigateToDetailPage(item)"
|
||||
>
|
||||
<div
|
||||
v-for="(promotionItem, promotionIndex) in getPromotion(item)"
|
||||
:key="promotionIndex"
|
||||
>
|
||||
<span v-if="promotionItem.indexOf('COUPON') != -1">劵</span>
|
||||
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1">满减</span>
|
||||
<span v-if="promotionItem.indexOf('SECKILL') != -1">秒杀</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="count-config"
|
||||
@click="navigateToDetailPage(item)"
|
||||
>
|
||||
<span>已售 {{ item.content.buyCount || '0' }}</span>
|
||||
<span>{{ item.content.commentNum || '0' }}条评论</span>
|
||||
</div>
|
||||
<div
|
||||
class="store-seller-name"
|
||||
@click="navigateToStoreDetailPage(item)"
|
||||
>
|
||||
<div class="text-hidden">
|
||||
<u-tag
|
||||
style="margin-right: 10rpx"
|
||||
size="mini"
|
||||
mode="dark"
|
||||
v-if="item.selfOperated"
|
||||
text="自营"
|
||||
type="error"
|
||||
/>
|
||||
<span>{{ item.content.storeName || '暂无' }}</span>
|
||||
</div>
|
||||
<span>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</span>
|
||||
</div>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-loadmore
|
||||
style="padding: 10px 0"
|
||||
bg-color="#f8f8f8"
|
||||
:status="loadStatus"
|
||||
@loadmore="getData"
|
||||
></u-loadmore>
|
||||
</view>
|
||||
<u-empty
|
||||
v-else
|
||||
class="mt20"
|
||||
style="margin-top: 20%"
|
||||
text="暂无数据"
|
||||
mode="data"
|
||||
></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGoodsList } from '@/api/goods.js';
|
||||
export default {
|
||||
props: {
|
||||
keywords: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: 1, // 在tabs中的索引
|
||||
loadStatus: 'loadmore',
|
||||
flowList: [],
|
||||
page: 0,
|
||||
totalPage: 0,
|
||||
search: ''
|
||||
// 查询商品参数
|
||||
// params: {
|
||||
// pageNumber: 1,
|
||||
// pageSize: 10,
|
||||
// keyword: "",
|
||||
// }
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
async getData() {
|
||||
if (this.loadStatus != 'loadmore') return;
|
||||
console.log('加载商品数据');
|
||||
this.page += 1;
|
||||
var params = {
|
||||
pageNumber: this.page,
|
||||
pageSize: 10,
|
||||
keyword: this.search
|
||||
};
|
||||
var res = await getGoodsList(params);
|
||||
console.log(res);
|
||||
if (res.data.result.content.length < 10) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.loadStatus = 'loadmore';
|
||||
}
|
||||
this.flowList.push(...res.data.result.content);
|
||||
},
|
||||
initData() {
|
||||
this.search = this.keywords;
|
||||
this.page = 0;
|
||||
this.totalPage = 0;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
console.log('初始化商品数据');
|
||||
this.getData();
|
||||
},
|
||||
formatPrice(val) {
|
||||
if (typeof val == 'undefined') {
|
||||
return val;
|
||||
}
|
||||
return val.toFixed(2).split('.');
|
||||
},
|
||||
// 数据去重一下 只显示一次 减免 劵 什么的
|
||||
getPromotion(item) {
|
||||
if (item.promotionMap) {
|
||||
let array = [];
|
||||
Object.keys(item.promotionMap).forEach((child) => {
|
||||
if (!array.includes(child.split('-')[0])) {
|
||||
array.push(child.split('-')[0]);
|
||||
}
|
||||
});
|
||||
|
||||
return array;
|
||||
}
|
||||
},
|
||||
removeOssStyle(url) {
|
||||
return url.split('?')[0];
|
||||
},
|
||||
// 跳转到商品详情
|
||||
navigateToDetailPage(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.content.id}&goodsId=${item.content.goodsId}`
|
||||
});
|
||||
},
|
||||
// 跳转地址
|
||||
navigateToStoreDetailPage(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/shopPage?id=${item.content.storeId}`
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mt20 {
|
||||
margin-top: 20% !important;
|
||||
}
|
||||
.sort-active {
|
||||
border: 1px solid $light-color;
|
||||
color: $light-color;
|
||||
background: $price-light-color !important;
|
||||
}
|
||||
|
||||
.oldKeyList {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 20rpx 3%;
|
||||
> .oldKeyItem {
|
||||
padding: 4rpx 24rpx;
|
||||
background: #f0f2f5;
|
||||
margin-right: 20rpx;
|
||||
max-width: 200rpx;
|
||||
border-radius: 100px;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.promotion {
|
||||
margin-top: 4rpx;
|
||||
display: flex;
|
||||
div {
|
||||
span {
|
||||
font-size: 24rpx;
|
||||
color: $light-color;
|
||||
margin-right: 10rpx;
|
||||
padding: 0 4rpx;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.status_bar {
|
||||
height: var(--status-bar-height);
|
||||
background: #fff !important;
|
||||
width: 100%;
|
||||
}
|
||||
page {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
.sort-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background: #f7f7f7;
|
||||
.sort-list {
|
||||
margin: 20rpx 0;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
> .sort-item {
|
||||
> .sort-title {
|
||||
margin: 20rpx 0;
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.null-view {
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.sort-btn {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
border-top: 1px solid #f7f7f7;
|
||||
height: 100rpx;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
align-items: center;
|
||||
> view {
|
||||
width: 50%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
margin: 0 20rpx;
|
||||
border-radius: 1000px;
|
||||
}
|
||||
> .sort-btn-repick {
|
||||
border: 1px solid #ededed;
|
||||
}
|
||||
> .sort-btn-confim {
|
||||
color: #fff;
|
||||
background-image: linear-gradient(90deg, #ff6b35, #ff9f28, #ffcc03);
|
||||
}
|
||||
}
|
||||
.uinput {
|
||||
width: 50% !important;
|
||||
> .sort-radius {
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
/deep/ .uni-input-input {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
.sort-radius {
|
||||
margin: 0 12rpx;
|
||||
background: #f7f7f7;
|
||||
height: 65rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 1000px;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.flex {
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
> .sort-brand-item {
|
||||
width: 33%;
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
.scoll-page {
|
||||
overflow: auto;
|
||||
}
|
||||
.content {
|
||||
background-color: $bg-color;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.index-nav-arrow:last-child {
|
||||
margin-top: -22rpx;
|
||||
}
|
||||
.line1-store-name {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
.to-store {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.img {
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
}
|
||||
.goods-row {
|
||||
background: #fff;
|
||||
padding: 16rpx;
|
||||
|
||||
> .goods-col {
|
||||
display: flex;
|
||||
> .goods-img {
|
||||
flex: 4;
|
||||
}
|
||||
> .goods-detail {
|
||||
flex: 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add1 {
|
||||
background: #fff;
|
||||
padding: 30rpx 0;
|
||||
}
|
||||
|
||||
.oldKeyRow {
|
||||
background: #fff;
|
||||
padding: 34rpx 3%;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.clamp3 {
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
font-weight: 400;
|
||||
display: -webkit-box;
|
||||
height: 80rpx;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
-webkit-line-clamp: 2 !important;
|
||||
|
||||
overflow: hidden;
|
||||
> span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.store-seller-name {
|
||||
color: #666;
|
||||
overflow: hidden;
|
||||
|
||||
> div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
> span {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.count-config {
|
||||
padding: 10rpx 0;
|
||||
color: #666;
|
||||
display: flex;
|
||||
font-size: 24rpx;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
z-index: 99;
|
||||
width: 100%;
|
||||
background: $light-color;
|
||||
padding: 20rpx 2.5%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.search-box .mSearch-input-box {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-box .input-box {
|
||||
width: 85%;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-box .search-btn {
|
||||
width: 15%;
|
||||
margin: 0 0 0 2%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(to right, #ff9801, #ff570a);
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
|
||||
.search-box .input-box > input {
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
font-size: 32rpx;
|
||||
border: 0;
|
||||
border-radius: 60rpx;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
padding: 0 3%;
|
||||
margin: 0;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.uni-scroll-view-content {
|
||||
background: #ededed !important;
|
||||
}
|
||||
|
||||
.placeholder-class {
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
.search-keyword {
|
||||
width: 100%;
|
||||
background-color: #ededed;
|
||||
}
|
||||
|
||||
.keyword-list-box {
|
||||
height: calc(100vh - 110rpx);
|
||||
padding-top: 10rpx;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.keyword-entry-tap {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.keyword-entry {
|
||||
width: 94%;
|
||||
height: 80rpx;
|
||||
margin: 0 3%;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: solid 1rpx #e7e7e7;
|
||||
}
|
||||
|
||||
.keyword-entry image {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
.keyword-entry .keyword-text,
|
||||
.keyword-entry .keyword-img {
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keyword-entry .keyword-text {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.keyword-entry .keyword-img {
|
||||
width: 10%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.keyword-box {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.keyword-box .keyword-block {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.keyword-box .keyword-block .keyword-list-header {
|
||||
width: 100%;
|
||||
padding: 20rpx 3%;
|
||||
font-size: 27rpx;
|
||||
color: #333;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.keyword-box .keyword-block .keyword-list-header image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.keyword-box .keyword-block .keyword > view {
|
||||
width: 50%;
|
||||
line-height: 1.75;
|
||||
overflow: hidden;
|
||||
padding: 0 3% 0 3% !important;
|
||||
}
|
||||
|
||||
.u-tips {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.keyword-box {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.clear {
|
||||
color: #666666;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.keyword-box .keyword-block .hide-hot-tis {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: #fff;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
|
||||
z-index: 10;
|
||||
// position: fixed;
|
||||
// left: 0;
|
||||
// top: var(--status-bar-height);
|
||||
.nav-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
font-size: 30rpx;
|
||||
color: $font-color-dark;
|
||||
position: relative;
|
||||
}
|
||||
.current {
|
||||
color: $light-color;
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
transform: translateX(-50%);
|
||||
width: 40rpx;
|
||||
height: 0;
|
||||
border-bottom: 4rpx solid $light-color;
|
||||
}
|
||||
}
|
||||
.p-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.yticon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30rpx;
|
||||
height: 14rpx;
|
||||
line-height: 1;
|
||||
margin-left: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.xia {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
}
|
||||
|
||||
.cate-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 80rpx;
|
||||
position: relative;
|
||||
font-size: 44rpx;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border-left: 1px solid #ddd;
|
||||
width: 0;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分类 */
|
||||
.cate-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: var(--window-top);
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
z-index: 95;
|
||||
transition: 0.3s;
|
||||
|
||||
.cate-content {
|
||||
width: 630rpx;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
float: right;
|
||||
transform: translateX(100%);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
&.none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.show {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
|
||||
.cate-content {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cate-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.cate-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
padding-left: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.two {
|
||||
height: 64rpx;
|
||||
color: #303133;
|
||||
font-size: 30rpx;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
}
|
||||
.price-box {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-right: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: $main-color;
|
||||
font-weight: bold;
|
||||
/deep/ span:nth-of-type(1) {
|
||||
font-size: 38rpx;
|
||||
}
|
||||
}
|
||||
/* 商品列表 */
|
||||
.goods-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 10rpx 20rpx 0;
|
||||
|
||||
// background: #fff;
|
||||
width: 100%;
|
||||
.goods-item {
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
border-radius: 16rpx;
|
||||
flex-direction: column;
|
||||
width: calc(50% - 30rpx);
|
||||
margin-bottom: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
&:nth-child(2n + 1) {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.goods-detail {
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 330rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: $font-base;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.5;
|
||||
height: 84rpx;
|
||||
padding: 10rpx 0 0;
|
||||
display: -webkit-box;
|
||||
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
-webkit-line-clamp: 2;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.count-config,
|
||||
.store-seller-name {
|
||||
font-size: $font-sm;
|
||||
}
|
||||
|
||||
.text-hidden {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.status_bar {
|
||||
height: var(--status-bar-height);
|
||||
width: 100%;
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding-top: 300rpx;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
/deep/ .u-image {
|
||||
width: 346rpx;
|
||||
height: 304rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
288
pages/search/tuangou.vue
Normal file
288
pages/search/tuangou.vue
Normal file
@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<view class="wrapper">
|
||||
<!-- 商品栏 -->
|
||||
<div class="swiper">
|
||||
<div v-if="groupBuy.length != 0">
|
||||
<view
|
||||
class="view-item"
|
||||
v-for="(groupItem, groupIndex) in groupBuy"
|
||||
:key="groupIndex"
|
||||
>
|
||||
<view class="view-left">
|
||||
<u-image
|
||||
border-radius="10"
|
||||
shape="square"
|
||||
:src="groupItem.thumbnail"
|
||||
width="186rpx"
|
||||
height="186rpx"
|
||||
>
|
||||
<view
|
||||
slot="error"
|
||||
style="font-size: 24rpx"
|
||||
>
|
||||
加载失败
|
||||
</view>
|
||||
</u-image>
|
||||
</view>
|
||||
<view class="view-content">
|
||||
<view class="view-content-name">
|
||||
{{ groupItem.goodsName }}
|
||||
</view>
|
||||
<view class="view-content-bottom">
|
||||
<view>
|
||||
<view class="view-content-price">
|
||||
<!-- ¥{{groupItem.sales_price | unitPrice }} <span v-if="groupItem.point">+{{groupItem.point}}积分</span> -->
|
||||
¥{{ groupItem.price | unitPrice }}
|
||||
</view>
|
||||
<view class="view-content-original_price">¥{{ groupItem.originalPrice | unitPrice }}</view>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<view
|
||||
class="btn-group"
|
||||
@click="toHref(groupItem)"
|
||||
>
|
||||
去拼团
|
||||
</view>
|
||||
<view class="buy-content">已售{{ groupItem.num || 0 }}件</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore
|
||||
style="padding: 10px 0"
|
||||
bg-color="#f8f8f8"
|
||||
:status="status"
|
||||
/>
|
||||
</div>
|
||||
<u-empty
|
||||
v-else
|
||||
style="margin-top: 20%"
|
||||
text="暂无数据"
|
||||
mode="data"
|
||||
></u-empty>
|
||||
</div>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Promotions from '@/api/promotions';
|
||||
import * as API_Goods from '@/api/goods';
|
||||
export default {
|
||||
props: {
|
||||
keywords: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: 3, //tabs中的索引
|
||||
status: 'loadmore',
|
||||
is_empty: false,
|
||||
search: false,
|
||||
title: '拼团活动',
|
||||
background: {
|
||||
backgroundColor: '#fff'
|
||||
},
|
||||
empty: false,
|
||||
params: {
|
||||
pageNumber: 0,
|
||||
pageSize: 10,
|
||||
categoryPath: '',
|
||||
goodsName: ''
|
||||
},
|
||||
groupBuy: [],
|
||||
search: ''
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
|
||||
methods: {
|
||||
initData() {
|
||||
this.search = this.keywords;
|
||||
this.status = 'loadmore';
|
||||
this.params = {
|
||||
pageNumber: 0,
|
||||
pageSize: 10,
|
||||
categoryPath: '',
|
||||
goodsName: this.search
|
||||
};
|
||||
this.groupBuy = [];
|
||||
console.log('初始化团购数据');
|
||||
this.getData();
|
||||
},
|
||||
|
||||
toHref(goods) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${goods.goodsId}`
|
||||
});
|
||||
},
|
||||
|
||||
// 请求拼团数据
|
||||
getData() {
|
||||
if (this.status !== 'loadmore') return;
|
||||
this.params.pageNumber++;
|
||||
this.status = 'loading';
|
||||
this.params.goodsName = this.search;
|
||||
const params = JSON.parse(JSON.stringify(this.params));
|
||||
if (params.category_id === 0) delete params.category_id;
|
||||
|
||||
API_Promotions.getAssembleList(params)
|
||||
.then((response) => {
|
||||
const data = response.data.result.records;
|
||||
|
||||
if (!data || !data.length) {
|
||||
this.is_empty = true;
|
||||
this.status = 'nomore';
|
||||
} else {
|
||||
if (data.length < this.params.pageSize) {
|
||||
this.status = 'nomore';
|
||||
} else {
|
||||
this.status = 'loadmore';
|
||||
}
|
||||
this.is_empty = false;
|
||||
this.groupBuy.push(...(data || []));
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.view-item {
|
||||
background: #fff;
|
||||
border-radius: 0.4em;
|
||||
margin: 20rpx 30rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.nodata {
|
||||
text-align: center;
|
||||
margin: 40rpx 0 20rpx 0;
|
||||
}
|
||||
|
||||
.container-wrap {
|
||||
width: 100%;
|
||||
}
|
||||
.white_class {
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.popupTips {
|
||||
font-size: 22rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
color: #999999;
|
||||
margin: 0 20rpx;
|
||||
|
||||
/deep/ view {
|
||||
line-height: 1.75;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
margin: 30rpx 20rpx !important;
|
||||
}
|
||||
|
||||
.view-left,
|
||||
.view-content,
|
||||
.view-right,
|
||||
.view-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.view-left {
|
||||
width: 226rpx;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.view-content {
|
||||
width: calc((100% - 240rpx));
|
||||
padding-left: 20rpx;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.buy-content {
|
||||
font-size: 22rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
margin-top: 15rpx;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
}
|
||||
.view-content-bottom {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.group-wrapper {
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
.view-content-name {
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
color: #333333;
|
||||
font-size: 28rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
.view-content-price {
|
||||
margin: 10rpx 0;
|
||||
letter-spacing: 0px;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
text-align: left;
|
||||
color: #ff5a10;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.view-content-original_price {
|
||||
font-size: 22rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
text-decoration: line-through;
|
||||
text-align: left;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
background: $aider-light-color;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang SC, PingFang SC-Regular;
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 6rpx 16rpx;
|
||||
}
|
||||
/deep/ .empty {
|
||||
position: relative;
|
||||
padding-top: 20%;
|
||||
> .empty-content {
|
||||
position: relative;
|
||||
padding-top: 20%;
|
||||
}
|
||||
}
|
||||
</style>
|
220
pages/search/user.vue
Normal file
220
pages/search/user.vue
Normal file
@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view v-if="flowList.length">
|
||||
<view
|
||||
class="flex-box"
|
||||
v-for="i in flowList"
|
||||
v-if="i.id != id"
|
||||
:key="i.id"
|
||||
>
|
||||
<u-image
|
||||
:src="i.face"
|
||||
class="flxleft"
|
||||
width="120"
|
||||
height="120"
|
||||
shape="circle"
|
||||
loading-icon="/static/missing-face.png"
|
||||
error-icon="/static/missing-face.png"
|
||||
style="display: flex; align-items: center"
|
||||
></u-image>
|
||||
|
||||
<view class="flxcenter">
|
||||
<view class="nkname">{{ i.nickname }}</view>
|
||||
<!-- <view class="fans">粉丝:125.2万</view> -->
|
||||
</view>
|
||||
<view class="flxright">
|
||||
<u-button
|
||||
type="error"
|
||||
@click="follow(i)"
|
||||
size="mini"
|
||||
v-if="i.followStatus == '未关注'"
|
||||
>
|
||||
关注
|
||||
</u-button>
|
||||
<u-button
|
||||
v-else
|
||||
type="plain"
|
||||
@click="cancelFollow(i)"
|
||||
size="mini"
|
||||
>
|
||||
{{ i.followStatus }}
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore
|
||||
style="padding: 10px 0"
|
||||
bg-color="#f8f8f8"
|
||||
:status="loadStatus"
|
||||
@loadmore="getData"
|
||||
></u-loadmore>
|
||||
</view>
|
||||
<u-empty
|
||||
v-else
|
||||
style="margin-top: 20%"
|
||||
text="暂无数据"
|
||||
mode="data"
|
||||
></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage.js'; //缓存
|
||||
import { vlogSearchUser, vlogFansFollow, vlogFansCancel } from '@/api/vlog';
|
||||
export default {
|
||||
props: {
|
||||
keywords: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: 2, // 在tabs中的索引
|
||||
loadStatus: 'loadmore',
|
||||
flowList: [],
|
||||
page: 0,
|
||||
totalPage: 0,
|
||||
search: '',
|
||||
id: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
async getData() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
var info = storage.getVlogUserInfo();
|
||||
var id = '';
|
||||
if (info != null) {
|
||||
id = info.id;
|
||||
}
|
||||
this.id = id;
|
||||
this.loadStatus = 'loading';
|
||||
this.page += 1;
|
||||
console.log('加载用户数据');
|
||||
|
||||
var params = {
|
||||
id: id,
|
||||
nickname: this.search,
|
||||
page: this.page,
|
||||
pageSize: 10
|
||||
};
|
||||
console.log(params);
|
||||
var result = await vlogSearchUser(params);
|
||||
console.log(result);
|
||||
if (result.data.status == 200) {
|
||||
var data = result.data.data || [];
|
||||
if (!data.length) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
if (data.length < 10) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.loadStatus = 'loadmore';
|
||||
}
|
||||
data.forEach((i) => {
|
||||
i.doIflow = false;
|
||||
this.flowList.push(i);
|
||||
});
|
||||
// this.flowList.push(...data);
|
||||
}
|
||||
}
|
||||
},
|
||||
initData() {
|
||||
this.search = this.keywords;
|
||||
this.page = 0;
|
||||
this.totalPage = 0;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
console.log('初始化用户数据');
|
||||
this.getData();
|
||||
},
|
||||
async follow(item) {
|
||||
let userInfo = storage.getVlogUserInfo();
|
||||
if (userInfo == null) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/passport/login',
|
||||
animationType: 'slide-in-bottom'
|
||||
});
|
||||
return;
|
||||
}
|
||||
let data = {
|
||||
myId: userInfo.id,
|
||||
vlogerId: item.id
|
||||
};
|
||||
var result = await vlogFansFollow(data);
|
||||
console.log(result);
|
||||
if (result.data.status == 200) {
|
||||
item.followStatus = '已关注';
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
},
|
||||
async cancelFollow(item) {
|
||||
let userInfo = storage.getVlogUserInfo();
|
||||
if (userInfo == null) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/passport/login',
|
||||
animationType: 'slide-in-bottom'
|
||||
});
|
||||
return;
|
||||
}
|
||||
let data = {
|
||||
myId: userInfo.id,
|
||||
vlogerId: item.id
|
||||
};
|
||||
var result = await vlogFansCancel(data);
|
||||
console.log(result);
|
||||
if (result.data.status == 200) {
|
||||
item.doIflow = false;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.data.msg,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flex-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
.flxleft {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.flxcenter {
|
||||
flex: 1;
|
||||
}
|
||||
.nkname {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.fans {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
.flxright {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
@ -1,24 +1,27 @@
|
||||
<template>
|
||||
<div style="height: 100%">
|
||||
<div class="jolkp">
|
||||
<div class="fan" :style="{ marginRight: statue == 0 ? '50%' : '50%' }">
|
||||
<div
|
||||
@click="hui(0)"
|
||||
:style="{ marginTop: '35px', color: '#fff' }"
|
||||
v-if="statue == 1 || 6"
|
||||
>
|
||||
<
|
||||
</div>
|
||||
</div>
|
||||
<!-- <TUIContact v-else-if="statue==1" :stu="2" /> -->
|
||||
<div
|
||||
@click="hui(6)"
|
||||
class="jolkp_z"
|
||||
v-if="statue == 0 || 6"
|
||||
:style="{ marginTop: '40px' }"
|
||||
>
|
||||
<div class="tiole">{{ tole }}</div>
|
||||
</div>
|
||||
<div style="height: 100%">
|
||||
<div class="jolkp">
|
||||
<div
|
||||
class="fan"
|
||||
:style="{ marginRight: statue == 0 ? '50%' : '50%' }"
|
||||
>
|
||||
<div
|
||||
@click="hui(0)"
|
||||
:style="{ marginTop: '35px', color: '#fff' }"
|
||||
v-if="statue == 1 || 6"
|
||||
>
|
||||
<
|
||||
</div>
|
||||
</div>
|
||||
<!-- <TUIContact v-else-if="statue==1" :stu="2" /> -->
|
||||
<div
|
||||
@click="hui(6)"
|
||||
class="jolkp_z"
|
||||
v-if="statue == 0 || 6"
|
||||
:style="{ marginTop: '40px' }"
|
||||
>
|
||||
<div class="tiole">{{ tole }}</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@click="hui(1)"
|
||||
@ -83,10 +86,13 @@
|
||||
</div>
|
||||
</scroll-view>
|
||||
|
||||
<!-- </div> -->
|
||||
<!-- 会话 -->
|
||||
<TUIConversation style="height: 100%" v-else />
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
<!-- 会话 -->
|
||||
<TUIConversation
|
||||
style="height: 100%"
|
||||
v-else
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -157,7 +163,52 @@ export default {
|
||||
userSig: par.userSig,
|
||||
useUploadPlugin: true, // If you need to send rich media messages, please set to true.
|
||||
framework: `vue${vueVersion}`, // framework used vue2 / vue3
|
||||
});
|
||||
}).then(()=>{
|
||||
Push.setRegistrationID(par.userID, () => {
|
||||
console.log('设置id设置id设置id设置id设置id设置id设置id设置id设置id设置id', par.userID);
|
||||
|
||||
Push.registerPush(
|
||||
par.sdkAppId,
|
||||
'vkFpe55aYqfV7Sk5uGaoxhEstJ3tcI9dquk7JwG1GloDSLD2HeMWeQweWWXgNlhC',
|
||||
(data) => {
|
||||
console.log('registerPush ok', data);
|
||||
Push.getRegistrationID((registrationID) => {
|
||||
console.log('getRegistrationID ok', registrationID);
|
||||
});
|
||||
},
|
||||
(errCode, errMsg) => {
|
||||
console.error('registerPush failed', errCode, errMsg);
|
||||
}
|
||||
);
|
||||
});
|
||||
// 监听通知栏点击事件,获取推送扩展信息
|
||||
Push.addPushListener(Push.EVENT.NOTIFICATION_CLICKED, (res) => {
|
||||
console.log('notification clicked', res);
|
||||
// 解析扩展信息,跳转到相应的会话(代码仅供参考,发布前需要完善)
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
const conv_type = data?.entity?.chatType === 1 ? 'C2C' : 'GROUP';
|
||||
// 根据推送信息拼的 conversationID
|
||||
const conversationID = `${conv_type}${data.entity.sender}`;
|
||||
// 切换会话
|
||||
TUIConversationService.switchConversation(conversationID);
|
||||
const chatPath = '/TUIKit/components/TUIChat/index';
|
||||
uni.navigateTo({ url: chatPath });
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
});
|
||||
// 监听在线推送
|
||||
Push.addPushListener(Push.EVENT.MESSAGE_RECEIVED, (res) => {
|
||||
// res 为消息内容
|
||||
console.log('message received', res);
|
||||
});
|
||||
// 监听在线推送被撤回
|
||||
Push.addPushListener(Push.EVENT.MESSAGE_REVOKED, (res) => {
|
||||
// res 为被撤回的消息 ID
|
||||
console.log('message revoked', res);
|
||||
});
|
||||
})
|
||||
} else {
|
||||
// 接口返回非 200 状态码,跳转登录页面
|
||||
uni.navigateTo({
|
||||
@ -318,152 +369,152 @@ uni-page-body,
|
||||
html,
|
||||
body,
|
||||
page {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
overflow: hidden;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
.jolkp {
|
||||
height: 66px;
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
justify-content: end;
|
||||
/* 设置背景图 */
|
||||
background-image: url("@/static/im/Rectangle.png");
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
height: 66px;
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
justify-content: end;
|
||||
/* 设置背景图 */
|
||||
background-image: url('@/static/im/Rectangle.png');
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.jolkp_l {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-image: url("@/static/im/Frame.png");
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 35px;
|
||||
margin-right: 10px;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-image: url('@/static/im/Frame.png');
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 35px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.jolkp_h {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-image: url("@/static/im/user.png");
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 35px;
|
||||
margin-right: 20px;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-image: url('@/static/im/user.png');
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 35px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.jolkp_z {
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
background-image: url("@/static/im/znx.png");
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-size: 100% 100%;
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
background-image: url('@/static/im/znx.png');
|
||||
/* 让背景图覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 背景图不重复 */
|
||||
background-size: 100% 100%;
|
||||
|
||||
margin-top: 35px;
|
||||
margin-right: 20px;
|
||||
margin-top: 35px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.tiole {
|
||||
margin-top: -10px;
|
||||
margin-left: 105%;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
margin-top: -10px;
|
||||
margin-left: 105%;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
/* 调整弹出框的位置 */
|
||||
right: 5px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
/* 调整弹出框的位置 */
|
||||
right: 5px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.popup ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.popup li {
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.popup li:hover {
|
||||
background-color: #f0f0f0;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.fan {
|
||||
width: 10%;
|
||||
height: "100%";
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
width: 10%;
|
||||
height: '100%';
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
|
||||
padding: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
@media screen and (device-width: 393px) and (device-height: 851px) and (-webkit-device-pixel-ratio: 3) {
|
||||
.fan {
|
||||
margin-right: 56% !important;
|
||||
width: 10%;
|
||||
height: "100%";
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
margin-top: 85%;
|
||||
padding: 5px;
|
||||
}
|
||||
.fan {
|
||||
margin-right: 56% !important;
|
||||
width: 10%;
|
||||
height: '100%';
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
margin-top: 85%;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.three {
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background: rgb(255, 255, 255);
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background: rgb(255, 255, 255);
|
||||
}
|
||||
.con {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.three_div1 {
|
||||
height: 3rem;
|
||||
width: 40%;
|
||||
background-image: url("@/static/im/kf.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
height: 3rem;
|
||||
width: 40%;
|
||||
background-image: url('@/static/im/kf.png');
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.three_div2 {
|
||||
width: 40%;
|
||||
height: 3rem;
|
||||
background-image: url("@/static/im/hy.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 40%;
|
||||
width: 40%;
|
||||
height: 3rem;
|
||||
background-image: url('@/static/im/hy.png');
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.three_div3 {
|
||||
height: 3rem;
|
||||
background-image: url("@/static/im/da.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 40%;
|
||||
height: 3rem;
|
||||
background-image: url('@/static/im/da.png');
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 40%;
|
||||
}
|
||||
.tui-conversation-item {
|
||||
/* height: 10%; */
|
||||
@ -479,39 +530,39 @@ page {
|
||||
position: relative;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding-left: 8px;
|
||||
justify-content: end;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding-left: 8px;
|
||||
justify-content: end;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left {
|
||||
position: relative;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.znx {
|
||||
max-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
max-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.delete-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100px;
|
||||
background-color: red;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100px;
|
||||
background-color: red;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user