main
parent
742e85ae65
commit
fa2ee0cd6a
@ -0,0 +1,50 @@ |
||||
import request from '@/config/axios' |
||||
|
||||
// 获得微信群列表
|
||||
export const getWxGroupPage = (params) => { |
||||
return request.get({ url: '/admin-api/crm/wxgroup/page', params }) |
||||
} |
||||
|
||||
// 创建微信群
|
||||
export const createWxGroup = (data) => { |
||||
return request.post({ url: '/admin-api/crm/wxgroup/create', data, isSubmitForm: true }) |
||||
} |
||||
|
||||
// 更新微信群
|
||||
export const updateWxGroup = (data) => { |
||||
return request.put({ url: '/admin-api/crm/wxgroup/update', data }) |
||||
} |
||||
|
||||
// 删除微信群
|
||||
export const deleteWxGroup = (id) => { |
||||
return request.delete({ url: `/admin-api/crm/wxgroup?groupId=${id}` }) |
||||
} |
||||
|
||||
export const getWxGroupSimpleList = async () => { |
||||
return await request.get({ url: '/admin-api/crm/wxgroup/simple-list' }) |
||||
} |
||||
|
||||
// 报备
|
||||
export const reportClue = (data) => { |
||||
return request.post({ url: '/admin-api/crm/clue-remark/remark/save', data }) |
||||
} |
||||
|
||||
// 接待提交报名信息
|
||||
export const registerClue = (data) => { |
||||
return request.post({ url: '/admin-api/crm/clue-remark/sign/save', data }) |
||||
} |
||||
|
||||
// 分页查询报备信息
|
||||
export const getClueRemarkPage = (params) => { |
||||
return request.get({ url: '/admin-api/crm/clue-remark/page', params }) |
||||
} |
||||
|
||||
// 区域查询报备信息
|
||||
export const getClueRemarkByRemarkId = (params) => { |
||||
return request.get({ url: `/admin-api/crm/clue-remark/sign/get`, params }) |
||||
} |
||||
|
||||
// 销售查询报备信息
|
||||
export const getClueRemarkByClueId = (params) => { |
||||
return request.get({ url: `/admin-api/crm/clue-remark/remark/get`, params }) |
||||
} |
||||
@ -0,0 +1,161 @@ |
||||
<template> |
||||
<div> |
||||
<el-form :model="searchForm" label-width="0" inline> |
||||
<el-form-item> |
||||
<el-input v-model="searchForm.name" placeholder="学员姓名" clearable style="width: 120px" /> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-input |
||||
v-model="searchForm.phone" |
||||
placeholder="联系方式" |
||||
clearable |
||||
style="width: 120px" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-select |
||||
v-model="searchForm.signUser" |
||||
placeholder="跟进人" |
||||
clearable |
||||
filterable |
||||
style="width: 120px" |
||||
> |
||||
<el-option |
||||
v-for="item in userOptions" |
||||
:key="item.id" |
||||
:label="item.nickname" |
||||
:value="item.id" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-date-picker |
||||
v-model="searchForm.dealDate" |
||||
type="daterange" |
||||
format="YYYY-MM-DD" |
||||
value-format="YYYY-MM-DD" |
||||
range-separator="-" |
||||
start-placeholder="报备日期" |
||||
end-placeholder="报备日期" |
||||
style="width: 240px" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-date-picker |
||||
v-model="searchForm.createDate" |
||||
type="daterange" |
||||
format="YYYY-MM-DD" |
||||
value-format="YYYY-MM-DD" |
||||
range-separator="-" |
||||
start-placeholder="报名日期" |
||||
end-placeholder="报名日期" |
||||
style="width: 240px" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-select |
||||
v-model="searchForm.signUser" |
||||
placeholder="报名状态" |
||||
clearable |
||||
filterable |
||||
style="width: 120px" |
||||
> |
||||
<el-option label="未报名" :value="0" /> |
||||
<el-option label="已报名" :value="1" /> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-select |
||||
v-model="searchForm.signUser" |
||||
placeholder="登记状态" |
||||
clearable |
||||
filterable |
||||
style="width: 120px" |
||||
> |
||||
<el-option label="未登记" :value="0" /> |
||||
<el-option label="已登记" :value="1" /> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-button @click="handleSearch">查询</el-button> |
||||
<el-button @click="handleReset">重置</el-button> |
||||
</el-form-item> |
||||
</el-form> |
||||
|
||||
<el-table v-loading="loading" :data="tableList" border show-summary> |
||||
<el-table-column prop="name" label="学员姓名" width="90px" /> |
||||
<el-table-column prop="phone" label="联系方式" width="120px" /> |
||||
<el-table-column prop="signUserName" label="跟进人" width="90" /> |
||||
<el-table-column prop="dealDate" label="报备日期" width="120px" :formatter="dateFormatter" /> |
||||
<el-table-column prop="signSchool" label="报备人" width="90px" /> |
||||
<el-table-column prop="signPlace" label="报备内容" min-width="150px" /> |
||||
<el-table-column prop="dealDate" label="报名日期" width="120px" :formatter="dateFormatter" /> |
||||
<el-table-column prop="signSchool" label="接待人" width="90px" /> |
||||
<el-table-column prop="signPlace" label="报名信息" min-width="150px" /> |
||||
<el-table-column prop="isCommissioned" label="报名状态" width="90px" fixed="right" /> |
||||
<el-table-column prop="settlementState" label="登记状态" width="90px" fixed="right" /> |
||||
</el-table> |
||||
<Pagination |
||||
v-model:limit="searchForm.pageSize" |
||||
v-model:page="searchForm.pageNo" |
||||
:total="total" |
||||
@pagination="getList" |
||||
/> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { getSimpleUserList as getUserOption } from '@/api/system/user' |
||||
// import { removeNullField } from '@/utils/index' |
||||
import { dateFormatter } from '@/utils/formatTime' |
||||
|
||||
onMounted(() => { |
||||
getOptions() |
||||
handleSearch() |
||||
}) |
||||
|
||||
const userOptions = ref([]) |
||||
function getOptions() { |
||||
getUserOption().then((data) => { |
||||
userOptions.value = data |
||||
}) |
||||
} |
||||
|
||||
const searchForm = ref({ |
||||
name: undefined, |
||||
phone: undefined, |
||||
pageSize: 20, |
||||
pageNo: 1 |
||||
}) |
||||
|
||||
function handleReset() { |
||||
searchForm.value = { |
||||
name: undefined, |
||||
phone: undefined, |
||||
pageSize: 20, |
||||
pageNo: 1 |
||||
} |
||||
} |
||||
|
||||
function handleSearch() { |
||||
searchForm.value.pageNo = 1 |
||||
getList() |
||||
} |
||||
|
||||
const loading = ref(false) |
||||
const tableList = ref([]) |
||||
const total = ref(0) |
||||
|
||||
async function getList() { |
||||
loading.value = true |
||||
try { |
||||
// const data = await SettleApi.getSchoolSettlePage(removeNullField(searchForm.value)) |
||||
// tableList.value = data.list |
||||
// total.value = data.total |
||||
} finally { |
||||
loading.value = false |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
||||
@ -0,0 +1,104 @@ |
||||
<template> |
||||
<Dialog title="邀约报备" v-model="show" width="600px"> |
||||
<el-form :model="form" ref="formRef" :rules="rules" label-width="0"> |
||||
<el-form-item prop="remarkContent"> |
||||
<el-input |
||||
type="textarea" |
||||
placeholder="请输入报备信息" |
||||
v-model="form.remarkContent" |
||||
:autosize="{ minRows: 10 }" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item prop="groupId"> |
||||
<el-select v-model="form.groupId" placeholder="选择群聊发送报备信息并@区域" filterable> |
||||
<el-option |
||||
v-for="item in groupOptions" |
||||
:key="item.groupId" |
||||
:label="item.groupName" |
||||
:value="item.groupId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<span> |
||||
<el-button @click="show = false">取 消</el-button> |
||||
<el-button :disabled="formLoading" type="primary" @click="handleSave">提 交</el-button> |
||||
</span> |
||||
</template> |
||||
</Dialog> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { getWxGroupSimpleList, getClueRemarkByClueId, reportClue } from '@/api/clue/clueRemark' |
||||
import { useUserStore } from '@/store/modules/user' |
||||
|
||||
const userStore = useUserStore() |
||||
|
||||
const form = ref({ |
||||
remarkContent: '', |
||||
groupId: '' |
||||
}) |
||||
const rules = { |
||||
remarkContent: [{ required: true, message: '请输入报备信息', trigger: 'blur' }], |
||||
groupId: [{ required: true, message: '请选择群聊', trigger: 'change' }] |
||||
} |
||||
const formLoading = ref(false) |
||||
|
||||
const show = ref(false) |
||||
async function open(row) { |
||||
show.value = true |
||||
// 查询群聊 |
||||
getOptions() |
||||
|
||||
// 查询报备信息 |
||||
const data = await getClueRemarkByClueId({ clueId: row.clueId }) |
||||
if (data && data.remarkId) { |
||||
form.value = { ...data } |
||||
return |
||||
} |
||||
|
||||
form.value.clueId = row.clueId |
||||
let remarkInfo = `学员姓名:${row.name}\n联系方式:${row.phone}\n意向班型:` |
||||
if (row.diyParams?.licenseType) { |
||||
remarkInfo += `${row.diyParams.licenseType}\n` |
||||
} else { |
||||
remarkInfo += `\n` |
||||
} |
||||
const name = userStore.getUser.nickname.substring(0, 1) |
||||
remarkInfo += `意向成交价:\n邀约时间:\n邀约人:${name}教练\n备注:` |
||||
form.value.remarkContent = remarkInfo |
||||
} |
||||
|
||||
defineExpose({ open }) |
||||
|
||||
const groupOptions = ref([]) |
||||
|
||||
function getOptions() { |
||||
getWxGroupSimpleList().then((response) => { |
||||
groupOptions.value = response |
||||
}) |
||||
} |
||||
|
||||
const formRef = ref(null) |
||||
function handleSave() { |
||||
formRef.value.validate(async (valid) => { |
||||
if (valid) { |
||||
formLoading.value = true |
||||
try { |
||||
const data = await reportClue(form.value) |
||||
message.success(data) |
||||
} catch (error) { |
||||
console.error('提交报备信息失败', error) |
||||
} finally { |
||||
formLoading.value = false |
||||
} |
||||
} else { |
||||
console.log('表单验证失败') |
||||
return false |
||||
} |
||||
}) |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
||||
@ -0,0 +1,100 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="always" :body-style="{ padding: '10px' }"> |
||||
<template #header> |
||||
<div> |
||||
<span>报备❤</span> |
||||
</div> |
||||
</template> |
||||
<el-input |
||||
class="remark" |
||||
type="textarea" |
||||
v-model="remarkContent" |
||||
:autosize="{ minRows: 5 }" |
||||
readonly |
||||
/> |
||||
</el-card> |
||||
<el-card shadow="always" :body-style="{ padding: '10px' }" class="mt-10px"> |
||||
<template #header> |
||||
<div> |
||||
<span>接待录入</span> |
||||
</div> |
||||
</template> |
||||
<el-form :model="form" ref="formRef" :rules="rules" label-width="0"> |
||||
<el-form-item prop="signInfo"> |
||||
<el-input |
||||
class="remark" |
||||
type="textarea" |
||||
placeholder="请输入报名信息" |
||||
v-model="form.signInfo" |
||||
:autosize="{ minRows: 5 }" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item prop="group"> |
||||
<el-select v-model="form.group" placeholder="选择群聊并发送报名信息" filterable> |
||||
<el-option |
||||
v-for="item in groupOptions" |
||||
:key="item.groupId" |
||||
:label="item.groupName" |
||||
:value="item.groupId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-button class="w-full" type="primary" size="large" @click="handleSubmit"> |
||||
提交 |
||||
</el-button> |
||||
</el-form-item> |
||||
</el-form> |
||||
</el-card> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import { getWxGroupSimpleList } from '@/api/clue/clueRemark' |
||||
|
||||
const remarkContent = ref( |
||||
`学员姓名:测试1\n联系方式:1234321\n意向班型:\n意向成交价:\n邀约时间:\n邀约人:仇教练\n备注:` |
||||
) |
||||
|
||||
const groupOptions = ref([]) |
||||
|
||||
const form = ref({ |
||||
signInfo: '', |
||||
group: '' |
||||
}) |
||||
const rules = { |
||||
signInfo: [{ required: true, message: '请输入接待信息', trigger: 'blur' }], |
||||
group: [{ required: true, message: '请选择群聊', trigger: 'change' }] |
||||
} |
||||
|
||||
const formRef = ref(null) |
||||
|
||||
function handleSubmit() { |
||||
formRef.value.validate((valid) => { |
||||
if (valid) { |
||||
console.log('提交成功', form) |
||||
// 在这里处理提交逻辑 |
||||
} else { |
||||
console.log('表单验证失败') |
||||
return false |
||||
} |
||||
}) |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getWxGroupSimpleList().then((response) => { |
||||
groupOptions.value = response.data |
||||
}) |
||||
}) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
::v-deep(.remark .el-textarea__inner) { |
||||
font-size: 15px; |
||||
color: #333; |
||||
} |
||||
::v-deep(.el-card__header) { |
||||
padding: 10px; |
||||
} |
||||
</style> |
||||
@ -0,0 +1,228 @@ |
||||
<template> |
||||
<div> |
||||
<el-form ref="queryForm" :model="searchForm" label-width="0" inline> |
||||
<el-form-item> |
||||
<el-input |
||||
v-model="searchForm.groupName" |
||||
placeholder="请输入群名称" |
||||
clearable |
||||
@keyup.enter="handleQuery" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item> |
||||
<el-button @click="handleQuery">搜索</el-button> |
||||
<el-button @click="resetQuery">重置</el-button> |
||||
<el-button type="primary" @click="openForm('create', null)">新增</el-button> |
||||
</el-form-item> |
||||
</el-form> |
||||
<el-table v-loading="loading" :data="tableList"> |
||||
<el-table-column prop="groupName" label="群名称" /> |
||||
<el-table-column label="区域负责人" prop="areaUserName" /> |
||||
<el-table-column prop="remark" label="备注" /> |
||||
<el-table-column label="操作"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" style="padding: 0" text @click="openForm('update', row)"> |
||||
修改 |
||||
</el-button> |
||||
<el-button type="danger" text @click="handleDelete(row.groupId)"> 删除 </el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<Pagination |
||||
v-model:limit="searchForm.pageSize" |
||||
v-model:page="searchForm.pageNo" |
||||
:total="total" |
||||
@pagination="getList" |
||||
/> |
||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600px"> |
||||
<el-form |
||||
ref="formRef" |
||||
v-loading="formLoading" |
||||
:model="formData" |
||||
:rules="formRules" |
||||
label-width="100px" |
||||
> |
||||
<el-form-item label="微信群" prop="groupId"> |
||||
<el-select |
||||
filterable |
||||
v-model="formData.groupId" |
||||
placeholder="请选择群聊" |
||||
:disabled="dialogType === 'update'" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in groupOptions" |
||||
:key="item.wxGroupId" |
||||
:label="item.wxGroupName" |
||||
:value="item.wxGroupId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item label="区域负责人" prop="areaUser"> |
||||
<el-select v-model="formData.areaUser" placeholder="请选择" filterable> |
||||
<el-option |
||||
v-for="item in userOptions" |
||||
:key="item.id" |
||||
:label="item.nickname" |
||||
:value="item.id" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item label="备注" prop="remark"> |
||||
<el-input |
||||
type="textarea" |
||||
v-model="formData.remark" |
||||
placeholder="请输入备注" |
||||
:autosize="{ minRows: 4, maxRows: 8 }" |
||||
/> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> |
||||
<el-button @click="dialogVisible = false">取 消</el-button> |
||||
</template> |
||||
</Dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import * as wxgroupApi from '@/api/clue/clueRemark' |
||||
import { getSimpleUserList as getUserOption } from '@/api/system/user' |
||||
import { getWxGroupList } from '@/api/okr/meeting' |
||||
|
||||
const { t } = useI18n() // 国际化 |
||||
const message = useMessage() // 消息弹窗 |
||||
|
||||
const searchForm = ref({ |
||||
groupName: '', |
||||
pageSize: 20, |
||||
pageNo: 1 |
||||
}) |
||||
|
||||
const total = ref(0) |
||||
const tableList = ref([]) |
||||
const loading = ref(false) |
||||
|
||||
function handleQuery() { |
||||
searchForm.value.pageNo = 1 |
||||
getList() |
||||
} |
||||
function resetQuery() { |
||||
searchForm.value = { |
||||
groupName: '', |
||||
pageSize: 20, |
||||
pageNo: 1 |
||||
} |
||||
getList() |
||||
} |
||||
|
||||
async function getList() { |
||||
loading.value = true |
||||
try { |
||||
const data = await wxgroupApi.getWxGroupPage(searchForm.value) |
||||
tableList.value = data.list |
||||
total.value = data.total |
||||
} finally { |
||||
loading.value = false |
||||
} |
||||
} |
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示 |
||||
const dialogTitle = ref('') // 弹窗的标题 |
||||
const dialogType = ref('create') // 弹窗的类型 create新增 update修改 |
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 |
||||
const formData = ref({ |
||||
groupId: '', |
||||
areaUser: '', |
||||
remark: '' |
||||
}) |
||||
const formRules = reactive({ |
||||
groupId: [{ required: true, message: '微信群不能为空', trigger: 'change' }], |
||||
areaUser: [{ required: true, message: '区域负责人不能为空', trigger: 'change' }] |
||||
}) |
||||
const formRef = ref(null) // 表单的ref |
||||
const groupOptions = ref([]) // 微信群选项 |
||||
const userOptions = ref([]) // 用户选项 |
||||
|
||||
async function openForm(type, row) { |
||||
dialogType.value = type |
||||
dialogTitle.value = type === 'create' ? '新增报备群' : '修改报备群' |
||||
dialogVisible.value = true |
||||
resetForm() |
||||
// 修改时,设置数据 |
||||
if (row) { |
||||
formLoading.value = true |
||||
try { |
||||
formData.value = { ...row } |
||||
} finally { |
||||
formLoading.value = false |
||||
} |
||||
} |
||||
} |
||||
|
||||
function resetForm() { |
||||
formData.value = { |
||||
groupId: '', |
||||
areaUser: '', |
||||
remark: '' |
||||
} |
||||
if (formRef.value) { |
||||
formRef.value.clearValidate() |
||||
} |
||||
} |
||||
|
||||
async function handleDelete(id) { |
||||
try { |
||||
// 删除的二次确认 |
||||
await message.delConfirm() |
||||
// 发起删除 |
||||
await wxgroupApi.deleteWxGroup(id) |
||||
message.success(t('common.delSuccess')) |
||||
// 刷新列表 |
||||
await getList() |
||||
} catch {} |
||||
} |
||||
|
||||
function submitForm() { |
||||
if (!formRef.value) return |
||||
formRef.value.validate(async (valid) => { |
||||
if (valid) { |
||||
formLoading.value = true |
||||
formData.value.groupName = groupOptions.value.find( |
||||
(item) => item.wxGroupId == formData.value.groupId |
||||
)?.wxGroupName |
||||
try { |
||||
if (dialogType.value === 'create') { |
||||
await wxgroupApi.createWxGroup(formData.value) |
||||
message.success(t('common.addSuccess')) |
||||
} else { |
||||
await wxgroupApi.updateWxGroup(formData.value) |
||||
message.success(t('common.updateSuccess')) |
||||
} |
||||
dialogVisible.value = false |
||||
getList() |
||||
} finally { |
||||
formLoading.value = false |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function getOptions() { |
||||
getWxGroupList().then((resp) => { |
||||
groupOptions.value = resp || [] |
||||
}) |
||||
// 获取用户选项 |
||||
getUserOption().then((data) => { |
||||
userOptions.value = data |
||||
}) |
||||
} |
||||
|
||||
onMounted(() => { |
||||
handleQuery() |
||||
|
||||
getOptions() |
||||
}) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
||||
Loading…
Reference in new issue