feat: 新增核心企业管理(查询/新增/修改/批量删除)
parent
b647a8abf1
commit
e02c264381
|
|
@ -3,6 +3,7 @@ import cors from 'cors'
|
|||
import cookieParser from 'cookie-parser'
|
||||
import authRoutes from './routes/auth.js'
|
||||
import systemRoutes from './routes/system.js'
|
||||
import baseConfigRoutes from './routes/baseConfig.js'
|
||||
|
||||
const app = express()
|
||||
app.use(cors({ origin: 'http://localhost:5173', credentials: true }))
|
||||
|
|
@ -11,6 +12,7 @@ app.use(cookieParser())
|
|||
|
||||
app.use('/auth', authRoutes)
|
||||
app.use('/system', systemRoutes)
|
||||
app.use('/base-config', baseConfigRoutes)
|
||||
|
||||
const PORT = 8888
|
||||
app.listen(PORT, () => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
import express from 'express'
|
||||
import { orgs } from '../data/orgs.js'
|
||||
import { channels, nextChannelId } from '../data/channels.js'
|
||||
import { requireAuth } from '../middleware/requireAuth.js'
|
||||
|
||||
const router = express.Router()
|
||||
router.use(requireAuth)
|
||||
|
||||
function orgName(orgId) {
|
||||
return orgs.find((o) => o.id === orgId)?.name || ''
|
||||
}
|
||||
|
||||
function nowStr() {
|
||||
return new Date().toISOString().slice(0, 19).replace('T', ' ')
|
||||
}
|
||||
|
||||
// ---------------- 核心企业管理 ----------------
|
||||
|
||||
router.get('/channel/list', (req, res) => {
|
||||
const { orgId, channelCode, channelName, page = 1, pageSize = 10 } = req.query || {}
|
||||
let list = channels
|
||||
if (orgId) list = list.filter((c) => c.orgId === orgId)
|
||||
if (channelCode) list = list.filter((c) => c.channelCode.includes(channelCode))
|
||||
if (channelName) list = list.filter((c) => c.name.includes(channelName))
|
||||
|
||||
const total = list.length
|
||||
const start = (Number(page) - 1) * Number(pageSize)
|
||||
const pageList = list.slice(start, start + Number(pageSize)).map((c) => ({
|
||||
id: c.id,
|
||||
name: c.name,
|
||||
channelCode: c.channelCode,
|
||||
appCode: c.appCode,
|
||||
motherAccountBank: c.motherAccountBank,
|
||||
orgId: c.orgId,
|
||||
orgName: orgName(c.orgId),
|
||||
createdAt: c.createdAt
|
||||
}))
|
||||
res.json({ code: 200, msg: 'ok', data: { list: pageList, total } })
|
||||
})
|
||||
|
||||
router.post('/channel', (req, res) => {
|
||||
const { name, channelCode, appCode, motherAccountBank, orgId } = req.body || {}
|
||||
if (!name) return res.json({ code: 40025, msg: '请输入渠道名称', data: null })
|
||||
if (!channelCode) return res.json({ code: 40026, msg: '请输入渠道编号', data: null })
|
||||
if (!appCode) return res.json({ code: 40027, msg: '请输入应用编号', data: null })
|
||||
if (!motherAccountBank) return res.json({ code: 40028, msg: '请输入母户开户行', data: null })
|
||||
if (!orgId || !orgs.some((o) => o.id === orgId)) {
|
||||
return res.json({ code: 40029, msg: '请选择有效的所属机构', data: null })
|
||||
}
|
||||
|
||||
const channel = {
|
||||
id: nextChannelId(),
|
||||
name,
|
||||
channelCode,
|
||||
appCode,
|
||||
motherAccountBank,
|
||||
orgId,
|
||||
createdAt: nowStr()
|
||||
}
|
||||
channels.push(channel)
|
||||
res.json({ code: 200, msg: 'ok', data: channel })
|
||||
})
|
||||
|
||||
router.put('/channel/:id', (req, res) => {
|
||||
const { id } = req.params
|
||||
const { name, channelCode, appCode, motherAccountBank, orgId } = req.body || {}
|
||||
const channel = channels.find((c) => c.id === id)
|
||||
if (!channel) return res.json({ code: 40404, msg: '核心企业不存在', data: null })
|
||||
if (!name) return res.json({ code: 40025, msg: '请输入渠道名称', data: null })
|
||||
if (!channelCode) return res.json({ code: 40026, msg: '请输入渠道编号', data: null })
|
||||
if (!appCode) return res.json({ code: 40027, msg: '请输入应用编号', data: null })
|
||||
if (!motherAccountBank) return res.json({ code: 40028, msg: '请输入母户开户行', data: null })
|
||||
if (!orgId || !orgs.some((o) => o.id === orgId)) {
|
||||
return res.json({ code: 40029, msg: '请选择有效的所属机构', data: null })
|
||||
}
|
||||
|
||||
channel.name = name
|
||||
channel.channelCode = channelCode
|
||||
channel.appCode = appCode
|
||||
channel.motherAccountBank = motherAccountBank
|
||||
channel.orgId = orgId
|
||||
res.json({ code: 200, msg: 'ok', data: channel })
|
||||
})
|
||||
|
||||
router.delete('/channel/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 channel = channels.find((c) => c.id === id)
|
||||
if (!channel) {
|
||||
failed.push({ id, name: id, reason: '核心企业不存在' })
|
||||
return
|
||||
}
|
||||
successIds.push(id)
|
||||
})
|
||||
successIds.forEach((id) => {
|
||||
const index = channels.findIndex((c) => c.id === id)
|
||||
if (index !== -1) channels.splice(index, 1)
|
||||
})
|
||||
res.json({ code: 200, msg: 'ok', data: { successIds, failed } })
|
||||
})
|
||||
|
||||
export default router
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import request from './request'
|
||||
|
||||
// ---------------- 核心企业管理 ----------------
|
||||
export const fetchChannelListApi = (params) => request.get('/base-config/channel/list', { params })
|
||||
export const createChannelApi = (data) => request.post('/base-config/channel', 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 } })
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<div class="channel-list-page">
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
v-model:selected-row-keys="selectedRowKeys"
|
||||
:columns="columns"
|
||||
:fetch-data="loadChannelList"
|
||||
:initial-search="{ orgId: undefined, channelCode: '', channelName: '' }"
|
||||
>
|
||||
<template #search="{ form }">
|
||||
<a-form-item label="所属机构">
|
||||
<OrgTreeSelect v-model="form.orgId" placeholder="请选择所属机构" style="width: 200px" />
|
||||
</a-form-item>
|
||||
<a-form-item label="渠道编号">
|
||||
<a-input v-model:value="form.channelCode" placeholder="请输入渠道编号" allow-clear style="width: 160px" />
|
||||
</a-form-item>
|
||||
<a-form-item label="渠道名称">
|
||||
<a-input v-model:value="form.channelName" placeholder="请输入渠道名称" allow-clear style="width: 160px" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<a-space>
|
||||
<a-button v-permission="'channel:add'" type="primary" @click="openCreateModal">
|
||||
<PlusOutlined /> 新增
|
||||
</a-button>
|
||||
<a-popconfirm
|
||||
title="确定删除选中的核心企业吗?"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
@confirm="handleBatchDelete"
|
||||
>
|
||||
<a-button v-permission="'channel: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="'channel: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="name">
|
||||
<a-input v-model:value="form.name" placeholder="请输入渠道名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="渠道编号" name="channelCode">
|
||||
<a-input v-model:value="form.channelCode" placeholder="请输入渠道编号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="应用编号" name="appCode">
|
||||
<a-input v-model:value="form.appCode" placeholder="请输入应用编号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="母户开户行" name="motherAccountBank">
|
||||
<a-input v-model:value="form.motherAccountBank" placeholder="请输入母户开户行" />
|
||||
</a-form-item>
|
||||
<a-form-item label="所属机构" name="orgId">
|
||||
<OrgTreeSelect v-model="form.orgId" 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 OrgTreeSelect from '@/components/OrgTreeSelect.vue'
|
||||
import { fetchChannelListApi, createChannelApi, updateChannelApi, batchDeleteChannelApi } from '@/api/baseConfig'
|
||||
import { showBatchDeleteResult } from '@/utils/batchDeleteResult'
|
||||
|
||||
const columns = [
|
||||
{ title: '序号', dataIndex: 'index', width: 60 },
|
||||
{ title: '渠道名称', dataIndex: 'name' },
|
||||
{ title: '渠道编号', dataIndex: 'channelCode' },
|
||||
{ title: '应用编号', dataIndex: 'appCode' },
|
||||
{ title: '母户开户行', dataIndex: 'motherAccountBank' },
|
||||
{ title: '所属机构', dataIndex: 'orgName' },
|
||||
{ title: '创建时间', dataIndex: 'createdAt' },
|
||||
{ title: '操作', dataIndex: 'action', width: 100 }
|
||||
]
|
||||
|
||||
const proTableRef = ref(null)
|
||||
const selectedRowKeys = ref([])
|
||||
|
||||
async function loadChannelList(params) {
|
||||
const res = await fetchChannelListApi(params)
|
||||
if (res.data.code === 200) return res.data.data
|
||||
return { list: [], total: 0 }
|
||||
}
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const res = await batchDeleteChannelApi(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: '', name: '', channelCode: '', appCode: '', motherAccountBank: '', orgId: undefined })
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入渠道名称' }],
|
||||
channelCode: [{ required: true, message: '请输入渠道编号' }],
|
||||
appCode: [{ required: true, message: '请输入应用编号' }],
|
||||
motherAccountBank: [{ required: true, message: '请输入母户开户行' }],
|
||||
orgId: [{ required: true, message: '请选择所属机构' }]
|
||||
}
|
||||
|
||||
function openCreateModal() {
|
||||
modalMode.value = 'create'
|
||||
form.id = ''
|
||||
form.name = ''
|
||||
form.channelCode = ''
|
||||
form.appCode = ''
|
||||
form.motherAccountBank = ''
|
||||
form.orgId = undefined
|
||||
modalOpen.value = true
|
||||
}
|
||||
|
||||
function openEditModal(record) {
|
||||
modalMode.value = 'edit'
|
||||
form.id = record.id
|
||||
form.name = record.name
|
||||
form.channelCode = record.channelCode
|
||||
form.appCode = record.appCode
|
||||
form.motherAccountBank = record.motherAccountBank
|
||||
form.orgId = record.orgId
|
||||
modalOpen.value = true
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
submitting.value = true
|
||||
try {
|
||||
const payload = {
|
||||
name: form.name,
|
||||
channelCode: form.channelCode,
|
||||
appCode: form.appCode,
|
||||
motherAccountBank: form.motherAccountBank,
|
||||
orgId: form.orgId
|
||||
}
|
||||
const res =
|
||||
modalMode.value === 'create' ? await createChannelApi(payload) : await updateChannelApi(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