增加配送员列表

This commit is contained in:
aaron 2025-02-24 00:13:21 +08:00
parent af758aeeba
commit a34e74cbff
4 changed files with 495 additions and 119 deletions

View File

@ -25,6 +25,9 @@
<a-menu-item key="user-list">
<router-link to="/user/list">用户列表</router-link>
</a-menu-item>
<a-menu-item key="deliveryman-list">
<router-link to="/deliveryman/list">配送员列表</router-link>
</a-menu-item>
</a-sub-menu>
<a-sub-menu key="order">
@ -202,6 +205,12 @@ export default defineComponent({
}
]
},
{
key: 'deliveryman',
icon: () => h(UserOutlined),
title: '配送员管理',
path: '/deliveryman/list'
},
{
key: 'order',
icon: () => h(ShoppingOutlined),

View File

@ -22,6 +22,12 @@ const routes = [
component: () => import('../views/user/UserList.vue'),
meta: { title: '用户列表' }
},
{
path: '/deliveryman/list',
name: 'DeliverymanList',
component: () => import('../views/deliveryman/List.vue'),
meta: { title: '配送员列表' }
},
{
path: '/community/list',
name: 'CommunityList',

View File

@ -0,0 +1,476 @@
<template>
<page-container>
<div class="deliveryman-list">
<div class="table-header">
<h1>配送员列表</h1>
</div>
<!-- 添加筛选区域 -->
<div class="table-filter">
<a-form layout="inline">
<a-form-item label="手机号">
<a-input
v-model:value="filterForm.phone"
placeholder="请输入手机号"
style="width: 200px"
allowClear
@change="handleFilterChange"
/>
</a-form-item>
<a-form-item label="所属小区">
<a-select
v-model:value="filterForm.community_id"
style="width: 200px"
placeholder="请选择小区"
allowClear
:loading="communityLoading"
@change="handleFilterChange"
>
<a-select-option
v-for="item in communityOptions"
:key="item.id"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" @click="handleSearch">
查询
</a-button>
<a-button @click="handleReset">
重置
</a-button>
</a-space>
</a-form-item>
</a-form>
</div>
<a-table
:columns="columns"
:data-source="tableData"
:pagination="pagination"
:loading="loading"
@change="handleTableChange"
row-key="userid"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'phone'">
{{ formatPhone(record.phone) }}
</template>
<template v-if="column.key === 'community_name'">
<a-space>
<template v-if="record.community_name">
<a-tag color="green">{{ record.community_name }}</a-tag>
</template>
<template v-else>
<a-tag color="default">未设置</a-tag>
</template>
</a-space>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="handleEditCommunity(record)">
{{ record.community_name ? '修改小区' : '设置小区' }}
</a-button>
<a-button type="link" @click="handleEditCommission(record)">
设置分佣比例
</a-button>
</a-space>
</template>
</template>
</a-table>
<!-- 小区选择模态框 -->
<a-modal
v-model:visible="communityModalVisible"
:title="selectedCommunityId ? '修改所属小区' : '设置所属小区'"
:confirm-loading="communitySaving"
@ok="handleCommunitySave"
@cancel="handleCommunityCancel"
>
<a-form layout="vertical">
<a-form-item
label="选择小区"
:validate-status="selectedCommunityId === undefined ? 'error' : ''"
:help="selectedCommunityId === undefined ? '请选择小区' : ''"
>
<a-select
v-model:value="selectedCommunityId"
placeholder="请选择小区"
:loading="communityLoading"
:options="communityOptions.map(item => ({
value: item.id,
label: item.name
}))"
style="width: 100%"
allowClear
/>
</a-form-item>
</a-form>
</a-modal>
<!-- 分佣比例设置模态框 -->
<a-modal
v-model:visible="commissionModalVisible"
title="设置分佣比例"
:confirm-loading="commissionSaving"
@ok="handleCommissionSave"
@cancel="handleCommissionCancel"
>
<a-form layout="vertical">
<a-form-item
label="分佣比例(%"
required
:rules="[
{ required: true, message: '请输入分佣比例' },
{ type: 'number', min: 0, max: 100, message: '分佣比例必须在0-100之间' }
]"
>
<a-input-number
v-model:value="commissionRate"
:min="0"
:max="100"
style="width: 200px"
placeholder="请输入分佣比例"
addon-after="%"
/>
<div class="commission-tip">请输入0-100之间的整数</div>
</a-form-item>
</a-form>
</a-modal>
</div>
</page-container>
</template>
<script>
import { defineComponent, ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import request from '@/utils/request'
import PageContainer from '@/components/PageContainer.vue'
export default defineComponent({
name: 'DeliverymanList',
components: {
PageContainer
},
setup() {
const loading = ref(false)
const tableData = ref([])
const pagination = ref({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total} 条记录`
})
const columns = [
{
title: 'ID',
dataIndex: 'userid',
key: 'userid',
width: 80,
},
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname',
width: 120,
},
{
title: '手机号',
dataIndex: 'phone',
key: 'phone',
width: 120,
},
{
title: '所属小区',
dataIndex: 'community_name',
key: 'community_name',
width: 200,
},
{
title: '分佣比例(%',
dataIndex: 'delivery_commission_rate',
key: 'commission',
width: 100,
align: 'right',
render: (text) => text ? `${text}%` : '-'
},
{
title: '操作',
key: 'action',
width: 200,
fixed: 'right'
}
]
//
const formatPhone = (phone) => {
if (!phone) return ''
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
//
const filterForm = ref({
phone: undefined,
community_id: undefined
})
//
const fetchData = async () => {
try {
loading.value = true
const params = {
skip: (pagination.value.current - 1) * pagination.value.pageSize,
limit: pagination.value.pageSize,
role: 'deliveryman',
phone: filterForm.value.phone,
community_id: filterForm.value.community_id
}
const res = await request.get('/api/user/list', { params })
if (res.code === 200) {
tableData.value = res.data.items
pagination.value.total = res.data.total
} else {
message.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('获取配送员列表失败:', error)
message.error('获取数据失败')
} finally {
loading.value = false
}
}
//
const handleTableChange = (pag) => {
pagination.value.current = pag.current
pagination.value.pageSize = pag.pageSize
fetchData()
}
//
const currentUserId = ref(null)
const communityModalVisible = ref(false)
const communitySaving = ref(false)
const communityLoading = ref(false)
const selectedCommunityId = ref(undefined)
const communityOptions = ref([])
//
const fetchCommunityList = async () => {
try {
communityLoading.value = true
const res = await request.get('/api/community')
if (res.code === 200 && res.data) {
communityOptions.value = res.data.items || []
}
} catch (error) {
console.error('获取小区列表失败:', error)
message.error('获取小区列表失败')
} finally {
communityLoading.value = false
}
}
//
const handleEditCommunity = (record) => {
currentUserId.value = record.userid
selectedCommunityId.value = record.community_id
communityModalVisible.value = true
if (communityOptions.value.length === 0) {
fetchCommunityList()
}
}
//
const handleCommunitySave = async () => {
try {
communitySaving.value = true
await request.put('/api/user/community', {
user_id: currentUserId.value,
community_id: selectedCommunityId.value
})
message.success('修改成功')
communityModalVisible.value = false
fetchData()
} catch (error) {
console.error('修改所属小区失败:', error)
message.error('修改失败')
} finally {
communitySaving.value = false
}
}
//
const handleCommunityCancel = () => {
communityModalVisible.value = false
selectedCommunityId.value = undefined
currentUserId.value = null
}
//
const commissionModalVisible = ref(false)
const commissionSaving = ref(false)
const commissionRate = ref(0)
//
const handleEditCommission = (record) => {
currentUserId.value = record.userid
commissionRate.value = record.delivery_commission_rate || 0
commissionModalVisible.value = true
}
//
const handleCommissionSave = async () => {
try {
commissionSaving.value = true
await request.put(`/api/user/delivery-commission-rate`, {
user_id : currentUserId.value,
delivery_commission_rate: commissionRate.value
})
message.success('设置成功')
commissionModalVisible.value = false
fetchData()
} catch (error) {
console.error('设置分佣比例失败:', error)
message.error('设置失败')
} finally {
commissionSaving.value = false
}
}
//
const handleCommissionCancel = () => {
commissionModalVisible.value = false
commissionRate.value = 0
currentUserId.value = null
}
//
const handleFilterChange = () => {
pagination.value.current = 1 //
}
//
const handleSearch = () => {
pagination.value.current = 1
fetchData()
}
//
const handleReset = () => {
filterForm.value = {
phone: undefined,
community_id: undefined
}
pagination.value.current = 1
fetchData()
}
onMounted(() => {
fetchData()
fetchCommunityList()
})
return {
loading,
columns,
tableData,
pagination,
handleTableChange,
formatPhone,
communityModalVisible,
communitySaving,
communityLoading,
selectedCommunityId,
communityOptions,
handleEditCommunity,
handleCommunitySave,
handleCommunityCancel,
commissionModalVisible,
commissionSaving,
commissionRate,
handleEditCommission,
handleCommissionSave,
handleCommissionCancel,
filterForm,
handleFilterChange,
handleSearch,
handleReset
}
}
})
</script>
<style scoped>
.deliveryman-list {
padding: 24px;
background: #fff;
}
.table-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.table-header h1 {
margin: 0;
}
.table-filter {
margin-bottom: 16px;
padding: 16px 24px;
background: #fff;
border-radius: 2px;
}
:deep(.ant-form-item) {
margin-bottom: 0;
margin-right: 16px;
}
:deep(.ant-form-item:last-child) {
margin-right: 0;
}
:deep(.ant-select) {
width: 100% !important;
}
:deep(.ant-input) {
width: 200px !important;
}
:deep(.ant-table-content) {
overflow-x: auto;
}
:deep(.ant-tag) {
min-width: 80px;
text-align: center;
}
.commission-tip {
color: rgba(0, 0, 0, 0.45);
font-size: 12px;
margin-top: 4px;
}
:deep(.ant-input-number-group-addon) {
padding: 0 8px;
}
</style>

View File

@ -85,19 +85,6 @@
</a-button>
</a-space>
</template>
<template v-if="column.key === 'community_name'">
<a-space>
<template v-if="record.community_name">
<a-tag color="green">{{ record.community_name }}</a-tag>
</template>
<template v-else>
<a-tag color="default">未设置</a-tag>
</template>
<a-button type="link" size="small" @click="handleEditCommunity(record)">
{{ record.community_name ? '修改' : '设置' }}
</a-button>
</a-space>
</template>
</template>
</a-table>
</div>
@ -148,35 +135,6 @@
</a-space>
</template>
</a-modal>
<!-- 添加小区选择模态框 -->
<a-modal
v-model:visible="communityModalVisible"
:title="selectedCommunityId ? '修改所属小区' : '设置所属小区'"
:confirm-loading="communitySaving"
@ok="handleCommunitySave"
@cancel="handleCommunityCancel"
>
<a-form layout="vertical">
<a-form-item
label="选择小区"
:validate-status="selectedCommunityId === undefined ? 'error' : ''"
:help="selectedCommunityId === undefined ? '请选择小区' : ''"
>
<a-select
v-model:value="selectedCommunityId"
placeholder="请选择小区"
:loading="communityLoading"
:options="communityOptions.map(item => ({
value: item.id,
label: item.name
}))"
style="width: 100%"
allowClear
/>
</a-form-item>
</a-form>
</a-modal>
</page-container>
</template>
@ -245,12 +203,6 @@ export default defineComponent({
key: 'roles',
width: 200,
},
{
title: '归属小区',
dataIndex: 'community_name',
key: 'community_name',
width: 250,
},
{
title: '创建时间',
dataIndex: 'create_time',
@ -352,13 +304,6 @@ export default defineComponent({
const newPassword = ref('')
const passwordInput = ref(null)
//
const communityModalVisible = ref(false)
const communitySaving = ref(false)
const communityLoading = ref(false)
const selectedCommunityId = ref(undefined)
const communityOptions = ref([])
//
const availableRoles = [
{ label: '普通用户', value: 'user' },
@ -394,7 +339,10 @@ export default defineComponent({
newRoles.push('user')
}
await request.put(`/api/user/roles?user_id=${currentUserId.value}`, newRoles)
await request.put(`/api/user/roles`, {
user_id: currentUserId.value,
roles: newRoles
})
message.success('角色修改成功')
roleModalVisible.value = false
@ -488,69 +436,14 @@ export default defineComponent({
resetStates()
}
//
const fetchCommunityList = async () => {
try {
communityLoading.value = true
const res = await request.get('/api/community')
if (res.code === 200 && res.data) {
communityOptions.value = res.data.items || []
}
} catch (error) {
console.error('获取小区列表失败:', error)
message.error('获取小区列表失败')
} finally {
communityLoading.value = false
}
}
//
const handleEditCommunity = (record) => {
currentUserId.value = record.userid
selectedCommunityId.value = record.community_id
communityModalVisible.value = true
if (communityOptions.value.length === 0) {
fetchCommunityList()
}
}
//
const handleCommunitySave = async () => {
try {
communitySaving.value = true
await request.put('/api/user/community', {
user_id: currentUserId.value,
community_id: selectedCommunityId.value
})
message.success('修改成功')
communityModalVisible.value = false
fetchData() //
} catch (error) {
console.error('修改所属小区失败:', error)
message.error('修改失败')
} finally {
communitySaving.value = false
}
}
//
const handleCommunityCancel = () => {
communityModalVisible.value = false
resetStates()
}
//
const resetStates = () => {
currentUserId.value = null
selectedRoles.value = []
selectedCommunityId.value = undefined
}
onMounted(() => {
fetchData()
fetchCommunityList() //
})
return {
@ -579,14 +472,6 @@ export default defineComponent({
handleResetPassword,
handleCopyPassword,
handleClosePasswordModal,
communityModalVisible,
communitySaving,
communityLoading,
selectedCommunityId,
communityOptions,
handleEditCommunity,
handleCommunitySave,
handleCommunityCancel,
currentUserId
}
}