CRM里面的客户、线索管理适配手机端
This commit is contained in:
@@ -1,21 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="dialogVisible" :title="dialogTitle">
|
<el-drawer
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:close-on-press-escape="true"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form" v-loading="formLoading">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
v-loading="formLoading"
|
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="100px"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<el-row>
|
<!-- 基本信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">基本信息</div>
|
||||||
<el-form-item label="线索名称" prop="name">
|
<el-form-item label="线索名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入线索名称" />
|
<el-input v-model="formData.name" placeholder="请输入线索名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="客户来源" prop="source">
|
<el-form-item label="客户来源" prop="source">
|
||||||
<el-select v-model="formData.source" placeholder="请选择客户来源" class="w-1/1">
|
<el-select v-model="formData.source" placeholder="请选择客户来源" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -24,20 +31,11 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="手机" prop="mobile">
|
|
||||||
<el-input v-model="formData.mobile" placeholder="请输入手机" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="负责人" prop="ownerUserId">
|
<el-form-item label="负责人" prop="ownerUserId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.ownerUserId"
|
v-model="formData.ownerUserId"
|
||||||
:disabled="formType !== 'create'"
|
:disabled="formType !== 'create'"
|
||||||
class="w-1/1"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
@@ -47,36 +45,33 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 联系方式 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">联系方式</div>
|
||||||
|
<el-form-item label="手机" prop="mobile">
|
||||||
|
<el-input v-model="formData.mobile" placeholder="请输入手机" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="电话" prop="telephone">
|
<el-form-item label="电话" prop="telephone">
|
||||||
<el-input v-model="formData.telephone" placeholder="请输入电话" />
|
<el-input v-model="formData.telephone" placeholder="请输入电话" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱" prop="email">
|
||||||
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="微信" prop="wechat">
|
<el-form-item label="微信" prop="wechat">
|
||||||
<el-input v-model="formData.wechat" placeholder="请输入微信" />
|
<el-input v-model="formData.wechat" placeholder="请输入微信" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="QQ" prop="qq">
|
<el-form-item label="QQ" prop="qq">
|
||||||
<el-input v-model="formData.qq" placeholder="请输入 QQ" />
|
<el-input v-model="formData.qq" placeholder="请输入 QQ" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 客户信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">客户信息</div>
|
||||||
<el-form-item label="客户行业" prop="industryId">
|
<el-form-item label="客户行业" prop="industryId">
|
||||||
<el-select v-model="formData.industryId" placeholder="请选择客户行业" class="w-1/1">
|
<el-select v-model="formData.industryId" placeholder="请选择客户行业" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -85,10 +80,8 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="客户级别" prop="level">
|
<el-form-item label="客户级别" prop="level">
|
||||||
<el-select v-model="formData.level" placeholder="请选择客户级别" class="w-1/1">
|
<el-select v-model="formData.level" placeholder="请选择客户级别" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -97,52 +90,52 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 地址信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">地址信息</div>
|
||||||
<el-form-item label="地址" prop="areaId">
|
<el-form-item label="地址" prop="areaId">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
v-model="formData.areaId"
|
v-model="formData.areaId"
|
||||||
:options="areaList"
|
:options="areaList"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
class="w-1/1"
|
style="width: 100%"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择城市"
|
placeholder="请选择城市"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="详细地址" prop="detailAddress">
|
<el-form-item label="详细地址" prop="detailAddress">
|
||||||
<el-input v-model="formData.detailAddress" placeholder="请输入详细地址" />
|
<el-input v-model="formData.detailAddress" placeholder="请输入详细地址" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 其他信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">其他信息</div>
|
||||||
<el-form-item label="下次联系时间" prop="contactNextTime">
|
<el-form-item label="下次联系时间" prop="contactNextTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.contactNextTime"
|
v-model="formData.contactNextTime"
|
||||||
placeholder="选择下次联系时间"
|
placeholder="选择下次联系时间"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
value-format="x"
|
value-format="x"
|
||||||
class="!w-1/1"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
|
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" :rows="3" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
</Dialog>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -258,3 +251,44 @@ const resetForm = () => {
|
|||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div class="mobile-detail-header" v-loading="loading">
|
||||||
<div class="flex items-start justify-between">
|
<!-- 标题和操作按钮 -->
|
||||||
<div>
|
<div class="mobile-detail-header__top">
|
||||||
<!-- 左上:线索基本信息 -->
|
<div class="mobile-detail-header__title">{{ clue.name }}</div>
|
||||||
<el-col>
|
<div class="mobile-detail-header__actions">
|
||||||
<el-row>
|
|
||||||
<span class="text-xl font-bold">{{ clue.name }}</span>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<!-- 右上:按钮 -->
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- 关键信息卡片 -->
|
||||||
<ContentWrap class="mt-10px">
|
<div class="mobile-detail-header__card">
|
||||||
<el-descriptions :column="5" direction="vertical">
|
<div class="mobile-info-list">
|
||||||
<el-descriptions-item label="线索来源">
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">线索来源</span>
|
||||||
|
<span class="mobile-info-row__value">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="clue.source" />
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="clue.source" />
|
||||||
</el-descriptions-item>
|
</span>
|
||||||
<el-descriptions-item label="手机"> {{ clue.mobile }} </el-descriptions-item>
|
</div>
|
||||||
<el-descriptions-item label="负责人">
|
<div class="mobile-info-row">
|
||||||
{{ clue.ownerUserName }}
|
<span class="mobile-info-row__label">手机</span>
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__value">{{ clue.mobile || '-' }}</span>
|
||||||
<el-descriptions-item label="创建时间">
|
</div>
|
||||||
{{ formatDate(clue.createTime) }}
|
<div class="mobile-info-row">
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__label">负责人</span>
|
||||||
</el-descriptions>
|
<span class="mobile-info-row__value">{{ clue.ownerUserName || '-' }}</span>
|
||||||
</ContentWrap>
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">创建时间</span>
|
||||||
|
<span class="mobile-info-row__value">{{ formatDate(clue.createTime) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
@@ -41,3 +43,57 @@ defineProps<{
|
|||||||
loading: boolean // 加载中
|
loading: boolean // 加载中
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-detail-header {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
.mobile-detail-header__top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.mobile-detail-header__title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
flex: 1;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
.mobile-detail-header__actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.mobile-detail-header__card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-info-list {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.mobile-info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 0;
|
||||||
|
border-bottom: 1px solid #f5f5f5;
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
&__label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
&__value {
|
||||||
|
color: #303133;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,61 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<ContentWrap>
|
<div class="mobile-detail-info">
|
||||||
<el-collapse v-model="activeNames" class="">
|
<!-- 基本信息 -->
|
||||||
<el-collapse-item name="basicInfo">
|
<div class="mobile-form__section">
|
||||||
<template #title>
|
<div class="mobile-form__section-title">基本信息</div>
|
||||||
<span class="text-base font-bold">基本信息</span>
|
<div class="mobile-info-list">
|
||||||
</template>
|
<div class="mobile-info-row">
|
||||||
<el-descriptions :column="4">
|
<span class="mobile-info-row__label">线索名称</span>
|
||||||
<el-descriptions-item label="线索名称">
|
<span class="mobile-info-row__value">{{ clue.name || '-' }}</span>
|
||||||
{{ clue.name }}
|
</div>
|
||||||
</el-descriptions-item>
|
<div class="mobile-info-row">
|
||||||
<el-descriptions-item label="客户来源">
|
<span class="mobile-info-row__label">客户来源</span>
|
||||||
|
<span class="mobile-info-row__value">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="clue.source" />
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="clue.source" />
|
||||||
</el-descriptions-item>
|
</span>
|
||||||
<el-descriptions-item label="手机">{{ clue.mobile }}</el-descriptions-item>
|
</div>
|
||||||
<el-descriptions-item label="电话">{{ clue.telephone }}</el-descriptions-item>
|
<div class="mobile-info-row">
|
||||||
<el-descriptions-item label="邮箱">{{ clue.email }}</el-descriptions-item>
|
<span class="mobile-info-row__label">手机</span>
|
||||||
<el-descriptions-item label="地址">
|
<span class="mobile-info-row__value">{{ clue.mobile || '-' }}</span>
|
||||||
{{ clue.areaName }} {{ clue.detailAddress }}
|
</div>
|
||||||
</el-descriptions-item>
|
<div class="mobile-info-row">
|
||||||
<el-descriptions-item label="QQ">{{ clue.qq }}</el-descriptions-item>
|
<span class="mobile-info-row__label">电话</span>
|
||||||
<el-descriptions-item label="微信">{{ clue.wechat }}</el-descriptions-item>
|
<span class="mobile-info-row__value">{{ clue.telephone || '-' }}</span>
|
||||||
<el-descriptions-item label="客户行业">
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">邮箱</span>
|
||||||
|
<span class="mobile-info-row__value">{{ clue.email || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">地址</span>
|
||||||
|
<span class="mobile-info-row__value">{{ clue.areaName || '' }} {{ clue.detailAddress || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">QQ</span>
|
||||||
|
<span class="mobile-info-row__value">{{ clue.qq || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">微信</span>
|
||||||
|
<span class="mobile-info-row__value">{{ clue.wechat || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">客户行业</span>
|
||||||
|
<span class="mobile-info-row__value">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="clue.industryId" />
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="clue.industryId" />
|
||||||
</el-descriptions-item>
|
</span>
|
||||||
<el-descriptions-item label="客户级别">
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">客户级别</span>
|
||||||
|
<span class="mobile-info-row__value">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="clue.level" />
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="clue.level" />
|
||||||
</el-descriptions-item>
|
</span>
|
||||||
<el-descriptions-item label="下次联系时间">
|
</div>
|
||||||
{{ formatDate(clue.contactNextTime) }}
|
<div class="mobile-info-row">
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__label">下次联系时间</span>
|
||||||
<el-descriptions-item label="备注">{{ clue.remark }}</el-descriptions-item>
|
<span class="mobile-info-row__value">{{ formatDate(clue.contactNextTime) || '-' }}</span>
|
||||||
</el-descriptions>
|
</div>
|
||||||
</el-collapse-item>
|
<div class="mobile-info-row" v-if="clue.remark">
|
||||||
<el-collapse-item name="systemInfo">
|
<span class="mobile-info-row__label">备注</span>
|
||||||
<template #title>
|
<span class="mobile-info-row__value">{{ clue.remark }}</span>
|
||||||
<span class="text-base font-bold">系统信息</span>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
<el-descriptions :column="4">
|
</div>
|
||||||
<el-descriptions-item label="负责人">{{ clue.ownerUserName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="最后跟进记录">
|
<!-- 系统信息 -->
|
||||||
{{ clue.contactLastContent }}
|
<div class="mobile-form__section">
|
||||||
</el-descriptions-item>
|
<div class="mobile-form__section-title">系统信息</div>
|
||||||
<el-descriptions-item label="最后跟进时间">
|
<div class="mobile-info-list">
|
||||||
{{ formatDate(clue.contactLastTime) }}
|
<div class="mobile-info-row">
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__label">负责人</span>
|
||||||
<el-descriptions-item label=""> </el-descriptions-item>
|
<span class="mobile-info-row__value">{{ clue.ownerUserName || '-' }}</span>
|
||||||
<el-descriptions-item label="创建人">{{ clue.creatorName }}</el-descriptions-item>
|
</div>
|
||||||
<el-descriptions-item label="创建时间">
|
<div class="mobile-info-row" v-if="clue.contactLastContent">
|
||||||
{{ formatDate(clue.createTime) }}
|
<span class="mobile-info-row__label">最后跟进记录</span>
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__value">{{ clue.contactLastContent }}</span>
|
||||||
<el-descriptions-item label="更新时间">
|
</div>
|
||||||
{{ formatDate(clue.updateTime) }}
|
<div class="mobile-info-row">
|
||||||
</el-descriptions-item>
|
<span class="mobile-info-row__label">最后跟进时间</span>
|
||||||
</el-descriptions>
|
<span class="mobile-info-row__value">{{ formatDate(clue.contactLastTime) || '-' }}</span>
|
||||||
</el-collapse-item>
|
</div>
|
||||||
</el-collapse>
|
<div class="mobile-info-row">
|
||||||
</ContentWrap>
|
<span class="mobile-info-row__label">创建人</span>
|
||||||
|
<span class="mobile-info-row__value">{{ clue.creatorName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">创建时间</span>
|
||||||
|
<span class="mobile-info-row__value">{{ formatDate(clue.createTime) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-info-row">
|
||||||
|
<span class="mobile-info-row__label">更新时间</span>
|
||||||
|
<span class="mobile-info-row__value">{{ formatDate(clue.updateTime) || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as ClueApi from '@/api/crm/clue'
|
import * as ClueApi from '@/api/crm/clue'
|
||||||
@@ -66,7 +102,48 @@ defineOptions({ name: 'CrmClueDetailsInfo' })
|
|||||||
const { clue } = defineProps<{
|
const { clue } = defineProps<{
|
||||||
clue: ClueApi.ClueVO // 线索明细
|
clue: ClueApi.ClueVO // 线索明细
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const activeNames = ref(['basicInfo', 'systemInfo']) // 展示的折叠面板
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-detail-info {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-info-list {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.mobile-info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 0;
|
||||||
|
border-bottom: 1px solid #f5f5f5;
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
&__label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
&__value {
|
||||||
|
color: #303133;
|
||||||
|
text-align: right;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,52 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<doc-alert title="【线索】线索管理" url="https://doc.iocoder.cn/crm/clue/" />
|
<div class="mobile-page">
|
||||||
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
|
<!-- 搜索头部 -->
|
||||||
|
<div class="mobile-page__header">
|
||||||
<ContentWrap>
|
<div class="mobile-page__search">
|
||||||
<!-- 搜索工作栏 -->
|
|
||||||
<el-form
|
|
||||||
class="-mb-15px"
|
|
||||||
:model="queryParams"
|
|
||||||
ref="queryFormRef"
|
|
||||||
:inline="true"
|
|
||||||
label-width="68px"
|
|
||||||
>
|
|
||||||
<el-form-item label="线索名称" prop="name">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
placeholder="请输入线索名称"
|
placeholder="搜索线索名称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
class="!w-240px"
|
:prefix-icon="Search"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
<el-button type="primary" :icon="Filter" @click="filterDrawerVisible = true" />
|
||||||
<el-form-item label="转化状态" prop="transformStatus">
|
</div>
|
||||||
<el-select v-model="queryParams.transformStatus" class="!w-240px">
|
<div class="mobile-page__actions">
|
||||||
<el-option :value="false" label="未转化" />
|
|
||||||
<el-option :value="true" label="已转化" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="手机号" prop="mobile">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.mobile"
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="电话" prop="telephone">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.telephone"
|
|
||||||
placeholder="请输入电话"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
|
||||||
<el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:clue:create']">
|
<el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:clue:create']">
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -57,108 +23,129 @@
|
|||||||
:loading="exportLoading"
|
:loading="exportLoading"
|
||||||
v-hasPermi="['crm:clue:export']"
|
v-hasPermi="['crm:clue:export']"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-form>
|
</div>
|
||||||
</ContentWrap>
|
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- Tab 切换 -->
|
||||||
<ContentWrap>
|
<div class="mobile-page__tabs">
|
||||||
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
||||||
<el-tab-pane label="我负责的" name="1" />
|
<el-tab-pane label="我负责的" name="1" />
|
||||||
<el-tab-pane label="我参与的" name="2" />
|
<el-tab-pane label="我参与的" name="2" />
|
||||||
<el-tab-pane label="下属负责的" name="3" />
|
<el-tab-pane label="下属负责的" name="3" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
</div>
|
||||||
<el-table-column label="线索名称" align="center" prop="name" fixed="left" width="160">
|
|
||||||
<template #default="scope">
|
<!-- 线索列表 -->
|
||||||
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
<div class="mobile-page__content" v-loading="loading">
|
||||||
{{ scope.row.name }}
|
<div class="mobile-item-list">
|
||||||
</el-link>
|
<div
|
||||||
</template>
|
v-for="item in list"
|
||||||
</el-table-column>
|
:key="item.id"
|
||||||
<el-table-column label="线索来源" align="center" prop="source" width="100">
|
class="mobile-item-card mobile-item-card--clickable"
|
||||||
<template #default="scope">
|
@click="openDetail(item.id)"
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
|
>
|
||||||
</template>
|
<div class="mobile-item-card__header">
|
||||||
</el-table-column>
|
<span class="mobile-item-card__name">{{ item.name }}</span>
|
||||||
<el-table-column label="手机" align="center" prop="mobile" width="120" />
|
<el-tag v-if="item.transformStatus" type="success" size="small">已转化</el-tag>
|
||||||
<el-table-column label="电话" align="center" prop="telephone" width="130" />
|
<el-tag v-else type="info" size="small">未转化</el-tag>
|
||||||
<el-table-column label="邮箱" align="center" prop="email" width="180" />
|
</div>
|
||||||
<el-table-column label="地址" align="center" prop="detailAddress" width="180" />
|
<div class="mobile-item-card__body">
|
||||||
<el-table-column align="center" label="客户行业" prop="industryId" width="100">
|
<div class="mobile-item-card__info-row">
|
||||||
<template #default="scope">
|
<span class="mobile-item-card__info-label">线索来源</span>
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
|
<span class="mobile-item-card__info-value">
|
||||||
</template>
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="item.source" />
|
||||||
</el-table-column>
|
</span>
|
||||||
<el-table-column align="center" label="客户级别" prop="level" width="135">
|
</div>
|
||||||
<template #default="scope">
|
<div class="mobile-item-card__info-row">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
|
<span class="mobile-item-card__info-label">手机</span>
|
||||||
</template>
|
<span class="mobile-item-card__info-value">{{ item.mobile || '-' }}</span>
|
||||||
</el-table-column>
|
</div>
|
||||||
<el-table-column
|
<div class="mobile-item-card__info-row">
|
||||||
:formatter="dateFormatter"
|
<span class="mobile-item-card__info-label">负责人</span>
|
||||||
align="center"
|
<span class="mobile-item-card__info-value">{{ item.ownerUserName || '-' }}</span>
|
||||||
label="下次联系时间"
|
</div>
|
||||||
prop="contactNextTime"
|
<div class="mobile-item-card__info-row">
|
||||||
width="180px"
|
<span class="mobile-item-card__info-label">客户级别</span>
|
||||||
/>
|
<span class="mobile-item-card__info-value">
|
||||||
<el-table-column align="center" label="备注" prop="remark" width="200" />
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="item.level" />
|
||||||
<el-table-column
|
</span>
|
||||||
label="最后跟进时间"
|
</div>
|
||||||
align="center"
|
<div class="mobile-item-card__info-row">
|
||||||
prop="contactLastTime"
|
<span class="mobile-item-card__info-label">最后跟进</span>
|
||||||
:formatter="dateFormatter"
|
<span class="mobile-item-card__info-value">{{ item.contactLastTime ? dateFormatter(null, null, item.contactLastTime) : '-' }}</span>
|
||||||
width="180px"
|
</div>
|
||||||
/>
|
</div>
|
||||||
<el-table-column align="center" label="最后跟进记录" prop="contactLastContent" width="200" />
|
<div class="mobile-item-card__footer" @click.stop>
|
||||||
<el-table-column align="center" label="负责人" prop="ownerUserName" width="100px" />
|
|
||||||
<el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100" />
|
|
||||||
<el-table-column
|
|
||||||
label="更新时间"
|
|
||||||
align="center"
|
|
||||||
prop="updateTime"
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
label="创建时间"
|
|
||||||
align="center"
|
|
||||||
prop="createTime"
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
|
|
||||||
<el-table-column label="操作" align="center" min-width="110" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
<el-button
|
||||||
link
|
size="small"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', item.id)"
|
||||||
v-hasPermi="['crm:clue:update']"
|
v-hasPermi="['crm:clue:update']"
|
||||||
>
|
>编辑</el-button>
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
link
|
size="small"
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(item.id)"
|
||||||
v-hasPermi="['crm:clue:delete']"
|
v-hasPermi="['crm:clue:delete']"
|
||||||
>
|
>删除</el-button>
|
||||||
删除
|
</div>
|
||||||
</el-button>
|
</div>
|
||||||
</template>
|
<div v-if="list.length === 0 && !loading" class="mobile-empty-tip">暂无线索数据</div>
|
||||||
</el-table-column>
|
</div>
|
||||||
</el-table>
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<div class="mobile-pagination" v-if="total > 0">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
:page-sizes="[10, 20]"
|
||||||
v-model:limit="queryParams.pageSize"
|
layout="total, prev, pager, next"
|
||||||
@pagination="getList"
|
:pager-count="5"
|
||||||
|
@size-change="getList"
|
||||||
|
@current-change="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 筛选抽屉 -->
|
||||||
|
<el-drawer
|
||||||
|
v-model="filterDrawerVisible"
|
||||||
|
title="筛选条件"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:append-to-body="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form">
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">筛选条件</div>
|
||||||
|
<el-form :model="queryParams" ref="queryFormRef" label-position="top">
|
||||||
|
<el-form-item label="线索名称" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入线索名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="转化状态" prop="transformStatus">
|
||||||
|
<el-select v-model="queryParams.transformStatus" style="width: 100%">
|
||||||
|
<el-option :value="false" label="未转化" />
|
||||||
|
<el-option :value="true" label="已转化" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号" prop="mobile">
|
||||||
|
<el-input v-model="queryParams.mobile" placeholder="请输入手机号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="电话" prop="telephone">
|
||||||
|
<el-input v-model="queryParams.telephone" placeholder="请输入电话" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-form__footer">
|
||||||
|
<el-button @click="resetQuery" style="flex: 1">重置</el-button>
|
||||||
|
<el-button type="primary" @click="handleFilterConfirm" style="flex: 1">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<ClueForm ref="formRef" @success="getList" />
|
<ClueForm ref="formRef" @success="getList" />
|
||||||
@@ -171,6 +158,7 @@ import download from '@/utils/download'
|
|||||||
import * as ClueApi from '@/api/crm/clue'
|
import * as ClueApi from '@/api/crm/clue'
|
||||||
import ClueForm from './ClueForm.vue'
|
import ClueForm from './ClueForm.vue'
|
||||||
import { TabsPaneContext } from 'element-plus'
|
import { TabsPaneContext } from 'element-plus'
|
||||||
|
import { Search, Filter } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmClue' })
|
defineOptions({ name: 'CrmClue' })
|
||||||
|
|
||||||
@@ -180,6 +168,7 @@ const { t } = useI18n() // 国际化
|
|||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
|
const filterDrawerVisible = ref(false) // 筛选抽屉
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -263,8 +252,149 @@ const handleExport = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 筛选确认 */
|
||||||
|
const handleFilterConfirm = () => {
|
||||||
|
filterDrawerVisible.value = false
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-page {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.mobile-page__header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-page__search {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.mobile-page__actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.mobile-page__tabs {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-page__content {
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
.mobile-item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.mobile-item-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
&--clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
&:active {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
&__name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
&__body {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
&__info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
&__info-label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
&__info-value {
|
||||||
|
color: #606266;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
&__footer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
padding: 40px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.mobile-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,21 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="dialogVisible" :title="dialogTitle">
|
<el-drawer
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:close-on-press-escape="true"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form" v-loading="formLoading">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
v-loading="formLoading"
|
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="100px"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<el-row>
|
<!-- 基本信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">基本信息</div>
|
||||||
<el-form-item label="客户名称" prop="name">
|
<el-form-item label="客户名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入客户名称" />
|
<el-input v-model="formData.name" placeholder="请输入客户名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="客户来源" prop="source">
|
<el-form-item label="客户来源" prop="source">
|
||||||
<el-select v-model="formData.source" placeholder="请选择客户来源" class="w-1/1">
|
<el-select v-model="formData.source" placeholder="请选择客户来源" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -24,20 +31,11 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="手机" prop="mobile">
|
|
||||||
<el-input v-model="formData.mobile" placeholder="请输入手机" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="负责人" prop="ownerUserId">
|
<el-form-item label="负责人" prop="ownerUserId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.ownerUserId"
|
v-model="formData.ownerUserId"
|
||||||
:disabled="formType !== 'create'"
|
:disabled="formType !== 'create'"
|
||||||
class="w-1/1"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
@@ -47,36 +45,33 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 联系方式 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">联系方式</div>
|
||||||
|
<el-form-item label="手机" prop="mobile">
|
||||||
|
<el-input v-model="formData.mobile" placeholder="请输入手机" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="电话" prop="telephone">
|
<el-form-item label="电话" prop="telephone">
|
||||||
<el-input v-model="formData.telephone" placeholder="请输入电话" />
|
<el-input v-model="formData.telephone" placeholder="请输入电话" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱" prop="email">
|
||||||
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="微信" prop="wechat">
|
<el-form-item label="微信" prop="wechat">
|
||||||
<el-input v-model="formData.wechat" placeholder="请输入微信" />
|
<el-input v-model="formData.wechat" placeholder="请输入微信" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="QQ" prop="qq">
|
<el-form-item label="QQ" prop="qq">
|
||||||
<el-input v-model="formData.qq" placeholder="请输入 QQ" />
|
<el-input v-model="formData.qq" placeholder="请输入 QQ" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 客户信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">客户信息</div>
|
||||||
<el-form-item label="客户行业" prop="industryId">
|
<el-form-item label="客户行业" prop="industryId">
|
||||||
<el-select v-model="formData.industryId" placeholder="请选择客户行业" class="w-1/1">
|
<el-select v-model="formData.industryId" placeholder="请选择客户行业" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -85,10 +80,8 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="客户级别" prop="level">
|
<el-form-item label="客户级别" prop="level">
|
||||||
<el-select v-model="formData.level" placeholder="请选择客户级别" class="w-1/1">
|
<el-select v-model="formData.level" placeholder="请选择客户级别" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -97,52 +90,52 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 地址信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">地址信息</div>
|
||||||
<el-form-item label="地址" prop="areaId">
|
<el-form-item label="地址" prop="areaId">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
v-model="formData.areaId"
|
v-model="formData.areaId"
|
||||||
:options="areaList"
|
:options="areaList"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
class="w-1/1"
|
style="width: 100%"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择城市"
|
placeholder="请选择城市"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="详细地址" prop="detailAddress">
|
<el-form-item label="详细地址" prop="detailAddress">
|
||||||
<el-input v-model="formData.detailAddress" placeholder="请输入详细地址" />
|
<el-input v-model="formData.detailAddress" placeholder="请输入详细地址" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<!-- 其他信息 -->
|
||||||
<el-col :span="12">
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">其他信息</div>
|
||||||
<el-form-item label="下次联系时间" prop="contactNextTime">
|
<el-form-item label="下次联系时间" prop="contactNextTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.contactNextTime"
|
v-model="formData.contactNextTime"
|
||||||
placeholder="选择下次联系时间"
|
placeholder="选择下次联系时间"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
value-format="x"
|
value-format="x"
|
||||||
class="!w-1/1"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
|
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" :rows="3" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
</Dialog>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -258,3 +251,44 @@ const resetForm = () => {
|
|||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
<!-- 客户导入窗口 -->
|
<!-- 客户导入窗口 -->
|
||||||
<template>
|
<template>
|
||||||
<Dialog v-model="dialogVisible" title="客户导入" width="400">
|
<el-drawer
|
||||||
<div class="flex items-center my-10px">
|
v-model="dialogVisible"
|
||||||
<span class="mr-10px">负责人</span>
|
title="客户导入"
|
||||||
<el-select v-model="ownerUserId" class="!w-240px" clearable>
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:close-on-press-escape="true"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form" v-loading="formLoading">
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">导入设置</div>
|
||||||
|
<el-form label-position="top">
|
||||||
|
<el-form-item label="负责人">
|
||||||
|
<el-select v-model="ownerUserId" style="width: 100%" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -11,7 +22,12 @@
|
|||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">上传文件</div>
|
||||||
<el-upload
|
<el-upload
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
@@ -43,11 +59,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<template #footer>
|
</div>
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
</Dialog>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as CustomerApi from '@/api/crm/customer'
|
import * as CustomerApi from '@/api/crm/customer'
|
||||||
@@ -156,3 +176,44 @@ const importTemplate = async () => {
|
|||||||
download.excel(res, '客户导入模版.xls')
|
download.excel(res, '客户导入模版.xls')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,41 +1,139 @@
|
|||||||
<template>
|
<template>
|
||||||
<doc-alert title="【客户】客户管理、公海客户" url="https://doc.iocoder.cn/crm/customer/" />
|
<div class="mobile-page">
|
||||||
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
|
<!-- 搜索头部 -->
|
||||||
|
<div class="mobile-page__header">
|
||||||
<ContentWrap>
|
<div class="mobile-page__search">
|
||||||
<!-- 搜索工作栏 -->
|
|
||||||
<el-form
|
|
||||||
ref="queryFormRef"
|
|
||||||
:inline="true"
|
|
||||||
:model="queryParams"
|
|
||||||
class="-mb-15px"
|
|
||||||
label-width="68px"
|
|
||||||
>
|
|
||||||
<el-form-item label="客户名称" prop="name">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
class="!w-240px"
|
placeholder="搜索客户名称"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请输入客户名称"
|
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
|
:prefix-icon="Search"
|
||||||
/>
|
/>
|
||||||
|
<el-button type="primary" :icon="Filter" @click="filterDrawerVisible = true" />
|
||||||
|
</div>
|
||||||
|
<div class="mobile-page__actions">
|
||||||
|
<el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:customer:create']">
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button type="warning" plain @click="handleImport" v-hasPermi="['crm:customer:import']">
|
||||||
|
导入
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['crm:customer:export']"
|
||||||
|
>
|
||||||
|
导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab 切换 -->
|
||||||
|
<div class="mobile-page__tabs">
|
||||||
|
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
||||||
|
<el-tab-pane label="我负责的" name="1" />
|
||||||
|
<el-tab-pane label="我参与的" name="2" />
|
||||||
|
<el-tab-pane label="下属负责的" name="3" />
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 客户列表 -->
|
||||||
|
<div class="mobile-page__content" v-loading="loading">
|
||||||
|
<div class="mobile-item-list">
|
||||||
|
<div
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="mobile-item-card mobile-item-card--clickable"
|
||||||
|
@click="openDetail(item.id)"
|
||||||
|
>
|
||||||
|
<div class="mobile-item-card__header">
|
||||||
|
<span class="mobile-item-card__name">{{ item.name }}</span>
|
||||||
|
<el-tag v-if="item.dealStatus" type="success" size="small">已成交</el-tag>
|
||||||
|
<el-tag v-else type="info" size="small">未成交</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__body">
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">客户来源</span>
|
||||||
|
<span class="mobile-item-card__info-value">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="item.source" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">手机</span>
|
||||||
|
<span class="mobile-item-card__info-value">{{ item.mobile || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">负责人</span>
|
||||||
|
<span class="mobile-item-card__info-value">{{ item.ownerUserName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">客户级别</span>
|
||||||
|
<span class="mobile-item-card__info-value">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="item.level" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">最后跟进</span>
|
||||||
|
<span class="mobile-item-card__info-value">{{ item.contactLastTime ? dateFormatter(null, null, item.contactLastTime) : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__footer" @click.stop>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', item.id)"
|
||||||
|
v-hasPermi="['crm:customer:update']"
|
||||||
|
>编辑</el-button>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(item.id)"
|
||||||
|
v-hasPermi="['crm:customer:delete']"
|
||||||
|
>删除</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="list.length === 0 && !loading" class="mobile-empty-tip">暂无客户数据</div>
|
||||||
|
</div>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="mobile-pagination" v-if="total > 0">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20]"
|
||||||
|
layout="total, prev, pager, next"
|
||||||
|
:pager-count="5"
|
||||||
|
@size-change="getList"
|
||||||
|
@current-change="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 筛选抽屉 -->
|
||||||
|
<el-drawer
|
||||||
|
v-model="filterDrawerVisible"
|
||||||
|
title="筛选条件"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:append-to-body="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form">
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">筛选条件</div>
|
||||||
|
<el-form :model="queryParams" ref="queryFormRef" label-position="top">
|
||||||
|
<el-form-item label="客户名称" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入客户名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="queryParams.mobile" placeholder="请输入手机" clearable />
|
||||||
v-model="queryParams.mobile"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入手机"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属行业" prop="industryId">
|
<el-form-item label="所属行业" prop="industryId">
|
||||||
<el-select
|
<el-select v-model="queryParams.industryId" placeholder="请选择所属行业" clearable style="width: 100%">
|
||||||
v-model="queryParams.industryId"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择所属行业"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -45,12 +143,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户级别" prop="level">
|
<el-form-item label="客户级别" prop="level">
|
||||||
<el-select
|
<el-select v-model="queryParams.level" placeholder="请选择客户级别" clearable style="width: 100%">
|
||||||
v-model="queryParams.level"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择客户级别"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -60,12 +153,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户来源" prop="source">
|
<el-form-item label="客户来源" prop="source">
|
||||||
<el-select
|
<el-select v-model="queryParams.source" placeholder="请选择客户来源" clearable style="width: 100%">
|
||||||
v-model="queryParams.source"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择客户来源"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -74,146 +162,14 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="handleQuery">
|
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
|
||||||
搜索
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="resetQuery">
|
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button v-hasPermi="['crm:customer:create']" type="primary" @click="openForm('create')">
|
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
<el-button v-hasPermi="['crm:customer:import']" plain type="warning" @click="handleImport">
|
|
||||||
<Icon icon="ep:upload" />
|
|
||||||
导入
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['crm:customer:export']"
|
|
||||||
:loading="exportLoading"
|
|
||||||
plain
|
|
||||||
type="success"
|
|
||||||
@click="handleExport"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:download" />
|
|
||||||
导出
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</div>
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<!-- 列表 -->
|
<el-button @click="resetQuery" style="flex: 1">重置</el-button>
|
||||||
<ContentWrap>
|
<el-button type="primary" @click="handleFilterConfirm" style="flex: 1">确认</el-button>
|
||||||
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
</div>
|
||||||
<el-tab-pane label="我负责的" name="1" />
|
</div>
|
||||||
<el-tab-pane label="我参与的" name="2" />
|
</el-drawer>
|
||||||
<el-tab-pane label="下属负责的" name="3" />
|
|
||||||
</el-tabs>
|
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
|
||||||
<el-table-column align="center" fixed="left" label="客户名称" prop="name" width="160">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
|
||||||
{{ scope.row.name }}
|
|
||||||
</el-link>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="客户来源" prop="source" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="手机" prop="mobile" width="120" />
|
|
||||||
<el-table-column align="center" label="电话" prop="telephone" width="130" />
|
|
||||||
<el-table-column align="center" label="邮箱" prop="email" width="180" />
|
|
||||||
<el-table-column align="center" label="客户级别" prop="level" width="135">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="客户行业" prop="industryId" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="下次联系时间"
|
|
||||||
prop="contactNextTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="备注" prop="remark" width="200" />
|
|
||||||
<el-table-column align="center" label="锁定状态" prop="lockStatus">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.lockStatus" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="成交状态" prop="dealStatus">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="最后跟进时间"
|
|
||||||
prop="contactLastTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="最后跟进记录" prop="contactLastContent" width="200" />
|
|
||||||
<el-table-column align="center" label="地址" prop="detailAddress" width="180" />
|
|
||||||
<el-table-column align="center" label="距离进入公海天数" prop="poolDay" width="140">
|
|
||||||
<template #default="scope"> {{ scope.row.poolDay }} 天</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="负责人" prop="ownerUserName" width="100px" />
|
|
||||||
<el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100px" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="更新时间"
|
|
||||||
prop="updateTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
|
||||||
prop="createTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
|
|
||||||
<el-table-column align="center" fixed="right" label="操作" min-width="150">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['crm:customer:update']"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="openForm('update', scope.row.id)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['crm:customer:delete']"
|
|
||||||
link
|
|
||||||
type="danger"
|
|
||||||
@click="handleDelete(scope.row.id)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<Pagination
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
:total="total"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
</ContentWrap>
|
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<CustomerForm ref="formRef" @success="getList" />
|
<CustomerForm ref="formRef" @success="getList" />
|
||||||
@@ -228,6 +184,7 @@ import * as CustomerApi from '@/api/crm/customer'
|
|||||||
import CustomerForm from './CustomerForm.vue'
|
import CustomerForm from './CustomerForm.vue'
|
||||||
import CustomerImportForm from './CustomerImportForm.vue'
|
import CustomerImportForm from './CustomerImportForm.vue'
|
||||||
import { TabsPaneContext } from 'element-plus'
|
import { TabsPaneContext } from 'element-plus'
|
||||||
|
import { Search, Filter } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmCustomer' })
|
defineOptions({ name: 'CrmCustomer' })
|
||||||
|
|
||||||
@@ -237,6 +194,7 @@ const { t } = useI18n() // 国际化
|
|||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
|
const filterDrawerVisible = ref(false) // 筛选抽屉
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -328,6 +286,12 @@ const handleExport = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 筛选确认 */
|
||||||
|
const handleFilterConfirm = () => {
|
||||||
|
filterDrawerVisible.value = false
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
/** 监听路由变化更新列表 */
|
/** 监听路由变化更新列表 */
|
||||||
watch(
|
watch(
|
||||||
() => currentRoute.value,
|
() => currentRoute.value,
|
||||||
@@ -341,3 +305,138 @@ onMounted(() => {
|
|||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-page {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.mobile-page__header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-page__search {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.mobile-page__actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.mobile-page__tabs {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-page__content {
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
.mobile-item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.mobile-item-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
&--clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
&:active {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
&__name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
&__body {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
&__info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
&__info-label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
&__info-value {
|
||||||
|
color: #606266;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
&__footer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
padding: 40px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.mobile-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
<el-drawer
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:close-on-press-escape="true"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form" v-loading="formLoading">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="200px"
|
label-position="top"
|
||||||
v-loading="formLoading"
|
|
||||||
>
|
>
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">规则设置</div>
|
||||||
<el-form-item label="规则适用人群" prop="userIds">
|
<el-form-item label="规则适用人群" prop="userIds">
|
||||||
<el-select multiple filterable v-model="formData.userIds">
|
<el-select multiple filterable v-model="formData.userIds" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -27,6 +37,7 @@
|
|||||||
check-strictly
|
check-strictly
|
||||||
node-key="id"
|
node-key="id"
|
||||||
placeholder="请选择规则适用部门"
|
placeholder="请选择规则适用部门"
|
||||||
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
@@ -37,7 +48,7 @@
|
|||||||
"
|
"
|
||||||
prop="maxCount"
|
prop="maxCount"
|
||||||
>
|
>
|
||||||
<el-input-number v-model="formData.maxCount" placeholder="请输入数量上限" />
|
<el-input-number v-model="formData.maxCount" placeholder="请输入数量上限" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="成交客户是否占用拥有客户数"
|
label="成交客户是否占用拥有客户数"
|
||||||
@@ -46,12 +57,16 @@
|
|||||||
>
|
>
|
||||||
<el-switch v-model="formData.dealCountEnabled" />
|
<el-switch v-model="formData.dealCountEnabled" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
|
||||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
</Dialog>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as CustomerLimitConfigApi from '@/api/crm/customer/limitConfig'
|
import * as CustomerLimitConfigApi from '@/api/crm/customer/limitConfig'
|
||||||
@@ -148,3 +163,44 @@ const resetForm = () => {
|
|||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,84 +1,83 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-button plain @click="handleQuery"> <Icon icon="ep:refresh" class="mr-5px" /> 刷新 </el-button>
|
<div class="mobile-list-page">
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div class="mobile-list-page__actions">
|
||||||
|
<el-button plain size="small" @click="handleQuery">
|
||||||
|
<Icon icon="ep:refresh" class="mr-5px" /> 刷新
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
size="small"
|
||||||
@click="openForm('create')"
|
@click="openForm('create')"
|
||||||
v-hasPermi="['crm:customer-limit-config:create']"
|
v-hasPermi="['crm:customer-limit-config:create']"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-table
|
</div>
|
||||||
v-loading="loading"
|
|
||||||
:data="list"
|
<!-- 列表 -->
|
||||||
:stripe="true"
|
<div class="mobile-item-list" v-loading="loading">
|
||||||
:show-overflow-tooltip="true"
|
<div
|
||||||
class="mt-4"
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="mobile-item-card"
|
||||||
>
|
>
|
||||||
<el-table-column label="编号" align="center" prop="id" />
|
<div class="mobile-item-card__header">
|
||||||
<el-table-column
|
<span class="mobile-item-card__name">规则 #{{ item.id }}</span>
|
||||||
label="规则适用人群"
|
<el-tag type="primary" size="small">上限 {{ item.maxCount }}</el-tag>
|
||||||
align="center"
|
</div>
|
||||||
:formatter="(row) => row.users?.map((user: any) => user.nickname).join(',')"
|
<div class="mobile-item-card__body">
|
||||||
/>
|
<div class="mobile-item-card__info-row">
|
||||||
<el-table-column
|
<span class="mobile-item-card__info-label">适用人群</span>
|
||||||
label="规则适用部门"
|
<span class="mobile-item-card__info-value">{{ item.users?.map((user: any) => user.nickname).join(',') || '-' }}</span>
|
||||||
align="center"
|
</div>
|
||||||
:formatter="(row) => row.depts?.map((dept: any) => dept.name).join(',')"
|
<div class="mobile-item-card__info-row">
|
||||||
/>
|
<span class="mobile-item-card__info-label">适用部门</span>
|
||||||
<el-table-column
|
<span class="mobile-item-card__info-value">{{ item.depts?.map((dept: any) => dept.name).join(',') || '-' }}</span>
|
||||||
:label="
|
</div>
|
||||||
confType === LimitConfType.CUSTOMER_QUANTITY_LIMIT ? '拥有客户数上限' : '锁定客户数上限'
|
<div class="mobile-item-card__info-row" v-if="confType === LimitConfType.CUSTOMER_QUANTITY_LIMIT">
|
||||||
"
|
<span class="mobile-item-card__info-label">成交客户占用</span>
|
||||||
align="center"
|
<span class="mobile-item-card__info-value">
|
||||||
prop="maxCount"
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="item.dealCountEnabled" />
|
||||||
/>
|
</span>
|
||||||
<el-table-column
|
</div>
|
||||||
v-if="confType === LimitConfType.CUSTOMER_QUANTITY_LIMIT"
|
<div class="mobile-item-card__info-row">
|
||||||
label="成交客户是否占用拥有客户数"
|
<span class="mobile-item-card__info-label">创建时间</span>
|
||||||
align="center"
|
<span class="mobile-item-card__info-value">{{ dateFormatter(null, null, item.createTime) }}</span>
|
||||||
prop="dealCountEnabled"
|
</div>
|
||||||
min-width="100"
|
</div>
|
||||||
>
|
<div class="mobile-item-card__footer">
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealCountEnabled" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
label="创建时间"
|
|
||||||
align="center"
|
|
||||||
prop="createTime"
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column label="操作" align="center" min-width="110" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
<el-button
|
||||||
link
|
size="small"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', item.id)"
|
||||||
v-hasPermi="['crm:customer-limit-config:update']"
|
v-hasPermi="['crm:customer-limit-config:update']"
|
||||||
>
|
>编辑</el-button>
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
link
|
size="small"
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(item.id)"
|
||||||
v-hasPermi="['crm:customer-limit-config:delete']"
|
v-hasPermi="['crm:customer-limit-config:delete']"
|
||||||
>
|
>删除</el-button>
|
||||||
删除
|
</div>
|
||||||
</el-button>
|
</div>
|
||||||
</template>
|
<div v-if="list.length === 0 && !loading" class="mobile-empty-tip">暂无配置数据</div>
|
||||||
</el-table-column>
|
</div>
|
||||||
</el-table>
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<div class="mobile-pagination" v-if="total > 0">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
:page-sizes="[10, 20]"
|
||||||
v-model:limit="queryParams.pageSize"
|
layout="total, prev, pager, next"
|
||||||
@pagination="getList"
|
:pager-count="5"
|
||||||
|
@size-change="getList"
|
||||||
|
@current-change="getList"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<CustomerLimitConfigForm ref="formRef" @success="getList" />
|
<CustomerLimitConfigForm ref="formRef" @success="getList" />
|
||||||
@@ -148,3 +147,79 @@ onMounted(() => {
|
|||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-list-page {
|
||||||
|
padding: 12px 0;
|
||||||
|
}
|
||||||
|
.mobile-list-page__actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.mobile-item-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
&__name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
&__body {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
&__info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
&__info-label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
&__info-value {
|
||||||
|
color: #606266;
|
||||||
|
text-align: right;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
&__footer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
padding: 40px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.mobile-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<doc-alert title="【客户】客户管理、公海客户" url="https://doc.iocoder.cn/crm/customer/" />
|
<div class="mobile-page">
|
||||||
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
|
<!-- Tab 切换 -->
|
||||||
|
<div class="mobile-page__tabs">
|
||||||
<!-- 列表 -->
|
<el-tabs v-model="activeTab">
|
||||||
<ContentWrap>
|
<el-tab-pane label="拥有客户数限制" name="quantity">
|
||||||
<el-tabs>
|
|
||||||
<el-tab-pane label="拥有客户数限制">
|
|
||||||
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_QUANTITY_LIMIT" />
|
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_QUANTITY_LIMIT" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="锁定客户数限制">
|
<el-tab-pane label="锁定客户数限制" name="lock">
|
||||||
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_LOCK_LIMIT" />
|
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_LOCK_LIMIT" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</ContentWrap>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CustomerLimitConfigList from './CustomerLimitConfigList.vue'
|
import CustomerLimitConfigList from './CustomerLimitConfigList.vue'
|
||||||
import { LimitConfType } from '@/api/crm/customer/limitConfig'
|
import { LimitConfType } from '@/api/crm/customer/limitConfig'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmCustomerLimitConfig' })
|
defineOptions({ name: 'CrmCustomerLimitConfig' })
|
||||||
|
|
||||||
|
const activeTab = ref('quantity')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-page {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.mobile-page__tabs {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog v-model="dialogVisible" title="分配客户">
|
<el-drawer
|
||||||
|
v-model="dialogVisible"
|
||||||
|
title="分配客户"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:close-on-press-escape="true"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form" v-loading="formLoading">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
v-loading="formLoading"
|
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="100px"
|
label-position="top"
|
||||||
>
|
>
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">分配设置</div>
|
||||||
<el-form-item label="负责人" prop="ownerUserId">
|
<el-form-item label="负责人" prop="ownerUserId">
|
||||||
<el-select v-model="formData.ownerUserId" class="w-1/1">
|
<el-select v-model="formData.ownerUserId" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -17,12 +27,16 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
</Dialog>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as CustomerApi from '@/api/crm/customer'
|
import * as CustomerApi from '@/api/crm/customer'
|
||||||
@@ -83,3 +97,44 @@ const resetForm = () => {
|
|||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,41 +1,106 @@
|
|||||||
<template>
|
<template>
|
||||||
<doc-alert title="【客户】客户管理、公海客户" url="https://doc.iocoder.cn/crm/customer/" />
|
<div class="mobile-page">
|
||||||
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
|
<!-- 搜索头部 -->
|
||||||
|
<div class="mobile-page__header">
|
||||||
<ContentWrap>
|
<div class="mobile-page__search">
|
||||||
<!-- 搜索工作栏 -->
|
|
||||||
<el-form
|
|
||||||
ref="queryFormRef"
|
|
||||||
:inline="true"
|
|
||||||
:model="queryParams"
|
|
||||||
class="-mb-15px"
|
|
||||||
label-width="68px"
|
|
||||||
>
|
|
||||||
<el-form-item label="客户名称" prop="name">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
class="!w-240px"
|
placeholder="搜索客户名称"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请输入客户名称"
|
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
|
:prefix-icon="Search"
|
||||||
/>
|
/>
|
||||||
|
<el-button type="primary" :icon="Filter" @click="filterDrawerVisible = true" />
|
||||||
|
</div>
|
||||||
|
<div class="mobile-page__actions">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['crm:customer:export']"
|
||||||
|
>
|
||||||
|
导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 公海客户列表 -->
|
||||||
|
<div class="mobile-page__content" v-loading="loading">
|
||||||
|
<div class="mobile-item-list">
|
||||||
|
<div
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="mobile-item-card mobile-item-card--clickable"
|
||||||
|
@click="openDetail(item.id)"
|
||||||
|
>
|
||||||
|
<div class="mobile-item-card__header">
|
||||||
|
<span class="mobile-item-card__name">{{ item.name }}</span>
|
||||||
|
<el-tag v-if="item.dealStatus" type="success" size="small">已成交</el-tag>
|
||||||
|
<el-tag v-else type="info" size="small">未成交</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__body">
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">客户来源</span>
|
||||||
|
<span class="mobile-item-card__info-value">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="item.source" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">手机</span>
|
||||||
|
<span class="mobile-item-card__info-value">{{ item.mobile || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">客户级别</span>
|
||||||
|
<span class="mobile-item-card__info-value">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="item.level" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-item-card__info-row">
|
||||||
|
<span class="mobile-item-card__info-label">最后跟进</span>
|
||||||
|
<span class="mobile-item-card__info-value">{{ item.contactLastTime ? dateFormatter(null, null, item.contactLastTime) : '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="list.length === 0 && !loading" class="mobile-empty-tip">暂无公海客户数据</div>
|
||||||
|
</div>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="mobile-pagination" v-if="total > 0">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20]"
|
||||||
|
layout="total, prev, pager, next"
|
||||||
|
:pager-count="5"
|
||||||
|
@size-change="getList"
|
||||||
|
@current-change="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 筛选抽屉 -->
|
||||||
|
<el-drawer
|
||||||
|
v-model="filterDrawerVisible"
|
||||||
|
title="筛选条件"
|
||||||
|
direction="rtl"
|
||||||
|
size="100%"
|
||||||
|
:append-to-body="true"
|
||||||
|
class="mobile-form-drawer"
|
||||||
|
>
|
||||||
|
<div class="mobile-form">
|
||||||
|
<div class="mobile-form__section">
|
||||||
|
<div class="mobile-form__section-title">筛选条件</div>
|
||||||
|
<el-form :model="queryParams" ref="queryFormRef" label-position="top">
|
||||||
|
<el-form-item label="客户名称" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入客户名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="queryParams.mobile" placeholder="请输入手机" clearable />
|
||||||
v-model="queryParams.mobile"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入手机"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属行业" prop="industryId">
|
<el-form-item label="所属行业" prop="industryId">
|
||||||
<el-select
|
<el-select v-model="queryParams.industryId" placeholder="请选择所属行业" clearable style="width: 100%">
|
||||||
v-model="queryParams.industryId"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择所属行业"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -45,12 +110,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户级别" prop="level">
|
<el-form-item label="客户级别" prop="level">
|
||||||
<el-select
|
<el-select v-model="queryParams.level" placeholder="请选择客户级别" clearable style="width: 100%">
|
||||||
v-model="queryParams.level"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择客户级别"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -60,12 +120,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="客户来源" prop="source">
|
<el-form-item label="客户来源" prop="source">
|
||||||
<el-select
|
<el-select v-model="queryParams.source" placeholder="请选择客户来源" clearable style="width: 100%">
|
||||||
v-model="queryParams.source"
|
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请选择客户来源"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@@ -74,102 +129,14 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="handleQuery">
|
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
|
||||||
搜索
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="resetQuery(undefined)">
|
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['crm:customer:export']"
|
|
||||||
:loading="exportLoading"
|
|
||||||
plain
|
|
||||||
type="success"
|
|
||||||
@click="handleExport"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:download" />
|
|
||||||
导出
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</div>
|
||||||
|
<div class="mobile-form__footer">
|
||||||
<!-- 列表 -->
|
<el-button @click="resetQuery" style="flex: 1">重置</el-button>
|
||||||
<ContentWrap>
|
<el-button type="primary" @click="handleFilterConfirm" style="flex: 1">确认</el-button>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
</div>
|
||||||
<el-table-column align="center" label="客户名称" fixed="left" prop="name" width="160">
|
</div>
|
||||||
<template #default="scope">
|
</el-drawer>
|
||||||
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
|
||||||
{{ scope.row.name }}
|
|
||||||
</el-link>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="客户来源" prop="source" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="手机" align="center" prop="mobile" width="120" />
|
|
||||||
<el-table-column label="电话" align="center" prop="telephone" width="130" />
|
|
||||||
<el-table-column label="邮箱" align="center" prop="email" width="180" />
|
|
||||||
<el-table-column align="center" label="客户级别" prop="level" width="135">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="客户行业" prop="industryId" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="下次联系时间"
|
|
||||||
prop="contactNextTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="备注" prop="remark" width="200" />
|
|
||||||
<el-table-column align="center" label="成交状态" prop="dealStatus">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="最后跟进时间"
|
|
||||||
prop="contactLastTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="最后跟进记录" prop="contactLastContent" width="200" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="更新时间"
|
|
||||||
prop="updateTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
|
||||||
prop="createTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
|
|
||||||
</el-table>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<Pagination
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
:total="total"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
</ContentWrap>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -177,6 +144,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
import * as CustomerApi from '@/api/crm/customer'
|
import * as CustomerApi from '@/api/crm/customer'
|
||||||
|
import { Search, Filter } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmCustomerPool' })
|
defineOptions({ name: 'CrmCustomerPool' })
|
||||||
|
|
||||||
@@ -185,6 +153,7 @@ const message = useMessage() // 消息弹窗
|
|||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
|
const filterDrawerVisible = ref(false) // 筛选抽屉
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -255,6 +224,12 @@ const handleExport = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 筛选确认 */
|
||||||
|
const handleFilterConfirm = () => {
|
||||||
|
filterDrawerVisible.value = false
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
/** 监听路由变化更新列表 */
|
/** 监听路由变化更新列表 */
|
||||||
watch(
|
watch(
|
||||||
() => currentRoute.value,
|
() => currentRoute.value,
|
||||||
@@ -268,3 +243,124 @@ onMounted(() => {
|
|||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-page {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.mobile-page__header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mobile-page__search {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.mobile-page__actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.mobile-page__content {
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
.mobile-item-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.mobile-item-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
&--clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
&:active {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
&__name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
&__body {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
&__info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
&__info-label {
|
||||||
|
color: #909399;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
&__info-value {
|
||||||
|
color: #606266;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
padding: 40px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.mobile-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobile-form {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||||
|
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0 -4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,62 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<doc-alert title="【客户】客户管理、公海客户" url="https://doc.iocoder.cn/crm/customer/" />
|
<div class="mobile-page" v-loading="formLoading">
|
||||||
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
|
|
||||||
|
|
||||||
<ContentWrap>
|
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="160px"
|
label-position="top"
|
||||||
v-loading="formLoading"
|
|
||||||
>
|
>
|
||||||
<el-card shadow="never">
|
<!-- 公海规则设置 -->
|
||||||
<!-- 操作 -->
|
<div class="mobile-form__section">
|
||||||
<template #header>
|
<div class="mobile-form__section-header">
|
||||||
<div class="flex items-center justify-between">
|
<span class="mobile-form__section-title">客户公海规则设置</span>
|
||||||
<CardTitle title="客户公海规则设置" />
|
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
size="small"
|
||||||
@click="onSubmit"
|
@click="onSubmit"
|
||||||
v-hasPermi="['crm:customer-pool-config:update']"
|
v-hasPermi="['crm:customer-pool-config:update']"
|
||||||
>
|
>
|
||||||
保存
|
保存
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<el-form-item label="客户公海规则" prop="enabled">
|
||||||
<!-- 表单 -->
|
<el-radio-group v-model="formData.enabled" @change="changeEnable">
|
||||||
<el-form-item label="客户公海规则设置" prop="enabled">
|
<el-radio :value="false">不启用</el-radio>
|
||||||
<el-radio-group v-model="formData.enabled" @change="changeEnable" class="ml-4">
|
<el-radio :value="true">启用</el-radio>
|
||||||
<el-radio :value="false" size="large">不启用</el-radio>
|
|
||||||
<el-radio :value="true" size="large">启用</el-radio>
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="formData.enabled">
|
</div>
|
||||||
<el-form-item>
|
|
||||||
<el-input-number class="mr-2" v-model="formData.contactExpireDays" />
|
<!-- 规则详情 -->
|
||||||
天不跟进或
|
<div class="mobile-form__section" v-if="formData.enabled">
|
||||||
<el-input-number class="mx-2" v-model="formData.dealExpireDays" />
|
<div class="mobile-form__section-title">规则详情</div>
|
||||||
天未成交
|
<div class="mobile-form__inline-group">
|
||||||
</el-form-item>
|
<el-input-number v-model="formData.contactExpireDays" :min="1" style="width: 80px" />
|
||||||
<el-form-item label="提前提醒设置" prop="notifyEnabled">
|
<span class="mobile-form__inline-text">天不跟进或</span>
|
||||||
<el-radio-group
|
<el-input-number v-model="formData.dealExpireDays" :min="1" style="width: 80px" />
|
||||||
v-model="formData.notifyEnabled"
|
<span class="mobile-form__inline-text">天未成交</span>
|
||||||
@change="changeNotifyEnable"
|
</div>
|
||||||
class="ml-4"
|
<el-form-item label="提前提醒设置" prop="notifyEnabled" style="margin-top: 16px">
|
||||||
>
|
<el-radio-group v-model="formData.notifyEnabled" @change="changeNotifyEnable">
|
||||||
<el-radio :value="false" size="large">不提醒</el-radio>
|
<el-radio :value="false">不提醒</el-radio>
|
||||||
<el-radio :value="true" size="large">提醒</el-radio>
|
<el-radio :value="true">提醒</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="formData.notifyEnabled">
|
<div class="mobile-form__inline-group" v-if="formData.notifyEnabled">
|
||||||
<el-form-item>
|
<span class="mobile-form__inline-text">提前</span>
|
||||||
提前 <el-input-number class="mx-2" v-model="formData.notifyDays" /> 天提醒
|
<el-input-number v-model="formData.notifyDays" :min="1" style="width: 80px" />
|
||||||
</el-form-item>
|
<span class="mobile-form__inline-text">天提醒</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as CustomerPoolConfigApi from '@/api/crm/customer/poolConfig'
|
import * as CustomerPoolConfigApi from '@/api/crm/customer/poolConfig'
|
||||||
@@ -134,3 +127,42 @@ onMounted(() => {
|
|||||||
getConfig()
|
getConfig()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mobile-page {
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.mobile-form__section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.mobile-form__section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.mobile-form__section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.mobile-form__inline-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.mobile-form__inline-text {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user