添加系统码
This commit is contained in:
+4
-4
@@ -65,16 +65,16 @@ export class CrmService {
|
||||
})
|
||||
}
|
||||
//标签列表/crm/tagGroup/list
|
||||
static tagGrouplist() {
|
||||
static tagGrouplist(params: any) {
|
||||
return request.get<any>({
|
||||
url: '/crm/tagGroup/list'
|
||||
url: '/crm/tagGroup/list',
|
||||
params
|
||||
})
|
||||
}
|
||||
//更新客户标签 /crm/tagGroup/updatePivot
|
||||
static tagGroupupdatePivot(params: any) {
|
||||
return request.get<Api.Work.AddResponse>({
|
||||
url: '/crm/tagGroup/updatePivot',
|
||||
params
|
||||
url: '/crm/tagGroup/updatePivot'
|
||||
})
|
||||
}
|
||||
//跟进列表crm/follow/list
|
||||
|
||||
@@ -6,6 +6,12 @@ export class UserService {
|
||||
return request.get<Api.Brand.BrandInfo>({
|
||||
url: '/common/preset/corps'
|
||||
})
|
||||
}
|
||||
//获取系统
|
||||
static getsystemsList() {
|
||||
return request.get<Api.Brand.BrandInfo>({
|
||||
url: '/common/preset/systems'
|
||||
})
|
||||
}
|
||||
//注册
|
||||
static register(params: any) {
|
||||
|
||||
@@ -25,6 +25,8 @@ export const useUserStore = defineStore(
|
||||
const refreshToken = ref('')
|
||||
const companyid = ref('')
|
||||
const companyabbr = ref('')
|
||||
const systemsid = ref('')
|
||||
const systemsabbr = ref('')
|
||||
const loginType = ref<'feishu' | 'upwd'>('upwd')
|
||||
const tokenExpireAt = ref<number>(0)
|
||||
|
||||
@@ -76,6 +78,11 @@ export const useUserStore = defineStore(
|
||||
companyid.value = id
|
||||
companyabbr.value = abbr
|
||||
}
|
||||
const setSystems= (id: string, abbr: string) => {
|
||||
systemsid.value = id
|
||||
systemsabbr.value = abbr
|
||||
}
|
||||
|
||||
function restoreTokenTimer() {
|
||||
const expireAt = Number(localStorage.getItem('token_expire_at') || '0')
|
||||
if (accessToken.value && expireAt > Date.now()) {
|
||||
@@ -139,6 +146,8 @@ export const useUserStore = defineStore(
|
||||
info,
|
||||
companyid,
|
||||
companyabbr,
|
||||
systemsid,
|
||||
systemsabbr,
|
||||
searchHistory,
|
||||
loginType,
|
||||
accessToken,
|
||||
@@ -155,6 +164,7 @@ export const useUserStore = defineStore(
|
||||
setLockPassword,
|
||||
setToken,
|
||||
setCompany,
|
||||
setSystems,
|
||||
setLoginType,
|
||||
logOut,
|
||||
restoreTokenTimer
|
||||
|
||||
@@ -47,9 +47,10 @@ axiosInstance.interceptors.request.use(
|
||||
const { language } = useUserStore()
|
||||
const { loginType } = useUserStore()
|
||||
const { companyabbr } = useUserStore()
|
||||
const { systemsabbr } = useUserStore()
|
||||
request.headers.set('Fdesk-Language', language)
|
||||
request.headers.set('Fdesk-Corp-Abbr', companyabbr)
|
||||
request.headers.set('Fdesk-System-Code', 'fdesk')
|
||||
request.headers.set('Fdesk-System-Code', systemsabbr)
|
||||
request.headers.set('Fdesk-Login-Type', loginType)
|
||||
// 设置 token 和 请求头
|
||||
if (accessToken) {
|
||||
|
||||
@@ -72,6 +72,18 @@
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="company" label="系统">
|
||||
<ElSelect v-model="formData.systems" class="account-select" @change="changesystems">
|
||||
<ElOption
|
||||
v-for="account in systemsList"
|
||||
:key="account.id"
|
||||
:label="account.name"
|
||||
:value="account.id"
|
||||
>
|
||||
<span>{{ account.name }}</span>
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<div class="drag-verify">
|
||||
<div class="drag-verify-content" :class="{ error: !isPassing && isClickPass }">
|
||||
<ArtDragVerify
|
||||
@@ -127,6 +139,18 @@
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="company" label="系统">
|
||||
<ElSelect v-model="formData.systems" class="account-select" @change="changesystems">
|
||||
<ElOption
|
||||
v-for="account in systemsList"
|
||||
:key="account.id"
|
||||
:label="account.name"
|
||||
:value="account.id"
|
||||
>
|
||||
<span>{{ account.name }}</span>
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<div class="qrcode-login" v-if="!isInFeishu">
|
||||
<div id="login_container"></div>
|
||||
@@ -175,13 +199,18 @@
|
||||
const formRef = ref<FormInstance>()
|
||||
const companyid = ref('')
|
||||
companyid.value = useUserStore().companyid
|
||||
const systemsid = ref('')
|
||||
systemsid.value = useUserStore().systemsid
|
||||
const iscompany = ref(false)
|
||||
const { companyabbr } = useUserStore()
|
||||
//获取公司 getCompanyList
|
||||
const companyList = ref<any>()
|
||||
//系统
|
||||
const systemsList = ref<any>()
|
||||
const feishuresponse=ref()
|
||||
const formData = reactive({
|
||||
account: '',
|
||||
systems: useUserStore().companyid?Number(useUserStore().companyid):'',
|
||||
company: useUserStore().companyid?Number(useUserStore().companyid):'',
|
||||
username: '',
|
||||
password: '',
|
||||
@@ -198,11 +227,19 @@
|
||||
const { width } = useWindowSize()
|
||||
const getcompanyList = async () => {
|
||||
try {
|
||||
// 这里调用获取品牌列表的接口
|
||||
// 这里调用公司列表的接口
|
||||
const response = await UserService.getCompanyList()
|
||||
companyList.value = response || []
|
||||
} catch (error) { }
|
||||
}
|
||||
const getsystemsList = async () => {
|
||||
try {
|
||||
// 这里调用公司列表的接口
|
||||
const response = await UserService.getsystemsList()
|
||||
systemsList.value = response || []
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
const { locale } = useI18n()
|
||||
|
||||
@@ -214,7 +251,7 @@
|
||||
|
||||
const getfeishuAppList = async () => {
|
||||
try {
|
||||
// 这里调用获取品牌列表的接口
|
||||
// 这里调用飞书
|
||||
feishuresponse.value = await UserService.getfeishuAppList({ corp_id: companyid.value })
|
||||
if(activeLoginType.value=='qrcode'){
|
||||
feishulogin()
|
||||
@@ -222,6 +259,12 @@
|
||||
console.log(feishuresponse)
|
||||
} catch (error) { }
|
||||
}
|
||||
//切换系统
|
||||
const changesystems = (systems: any) => {
|
||||
const systemsdata = systemsList.value.find((c: any) => c.id === systems)
|
||||
systemsid.value = systems
|
||||
userStore.setSystems(systems,systemsdata?.code)
|
||||
}
|
||||
//切换公司
|
||||
|
||||
const changeCompany = (company: any) => {
|
||||
@@ -383,6 +426,7 @@
|
||||
|
||||
onMounted(() => {
|
||||
getcompanyList()
|
||||
getsystemsList()
|
||||
// 自动读取 query 参数并存入 userStore
|
||||
const companyid = Array.isArray(route.query.corp_id) ? route.query.corp_id[0] : route.query.corp_id
|
||||
const companyabbr = Array.isArray(route.query.corp_abbr) ? route.query.corp_abbr[0] : route.query.corp_abbr
|
||||
|
||||
@@ -185,7 +185,7 @@ function addtag(){
|
||||
}
|
||||
const tagGrouplistfn = async () => {
|
||||
try {
|
||||
const res = await CrmService.tagGrouplist()
|
||||
const res = await CrmService.tagGrouplist({})
|
||||
tagGroups.value = res || []
|
||||
// 回显选中
|
||||
if (customerInfo.value && Array.isArray(customerInfo.value.tags)) {
|
||||
|
||||
@@ -19,46 +19,43 @@
|
||||
|
||||
<!-- 筛选标签 -->
|
||||
<div class="customer-tags boxshadow">
|
||||
<div class="filter-row">
|
||||
<span class="filter-label">价值标签</span>
|
||||
<!-- 前3组 -->
|
||||
<div class="filter-row" v-for="item in visibleTagGroups" :key="item.id">
|
||||
<span class="filter-label">{{item.name}}</span>
|
||||
<div class="filter-tags">
|
||||
<span v-for="item in valueTags" :key="item.label" :class="['tag-item', { 'tag-active': tagActiveMap['value'] === item.label }]" @click="handleTagClick('value', item.label)">
|
||||
{{ item.label }}({{ item.count }})
|
||||
<span
|
||||
v-for="item1 in item.tags"
|
||||
:key="item1.id"
|
||||
:class="['tag-item', { 'tag-active': tagActiveMap[item.id] === item1.id }]"
|
||||
@click="handleTagClick(item.id, item1.id)"
|
||||
>
|
||||
{{ item1.name }}({{ item1.count }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-row">
|
||||
<span class="filter-label">生命周期标签</span>
|
||||
<div class="filter-tags">
|
||||
<span v-for="item in lifeTags" :key="item.label" :class="['tag-item', { 'tag-active': tagActiveMap['life'] === item.label }]" @click="handleTagClick('life', item.label)">
|
||||
{{ item.label }}({{ item.count }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-row">
|
||||
<span class="filter-label">行为标签</span>
|
||||
<div class="filter-tags">
|
||||
<span v-for="item in actionTags" :key="item.label" :class="['tag-item', { 'tag-active': tagActiveMap['action'] === item.label }]" @click="handleTagClick('action', item.label)">
|
||||
{{ item.label }}({{ item.count }})
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- 更多 -->
|
||||
<transition name="fade">
|
||||
<div v-if="showMore" class="filter-row">
|
||||
<span class="filter-label">更多标签</span>
|
||||
<div class="filter-tags">
|
||||
<span v-for="item in moreTags" :key="item.label" :class="['tag-item', { 'tag-active': tagActiveMap['more'] === item.label }]" @click="handleTagClick('more', item.label)">
|
||||
{{ item.label }}({{ item.count }})
|
||||
</span>
|
||||
<div v-if="showMore">
|
||||
<div class="filter-row" v-for="item in moreTagGroups" :key="item.id">
|
||||
<span class="filter-label">{{item.name}}</span>
|
||||
<div class="filter-tags">
|
||||
<span
|
||||
v-for="item1 in item.tags"
|
||||
:key="item1.id"
|
||||
:class="['tag-item', { 'tag-active': tagActiveMap[item.id] === item1.id }]"
|
||||
@click="handleTagClick(item.id, item1.id)"
|
||||
>
|
||||
{{ item1.name }}({{ item1.count }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="filter-more-btn">
|
||||
<el-link :underline="false" @click="showMore = !showMore">
|
||||
<div class="filter-more-btn" v-if="moreTagGroups.length">
|
||||
<el-link underline="never" @click="showMore = !showMore">
|
||||
{{ showMore ? '收起' : '更多' }}
|
||||
<i v-if="showMore" class="iconfont-sys"> </i>
|
||||
<i v-else class="iconfont-sys"></i>
|
||||
<i v-else class="iconfont-sys"></i>
|
||||
</el-link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,8 +87,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" width="200px" align="center">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" :underline="false" style="margin-right: 8px;" @click="goEdit(scope.row)"> <i class="iconfont-sys"> </i>查看</el-link>
|
||||
<el-link type="primary" :underline="false" @click="goAddFollow(scope.row)"> <i class="iconfont-sys"> </i> 添加跟进</el-link>
|
||||
<el-link type="primary" underline="never" style="margin-right: 8px;" @click="goEdit(scope.row)"> <i class="iconfont-sys"> </i>查看</el-link>
|
||||
<el-link type="primary" underline="never" @click="goAddFollow(scope.row)"> <i class="iconfont-sys"> </i> 添加跟进</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
@@ -102,7 +99,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { CrmService } from '@/api/crmApi'
|
||||
const searchValue = ref('')
|
||||
@@ -121,40 +118,24 @@ const selectOptions = [
|
||||
{ label: '近三天', value: '1' },
|
||||
{ label: '近七天', value: '2' }
|
||||
]
|
||||
|
||||
const valueTags = [
|
||||
{ label: '高价值', count: 10 },
|
||||
{ label: '中价值', count: 10 },
|
||||
{ label: '低价值', count: 10 },
|
||||
{ label: '潜在高价值', count: 10 }
|
||||
]
|
||||
const lifeTags = [
|
||||
{ label: '新客户', count: 10 },
|
||||
{ label: '活跃', count: 10 },
|
||||
{ label: '深度', count: 10 },
|
||||
{ label: '流失', count: 10 }
|
||||
]
|
||||
const actionTags = [
|
||||
{ label: '高频购买', count: 10 },
|
||||
{ label: '大单', count: 10 },
|
||||
{ label: '促销敏感', count: 10 }
|
||||
]
|
||||
const moreTags = [
|
||||
{ label: '标签A', count: 5 },
|
||||
{ label: '标签B', count: 3 }
|
||||
]
|
||||
//获取标签
|
||||
const tagGroups = ref<any[]>([])
|
||||
type TagGroup = { id: string; name: string; tags: { id: string; name: string; count: number }[] }
|
||||
const tagGroups = ref<TagGroup[]>([])
|
||||
const tagGrouplistfn = async () => {
|
||||
try {
|
||||
const res = await CrmService.tagGrouplist()
|
||||
tagGroups.value = res || []
|
||||
} catch (error) { }
|
||||
try {
|
||||
const res = await CrmService.tagGrouplist({scene:'customers'})
|
||||
tagGroups.value = res || []
|
||||
} catch (error) { }
|
||||
}
|
||||
// 计算前3组和更多组
|
||||
defineProps()
|
||||
const visibleTagGroups = computed(() => tagGroups.value.slice(0, 3))
|
||||
const moreTagGroups = computed(() => tagGroups.value.slice(3))
|
||||
// 表格数据
|
||||
const tableData = ref<any[]>([])
|
||||
onMounted(() => {
|
||||
gettableList()
|
||||
tagGrouplistfn()
|
||||
})
|
||||
// tabs 切换联动
|
||||
watch([activeTab, searchValue, selectValue], () => {
|
||||
@@ -162,6 +143,7 @@ watch([activeTab, searchValue, selectValue], () => {
|
||||
gettableList()
|
||||
})
|
||||
// 获取列表数据
|
||||
const tagActiveMap = reactive<{ [groupId: string]: string }>({})
|
||||
const gettableList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -173,11 +155,12 @@ const gettableList = async () => {
|
||||
if (searchValue.value) params.keyword = searchValue.value
|
||||
if (selectValue.value) params.follow_last = selectValue.value
|
||||
if (activeTab.value && activeTab.value !== '') params.follow = activeTab.value
|
||||
// 标签参数
|
||||
if (tagActiveMap.value) params.value_tag = tagActiveMap.value
|
||||
if (tagActiveMap.life) params.life_tag = tagActiveMap.life
|
||||
if (tagActiveMap.action) params.action_tag = tagActiveMap.action
|
||||
if (tagActiveMap.more) params.more_tag = tagActiveMap.more
|
||||
// 标签参数,所有选中的标签id组成数组
|
||||
const selectedTagIds = Object.values(tagActiveMap).filter(Boolean)
|
||||
if (selectedTagIds.length) {
|
||||
params.tag_id = selectedTagIds
|
||||
}
|
||||
console.log(params)
|
||||
const { data, current, size, total } = await CrmService.getcustomerList(params)
|
||||
tableData.value = data.map((item: any, index: number) => ({
|
||||
...item
|
||||
@@ -191,13 +174,12 @@ const gettableList = async () => {
|
||||
}
|
||||
// 处理表格分页变化
|
||||
const handleSizeChange = (newPageSize: number) => {
|
||||
pagination.pageSize = newPageSize
|
||||
// getWorkList()
|
||||
pagination.pageSize = newPageSize
|
||||
// getWorkList()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (newCurrentPage: number) => {
|
||||
pagination.currentPage = newCurrentPage
|
||||
// getWorkList()
|
||||
pagination.currentPage = newCurrentPage
|
||||
// getWorkList()
|
||||
}
|
||||
function statusClass(status: any) {
|
||||
if (status === 0) return 'status-following'
|
||||
@@ -205,32 +187,28 @@ function statusClass(status: any) {
|
||||
if (status === 2) return 'status-lost'
|
||||
return ''
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
function goAdd() {
|
||||
router.push('/crmpc/customer/add')
|
||||
}
|
||||
function goEdit(row: any) {
|
||||
router.push({
|
||||
path: '/crmpc/customer/show',
|
||||
query: { id: row.id }
|
||||
})
|
||||
}
|
||||
function goAddFollow(row: any) {
|
||||
router.push({
|
||||
path: '/crmpc/customer/followadd',
|
||||
query: { id: row.id } // 可带客户名等参数
|
||||
})
|
||||
}
|
||||
|
||||
// 标签选中状态,key为组名,值为选中的标签label
|
||||
const tagActiveMap = reactive<{ [group: string]: string }>({})
|
||||
|
||||
function handleTagClick(group: string, label: string) {
|
||||
if (tagActiveMap[group] === label) {
|
||||
tagActiveMap[group] = '' // 取消选中
|
||||
function goAdd() {
|
||||
router.push('/crmpc/customer/add')
|
||||
}
|
||||
function goEdit(row: any) {
|
||||
router.push({
|
||||
path: '/crmpc/customer/show',
|
||||
query: { id: row.id }
|
||||
})
|
||||
}
|
||||
function goAddFollow(row: any) {
|
||||
router.push({
|
||||
path: '/crmpc/customer/followadd',
|
||||
query: { id: row.id } // 可带客户名等参数
|
||||
})
|
||||
}
|
||||
// 标签选中状态,key为组id,值为选中的标签id
|
||||
function handleTagClick(groupId: string, tagId: string) {
|
||||
if (tagActiveMap[groupId] === tagId) {
|
||||
tagActiveMap[groupId] = '' // 取消选中
|
||||
} else {
|
||||
tagActiveMap[group] = label // 选中
|
||||
tagActiveMap[groupId] = tagId // 选中
|
||||
}
|
||||
pagination.currentPage = 1
|
||||
gettableList()
|
||||
@@ -338,6 +316,14 @@ function handleTagClick(group: string, label: string) {
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
.tag-item { cursor: pointer; border-radius: 4px; padding: 2px 10px; margin-right: 8px; transition: background 0.2s; }
|
||||
.tag-item {
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
padding: 2px 10px;
|
||||
margin-right: 8px;
|
||||
transition: background 0.2s;
|
||||
min-width: 100px;
|
||||
display: inline-block;
|
||||
}
|
||||
.tag-active { background: #3471FF; color: #fff; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user