Commit 4d72e4b0 authored by chenqikuai's avatar chenqikuai

feat: 通讯录

parent c07cc217
import { eRole } from '@/types/roleType'
import { chatAuthCheck } from '@/utils/authCheck'
import { getUserMsg } from '@/utils/userMsg'
import { Toast } from 'vant'
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { eRole } from "@/types/roleType";
import { chatAuthCheck } from "@/utils/authCheck";
import { getUserMsg } from "@/utils/userMsg";
import { Toast } from "vant";
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: { name: 'Home' },
path: "/",
redirect: { name: "Home" },
component: () =>
import(/* webpackChunkName: "withMenu" */ '@/views/withMenu/index.vue'),
import(/* webpackChunkName: "withMenu" */ "@/views/withMenu/index.vue"),
children: [
{
path: '/home',
name: 'Home',
path: "/home",
name: "Home",
meta: {
activeTab: "Home",
},
component: () =>
import(
/* webpackChunkName: "Home" */ '@/views/withMenu/Home/index.vue'
/* webpackChunkName: "Home" */ "@/views/withMenu/Home/index.vue"
),
},
{
path: '/mine',
name: 'Mine',
path: "/mine",
name: "Mine",
meta: {
activeTab: "Mine",
},
component: () =>
import(
/* webpackChunkName: "mine" */ '@/views/withMenu/Mine/index.vue'
/* webpackChunkName: "mine" */ "@/views/withMenu/Mine/index.vue"
),
},
{
path: '/loan',
name: 'Loan',
path: "/loan",
name: "Loan",
meta: {
activeTab: "Loan",
},
component: () =>
import(
/* webpackChunkName: "mine" */ '@/views/withMenu/Loan/index.vue'
/* webpackChunkName: "mine" */ "@/views/withMenu/Loan/index.vue"
),
},
{
path: '/chatList',
name: 'ChatList',
path: "/chatList",
name: "ChatList",
meta: {
needAuth: true,
activeTab: "ChatList",
},
component: () =>
import(
/* webpackChunkName: "chatList" */ "@/views/withMenu/ChatList/index.vue"
),
},
{
path: "/addressBook",
name: "AddressBook",
meta: {
activeTab: "ChatList",
},
component: () =>
import(
/* webpackChunkName: "chatList" */ '@/views/withMenu/ChatList/index.vue'
/* webpackChunkName: "addressBook" */ "@/views/withMenu/AddressBook/index.vue"
),
},
],
},
{
path: '/loanList/:mode',
name: 'LoanList',
path: "/loanList/:mode",
name: "LoanList",
component: () =>
import(/* webpackChunkName: "LoanList" */ '@/views/LoanList/index.vue'),
import(/* webpackChunkName: "LoanList" */ "@/views/LoanList/index.vue"),
},
{
path: '/loanDetail/:uuid',
name: 'LoanDetail',
path: "/loanDetail/:uuid",
name: "LoanDetail",
component: () =>
import(
/* webpackChunkName: "LoanDetail" */ '@/views/LoanDetail/index.vue'
/* webpackChunkName: "LoanDetail" */ "@/views/LoanDetail/index.vue"
),
},
{
path: '/activityList',
name: 'ActivityList',
path: "/activityList",
name: "ActivityList",
component: () =>
import(
/* webpackChunkName: "ActivityList" */ '@/views/ActivityList/index.vue'
/* webpackChunkName: "ActivityList" */ "@/views/ActivityList/index.vue"
),
},
{
path: '/activityDetail/:uuid',
name: 'ActivityDetail',
path: "/activityDetail/:uuid",
name: "ActivityDetail",
component: () =>
import(
/* webpackChunkName: "ActivityDetail" */ '@/views/ActivityDetail/index.vue'
/* webpackChunkName: "ActivityDetail" */ "@/views/ActivityDetail/index.vue"
),
},
{
path: '/policySupport',
name: 'PolicySupport',
path: "/policySupport",
name: "PolicySupport",
component: () =>
import(
/* webpackChunkName: "PolicySupport" */ '@/views/PolicySupport/index.vue'
/* webpackChunkName: "PolicySupport" */ "@/views/PolicySupport/index.vue"
),
},
{
path: '/news',
name: 'News',
path: "/news",
name: "News",
component: () =>
import(/* webpackChunkName: "News" */ '@/views/News/index.vue'),
import(/* webpackChunkName: "News" */ "@/views/News/index.vue"),
},
{
path: '/newsDetail',
name: 'NewsDetail',
path: "/newsDetail",
name: "NewsDetail",
component: () =>
import(
/* webpackChunkName: "NewsDetail" */ '@/views/NewsDetail/index.vue'
/* webpackChunkName: "NewsDetail" */ "@/views/NewsDetail/index.vue"
),
},
{
path: '/search',
name: 'Search',
path: "/search",
name: "Search",
component: () =>
import(/* webpackChunkName: "Search" */ '@/views/Search/index.vue'),
import(/* webpackChunkName: "Search" */ "@/views/Search/index.vue"),
},
{
path: '/auth',
path: "/auth",
component: () =>
import(/* webpackChunkName: "auth" */ '@/views/Auth/index.vue'),
import(/* webpackChunkName: "auth" */ "@/views/Auth/index.vue"),
redirect: {
name: 'Login',
name: "Login",
},
children: [
{
path: '/auth/Login',
name: 'Login',
path: "/auth/Login",
name: "Login",
component: () =>
import(
/* webpackChunkName: "Login" */ '@/views/Auth/Login/index.vue'
/* webpackChunkName: "Login" */ "@/views/Auth/Login/index.vue"
),
},
{
path: '/auth/UserAgreement',
name: 'UserAgreement',
path: "/auth/UserAgreement",
name: "UserAgreement",
component: () =>
import(
/* webpackChunkName: "UserAgreement" */ '@/views/Auth/UserAgreement/index.vue'
/* webpackChunkName: "UserAgreement" */ "@/views/Auth/UserAgreement/index.vue"
),
},
{
path: '/auth/PwdSetting',
name: 'PwdSetting',
path: "/auth/PwdSetting",
name: "PwdSetting",
component: () =>
import(
/* webpackChunkName: "PwdSetting" */ '@/views/Auth/PwdSetting/index.vue'
/* webpackChunkName: "PwdSetting" */ "@/views/Auth/PwdSetting/index.vue"
),
},
{
path: '/auth/PwdFind',
name: 'PwdFind',
path: "/auth/PwdFind",
name: "PwdFind",
component: () =>
import(
/* webpackChunkName: "PwdFind" */ '@/views/Auth/PwdFind/index.vue'
/* webpackChunkName: "PwdFind" */ "@/views/Auth/PwdFind/index.vue"
),
},
{
path: '/auth/PwdModify',
name: 'PwdModify',
path: "/auth/PwdModify",
name: "PwdModify",
component: () =>
import(
/* webpackChunkName: "PwdModify" */ '@/views/Auth/PwdModify/index.vue'
/* webpackChunkName: "PwdModify" */ "@/views/Auth/PwdModify/index.vue"
),
},
],
},
{
path: '/setting',
name: 'Setting',
path: "/setting",
name: "Setting",
component: () =>
import(
/* webpackChunkName: "Setting" */ '@/views/withMenu/Mine/setting.vue'
/* webpackChunkName: "Setting" */ "@/views/withMenu/Mine/setting.vue"
),
meta: {
needAuth: true,
},
},
{
path: '/aboutUs',
name: 'AboutUs',
path: "/aboutUs",
name: "AboutUs",
component: () =>
import(
/* webpackChunkName: "AboutUs" */ '@/views/withMenu/Mine/aboutUs.vue'
/* webpackChunkName: "AboutUs" */ "@/views/withMenu/Mine/aboutUs.vue"
),
},
{
path: '/msgManage',
name: 'MsgManage',
path: "/msgManage",
name: "MsgManage",
component: () =>
import(
/* webpackChunkName: "MsgManage" */ '@/views/withMenu/Mine/msg.vue'
/* webpackChunkName: "MsgManage" */ "@/views/withMenu/Mine/msg.vue"
),
},
{
path: '/msgDetail',
name: 'MsgDetail',
path: "/msgDetail",
name: "MsgDetail",
component: () =>
import(
/* webpackChunkName: "MsgDetail" */ '@/views/withMenu/Mine/msgDetail.vue'
/* webpackChunkName: "MsgDetail" */ "@/views/withMenu/Mine/msgDetail.vue"
),
},
{
path: '/branch',
name: 'Branch',
path: "/branch",
name: "Branch",
component: () =>
import(
/* webpackChunkName: "Branch" */ '@/views/withMenu/Mine/branch.vue'
/* webpackChunkName: "Branch" */ "@/views/withMenu/Mine/branch.vue"
),
},
{
path: '/chat',
name: 'Chat',
path: "/chat",
name: "Chat",
component: () =>
import(/* webpackChunkName: "Chat" */ '@/views/Chat/Chat.vue'),
import(/* webpackChunkName: "Chat" */ "@/views/Chat/Chat.vue"),
},
{
path: '/chatDetailMsg',
name: 'ChatDetailMsg',
path: "/chatDetailMsg",
name: "ChatDetailMsg",
component: () =>
import(
/* webpackChunkName: "ChatDetailMsg" */ '@/views/Chat/DetailMsg.vue'
/* webpackChunkName: "ChatDetailMsg" */ "@/views/Chat/DetailMsg.vue"
),
},
{
path: '/crop',
name: 'Crop',
path: "/crop",
name: "Crop",
component: () =>
import(/* webpackChunkName: "Crop" */ '@/views/Crop/index.vue'),
import(/* webpackChunkName: "Crop" */ "@/views/Crop/index.vue"),
},
{
path: '/:pathMatch(.*)*',
path: "/:pathMatch(.*)*",
redirect: {
name: 'Home',
name: "Home",
},
},
]
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
});
router.beforeEach((to, from, next) => {
const userMsg = getUserMsg()
const userMsg = getUserMsg();
if (to.meta.needAuth) {
if (!!userMsg) {
if (userMsg.role === eRole.user) next()
if (userMsg.role === eRole.user) next();
else if (userMsg.role === eRole.staff) {
if (to.name === 'ChatList') {
if (to.name === "ChatList") {
chatAuthCheck(
() => {
next()
next();
},
(mark: boolean | undefined) => {
/* 如果有mark为false,则表示检查聊天权限的逻辑走到了调用接口,但是返回auth为false */
mark === false &&
Toast('由于您现在是不在岗状态所以无法进入聊天!')
},
)
Toast("由于您现在是不在岗状态所以无法进入聊天!");
}
);
} else {
next()
next();
}
}
} else {
next({ name: 'Login' })
next({ name: "Login" });
}
} else {
next()
next();
}
})
});
export default router
export default router;
import baseAxios from '../index'
import baseAxios from "../index";
import { iContactPerson } from "@/types/chat/index";
export function getStaffOnDutyStatus() {
return baseAxios<boolean>({
url: '/staff/on_duty',
method: 'get',
})
url: "/staff/on_duty",
method: "get",
});
}
export function enableLive() {
return baseAxios({
url: '/staff/enable_live',
method: 'get'
})
url: "/staff/enable_live",
method: "get",
});
}
export function staffGetUsers(data: {
is_desc: boolean;
order_by: string;
page: number;
page_size: number;
}) {
return baseAxios<{ item: iContactPerson[]; total: number }>({
url: "/staff/myUsers",
method: "get",
params: data,
});
}
import baseAxios from "../index";
import { iContact, iUserinfo } from "./types";
import { iContactPerson } from "@/types/chat/index";
class UserService {
static instance: UserService;
static getInstance() {
......@@ -49,6 +50,22 @@ class UserService {
url: "/chat_info",
});
}
userGetAccountManager() {
return baseAxios<Omit<iContactPerson, "address"> & { addr: string }>({
url: "/user/myAccountManager",
method: "get",
}).then((ret) => {
const { addr, ...otherValues } = ret.data;
return {
...ret,
data: {
...otherValues,
address: addr,
},
};
});
}
}
export default UserService;
export interface iNotifyMsg {
staffMsg: string
userMsg: string
staffMsg: string;
userMsg: string;
}
export interface iContactPerson {
address: string;
phone: string;
token: string;
user_name: string;
uuid: string;
}
......@@ -2,8 +2,8 @@ import { eRole } from "./roleType";
export interface iUserMsg {
token: string;
role: eRole;
role2: eRole;
role: eRole.staff | eRole.user; //role把所有类型用户分成员工和客户
role2: eRole; // role2把用户分成 客户经理 管理员 客户
userInfo: {
phone?: string;
addr?: string;
......
import { iChatListCard } from '@/db'
import ContactPersonService from '@/db/ContactPersonService'
import OutletDBService from '@/db/OutletDBService'
import UserInfoDBService from '@/db/UserInfoService'
import AddressService from '@/service/AddressService'
import UserService from '@/service/UserService'
import { iContact } from '@/service/UserService/types'
import { eRole } from '@/types/roleType'
import { getUserMsg } from './userMsg'
import ContactPersonService from "@/db/ContactPersonService";
import OutletDBService from "@/db/OutletDBService";
import UserInfoDBService from "@/db/UserInfoService";
import AddressService from "@/service/AddressService";
import UserService from "@/service/UserService";
import { eRole } from "@/types/roleType";
import { getUserMsg } from "./userMsg";
/* 拿到地址对应的用户昵称 */
export const getDisplayNamesFromAddress = async (
addressList: string[],
addressList: string[]
): Promise<string[]> => {
/* 数据库查 有结果拿 没结果网上查且存 */
const user = getUserMsg()
const user = getUserMsg();
let foundList = [] as any[]
let notFoundList = [] as any[]
let foundList = [] as any[];
let notFoundList = [] as any[];
if (user?.role === eRole.user) {
const ret = await ContactPersonService.getInstance().findByList(addressList)
foundList = ret.foundList
notFoundList = ret.notFoundList
const ret = await ContactPersonService.getInstance().findByList(
addressList
);
foundList = ret.foundList;
notFoundList = ret.notFoundList;
} else if (user?.role === eRole.staff) {
const ret = await UserInfoDBService.getInstance().findByList(addressList)
foundList = ret.foundList
notFoundList = ret.notFoundList
const ret = await UserInfoDBService.getInstance().findByList(addressList);
foundList = ret.foundList;
notFoundList = ret.notFoundList;
}
const fullList = (foundList as unknown) as any
const fullList = foundList as unknown as any;
if (notFoundList.length !== 0) {
if (user?.role === eRole.user) {
const ret = await UserService.getInstance().staffInfo({
addrs: notFoundList,
})
});
if (ret.code === 200) {
const theoseNotFoundList = ret.data.item
ContactPersonService.getInstance().save(theoseNotFoundList)
fullList.push(...theoseNotFoundList)
const theoseNotFoundList = ret.data.item;
ContactPersonService.getInstance().save(theoseNotFoundList);
fullList.push(...theoseNotFoundList);
}
} else if (user?.role === eRole.staff) {
const ret = await UserService.getInstance().userInfo({
addrs: notFoundList,
})
});
if (ret.code === 200) {
const theoseNotFoundList = ret.data
UserInfoDBService.getInstance().save(theoseNotFoundList)
fullList.push(...theoseNotFoundList)
const theoseNotFoundList = ret.data;
UserInfoDBService.getInstance().save(theoseNotFoundList);
fullList.push(...theoseNotFoundList);
}
}
}
return addressList.map((item) => {
const msg = fullList.find((i: any) => i?.addr === item)
const msg = fullList.find((i: any) => i?.addr === item);
if (msg?.out_let_name) {
return msg?.out_let_name + msg.user_name
return msg?.out_let_name + msg.user_name;
} else {
return msg?.phone
return msg?.phone;
}
})
}
});
};
/* 获取网点名称 */
export const getDisplayNamesFromOutletId = async (outletids: number[]) => {
const promiseList = outletids.map(async (id) => {
const outlet = await OutletDBService.getInstance().get(id)
const outlet = await OutletDBService.getInstance().get(id);
if (!outlet) {
const ret = await AddressService.getInstance().getOutlet({
id,
})
});
if (ret.code === 200) {
await OutletDBService.getInstance().add({
name: ret.data.outlet_name,
id: ret.data.id,
})
return ret.data.outlet_name
});
return ret.data.outlet_name;
}
} else {
!outlet.isDeleted &&
......@@ -88,80 +88,82 @@ export const getDisplayNamesFromOutletId = async (outletids: number[]) => {
OutletDBService.getInstance().update({
name: ret.data.outlet_name,
id: ret.data.id,
})
});
} else {
OutletDBService.getInstance().update({
id,
isDeleted: true,
})
});
}
})
return `${outlet.name}${outlet.isDeleted ? '(已停止营业)' : ''}`
});
return `${outlet.name}${outlet.isDeleted ? "(已停止营业)" : ""}`;
}
})
const list = await Promise.all(promiseList)
return list
}
});
const list = await Promise.all(promiseList);
return list;
};
export const getDisplayNames = async (
list: { outletId?: number; address?: string }[],
list: { outletId?: number; address?: string }[]
) => {
const promiseList = list.map((i) => {
if (i.outletId !== undefined) {
return getDisplayNamesFromOutletId([i.outletId]).then((ret) => ret[0])
return getDisplayNamesFromOutletId([i.outletId]).then((ret) => ret[0]);
} else if (i.address !== undefined) {
return getDisplayNamesFromAddress([i.address]).then((ret) => ret[0])
} else return ''
})
return getDisplayNamesFromAddress([i.address]).then((ret) => ret[0]);
} else return "";
});
return Promise.all(promiseList)
}
return Promise.all(promiseList);
};
export const getMsgFromAddress = async (
addressList: string[],
addressList: string[]
): Promise<any[]> => {
/* 数据库查 有结果拿 没结果网上查且存 */
const user = getUserMsg()
const user = getUserMsg();
let foundList = [] as any[]
let notFoundList = [] as any[]
let foundList = [] as any[];
let notFoundList = [] as any[];
if (user?.role === eRole.user) {
const ret = await ContactPersonService.getInstance().findByList(addressList)
foundList = ret.foundList
notFoundList = ret.notFoundList
const ret = await ContactPersonService.getInstance().findByList(
addressList
);
foundList = ret.foundList;
notFoundList = ret.notFoundList;
} else if (user?.role === eRole.staff) {
const ret = await UserInfoDBService.getInstance().findByList(addressList)
foundList = ret.foundList
notFoundList = ret.notFoundList
const ret = await UserInfoDBService.getInstance().findByList(addressList);
foundList = ret.foundList;
notFoundList = ret.notFoundList;
}
const fullList = (foundList as unknown) as any
const fullList = foundList as unknown as any;
if (notFoundList.length !== 0) {
if (user?.role === eRole.user) {
const ret = await UserService.getInstance().staffInfo({
addrs: notFoundList,
})
});
if (ret.code === 200) {
const theoseNotFoundList = ret.data.item
ContactPersonService.getInstance().save(theoseNotFoundList)
fullList.push(...theoseNotFoundList)
const theoseNotFoundList = ret.data.item;
ContactPersonService.getInstance().save(theoseNotFoundList);
fullList.push(...theoseNotFoundList);
}
} else if (user?.role === eRole.staff) {
const ret = await UserService.getInstance().userInfo({
addrs: notFoundList,
})
});
if (ret.code === 200) {
const theoseNotFoundList = ret.data
UserInfoDBService.getInstance().save(theoseNotFoundList)
fullList.push(...theoseNotFoundList)
const theoseNotFoundList = ret.data;
UserInfoDBService.getInstance().save(theoseNotFoundList);
fullList.push(...theoseNotFoundList);
}
}
}
return addressList.map((item) => {
const msg = fullList.find((i: any) => i?.addr === item)
return msg
})
}
const msg = fullList.find((i: any) => i?.addr === item);
return msg;
});
};
<template>
<div
class="flex chatlistitem relative -mr-1 py-2 border-b"
@click="$emit('chat')"
>
<div class="self-center mr-4 flex-shrink-0">
<img
v-if="isStaff"
class="w-10 h-10 rounded-md object-cover"
src="@/assets/icons/avatar.png"
alt="avatar"
/>
<img
v-else
class="w-10 h-10 rounded-md object-contain"
src="@/assets/icons/staff.png"
alt="avatar"
/>
</div>
<div class="flex-grow overflow-hidden pr-1 flex items-center">
{{ displayName }}
</div>
</div>
</template>
<script setup lang="ts">
defineEmits(["chat"]);
defineProps({
displayName: String,
isStaff: Boolean,
});
</script>
<template>
<List @load="onLoad" v-model:loading="loading" :finished="finished">
<AddressBookItem
v-for="target in list"
:display-name="target.displayName"
@chat="
$router.push({
name: 'Chat',
query: {
targetId: target.address,
},
})
"
></AddressBookItem>
</List>
</template>
<script setup lang="ts">
import { staffGetUsers } from "@/service/StaffService";
import UserService from "@/service/UserService";
import { eRole } from "@/types/roleType";
import { getUserMsg } from "@/utils/userMsg";
import { ref } from "@vue/reactivity";
import { List } from "vant";
import { iContactPerson } from "@/types/chat/index";
import { getDisplayNamesFromAddress } from "@/utils/displayName";
import AddressBookItem from "./AddressBookItem.vue";
const list = ref<(iContactPerson & { displayName: string })[]>([]);
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const userMsg = getUserMsg();
const isStaff = userMsg?.role === eRole.staff;
const isUser = userMsg?.role === eRole.user;
async function staffLoadCustoms() {
const ret = await staffGetUsers({
is_desc: true,
order_by: "phone",
page: page.value,
page_size: pageSize.value,
});
if (ret.code === 200) {
const displayNames = ret.data.item.map((i) => i.phone);
list.value.push(
...ret.data.item.map((item, index) => {
return {
...item,
displayName: displayNames[index],
};
})
);
total.value = ret.data.total;
page.value++;
if (list.value.length === total.value) {
finished.value = true;
}
} else {
finished.value = true;
}
}
async function userLoadAccountManager() {
const ret = await UserService.getInstance().userGetAccountManager();
if (ret.code === 200) {
const displayNames = await getDisplayNamesFromAddress([ret.data.address]);
list.value.push({ ...ret.data, displayName: displayNames[0] });
finished.value = true;
}
}
async function onLoad() {
if (isStaff) {
staffLoadCustoms();
} else if (isUser) {
userLoadAccountManager();
}
loading.value = false;
}
</script>
<template>
<NavBar title="通讯录"></NavBar>
<div class="mx-5">
<AddressBookList />
</div>
</template>
<script setup lang="ts">
import NavBar from "@/components/NavBar/index.vue";
import AddressBookList from "./AddressBookList.vue";
</script>
<template>
<Navbar :title="navBarTitle" :showBackIcon="false">
<template #right>
<Icon name="icon-tongxunlu2" size="17" color="#4e61c9"></Icon>
<Icon
name="icon-tongxunlu2"
size="17"
color="#4e61c9"
@click="$router.push({ name: 'AddressBook' })"
></Icon>
</template>
</Navbar>
<div class="mx-5">
......
......@@ -47,6 +47,7 @@
iconName="icon-tongxunlu"
iconSize="19"
label="通讯录"
@click="$router.push({ name: 'AddressBook' })"
/>
</div>
<!-- 我的网点 -->
......
......@@ -15,7 +15,7 @@
<div
class="flex-grow ml-7 mr-2.5 border-b border-app-gray opacity-50"
></div>
<a class=" text-app-gray text-xs">浙ICP备2021029429号-1</a>
<a class="text-app-gray text-xs">浙ICP备2021029429号-1</a>
<div
class="flex-grow ml-2.5 mr-7 border-b border-app-gray opacity-50"
></div>
......@@ -43,7 +43,7 @@ export default defineComponent({
},
computed: {
activeTabRouteName() {
return this.$route.name;
return this.$route.meta.activeTab;
},
tabList() {
const theTabList = tabList.filter((i) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment