wee
This commit is contained in:
parent
1dbf6ffa5a
commit
c48931dd31
12
components.d.ts
vendored
12
components.d.ts
vendored
@ -12,10 +12,13 @@ declare module 'vue' {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
@ -23,21 +26,30 @@ declare module 'vue' {
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||
ElLink: typeof import('element-plus/es')['ElLink']
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSelectV2: typeof import('element-plus/es')['ElSelectV2']
|
||||
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElTour: typeof import('element-plus/es')['ElTour']
|
||||
ElTourStep: typeof import('element-plus/es')['ElTourStep']
|
||||
IndexUser: typeof import('./src/components/TagClass/indexUser.vue')['default']
|
||||
KeyWords: typeof import('./src/components/KeyWords/index.vue')['default']
|
||||
MaterialPublic: typeof import('./src/components/MaterialPublic/index.vue')['default']
|
||||
|
||||
@ -3,14 +3,20 @@ import request from '@/utils/request'
|
||||
|
||||
|
||||
|
||||
// export const getUserList = (params) => {
|
||||
// return request({
|
||||
// url: `admin/app/users`,
|
||||
// method: 'get',
|
||||
// params
|
||||
// })
|
||||
// }
|
||||
export const getUserList = (params) => {
|
||||
return request({
|
||||
url: `admin/app/users`,
|
||||
url: `admin/messages/latest`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const send_message = (data) => {
|
||||
return request({
|
||||
url: `admin/send_message`,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div v-for="(element, index) in list">
|
||||
<div class="materia-element" :class="{ robotSend : element.sender_id != sendeInfo.userInfo.user_id }">
|
||||
<el-image v-if="element.sender_id == sendeInfo.robotInfo.wx_id" class="tobot-image" :src="sendeInfo.robotInfo.head_url"></el-image>
|
||||
<template v-else>
|
||||
<!-- <el-image v-if="element.sender_id == sendeInfo.robotInfo.wx_id" class="tobot-image" :src="sendeInfo.robotInfo.head_url"></el-image>
|
||||
<template v-else> -->
|
||||
<el-image v-if="sendeInfo.userInfo.user_id != element.sender_id" class="tobot-image" :src="robot_avatar"></el-image>
|
||||
<el-image v-if="sendeInfo.userInfo.user_id == element.sender_id" class="tobot-image" :src="sendeInfo.userInfo.user_avatar"></el-image>
|
||||
<!-- <span class="tobot-image text-logo" v-else> {{ element.sender_name.charAt(0) }} </span> -->
|
||||
</template>
|
||||
<!-- </template> -->
|
||||
<div class="materia-info">
|
||||
<!-- <span class="robot-name">{{ element.sender_name }}</span> -->
|
||||
<!-- <span v-if="element.sender_id != sendeInfo.userInfo.user_id" class="robot-name">{{ sendeInfo.robotInfo.name }}</span>
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
<div style="width: 100%;">
|
||||
<el-input v-model="centent" suffix-icon="Search" @input="inputSearch" placeholder="搜索"></el-input>
|
||||
<ul v-infinite-scroll="load" class="infinite-list" style="overflow: auto" :style="'height:' + height" :infinite-scroll-immediate="false" infinite-scroll-distance="5">
|
||||
<li v-for="item in cardlist" :key="item.user_id" class="infinite-list-item" :class="{ active: item.active }"
|
||||
<li v-for="item in cardlist" :key="item.sender_id" class="infinite-list-item" :class="{ active: item.active }"
|
||||
@click="handleItem(item)">
|
||||
<el-image class="user-avatar" :src="item.user_avatar"></el-image>
|
||||
<span class="nickname">{{ item.user_name }}</span>
|
||||
<el-image class="user-avatar" :src="item.sender_avatar"></el-image>
|
||||
<span class="nickname">{{ item.sender_name }}</span>
|
||||
<span class="sex">
|
||||
<!-- <el-icon v-if="item.sex == '男'" style="color: rgb(121.3, 187.1, 255);">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
@ -67,7 +67,7 @@ const handleItem = (row) => {
|
||||
let arr = []
|
||||
props.cardlist.forEach((el) => {
|
||||
if (el.active === true) {
|
||||
arr.push(el.user_id)
|
||||
arr.push(el.sender_id)
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
@ -81,8 +81,8 @@ const handleItem = (row) => {
|
||||
// 再设当前为true
|
||||
row.active = true
|
||||
// emit后外部拿到的cardlist状态是唯一active
|
||||
emits('change', row.user_id)
|
||||
emits("update:modelValue", row.user_id)
|
||||
emits('change', row.sender_id)
|
||||
emits("update:modelValue", row.sender_id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ const goHome = () => {
|
||||
|
||||
<template>
|
||||
<div class="logo">
|
||||
SCRM
|
||||
小程序聊天管理
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export default {
|
||||
title: '猕猴桃 Scrm', //项目名称
|
||||
title: '小程序聊天管理', //项目名称
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ const sendeInfo = reactive({
|
||||
// 消息分页查询参数
|
||||
const msgQuery = reactive({
|
||||
page: 1,
|
||||
page_size: 190,
|
||||
page_size: 100,
|
||||
app_id: route.query.app_id,
|
||||
user_id: ''
|
||||
})
|
||||
@ -81,22 +81,24 @@ const isAutoScroll = ref(true) // 是否自动滚动到底部
|
||||
const messageTimer = ref(null) // 定时器实例
|
||||
|
||||
// 选择用户
|
||||
const onSelectUser = (id) => {
|
||||
const u = userList.value.find((it) => it.user_id == id)
|
||||
const onSelectUser = async (id) => {
|
||||
const u = userList.value.find((it) => it.sender_id == id)
|
||||
if (u) {
|
||||
userList.value.forEach((it) => (it.active = it.user_id === id))
|
||||
userList.value.forEach((it) => (it.active = it.sender_id === id))
|
||||
activeUser.value = u
|
||||
sendeInfo.userInfo = { user_id: u.user_id, user_name: u.user_name, user_avatar: u.user_avatar }
|
||||
sendeInfo.userInfo = { user_id: u.sender_id, user_name: u.sender_name, user_avatar: u.sender_avatar }
|
||||
sendeInfo.robotInfo = { wx_id: 'robot', head_url: mihoutai }
|
||||
|
||||
// 重置消息列表和分页
|
||||
messages.value = []
|
||||
msgQuery.page = 1
|
||||
msgQuery.user_id = u.user_id
|
||||
msgQuery.user_id = u.sender_id
|
||||
noMoreMessages.value = false
|
||||
|
||||
// 保持原有行为:先滚动到底部再加载(不 await),以免改变用户可感知的交互顺序
|
||||
|
||||
scrollToBottom()
|
||||
// await scrollToBottom()
|
||||
getMessages()
|
||||
|
||||
// 重启定时器
|
||||
@ -225,7 +227,7 @@ const loadMoreMessages = () => {
|
||||
|
||||
// 发送消息
|
||||
const send = () => {
|
||||
if (!activeUser.value.user_id) {
|
||||
if (!activeUser.value.sender_id) {
|
||||
ElMessage({ type: 'warning', message: '请先选择一个联系人' })
|
||||
return
|
||||
}
|
||||
@ -259,7 +261,7 @@ const send = () => {
|
||||
messages: content
|
||||
}),
|
||||
msg_type: 1,
|
||||
to_user_id: activeUser.value.user_id
|
||||
to_user_id: activeUser.value.sender_id
|
||||
}).then(() => {
|
||||
msg._sending = false
|
||||
msg._failed = false
|
||||
@ -312,13 +314,13 @@ const handleImageChange = (e) => {
|
||||
form.append('file', file)
|
||||
form.append('app_id', route.query.app_id)
|
||||
form.append('msg_type', 2)
|
||||
form.append('to_user_id', activeUser.value.user_id)
|
||||
form.append('to_user_id', activeUser.value.sender_id)
|
||||
uploadFile(form, import.meta.env.VITE_APP_BASE_API + 'admin/upload/image').then((resp) => {
|
||||
send_message({
|
||||
app_id: route.query.app_id,
|
||||
content: JSON.stringify({ messages: import.meta.env.VITE_APP_BASE_API + resp.preview_image_url }),
|
||||
msg_type: 2,
|
||||
to_user_id: activeUser.value.user_id
|
||||
to_user_id: activeUser.value.sender_id
|
||||
}).then(() => {
|
||||
msg._sending = false
|
||||
msg._failed = false
|
||||
@ -343,7 +345,7 @@ const handleRetry = (id) => {
|
||||
app_id: route.query.app_id,
|
||||
content: msg.content.content,
|
||||
msg_type: 1,
|
||||
to_user_id: activeUser.value.user_id
|
||||
to_user_id: activeUser.value.sender_id
|
||||
}).then(() => {
|
||||
msg._sending = false
|
||||
}).catch(() => {
|
||||
@ -356,7 +358,7 @@ const handleRetry = (id) => {
|
||||
form.append('file', msg.content.file)
|
||||
form.append('app_id', route.query.app_id)
|
||||
form.append('msg_type', 2)
|
||||
form.append('to_user_id', activeUser.value.user_id)
|
||||
form.append('to_user_id', activeUser.value.sender_id)
|
||||
send_message(form).then(() => {
|
||||
msg._sending = false
|
||||
}).catch(() => {
|
||||
@ -399,8 +401,8 @@ const getUsers = (append = false) => {
|
||||
userList.value = res.list || []
|
||||
}
|
||||
// 首次加载且没有选中用户时,默认选中第一个
|
||||
if (!append && userList.value.length && !activeUser.value.user_id) {
|
||||
onSelectUser(userList.value[0].user_id)
|
||||
if (!append && userList.value.length && !activeUser.value.sender_id) {
|
||||
onSelectUser(userList.value[0].sender_id)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -459,7 +461,7 @@ onUnmounted(() => {
|
||||
|
||||
// 监听活跃用户变化,重启定时器
|
||||
watch(activeUser, (newVal) => {
|
||||
if (newVal.user_id) {
|
||||
if (newVal.sender_id) {
|
||||
restartMessageTimer()
|
||||
} else {
|
||||
stopMessageTimer()
|
||||
|
||||
@ -12,7 +12,7 @@ import { getTime } from '@/utils/time';
|
||||
<div class="box">
|
||||
<div class="bottom">
|
||||
<h3 class="title">尊敬的用户,{{ getTime() }} </h3>
|
||||
<p class="subtitle">欢迎使用 猕猴桃 SCRM 系统!</p>
|
||||
<p class="subtitle">欢迎使用 小程序聊天管理 系统!</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
<el-col :span="12">
|
||||
<div class="row-login">
|
||||
<div class="login-form">
|
||||
<h2>SCRM 登录</h2>
|
||||
<h2>小程序聊天管理 登录</h2>
|
||||
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="0">
|
||||
<el-form-item label="" prop="username" style="margin-bottom: 30px;">
|
||||
<el-input v-model="ruleForm.username" placeholder="用户名" prefix-icon="User" size="large" />
|
||||
|
||||
@ -94,7 +94,9 @@
|
||||
<el-form-item label="小程序ID" prop="app_id">
|
||||
<el-input v-model="ruleForm.app_id" placeholder="请输入小程序ID" size="large" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="App_Secret" prop="app_secret">
|
||||
<el-input v-model="ruleForm.app_secret" placeholder="请输入app_secret" size="large" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="头像" prop="avatar">
|
||||
<Upload v-model="ruleForm.avatar" type="image" accept="image/*" :action="robotHost"
|
||||
@ -206,6 +208,11 @@ const rules = ref({
|
||||
required: true,
|
||||
message: '请上传小程序头像',
|
||||
trigger: 'change',
|
||||
}],
|
||||
app_secret: [{
|
||||
required: true,
|
||||
message: '请上传小程序头像',
|
||||
trigger: 'change',
|
||||
}]
|
||||
})
|
||||
const query = reactive({
|
||||
@ -260,7 +267,8 @@ const submitRobot = async () => {
|
||||
description: ruleForm.value.description,
|
||||
name: ruleForm.value.name,
|
||||
app_id: ruleForm.value.app_id,
|
||||
avatar: ruleForm.value.avatar
|
||||
avatar: ruleForm.value.avatar,
|
||||
app_secret: ruleForm.value.app_secret
|
||||
})
|
||||
// editItem = ruleForm.value
|
||||
// robotCards.value[editIndex] = editItem
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user