Browse Source

no message

master
xpz2018 10 months ago
parent
commit
41a91bef65
17 changed files with 301 additions and 681 deletions
  1. 4
      mock/sys/user.ts
  2. 0
      src/api/clue/index.ts
  3. 30
      src/api/message/model.ts
  4. 6
      src/locales/lang/zh-CN/routes/clue.ts
  5. 38
      src/router/menu.ts
  6. 24
      src/router/menus/modules/clue.ts
  7. 20
      src/router/menus/modules/message.ts
  8. 49
      src/router/routes/modules/clue.ts
  9. 40
      src/router/routes/modules/message.ts
  10. 2
      src/settings/projectSetting.ts
  11. 0
      src/views/clue/clueList/data.ts
  12. 71
      src/views/clue/clueList/index.vue
  13. 26
      src/views/clue/cluePool/data.ts
  14. 72
      src/views/clue/cluePool/index.vue
  15. 26
      src/views/clue/customer/data.ts
  16. 2
      src/views/clue/customer/index.vue
  17. 572
      src/views/message/chatInfo/index.vue

4
mock/sys/user.ts

@ -12,7 +12,7 @@ export function createFakeUserList() {
password: '123456',
token:
'QNT iHP4V/g6O5DXHixyNrf7tjJzhv1uzd15gp7AgTwJsmPLbOmqa7ZoSiaGTLfB/eLpbse0PBxScusDqEpdm1ZVRA==',
homePath: '/customer/user',
homePath: '/clue/clueList',
roles: [
{
roleName: 'Super Admin',
@ -28,7 +28,7 @@ export function createFakeUserList() {
avatar: 'https://q1.qlogo.cn/g?b=qq&nk=339449197&s=640',
desc: 'tester',
token: 'fakeToken2',
homePath: '/customer/user',
homePath: '/clue/clueList',
roles: [
{
roleName: 'Tester',

src/api/message/index.ts → src/api/clue/index.ts

30
src/api/message/model.ts

@ -1,30 +0,0 @@
export interface MessageItemModel {
nickName: string
contentTime: string
miId: string
userMarriageInformationType: number
}
export interface MessageRoomModel {
cityName: string
finalActivityTime: string
miId: string
finalContent: string
genderCode: number
roomId: string
roomName: string
roomPic: string
unreadContentCount: number
}
export interface MessageModel {
content: string
contentTime: string
readStatus: boolean
finalContent: string
roomContentRecordId: number
roomId: string
sendMiId: string
type: number
}

6
src/locales/lang/zh-CN/routes/clue.ts

@ -0,0 +1,6 @@
export default {
clue: '线索管理',
cluePool: '线索池',
clueList: '我的线索',
customer: '客户信息'
}

38
src/router/menu.ts

@ -1,31 +1,39 @@
import type { Menu } from '/@/router/types'
const messageMenu: Menu = {
path: '/message',
name: 'message',
const clueMenu: Menu = {
path: '/clue',
name: 'clue',
component: 'LAYOUT',
redirect: '/message/messageList',
redirect: '/clue/messageList',
meta: {
orderNo: 90013,
hideChildrenInMenu: false,
icon: 'ant-design:send-outlined',
title: 'routes.message.message',
icon: 'ant-design:dribbble-circle-filled',
title: 'routes.clue.clue',
},
children: [
{
path: 'messageList',
name: 'MessageList',
component: '/message/messageList/index.vue',
path: 'cluePool',
name: 'CluePool',
component: '/clue/cluePool/index.vue',
meta: {
title: 'routes.message.messageList',
title: 'routes.clue.cluePool',
},
},
{
path: 'chatInfo',
name: 'ChatInfo',
component: '/message/chatInfo/index.vue',
path: 'clueList',
name: 'ClueList',
component: '/clue/clueList/index.vue',
meta: {
title: 'routes.message.chatInfo',
title: 'routes.clue.clueList',
},
},
{
path: 'customer',
name: 'Customer',
component: '/clue/customer/index.vue',
meta: {
title: 'routes.clue.customer',
hideMenu: true,
},
},
@ -72,7 +80,7 @@ const systemMenu: Menu = {
}
const appMenuList: Menu[] = [
messageMenu,
clueMenu,
systemMenu,
]
// 测试账号:15014242835

24
src/router/menus/modules/clue.ts

@ -0,0 +1,24 @@
import type { MenuModule } from '/@/router/types'
import { t } from '/@/hooks/web/useI18n'
const clueMenu: MenuModule = {
orderNo: 90003,
menu: {
path: '/clue',
name: t('routes.clue.clue'),
children: [
{
path: 'cluePool',
name: t('routes.clue.cluePool'),
},
{
path: 'clueList',
name: t('routes.clue.clueList'),
},
{
path: 'customer',
name: t('routes.clue.customer'),
},
],
},
}
export default clueMenu

20
src/router/menus/modules/message.ts

@ -1,20 +0,0 @@
import type { MenuModule } from '/@/router/types'
import { t } from '/@/hooks/web/useI18n'
const messageMenu: MenuModule = {
orderNo: 90003,
menu: {
path: '/message',
name: t('routes.message.message'),
children: [
{
path: 'messageList',
name: t('routes.message.messageList'),
},
{
path: 'chatInfo',
name: t('routes.message.chatInfo'),
},
],
},
}
export default messageMenu

49
src/router/routes/modules/clue.ts

@ -0,0 +1,49 @@
import type { AppRouteModule } from '/@/router/types'
import { LAYOUT } from '/@/router/constant'
import { t } from '/@/hooks/web/useI18n'
const messageRoute: AppRouteModule = {
path: '/clue',
name: 'Clue',
component: LAYOUT,
redirect: '/clue/cluePool',
meta: {
orderNo: 90013,
hideChildrenInMenu: false,
icon: 'ant-design:dribbble-circle-filled',
title: t('routes.clue.clue'),
},
children: [
{
path: 'cluePool',
name: 'CluePool',
component: () => import('/src/views/clue/cluePool/index.vue'),
meta: {
// roles: ['/staff/staff'],
title: t('routes.clue.cluePool'),
},
},
{
path: 'clueList',
name: 'ClueList',
component: () => import('/src/views/clue/clueList/index.vue'),
meta: {
// roles: ['/staff/staff'],
title: t('routes.clue.clueList'),
},
},
{
path: 'customer',
name: 'Customer',
component: () => import('/src/views/clue/customer/index.vue'),
meta: {
// roles: ['/staff/staff'],
title: t('routes.clue.customer'),
hideMenu: true,
},
},
],
}
export default messageRoute

40
src/router/routes/modules/message.ts

@ -1,40 +0,0 @@
import type { AppRouteModule } from '/@/router/types'
import { LAYOUT } from '/@/router/constant'
import { t } from '/@/hooks/web/useI18n'
const messageRoute: AppRouteModule = {
path: '/message',
name: 'Message',
component: LAYOUT,
redirect: '/message/messageList',
meta: {
orderNo: 90013,
hideChildrenInMenu: false,
icon: 'ant-design:send-outlined',
title: t('routes.message.message'),
},
children: [
{
path: 'messageList',
name: 'MessageList',
component: () => import('/src/views/message/messageList/index.vue'),
meta: {
// roles: ['/staff/staff'],
title: t('routes.message.message'),
},
},
{
path: 'chatInfo',
name: 'ChatInfo',
component: () => import('/src/views/message/chatInfo/index.vue'),
meta: {
// roles: ['/staff/staff'],
title: t('routes.message.chatInfo'),
hideMenu: true,
},
},
],
}
export default messageRoute

2
src/settings/projectSetting.ts

@ -24,7 +24,7 @@ const setting: ProjectConfig = {
settingButtonPosition: SettingButtonPositionEnum.AUTO,
// Permission mode
permissionMode: PermissionModeEnum.BACK,
permissionMode: PermissionModeEnum.ROLE,
// Permission-related cache is stored in sessionStorage or localStorage
permissionCacheType: CacheTypeEnum.LOCAL,

src/views/message/messageList/data.ts → src/views/clue/clueList/data.ts

71
src/views/clue/clueList/index.vue

@ -0,0 +1,71 @@
<template>
<div class="order-list">
<BasicTable @register="registerTable">
<template #action="{ record }">
<TableAction
:actions="[
{
label: '详情',
onClick: toDetail.bind(null, record),
},
]"
/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
export default {
name: 'OrderList',
}
</script>
<script setup lang="ts">
import moment from 'moment/moment'
import { computed, ref } from 'vue'
import { Card } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import { tableColumns, tableFormSchema } from './data'
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getChatMessagePage } from '/@/api/clue'
const [registerTable] = useTable({
bordered: true,
useSearchForm: true,
columns: tableColumns,
showIndexColumn: true,
showTableSetting: false,
api: getChatMessagePage,
formConfig: {
labelWidth: 120,
schemas: tableFormSchema,
},
// beforeFetch: (arg) => {
// const { orderTime } = arg
// if (orderTime) {
// arg.orderTimeFrom = moment(orderTime[0]).format('YYYY-MM-DD 00:00:00')
// arg.orderTimeTo = moment(orderTime[1]).format('YYYY-MM-DD 23:59:59')
// delete arg.orderTime
// }
// },
actionColumn: {
width: 160,
title: '操作',
fixed: 'right',
dataIndex: 'action',
slots: { customRender: 'action' },
},
})
const router = useRouter()
function toDetail(record: any) {
const { miId, userMarriageInformationType } = record
router.push({
query: { miId, type: userMarriageInformationType },
path: '/message/chatInfo',
})
}
</script>
<style scoped lang="less">
</style>

26
src/views/clue/cluePool/data.ts

@ -0,0 +1,26 @@
import { BasicColumn, FormSchema } from '/@/components/Table'
const userTypeList = [
{ label: '正常用户', value: 1 },
{ label: '录入用户', value: 2},
{ label: '红娘', value: 3 },
]
export const tableColumns: BasicColumn[] = [
{ title: '用户昵称', dataIndex: 'nickName' },
{ title: '用户身份', dataIndex: 'userMarriageInformationType',
customRender: ({ text }) => {
return userTypeList.find((find) => find.value === text)?.label
},
},
// { title: '客户手机号', dataIndex: 'userPhone' },
{ title: '最新消息时间', dataIndex: 'contentTime' },
]
export const tableFormSchema: FormSchema[] = [
{
field: 'nickName',
label: '用户昵称',
component: 'Input',
colProps: { span: 8},
},
]

72
src/views/clue/cluePool/index.vue

@ -0,0 +1,72 @@
<template>
<div class="order-list">
<BasicTable @register="registerTable">
<template #action="{ record }">
<TableAction
:actions="[
{
label: '详情',
onClick: toDetail.bind(null, record),
},
]"
/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
export default {
name: 'OrderList',
}
</script>
<script setup lang="ts">
import moment from 'moment/moment'
import { computed, ref } from 'vue'
import { Card } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import { tableColumns, tableFormSchema } from './data'
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getChatMessagePage } from '/@/api/clue'
const [registerTable] = useTable({
bordered: true,
useSearchForm: true,
columns: tableColumns,
showIndexColumn: true,
showTableSetting: false,
api: getChatMessagePage,
formConfig: {
labelWidth: 120,
schemas: tableFormSchema,
},
// beforeFetch: (arg) => {
// const { orderTime } = arg
// if (orderTime) {
// arg.orderTimeFrom = moment(orderTime[0]).format('YYYY-MM-DD 00:00:00')
// arg.orderTimeTo = moment(orderTime[1]).format('YYYY-MM-DD 23:59:59')
// delete arg.orderTime
// }
// },
actionColumn: {
width: 160,
title: '操作',
fixed: 'right',
dataIndex: 'action',
slots: { customRender: 'action' },
},
})
const router = useRouter()
function toDetail(record: any) {
const { miId, userMarriageInformationType } = record
router.push({
query: { miId, type: userMarriageInformationType },
path: '/message/chatInfo',
})
}
</script>
<style scoped lang="less">
</style>

26
src/views/clue/customer/data.ts

@ -0,0 +1,26 @@
import { BasicColumn, FormSchema } from '/@/components/Table'
const userTypeList = [
{ label: '正常用户', value: 1 },
{ label: '录入用户', value: 2},
{ label: '红娘', value: 3 },
]
export const tableColumns: BasicColumn[] = [
{ title: '用户昵称', dataIndex: 'nickName' },
{ title: '用户身份', dataIndex: 'userMarriageInformationType',
customRender: ({ text }) => {
return userTypeList.find((find) => find.value === text)?.label
},
},
// { title: '客户手机号', dataIndex: 'userPhone' },
{ title: '最新消息时间', dataIndex: 'contentTime' },
]
export const tableFormSchema: FormSchema[] = [
{
field: 'nickName',
label: '用户昵称',
component: 'Input',
colProps: { span: 8},
},
]

src/views/message/messageList/index.vue → src/views/clue/customer/index.vue

@ -27,7 +27,7 @@
import { useRouter } from 'vue-router'
import { tableColumns, tableFormSchema } from './data'
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getChatMessagePage } from '/@/api/message'
import { getChatMessagePage } from '/@/api/clue'
const [registerTable] = useTable({
bordered: true,

572
src/views/message/chatInfo/index.vue

@ -1,572 +0,0 @@
<template>
<div class="flex-row" style="width: 100%;height: 100%;">
<div class="flex-col" style="width: 320px;height: 100%;border-right: 1px solid #ccc;">
<div style="width: 100%;padding: 10px 24px;">
<span style="font-size: 30px;font-weight: bold;color: #333;">用户资料</span>
</div>
<div class="flex-col" style="padding: 0px 20px;" v-if="details && details.code">
<img :src="avatar" style="height: 120px;width: 120px;border-radius: 50%;margin-top: 90px;"/>
<span style="font-size: 18px;font-weight: bold;color: #333;margin-top: 8px;">{{details.name}}</span>
<div class="flex-row" style="margin-top: 8px;" v-if="details.phone">
<span style="font-size: 14px;color: #333;">手机号</span>
<span style="font-size: 14px;color: #333;">{{details.phone}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">身份</span>
<span style="font-size: 14px;color: #333;">{{matchmakerTypeList.find((find) => find.value === details.type)?.label}}</span>
<span style="font-size: 14px;color: #333;" v-if="details.matchmakerLevel > 2"> / {{details.matchmakerLevel == 3 ? '站点服务商' : '区域服务商'}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;" v-if="details.storeName">
<span style="font-size: 14px;color: #333;">所属门店</span>
<span style="font-size: 14px;color: #333;">{{details.storeName}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">入驻时间</span>
<span style="font-size: 14px;color: #333;">{{details.validityPeriodFrom}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">到期时间</span>
<span style="font-size: 14px;color: #333;">{{details.validityPeriodTo}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">评分</span>
<span style="font-size: 14px;color: #333;">{{details.score || '5.0'}}</span>
</div>
</div>
<div class="flex-col" style="padding: 0px 20px;" v-else-if="details">
<img :src="avatar" style="height: 120px;width: 120px;border-radius: 50%;margin-top: 90px;"/>
<span style="font-size: 18px;font-weight: bold;color: #333;margin-top: 8px;">{{details.nickName}}</span>
<div class="flex-row" style="margin-top: 8px;" v-if="details.name">
<span style="font-size: 14px;color: #333;">姓名</span>
<span style="font-size: 14px;color: #333;">{{details.name}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;" v-if="details.phone">
<span style="font-size: 14px;color: #333;">手机号</span>
<span style="font-size: 14px;color: #333;">{{details.phone}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">性别</span>
<span style="font-size: 14px;color: #333;">{{details.genderCode == 0 ? '男' : '女'}}</span>
</div>
<div class="flex-row" style="margin-top: 8px;">
<span style="font-size: 14px;color: #333;">嘉宾来源</span>
<span style="font-size: 14px;color: #333;">{{details.identityTypeName || '红娘录入'}}</span>
</div>
</div>
</div>
<div class="flex-col" style="width: 375px;height: 100%;border-right: 1px solid #ccc;">
<div style="width: 100%;padding: 10px 24px;border-bottom: 1px solid #ccc;background:white;">
<span style="font-size: 30px;font-weight: bold;color: #333;">消息列表</span>
</div>
<div style="width: 100%;height: 80vh;overflow: auto;">
<div class="flex-row room-card" v-for="(item, index) in roomList" :key="item.roomId" :style="{background: roomIndex == index ? '#ddd' : 'white'}" @click="changeRoom(item, index)">
<Badge :count="item.unreadContentCount">
<img :src="item.roomPic || bAvatar" style="height: 64px;width: 64px;border-radius: 8px;"/>
</Badge>
<div class="flex-col" style="flex: 1;padding-left: 8px;">
<div class="flex-row-center-space" style="flex: 1;">
<span style="font-size: 16px;font-weight: bold;color: #333;">{{item.roomName}}</span>
<div class="flex-row" v-if="item.cityName">
<Icon size="18" icon="ant-design:environment-outlined" style="padding-top: 2px;"/>
<span style="font-size: 14px;color: #666;">{{item.cityName}}</span>
</div>
</div>
<div class="flex-col" style="flex: 1;">
<span style="font-size: 14px;color: #333;">{{item.finalContent}}</span>
<span style="font-size: 12px;color: #999;">{{item.finalActivityTime}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="flex-col" style="flex: 1;height: 100%;">
<Spin :spinning="loading" style="flex: 1;height: 100%;">
<div class="flex-col" style="flex: 1;height: 100%;">
<div class="flex-row-center-space" style="width: 100%;padding: 10px 24px;border-bottom: 1px solid #ccc;">
<span style="font-size: 30px;font-weight: bold;color: #333;">对话框</span>
<span style="font-size: 18px;color: #333;" v-if="nowItem">{{nowItem.roomName}}</span>
</div>
<Result subTitle="暂无消息记录" v-if="!loading && messageList.length == 0"></Result>
<div class="scroll_wrap" ref="scrollWrap">
<div class="chat-item" v-for="item in messageList" :key="item.roomContentRecordId">
<span class="chat-time" v-if="item.contentTime && item.contentTime.length">{{item.contentTime}}</span>
<!--图片消息 -->
<template v-if="item.type == 6">
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-content-container">
<div class="chat-text-container-super" style="justify-content: flex-end;">
<div class="chat-text-container chat-text-container-me">
<span class="chat-text chat-text-me">{{item.info.content || ''}}</span>
</div>
</div>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container" style="justify-content: flex-start;margin: 4px 8px 0px 8px;">
<div style="border-top: 1px solid #f3f3f3;padding: 12px;width: 300px;">
<span style="font-size: 15px;color: #333;">申请查看Ta的照片是否同意</span>
</div>
</div>
</div>
</template>
<!--图片消息 -->
<template v-else-if="item.type == 5">
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container chat-text-container-me" style="justify-content: flex-end;margin: 4px 8px 0px 8px;">
<Image :src="avatarImage(item)" style="height: 300px;width: 300px;border-radius: 8px 0 8px 8px;"/>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container" style="justify-content: flex-start;margin: 4px 8px 0px 8px;">
<Image :src="avatarImage(item)" style="height: 300px;width: 300px;border-radius: 0px 8px 8px 8px;"/>
</div>
</div>
</template>
<!--邀请发榜消息 -->
<template v-else-if="item.type == 4">
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container chat-text-container-me" style="justify-content: flex-end;margin: 4px 8px 0px 8px;">
<Image :src="avatarImage(item)" style="width: 300px;height: 240px;border-radius: 8px 0px 0px 0px;"/>
<div style="padding: 12px;background: white;border-radius: 0 0 8px 8px;">
<span style="font-size: 15px;color: #333;">{{item.info.content}}</span>
</div>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container" style="justify-content: flex-start;margin: 4px 8px 0px 8px;">
<Image :src="avatarImage(item)" style="height: 240px;width: 300px;border-radius: 0px 8px 0px 0px;"/>
<div style="border-top: 1px solid #f3f3f3;padding: 12px;width: 300px;">
<span style="font-size: 15px;color: #EE811B;">Hi!我是你的红娘邀请你发布悬赏现在去发布?</span>
</div>
</div>
</div>
</template>
<!--悬赏匹配资料消息 -->
<template v-else-if="item.type == 3">
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container chat-text-container-me" style="justify-content: flex-end;margin: 4px 8px 0px 8px;">
<img :src="avatarImage(item)" style="height: 225px;width: 300px;border-radius: 8px 0px 0px 0px;"/>
<div class="flex-row-center-space" style="padding: 8px 12px 4px 12px;color: #fff;">
<div class="flex-row-center-start">
<span style="font-size: 16px;font-weight: bold;margin-right: 6px;">{{item.info.nickName}}</span>
</div>
<span style="font-size: 12px;">{{item.info.age}} / {{item.info.height}}cm</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 4px 12px;color: #fff;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.nowtown}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.hometown}}</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 12px 12px;color: #fff;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.education}}</span>
<span style="margin: 0px 8px;font-size: 12px;" v-if="item.info.occupation">|</span>
<span style="font-size: 12px;" v-if="item.info.occupation">{{item.info.occupation}}</span>
<span style="margin: 0px 12px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.income}}</span>
</div>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container" style="justify-content: flex-start;margin: 4px 8px 0px 8px;">
<img :src="avatarImage(item)" style="height: 225px;width: 300px;border-radius: 0px 8px 0px 0px;"/>
<div class="flex-row-center-space" style="padding: 8px 12px 4px 12px;color: #333;">
<div class="flex-row-center-start">
<span style="font-size: 16px;font-weight: bold;margin-right: 6px;">{{item.info.nickName}}</span>
</div>
<span style="font-size: 12px;">{{item.info.age}} / {{item.info.height}}cm</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 4px 12px;color: #333;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.nowtown}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.hometown}}</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 12px 12px;color: #333;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.education}}</span>
<span style="margin: 0px 8px;font-size: 12px;" v-if="item.info.occupation">|</span>
<span style="font-size: 12px;" v-if="item.info.occupation">{{item.info.occupation}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.income}}</span>
</div>
<div style="border-top: 1px solid #f3f3f3;padding: 12px;">
<span style="font-size: 15px;color: #333;">嘉宾申请与你见面请确认</span>
</div>
<div style="padding: 0px 12px 12px 12px;width: 300px;" v-if="[2, 3].includes(item.info.miIdAttitude)">
<span style="font-size: 13px;color: #EE811B;" v-if="item.info.miIdAttitude == 2">你已接受见面待对方同意后红娘安排见面你也可主动联系对方红娘了解进程</span>
<span style="font-size: 13px;color: #ff0000;" v-if="item.info.miIdAttitude == 3">你已经拒绝见面</span>
</div>
</div>
</div>
</template>
<!--用户资料消息 -->
<template v-else-if="item.type == 2">
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container chat-text-container-me" style="justify-content: flex-end;margin: 4px 8px 0px 8px;">
<img :src="avatarImage(item)" style="height: 225px;width: 300px;border-radius: 8px 0px 0px 0px;"/>
<div class="flex-row-center-space" style="padding: 8px 12px 4px 12px;color: #fff;">
<div class="flex-row-center-start">
<span style="font-size: 16px;font-weight: bold;margin-right: 6px;">{{item.info.nickName}}</span>
</div>
<span style="font-size: 12px;">{{item.info.age}} / {{item.info.height}}cm</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 4px 12px;color: #fff;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.nowtown}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.hometown}}</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 12px 12px;color: #fff;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.education}}</span>
<span style="margin: 0px 8px;font-size: 12px;" v-if="item.info.occupation">|</span>
<span style="font-size: 12px;" v-if="item.info.occupation">{{item.info.occupation}}</span>
<span style="margin: 0px 12px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.income}}</span>
</div>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-profile-container" style="justify-content: flex-start;margin: 4px 8px 0px 8px;">
<img :src="avatarImage(item)" style="height: 225px;width: 300px;border-radius: 0px 8px 0px 0px;"/>
<div class="flex-row-center-space" style="padding: 8px 12px 4px 12px;color: #333;">
<div class="flex-row-center-start">
<span style="font-size: 16px;font-weight: bold;margin-right: 6px;">{{item.info.nickName}}</span>
</div>
<span style="font-size: 12px;">{{item.info.age}} / {{item.info.height}}cm</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 4px 12px;color: #333;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.nowtown}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.hometown}}</span>
</div>
<div class="flex-row-center-start" style="padding: 0px 12px 12px 12px;color: #333;max-width: 300px;">
<span style="font-size: 12px;">{{item.info.education}}</span>
<span style="margin: 0px 8px;font-size: 12px;" v-if="item.info.occupation">|</span>
<span style="font-size: 12px;" v-if="item.info.occupation">{{item.info.occupation}}</span>
<span style="margin: 0px 8px;font-size: 12px;">|</span>
<span style="font-size: 12px;">{{item.info.income}}</span>
</div>
</div>
</div>
</template>
<!--聊天消息 -->
<template v-else>
<div class="chat-container chat-location-me" v-if="isMe(item)">
<div class="chat-icon-container">
<img :src="avatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-content-container">
<div class="chat-text-container-super" style="justify-content: flex-end;">
<div class="chat-text-container chat-text-container-me">
<span class="chat-text chat-text-me">{{item.content || ''}}</span>
</div>
</div>
</div>
</div>
<div class="chat-container" v-else>
<div class="chat-icon-container">
<img :src="nowItem.roomPic || bAvatar" style="height: 40px;width: 40px;border-radius: 6px;"/>
</div>
<div class="chat-content-container">
<div class="chat-text-container-super" style="justify-content: flex-start;">
<div class="chat-text-container flex-col">
<span class="chat-text">{{item.content || ''}}</span>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</Spin>
</div>
</div>
</template>
<script>
import { Button, Badge, Result, Spin, Image } from 'ant-design-vue'
import { matchmakerTypeList } from '/@/enums/partnerEnum'
import Icon from '/@/components/Icon/src/Icon.vue'
import { getMarriageInformationDetailsById } from '/@/api/marriageInfo'
import { getMatchmakerInfo } from '/@/api/reward'
import { getChatMessageRoomList, getChatRoomMessageList } from '/@/api/message'
export default {
components: { Button, Badge, Icon, Result, Spin, Image },
data() {
return {
miId: null,
details: null,
avatar: null,
nowItem: null,
roomList: [],
roomIndex: 0,
pageIndex: 1,
messageList: [],
loading: true,
roomId: null,
noMore: false, //
matchmakerTypeList,
bAvatar: 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/B5B307276426.png'
};
},
mounted() {
this.miId = this.$route.query.miId
if(this.miId){
let type = Number(this.$route.query.type)
if(type == 3){
getMatchmakerInfo(this.miId).then(res => {
this.details = res
this.avatar = res.profilePhoto || this.bAvatar
})
} else {
getMarriageInformationDetailsById(this.miId).then(res => {
this.details = res
this.avatar = res.profilePhoto || this.bAvatar
})
}
getChatMessageRoomList({selfMiId: this.miId, pageSize: 100}).then(result => {
this.roomList = result.items || []
this.nowItem = this.roomList[0]
this.roomId = this.roomList[0].roomId
this.fetchMessageList()
})
}
this.$refs.scrollWrap.addEventListener("scroll", this.onScrollListener);
},
methods: {
//
onScrollListener() {
if (this.$refs.scrollWrap.scrollTop == 0) {
console.log("滚动到顶部了");
if (this.noMore) {
console.log("暂无更多数据");
return;
}
//
setTimeout(() => {
const scrollWrap = this.$refs.scrollWrap;
let h1 = scrollWrap.scrollHeight;
console.log("h1======" + h1);
this.fetchMessageList();
//listscrollHeight,
this.$nextTick(() => {
let h2 = scrollWrap.scrollHeight;
console.log("h======" + h2);
//50px
scrollWrap.scrollTo({
top: h2 - h1 - 50,
behavior: "instant", //auto- instant- smooth-
});
});
}, 1000);
}
},
//
scrollTop() {
this.$nextTick(() => {
const scrollWrap = this.$refs.scrollWrap;
scrollWrap.scrollTo({
top: 0,
behavior: "smooth", //auto- instant- smooth-
});
});
},
//
scrollBottom() {
this.$nextTick(() => {
let scrollWrap = this.$refs.scrollWrap;
scrollWrap.scrollTo({
top: scrollWrap.scrollHeight,
behavior: "smooth", //auto- instant- smooth-
});
});
},
//
async fetchMessageList() {
this.loading = true
const result = await getChatRoomMessageList({pageNum: this.pageNum, selfMiId: this.miId, roomId: this.roomId})
var respList = result.items || []
for (var index = respList.length - 1; index >= 0; index--) {
if(respList[index].type == 2 || respList[index].type == 3){
respList[index].info = JSON.parse(respList[index].content)
if(respList[index].info.type && Number(respList[index].info.type) > 3){
respList[index].type = Number(respList[index].info.type)
}
}
}
if(this.pageNum == result.pages){
this.noMore = true; //
console.log('数据全部加载完毕')
if(this.pageNum == 1){
this.messageList = respList
this.scrollBottom();
} else {
this.messageList = [...respList, ...this.messageList]
}
} else if(this.pageNum == 1){
this.messageList = respList
this.pageNum = result.current + 1
this.scrollBottom();
} else {
this.pageNum = result.current + 1
this.messageList = [...respList, ...this.messageList]
}
this.loading = false
},
changeRoom(item, index){
if(this.loading || this.roomId === item.roomId){
return
}
this.nowItem = item
this.pageNum = 1
this.roomIndex = index
this.noMore = false;
this.roomId = item.roomId
this.messageList = []
this.fetchMessageList()
},
isMe(item){
return item.sendMiId === this.miId
},
avatarImage(item){
if(item.info && item.info.url){
return item.info.url
}
if(item.info && item.info.profilePhoto){
return item.info.profilePhoto
}
return 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/64949726764B.jpg'
},
},
beforeDestroy() {
this.$refs.scrollWrap.removeEventListener("scroll", this.onScrollListener);
},
};
</script>
<style lang="less" scoped>
.scroll_wrap {
width: 100%;
height: 80vh;
// position: absolute;
// top: 30px;
// left: 50%;
// transform: translateX(-50%);
// border: 1px solid #333;
overflow: auto;
.item {
height: 50px;
line-height: 50px;
padding-left: 15px;
border-bottom: 1px solid #e4e4e4;
}
}
.room-card{
width: 100%;
padding: 12px;
border-bottom: 1px solid #ccc;
background: white;
}
.chat-item {
display: flex;
flex-direction: column;
padding: 10px;
}
.chat-time {
padding: 2px 0px;
text-align: center;
font-size: 12px;
color: #aaaaaa;
}
.chat-container {
display: flex;
flex-direction: row;
}
.chat-location-me {
flex-direction: row-reverse;
text-align: right;
}
.chat-icon-container {
margin-top: 4px;
}
.chat-icon{
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #eeeeee;
}
.chat-content-container {
margin: 0px 8px;
}
.chat-user-name{
font-size: 13px;
color: #888888;
}
.chat-profile-container{
text-align: left;
background-color: #fff;
border-radius: 0 8px 8px 8px;
}
.chat-text-container {
text-align: left;
background-color: #fff;
border-radius: 0 8px 8px 8px;
padding: 10px 12px 13px 12px;
margin-top: 1px;
max-width: 300px;
}
.chat-text-container-me {
background-color: #EE811B;
border-radius: 8px 0 8px 8px;
}
.chat-text-container-super {
display: flex;
flex-direction: row;
margin-top: 4px;
}
.chat-text {
font-size: 14px;
word-break: break-all;
max-width: 286px;
}
.chat-text-me {
color: white;
}
</style>
Loading…
Cancel
Save