Merge pull request 'zdg' (#152) from zdg into main

Reviewed-on: #152
This commit is contained in:
zhengdegang 2024-08-23 10:45:00 +08:00
commit b738ade9a4
4 changed files with 120 additions and 26 deletions

View File

@ -169,12 +169,12 @@ export class ImChat {
logout() {
if (!this.timChat) return
return this.timChat.TIMLogout().then(res => {
console.log('登出成功', res)
this.setConsole('%cim-chat: logout', '登出成功')
this.status.isLogin = false
this.timChat.TIMUninit() // 反初始化
return res
}).catch(error => {
console.log('登出失败', error)
this.setConsole('%cim-chat: logout', '登出失败', error)
return error
})
}

View File

@ -77,7 +77,7 @@ import { getSmarttalkPage, getPrepareById } from '@/api/file'
import SetHomework from '@/views/prepare/container/set-homework.vue'
import FileImage from '@/components/file-image/index.vue'
import { useGetHomework } from '@/hooks/useGetHomework'
import { ipcMsgSend, ipcMsgInvoke } from '@/utils/tool'
import { ipcMsgSend, ipcMsgSend2, ipcMsgInvoke } from '@/utils/tool'
import { useToolState } from '@/store/modules/tool'
import { asyncLocalFile } from '@/utils/talkFile'
import Lesson from './lesson.vue';
@ -113,6 +113,7 @@ const sendHomework = (row) => {
const closeHomework = async() => {
ipcMsgSend('tool-sphere:set:ignore', true)
// im-(app|)
console.log('发送im消息-推送作业(app|平板)', curRow.value.id)
await ipcMsgInvoke('im-chat:msg', curRow.value.id, MsgEnum.HEADS.MSG_0016)
setDialog.value = false
}

View File

@ -1,9 +1,15 @@
<template>
<div v-if="props.test">
<el-button type="primary" @click="trigger">点赞</el-button>
<el-button type="primary" @click="trigger(1, '学生A')">疑惑</el-button>
<el-button type="primary" @click="trigger" v-tap:trigger="">点赞</el-button>
<el-button type="primary" @click="trigger(2, '学生A')" v-tap:trigger="[2,'学生A']">疑惑</el-button>
</div>
<div ref="warpRef" class="c-warp">
<!-- 温度计-模式 -->
<div v-if="props.type == 2" class="c-anim">
<div class="item like" :style="`height:${wtData.like*5}px;`"></div>
<div class="item doubt" :style="`height:${wtData.doubt*5}px;`"></div>
</div>
<!-- (默认)弹幕-模式 -->
<div v-else ref="warpRef" class="c-warp">
<template v-for="(item, index) in iconCache.list">
<slot>
<el-icon v-if="props.def"><Star /></el-icon>
@ -19,29 +25,46 @@
</slot>
</template>
</div>
</template>
<script setup>
// -
import { ref, nextTick, useSlots, reactive } from 'vue'
import {Star} from '@element-plus/icons-vue'
const warpRef = ref(null)
const props = defineProps({ test: Boolean, def: Boolean })
const slots = useSlots() //
let iconCache = reactive({list:[]}) //
const isSlot = !!Object.keys(slots).length // 使
// === type 1 def ===
const props = defineProps({
test: Boolean, // -
def: Boolean, // 使
type: String, // 1- 2-
tback: Number, // -退
tsleep: Number, // -退
})
let iconCache = reactive({list:[]}) //
let wtData = reactive({ // -
like: 0, doubt: 0,
timeout: {like: null, doubt: null}, // -
interval: {like: null, doubt: null}, // -
})
// === type 1: 2: ===
const trigger = async (type, name) => {
if (typeof type == 'string') { name = type; type = 1 } //
iconCache.list.push({
name,
icon: isSlot||props.def ? '' : getRandomIcon(type) //
})
nextTick(() => {
const el = warpRef.value.lastElementChild //
const tipEl = el.querySelector('.tip') //
// console.log(el)
animInit(el, tipEl, type)
})
if (props.type == 2) { // -
weatherglassModel(type)
} else { // -
iconCache.list.push({
name,
icon: isSlot||props.def ? '' : getRandomIcon(type) //
})
nextTick(() => {
const el = warpRef.value.lastElementChild //
const tipEl = el.querySelector('.tip') //
// console.log(el)
animInit(el, tipEl, type)
})
}
}
//
const animInit = (el, tipEl, type) => {
@ -95,7 +118,31 @@ const animInit = (el, tipEl, type) => {
}
amFn() //
}
// - 1: 2:
const weatherglassModel = async(type) => {
const field = type == 2 ? 'doubt' : 'like'
wtData[field]++
autoReduce(type)
}
// -
const autoReduce = type => {
const field = type == 2 ? 'doubt' : 'like'
const reduceFn = () => { // : 1s
wtData.interval[field] = setInterval(() => {
wtData[field]--
// -
if (wtData[field] <= 0) {
clearInterval(wtData.interval[field])
wtData[field] = 0
}
}, (props.tback||100))
}
if (!!wtData.timeout[field]) clearInterval(wtData.timeout[field]) //
if (!!wtData.interval[field]) clearInterval(wtData.interval[field]) //
wtData.timeout[field] = setTimeout(() => {
reduceFn()
}, (props.tsleep||20) * 1000)
}
// -
const setStatic = (el, type, val, end) => el.style[type] = val + (end || '')
//
@ -107,7 +154,7 @@ const resetIconCache = () => {
const getRandomIcon = (type) => {
let iconArr = []
switch (type) {
case 1: // icon-
case 2: // icon-
iconArr = ['yiwen', 'a-yiwen', 'yihuo', 'yiwen-01']
break
default:
@ -132,11 +179,28 @@ const getRandomBool = () => Math.random() > 0.5
const toNumber = (v, pos = 2) => Number(v.toFixed(pos))
//
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
// -
const vTap = {
mounted(el, binding) {
const instance = binding.instance
const fn = binding.arg
const args = binding.value||[]
if (!fn) return
let cleId = null
el.addEventListener('mousedown', () => {
cleId = setInterval(() => {instance[fn](...args)}, 10);
})
el.addEventListener('mouseup', () => {
!!cleId && clearInterval(cleId)
})
}
}
//
defineExpose({ trigger })
</script>
<style lang="scss" scoped>
// -
.c-warp {
position: fixed;
right: 0;
@ -179,4 +243,31 @@ defineExpose({ trigger })
}
}
}
// -
.c-anim {
position: fixed;
// height: 90vh;
// border: 1px solid;
inset: auto auto 3em 1em;
display: flex;
gap: 10px;
align-items: flex-end;
.item{
flex: 1;
border-radius: 3px;
min-width: 15px;
// height: 500px;
&.like{
background-image: linear-gradient(to top, #fef0f0, #f56c6c);
// animation: striped-flow 5s linear infinite;
}
&.doubt{
background-image: linear-gradient(to top, #fdf6ec, #e6a23c);
}
}
}
@keyframes striped-flow {
0%{background-position: 0 500px;}
100%{background-position: 0 0;}
}
</style>

View File

@ -7,7 +7,7 @@
<side-vue v-ignore @ignore-mounted="sideMouse" @change="sideChange"></side-vue>
<!-- 点赞组件 -->
<upvote-vue ref="upvoteRef"></upvote-vue>
<upvote-vue ref="upvoteRef" type="2"></upvote-vue>
<!-- im-chat 聊天组件 -->
<im-chat ref="imChatRef" @change="chatChange" />
@ -67,7 +67,8 @@ const classObj = reactive({ // 课程相关
data: {} //
})
const msgIds = [] // id
const btnList = [ //
const electron = window.electron // electron
const btnList = [ //
{ label: '选择', value: 'select', icon: 'icon-mouse' },
{ label: '画笔', value: 'brush', icon: 'icon-huabi' },
{ label: '板擦', value: 'erase', icon: 'icon-xiangpica' },
@ -78,9 +79,10 @@ const btnList = [ // 工具栏按钮列表
]
// === ===
onMounted(async() => {
getClassInfo() // ex3
if (!electron) return //
getClassInfo() // ex3
setTimeout(() => {
resetStatus() // -
resetStatus() // -
}, 200);
})
@ -130,7 +132,7 @@ const chatChange = (type, data, ...args) => {
case MsgEnum.HEADS.MSG_0002: //
// console.log(':', data)
if(msgIds.includes(msgId)) return // -
upvoteRef.value.trigger(data.name) // |
upvoteRef.value.trigger(head, data.name) // |
if (msgIds.length >= 100) msgIds.shift() //
msgIds.push(msgId) //
break