hookehuyr

弹幕功能调整,API联调

......@@ -13,8 +13,8 @@ declare module 'vue' {
VanActionSheet: typeof import('vant/es')['ActionSheet']
VanCol: typeof import('vant/es')['Col']
VanField: typeof import('vant/es')['Field']
VanFloatingBubble: typeof import('vant/es')['FloatingBubble']
VanIcon: typeof import('vant/es')['Icon']
VanImage: typeof import('vant/es')['Image']
VanLoading: typeof import('vant/es')['Loading']
VanRow: typeof import('vant/es')['Row']
VanUploader: typeof import('vant/es')['Uploader']
......
......@@ -2,7 +2,7 @@
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-26 23:52:36
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-11 09:50:51
* @LastEditTime: 2024-04-12 06:04:39
* @FilePath: /fxPark/src/App.vue
* @Description:
-->
......
import { fn, fetch } from '@/api/fn';
const Api = {
GET_TREE: '/srv/?a=api&t=get_tree',
GET_DANMU: '/srv/?a=api&t=get_bulletscreen',
SAVE_DANMU: '/srv/?a=api&t=save_bulletscreen',
}
/**
* @description: 用户的植被数据
* @returns
*/
export const getTreeAPI = (params) => fn(fetch.get(Api.GET_TREE, params));
/**
* @description: 显示弹幕
* @returns
*/
export const getDanmuAPI = (params) => fn(fetch.get(Api.GET_DANMU, params));
/**
* @description: 保存弹幕
* @returns
*/
export const saveDanmuAPI = (params) => fn(fetch.post(Api.SAVE_DANMU, params));
<!--
* @Date: 2024-04-10 14:16:36
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-11 14:19:23
* @LastEditTime: 2024-04-12 12:27:41
* @FilePath: /fxPark/src/components/danmaku.vue
* @Description: 文件描述
-->
<template>
<div class="danmaku-page">
<vue-danmaku ref="danmaku" v-model:danmus="danmus" useSlot loop :channels="2" :speeds="50" :top="0" style="height:15rem; width:100vw; position: absolute; top:0; z-index: 10; padding-top: 1rem;">
<vue-danmaku ref="danmakuRef" v-model:danmus="danmus" useSlot loop :channels="2" :speeds="50" :top="0" style="height:15rem; width:100vw; position: absolute; top:0; z-index: 10; padding-top: 1rem;">
<template v-slot:dm="{ index, danmu }">
<div style="background-color: rgba(48, 48, 48, 0.50); padding: 0.25rem 1rem; border-radius: 14px; margin-top: 1rem;">{{ danmu.text }}</div>
<div class="dm-item">
<van-icon v-if="danmu.status === '2'" name="fire-o" color="red" />&nbsp;
<span>{{ danmu.note }}</span>
</div>
</template>
</vue-danmaku>
</div>
......@@ -24,6 +27,8 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { getDanmuAPI } from '@/api/carbon.js';
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
......@@ -32,20 +37,51 @@ const props = defineProps({
text: {
type: Object,
default: {}
},
show: {
type: Boolean,
default: false
}
});
watch(() => props.text, (v) => {
if (v.text) {
danmaku.value.add(v)
if (v.note) {
danmakuRef.value.add(v)
}
});
watch(() => props.show, (v) => {
nextTick(() => {
if (v) {
danmakuRef.value.show()
} else {
danmakuRef.value.hide()
}
})
}, {
immediate: true
});
const danmaku = ref(null)
const danmus = ref([{ name: 'a', text: 'aaa' }, { name: 'b', text: 'bbb' }])
const danmakuRef = ref(null)
const danmus = ref([]);
onMounted(async () => {
const { code, data } = await getDanmuAPI();
if (code) {
console.warn(data);
danmus.value = data;
}
})
</script>
<style lang="less" scoped>
.danmaku-page {}
.danmaku-page {
.dm-item {
background-color: rgba(48, 48, 48, 0.50);
padding: 0.25rem 1rem;
border-radius: 14px;
margin-top: 1rem;
font-size: 0.95rem;
}
}
</style>
......
......@@ -2,12 +2,12 @@
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-31 12:06:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-31 17:32:10
* @FilePath: /tswj/src/main.js
* @LastEditTime: 2024-04-12 11:15:38
* @FilePath: /fxPark/src/main.js
* @Description:
*/
import { createApp } from 'vue';
import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog, ActionSheet, Loading, Checkbox, Search, Notify } from 'vant';
import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog, ActionSheet, Loading, Checkbox, Search, Notify, FloatingBubble } from 'vant';
import router from './router';
import App from './App.vue';
// import axios from './utils/axios';
......@@ -21,6 +21,6 @@ const app = createApp(App);
app.config.globalProperties.$http = axios; // 关键语句
app.use(pinia).use(router).use(Button).use(VanImage).use(Col).use(Row).use(Icon).use(Form).use(Field).use(CellGroup).use(Toast).use(Uploader).use(Empty).use(Tab).use(Tabs).use(Overlay).use(NumberKeyboard).use(Lazyload).use(List).use(PullRefresh).use(Popup).use(Picker).use(Sticky).use(Stepper).use(Tag).use(Swipe).use(SwipeItem).use(Dialog).use(ActionSheet).use(Loading).use(Checkbox).use(Search).use(ConfigProvider).use(Notify);
app.use(pinia).use(router).use(Button).use(VanImage).use(Col).use(Row).use(Icon).use(Form).use(Field).use(CellGroup).use(Toast).use(Uploader).use(Empty).use(Tab).use(Tabs).use(Overlay).use(NumberKeyboard).use(Lazyload).use(List).use(PullRefresh).use(Popup).use(Picker).use(Sticky).use(Stepper).use(Tag).use(Swipe).use(SwipeItem).use(Dialog).use(ActionSheet).use(Loading).use(Checkbox).use(Search).use(ConfigProvider).use(Notify).use(FloatingBubble);
app.mount('#app');
......
/*
* @Date: 2024-04-07 10:14:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-11 15:36:49
* @LastEditTime: 2024-04-11 17:20:27
* @FilePath: /fxPark/src/router/routes/modules/fxPark/index.js
* @Description: 文件描述
*/
......
<!--
* @Date: 2024-04-07 10:15:55
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-11 15:45:54
* @LastEditTime: 2024-04-12 12:16:24
* @FilePath: /fxPark/src/views/fxPark/index.vue
* @Description: 文件描述
-->
<template>
<div class="fxPark-page">
<danmaku :text="add_text" />
<danmaku :show="show_danmu" :text="add_text" />
<div class="quick-entrance-wrapper">
<div class="quick-entrance-item" @click="goToAudio">
<van-icon name="chat-o" />&nbsp;&nbsp;<span>植物之声</span>
</div>
</div>
<div class="container" v-for="(item, index) in img_list" :key="index" @click="onClick(item)">
<img :src="item.src" class="img">
<div class="container" v-for="(item, index) in data_list" :key="index" @click="onChipClick()">
<img :src="item.chip_src" class="img">
</div>
<div style="position: fixed; bottom: 1rem; left: 0; right: 0; display: flex; z-index: 25;justify-content: space-evenly;">
<div @click="onShare" style="display: inline-flex; padding: 0.6rem 2rem; color: #F68015; background-color: #fff; align-items: center; border-radius: 1.5rem;">分享海报</div>
<div @click="commentsBtn" style="display: inline-flex; padding: 0.6rem 2rem; color: #fff; background-color: #F68015;align-items: center; border-radius: 1.5rem;">弹幕留言</div>
<div v-if="all_actived" @click="onShare" style="display: inline-flex; padding: 0.6rem 2rem; color: #F68015; background-color: #fff; align-items: center; border-radius: 1.5rem;">分享海报</div>
<!-- <div @click="commentsBtn" style="display: inline-flex; padding: 0.6rem 2rem; color: #fff; background-color: #F68015;align-items: center; border-radius: 1.5rem;">弹幕留言</div> -->
</div>
<van-action-sheet v-model:show="show_danmu" title="留言" :round="false" :close-on-click-overlay="false" @cancel="onCancel">
<van-action-sheet v-model:show="show_danmu_message" title="留言" :round="false" :close-on-click-overlay="false" @cancel="onCancel">
<div style="padding: 1rem 0; height: 10vh; display: flex; padding: 0.5rem;">
<!-- <van-field
v-model="message"
rows="3"
autosize
<van-field
ref="RefDanmu"
v-model="danmu_message"
label=""
type="textarea"
type="text"
placeholder="请输入留言"
@blur="onBlur"
/> -->
<van-field
v-model="message"
@blur="onDanmuBlur"
@keydown.enter="handleEnterPress"
enterkeyhint="send"
/>
<!-- <van-field
ref="RefDanmu"
v-model="danmu_message"
rows="3"
autosize
label=""
......@@ -41,12 +43,18 @@
placeholder="请输入留言"
@blur="onBlur"
@focus="onFocus"
enterkeyhint="send"
style="background-color: #F3F3F3; padding: 1rem; border-radius: 5px; flex: 1; margin-right: 1rem;"
/>
<div @click="sendMessage" style="display: flex; align-items: flex-end; justify-content: center; margin-right: 0.5rem;">发送</div>
<div @click="sendMessage" style="display: flex; align-items: flex-end; justify-content: center; margin-right: 0.5rem;">发送</div> -->
</div>
<div v-if="spaceDiv" style="height: 10vh;"></div>
</van-action-sheet>
<van-floating-bubble icon="chat" @click="onCloseDanmu" />
<div v-if="show_danmu" style="position: fixed; bottom: 0; left: 0; right: 0; background-color: white; z-index: 10; height: 5rem;">
<div @click="commentsBtn" style="background-color: #F3F3F3; margin: 1rem 0.85rem; border-radius: 10px; padding: 0.5rem 1rem; font-size: 0.9rem; color: #ABABAB;">发一条友好的弹幕吧</div>
</div>
</div>
</template>
......@@ -56,9 +64,11 @@ import { useRoute, useRouter } from 'vue-router'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
import { parseQueryString } from '@/utils/tools.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import danmaku from '@/components/danmaku.vue'
import danmaku from '@/components/danmaku.vue';
import { getTreeAPI, saveDanmuAPI } from '@/api/carbon.js';
// 初始化WX环境
import wx from 'weixin-js-sdk'
......@@ -69,74 +79,130 @@ const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const TREE_CHIP = { // 碎片图结构
1: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s1.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s1.png'
},
2: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s2.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s2.png'
},
3: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s3.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s3.png'
},
4: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s4.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s4.png'
},
5: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s5.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s5.png'
},
6: {
invalid: 'https://cdn.ipadbiz.cn/tmp/fx_park/s6.png',
active: 'https://cdn.ipadbiz.cn/tmp/fx_park/s6.png'
},
};
const data_list = ref([]);
const all_actived = ref(false); // 全部激活
onMounted(async () => {
const { code, data } = await getTreeAPI();
if (code) {
let index = data.findIndex(item => item.is_tree === 0); // 全点亮标识
if (index === -1) { // 未全点亮
data.forEach(item => {
item.chip_src = item.is_light === '0' ? TREE_CHIP[item.revision]['invalid'] : TREE_CHIP[item.revision]['active']; // 根据点亮状态,显示碎片地址
});
} else { // 全点亮
all_actived.value = true;
}
//
data_list.value = data;
}
});
const RefDanmu = ref(null);
const show_danmu = ref(false);
const message = ref('');
const show_danmu_message = ref(false);
const danmu_message = ref('');
const add_text = ref({});
const img_list = ref([{
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s1.png' ,
}, {
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s2.png' ,
}, {
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s3.png' ,
}, {
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s4.png' ,
}, {
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s5.png' ,
}, {
src:'https://cdn.ipadbiz.cn/tmp/fx_park/s6.png' ,
},])
const onClick = (item) => {
const onChipClick = () => { // 点击碎片回调
if (all_actived.value) return false; // 全点亮忽略
// 调用微信摄像头
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
console.log("🚀 ~ file: index.vue:73 ~ onClick ~ result:", result);
// let result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
// 跳转到相应植被介绍页
let result = 'http://oa.allforlove.org.cn/f/carbon/#/intro?revision=1';
let revision = parseQueryString(result).revision;
go('/intro', { revision });
},
fail: function (res) {
console.log("🚀 ~ file: index.vue:77 ~ onClick ~ res:", res);
console.error(res);
}
});
}
const commentsBtn = () => {
show_danmu.value = true;
show_danmu_message.value = true;
nextTick(() => {
spaceDiv.value = true;
RefDanmu.value.focus();
});
}
const spaceDiv = ref(false);
const sendMessage = () => {
show_danmu.value = false;
console.warn(message.value);
add_text.value = {
name: '123',
text: message.value
const sendMessage = async () => {
const { code, data } = await saveDanmuAPI({ note: danmu_message.value });
if (code) {
show_danmu_message.value = false;
add_text.value = {
status: '2',
note: danmu_message.value
}
// 清空输入框
danmu_message.value = '';
}
//
message.value = '';
}
const onBlur = () => {
const onDanmuBlur = (evt) => {
show_danmu_message.value = false;
spaceDiv.value = false;
}
const handleEnterPress = (evt) => {
if (evt.keyCode === 13) {
sendMessage();
}
}
const onFocus = () => {
spaceDiv.value = true;
// spaceDiv.value = true;
}
const onCancel = () => {
console.warn(0);
}
const onShare = () => {
const onShare = () => { // 分享海报按钮
go('/finish')
}
const goToAudio = () => {
go('/audio')
}
const onCloseDanmu = () => {
show_danmu.value = !show_danmu.value;
}
</script>
<style lang="less" scoped>
......
<!--
* @Date: 2024-04-10 16:08:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-11 17:10:21
* @LastEditTime: 2024-04-12 10:55:12
* @FilePath: /fxPark/src/views/fxPark/intro.vue
* @Description: 文件描述
-->
......@@ -10,7 +10,7 @@
<div></div>
<div style="margin: 1rem;">
<div style="margin-bottom: 1rem;">
<span style="font-size: 1.25rem;">悬铃木</span>
<span style="font-size: 1.25rem;">悬铃木{{ revision }}</span>
<span style="font-size: 0.85rem;">智者长老</span>
</div>
<div style="border: 1px solid #000; padding: 1rem; border-radius: 8px;">
......@@ -37,7 +37,7 @@
</div>
<div class="light-up-text">恭喜您植被已被点亮</div>
<div style="margin: 1rem 1rem 2rem 1rem; color: white; text-align: center;">
<div style="background-color: #F68015; display: inline-block; padding: 0.7rem 2rem; border-radius: 1.5rem;">生成海报</div>
<div @click="goToPoster" style="background-color: #F68015; display: inline-block; padding: 0.7rem 2rem; border-radius: 1.5rem;">生成海报</div>
</div>
</div>
</template>
......@@ -50,12 +50,30 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { getTreeAPI } from '@/api/carbon.js';
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const id = $route.query.id;
console.log("🚀 ~ file: intro.vue:58 ~ id:", id);
const revision = $route.query.revision; // revision 植被编号
console.log("🚀 ~ file: intro.vue:58 ~ revision:", revision);
onMounted(async () => {
const { code, data } = await getTreeAPI();
if (code) {
console.warn(data);
}
});
const goToPoster = () => {
$router.push({
path: '/poster',
query: {
revision
}
});
};
</script>
......