feat: 新增客户经理管理(查询/新增/修改/批量删除)
parent
e02c264381
commit
26792e73f0
|
|
@ -1,6 +1,7 @@
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { orgs } from '../data/orgs.js'
|
import { orgs } from '../data/orgs.js'
|
||||||
import { channels, nextChannelId } from '../data/channels.js'
|
import { channels, nextChannelId } from '../data/channels.js'
|
||||||
|
import { managers, nextManagerId } from '../data/managers.js'
|
||||||
import { requireAuth } from '../middleware/requireAuth.js'
|
import { requireAuth } from '../middleware/requireAuth.js'
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
@ -104,4 +105,84 @@ router.delete('/channel/batch', (req, res) => {
|
||||||
res.json({ code: 200, msg: 'ok', data: { successIds, failed } })
|
res.json({ code: 200, msg: 'ok', data: { successIds, failed } })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ---------------- 客户经理管理 ----------------
|
||||||
|
|
||||||
|
router.get('/manager/list', (req, res) => {
|
||||||
|
const { orgCode, orgName: orgNameQuery, name, jobNumber, page = 1, pageSize = 10 } = req.query || {}
|
||||||
|
let list = managers
|
||||||
|
if (orgCode) list = list.filter((m) => m.orgCode.includes(orgCode))
|
||||||
|
if (orgNameQuery) list = list.filter((m) => m.orgName.includes(orgNameQuery))
|
||||||
|
if (name) list = list.filter((m) => m.name.includes(name))
|
||||||
|
if (jobNumber) list = list.filter((m) => m.jobNumber.includes(jobNumber))
|
||||||
|
|
||||||
|
const total = list.length
|
||||||
|
const start = (Number(page) - 1) * Number(pageSize)
|
||||||
|
const pageList = list.slice(start, start + Number(pageSize))
|
||||||
|
res.json({ code: 200, msg: 'ok', data: { list: pageList, total } })
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post('/manager', (req, res) => {
|
||||||
|
const { orgCode, orgName: managerOrgName, jobNumber, name } = req.body || {}
|
||||||
|
if (!orgCode) return res.json({ code: 40030, msg: '请输入机构号', data: null })
|
||||||
|
if (!managerOrgName) return res.json({ code: 40031, msg: '请输入机构名称', data: null })
|
||||||
|
if (!jobNumber) return res.json({ code: 40032, msg: '请输入工号', data: null })
|
||||||
|
if (!name) return res.json({ code: 40033, msg: '请输入客户经理姓名', data: null })
|
||||||
|
if (managers.some((m) => m.jobNumber === jobNumber)) {
|
||||||
|
return res.json({ code: 40034, msg: '工号已存在', data: null })
|
||||||
|
}
|
||||||
|
|
||||||
|
const manager = {
|
||||||
|
id: nextManagerId(),
|
||||||
|
orgCode,
|
||||||
|
orgName: managerOrgName,
|
||||||
|
jobNumber,
|
||||||
|
name,
|
||||||
|
createdAt: nowStr()
|
||||||
|
}
|
||||||
|
managers.push(manager)
|
||||||
|
res.json({ code: 200, msg: 'ok', data: manager })
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put('/manager/:id', (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
const { orgCode, orgName: managerOrgName, jobNumber, name } = req.body || {}
|
||||||
|
const manager = managers.find((m) => m.id === id)
|
||||||
|
if (!manager) return res.json({ code: 40404, msg: '客户经理不存在', data: null })
|
||||||
|
if (!orgCode) return res.json({ code: 40030, msg: '请输入机构号', data: null })
|
||||||
|
if (!managerOrgName) return res.json({ code: 40031, msg: '请输入机构名称', data: null })
|
||||||
|
if (!jobNumber) return res.json({ code: 40032, msg: '请输入工号', data: null })
|
||||||
|
if (!name) return res.json({ code: 40033, msg: '请输入客户经理姓名', data: null })
|
||||||
|
if (managers.some((m) => m.jobNumber === jobNumber && m.id !== id)) {
|
||||||
|
return res.json({ code: 40034, msg: '工号已存在', data: null })
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.orgCode = orgCode
|
||||||
|
manager.orgName = managerOrgName
|
||||||
|
manager.jobNumber = jobNumber
|
||||||
|
manager.name = name
|
||||||
|
res.json({ code: 200, msg: 'ok', data: manager })
|
||||||
|
})
|
||||||
|
|
||||||
|
router.delete('/manager/batch', (req, res) => {
|
||||||
|
const { ids } = req.body || {}
|
||||||
|
if (!Array.isArray(ids) || ids.length === 0) {
|
||||||
|
return res.json({ code: 40024, msg: '请选择要删除的客户经理', data: null })
|
||||||
|
}
|
||||||
|
const successIds = []
|
||||||
|
const failed = []
|
||||||
|
ids.forEach((id) => {
|
||||||
|
const manager = managers.find((m) => m.id === id)
|
||||||
|
if (!manager) {
|
||||||
|
failed.push({ id, name: id, reason: '客户经理不存在' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
successIds.push(id)
|
||||||
|
})
|
||||||
|
successIds.forEach((id) => {
|
||||||
|
const index = managers.findIndex((m) => m.id === id)
|
||||||
|
if (index !== -1) managers.splice(index, 1)
|
||||||
|
})
|
||||||
|
res.json({ code: 200, msg: 'ok', data: { successIds, failed } })
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,9 @@ export const fetchChannelListApi = (params) => request.get('/base-config/channel
|
||||||
export const createChannelApi = (data) => request.post('/base-config/channel', data)
|
export const createChannelApi = (data) => request.post('/base-config/channel', data)
|
||||||
export const updateChannelApi = (id, data) => request.put(`/base-config/channel/${id}`, data)
|
export const updateChannelApi = (id, data) => request.put(`/base-config/channel/${id}`, data)
|
||||||
export const batchDeleteChannelApi = (ids) => request.delete('/base-config/channel/batch', { data: { ids } })
|
export const batchDeleteChannelApi = (ids) => request.delete('/base-config/channel/batch', { data: { ids } })
|
||||||
|
|
||||||
|
// ---------------- 客户经理管理 ----------------
|
||||||
|
export const fetchManagerListApi = (params) => request.get('/base-config/manager/list', { params })
|
||||||
|
export const createManagerApi = (data) => request.post('/base-config/manager', data)
|
||||||
|
export const updateManagerApi = (id, data) => request.put(`/base-config/manager/${id}`, data)
|
||||||
|
export const batchDeleteManagerApi = (ids) => request.delete('/base-config/manager/batch', { data: { ids } })
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
<template>
|
||||||
|
<div class="manager-list-page">
|
||||||
|
<ProTable
|
||||||
|
ref="proTableRef"
|
||||||
|
v-model:selected-row-keys="selectedRowKeys"
|
||||||
|
:columns="columns"
|
||||||
|
:fetch-data="loadManagerList"
|
||||||
|
:initial-search="{ orgCode: '', orgName: '', name: '', jobNumber: '' }"
|
||||||
|
@search="handleSearchResult"
|
||||||
|
>
|
||||||
|
<template #search="{ form }">
|
||||||
|
<a-form-item label="机构号">
|
||||||
|
<a-input v-model:value="form.orgCode" placeholder="请输入机构号" allow-clear style="width: 140px" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="机构名称">
|
||||||
|
<a-input v-model:value="form.orgName" placeholder="请输入机构名称" allow-clear style="width: 160px" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="客户经理姓名">
|
||||||
|
<a-input v-model:value="form.name" placeholder="请输入客户经理姓名" allow-clear style="width: 160px" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="工号">
|
||||||
|
<a-input v-model:value="form.jobNumber" placeholder="请输入工号" allow-clear style="width: 140px" />
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #actions>
|
||||||
|
<a-space>
|
||||||
|
<a-button v-permission="'manager:add'" type="primary" @click="openCreateModal">
|
||||||
|
<PlusOutlined /> 新增
|
||||||
|
</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定删除选中的客户经理吗?"
|
||||||
|
:disabled="selectedRowKeys.length === 0"
|
||||||
|
@confirm="handleBatchDelete"
|
||||||
|
>
|
||||||
|
<a-button v-permission="'manager:delete'" danger :disabled="selectedRowKeys.length === 0">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #bodyCell="{ column, record, index }">
|
||||||
|
<template v-if="column.dataIndex === 'index'">{{ index + 1 }}</template>
|
||||||
|
<template v-else-if="column.dataIndex === 'action'">
|
||||||
|
<a v-permission="'manager:edit'" @click="openEditModal(record)">修改</a>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ProTable>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalOpen"
|
||||||
|
:title="modalMode === 'create' ? '新增客户经理' : '修改客户经理'"
|
||||||
|
:confirm-loading="submitting"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form ref="formRef" layout="vertical" :model="form" :rules="rules">
|
||||||
|
<a-form-item label="机构号" name="orgCode">
|
||||||
|
<a-input v-model:value="form.orgCode" placeholder="请输入机构号" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="机构名称" name="orgName">
|
||||||
|
<a-input v-model:value="form.orgName" placeholder="请输入机构名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="工号" name="jobNumber">
|
||||||
|
<a-input v-model:value="form.jobNumber" placeholder="请输入工号" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="客户经理姓名" name="name">
|
||||||
|
<a-input v-model:value="form.name" placeholder="请输入客户经理姓名" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
|
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||||
|
import ProTable from '@/components/ProTable.vue'
|
||||||
|
import {
|
||||||
|
fetchManagerListApi,
|
||||||
|
createManagerApi,
|
||||||
|
updateManagerApi,
|
||||||
|
batchDeleteManagerApi
|
||||||
|
} from '@/api/baseConfig'
|
||||||
|
import { showBatchDeleteResult } from '@/utils/batchDeleteResult'
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: '序号', dataIndex: 'index', width: 60 },
|
||||||
|
{ title: '机构号', dataIndex: 'orgCode' },
|
||||||
|
{ title: '机构名称', dataIndex: 'orgName' },
|
||||||
|
{ title: '工号', dataIndex: 'jobNumber' },
|
||||||
|
{ title: '客户经理姓名', dataIndex: 'name' },
|
||||||
|
{ title: '操作', dataIndex: 'action', width: 100 }
|
||||||
|
]
|
||||||
|
|
||||||
|
const proTableRef = ref(null)
|
||||||
|
const selectedRowKeys = ref([])
|
||||||
|
const lastTotal = ref(0)
|
||||||
|
|
||||||
|
async function loadManagerList(params) {
|
||||||
|
const res = await fetchManagerListApi(params)
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
lastTotal.value = res.data.data.total
|
||||||
|
return res.data.data
|
||||||
|
}
|
||||||
|
lastTotal.value = 0
|
||||||
|
return { list: [], total: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSearchResult() {
|
||||||
|
if (lastTotal.value === 0) {
|
||||||
|
message.warning('客户经理不存在')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleBatchDelete() {
|
||||||
|
const res = await batchDeleteManagerApi(selectedRowKeys.value)
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
showBatchDeleteResult(res.data.data)
|
||||||
|
proTableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- 新增/修改弹窗 ----------------
|
||||||
|
const modalOpen = ref(false)
|
||||||
|
const modalMode = ref('create')
|
||||||
|
const submitting = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const form = reactive({ id: '', orgCode: '', orgName: '', jobNumber: '', name: '' })
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
orgCode: [{ required: true, message: '请输入机构号' }],
|
||||||
|
orgName: [{ required: true, message: '请输入机构名称' }],
|
||||||
|
jobNumber: [{ required: true, message: '请输入工号' }],
|
||||||
|
name: [{ required: true, message: '请输入客户经理姓名' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCreateModal() {
|
||||||
|
modalMode.value = 'create'
|
||||||
|
form.id = ''
|
||||||
|
form.orgCode = ''
|
||||||
|
form.orgName = ''
|
||||||
|
form.jobNumber = ''
|
||||||
|
form.name = ''
|
||||||
|
modalOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEditModal(record) {
|
||||||
|
modalMode.value = 'edit'
|
||||||
|
form.id = record.id
|
||||||
|
form.orgCode = record.orgCode
|
||||||
|
form.orgName = record.orgName
|
||||||
|
form.jobNumber = record.jobNumber
|
||||||
|
form.name = record.name
|
||||||
|
modalOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
await formRef.value.validate()
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
orgCode: form.orgCode,
|
||||||
|
orgName: form.orgName,
|
||||||
|
jobNumber: form.jobNumber,
|
||||||
|
name: form.name
|
||||||
|
}
|
||||||
|
const res =
|
||||||
|
modalMode.value === 'create' ? await createManagerApi(payload) : await updateManagerApi(form.id, payload)
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
message.success(modalMode.value === 'create' ? '新增成功' : '修改成功')
|
||||||
|
modalOpen.value = false
|
||||||
|
proTableRef.value.reload()
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue