17 changed files with 301 additions and 681 deletions
Split View
Diff Options
-
4mock/sys/user.ts
-
0src/api/clue/index.ts
-
30src/api/message/model.ts
-
6src/locales/lang/zh-CN/routes/clue.ts
-
38src/router/menu.ts
-
24src/router/menus/modules/clue.ts
-
20src/router/menus/modules/message.ts
-
49src/router/routes/modules/clue.ts
-
40src/router/routes/modules/message.ts
-
2src/settings/projectSetting.ts
-
0src/views/clue/clueList/data.ts
-
71src/views/clue/clueList/index.vue
-
26src/views/clue/cluePool/data.ts
-
72src/views/clue/cluePool/index.vue
-
26src/views/clue/customer/data.ts
-
2src/views/clue/customer/index.vue
-
572src/views/message/chatInfo/index.vue
@ -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 |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
export default { |
|||
clue: '线索管理', |
|||
cluePool: '线索池', |
|||
clueList: '我的线索', |
|||
customer: '客户信息' |
|||
} |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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> |
|||
@ -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}, |
|||
}, |
|||
] |
|||
@ -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> |
|||
@ -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}, |
|||
}, |
|||
] |
|||
@ -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(); |
|||
|
|||
//list更新后,等待页面渲染完毕再去拿scrollHeight,否则拿到的是之前的 |
|||
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> |
|||
Write
Preview
Loading…
Cancel
Save