feat: 新增多角色系统(派单/分润/推广/区域)

- 后端:RlzDispatch/Profit/Promotion/Region 控制器、服务、Mapper、领域模型
- 权限:MethodSecurityConfig + PermissionInterceptor
- 管理后台:派单/分润/推广/区域 页面与 API
- Android 陪护端:派单/运营/退款 Fragment 及布局
- 小程序:推广员子包、派单/运营/退款/检索子包、自定义 tabBar
- 文档:多角色系统方案、角色权限矩阵、用户操作手册等

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
renjianbo
2026-10-12 00:09:45 +08:00
parent 7562a5f20c
commit 805ed0298b
170 changed files with 8876 additions and 705 deletions

Binary file not shown.

View File

@@ -0,0 +1,26 @@
import request from '@/utils/request'
// 手动派单
export function assignOrder(orderId, caregiverId) {
return request({ url: '/system/dispatch/assign/' + orderId + '/' + caregiverId, method: 'post' })
}
// 获取待派单订单
export function getPendingOrders() {
return request({ url: '/system/dispatch/pending', method: 'get' })
}
// 获取空闲陪诊师
export function getAvailableCaregivers() {
return request({ url: '/system/dispatch/caregivers', method: 'get' })
}
// 获取指定医院的空闲陪诊师
export function getCaregiversByHospital(hospitalId) {
return request({ url: '/system/dispatch/caregivers/' + hospitalId, method: 'get' })
}
// 获取派单历史
export function getDispatchHistory() {
return request({ url: '/system/dispatch/history', method: 'get' })
}

View File

@@ -0,0 +1,41 @@
import request from '@/utils/request'
// 查询分润记录列表
export function listProfit(query) {
return request({ url: '/system/profit/list', method: 'get', params: query })
}
// 获取分润记录详情
export function getProfit(id) {
return request({ url: '/system/profit/' + id, method: 'get' })
}
// 根据订单查询分润
export function getProfitByOrder(orderId) {
return request({ url: '/system/profit/byOrder/' + orderId, method: 'get' })
}
// 根据用户查询分润
export function getProfitByUser(userId) {
return request({ url: '/system/profit/byUser/' + userId, method: 'get' })
}
// 查询用户余额
export function getBalance(userId) {
return request({ url: '/system/profit/balance/' + userId, method: 'get' })
}
// 删除分润记录
export function delProfit(ids) {
return request({ url: '/system/profit/' + ids, method: 'delete' })
}
// 重新计算分润
export function recalculateProfit(orderId) {
return request({ url: '/system/profit/calculate/' + orderId, method: 'post' })
}
// 回退分润
export function reverseProfit(orderId) {
return request({ url: '/system/profit/reverse/' + orderId, method: 'post' })
}

View File

@@ -0,0 +1,36 @@
import request from '@/utils/request'
// 查询推广关系列表
export function listPromotion(query) {
return request({ url: '/system/promotion/list', method: 'get', params: query })
}
// 获取推广关系详情
export function getPromotion(id) {
return request({ url: '/system/promotion/' + id, method: 'get' })
}
// 根据被邀请用户查询
export function getByInvitedUser(invitedUserId) {
return request({ url: '/system/promotion/byInvited/' + invitedUserId, method: 'get' })
}
// 根据推广员查询
export function getByPromoter(promoterId) {
return request({ url: '/system/promotion/byPromoter/' + promoterId, method: 'get' })
}
// 新增推广关系
export function addPromotion(data) {
return request({ url: '/system/promotion', method: 'post', data: data })
}
// 修改推广关系
export function updatePromotion(data) {
return request({ url: '/system/promotion', method: 'put', data: data })
}
// 删除推广关系
export function delPromotion(ids) {
return request({ url: '/system/promotion/' + ids, method: 'delete' })
}

View File

@@ -0,0 +1,31 @@
import request from '@/utils/request'
// 查询区域列表
export function listRegion(query) {
return request({ url: '/system/region/list', method: 'get', params: query })
}
// 获取区域详情
export function getRegion(id) {
return request({ url: '/system/region/' + id, method: 'get' })
}
// 获取子区域
export function getRegionChildren(parentId) {
return request({ url: '/system/region/children/' + parentId, method: 'get' })
}
// 新增区域
export function addRegion(data) {
return request({ url: '/system/region', method: 'post', data: data })
}
// 修改区域
export function updateRegion(data) {
return request({ url: '/system/region', method: 'put', data: data })
}
// 删除区域
export function delRegion(ids) {
return request({ url: '/system/region/' + ids, method: 'delete' })
}

View File

@@ -75,7 +75,7 @@ export default {
getList() {
this.loading = true;
listJiaoyiDetail(this.queryParams).then(response => {
this.detailList = response.rows;
this.detailList = response.data;
this.total = response.total;
this.loading = false;
});

View File

@@ -0,0 +1,129 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="订单ID" prop="orderId">
<el-input v-model="queryParams.orderId" placeholder="请输入订单ID" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="用户ID" prop="userId">
<el-input v-model="queryParams.userId" placeholder="请输入用户ID" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="角色类型" prop="roleType">
<el-select v-model="queryParams.roleType" placeholder="角色类型" clearable>
<el-option label="陪诊师" value="caregiver" />
<el-option label="推广员" value="promoter" />
<el-option label="调度员" value="dispatcher" />
<el-option label="运营经理" value="operations" />
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="状态" clearable>
<el-option label="未结算" value="0" />
<el-option label="已结算" value="1" />
<el-option label="已退回" value="7" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" width="80" />
<el-table-column label="订单ID" align="center" prop="orderId" width="100" />
<el-table-column label="用户ID" align="center" prop="userId" width="100" />
<el-table-column label="角色" align="center" prop="roleType" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.roleType === 'caregiver'" size="small">陪诊师</el-tag>
<el-tag v-else-if="scope.row.roleType === 'promoter'" type="warning" size="small">推广员</el-tag>
<el-tag v-else-if="scope.row.roleType === 'dispatcher'" type="info" size="small">调度员</el-tag>
<el-tag v-else-if="scope.row.roleType === 'operations'" type="success" size="small">运营经理</el-tag>
<span v-else>{{ scope.row.roleType }}</span>
</template>
</el-table-column>
<el-table-column label="分润类型" align="center" prop="profitType" width="120">
<template slot-scope="scope">
<span v-if="scope.row.profitType === 'service_fee'">服务费</span>
<span v-else-if="scope.row.profitType === 'promotion_l1'">一级推广</span>
<span v-else-if="scope.row.profitType === 'promotion_l2'">二级推广</span>
<span v-else-if="scope.row.profitType === 'promotion_l3'">三级推广</span>
<span v-else-if="scope.row.profitType === 'dispatch_fee'">调度费</span>
<span v-else-if="scope.row.profitType === 'ops_flow'">运营流水</span>
<span v-else>{{ scope.row.profitType }}</span>
</template>
</el-table-column>
<el-table-column label="金额" align="center" width="120">
<template slot-scope="scope">
<span style="color: #67C23A; font-weight: bold;">¥{{ scope.row.amount }}</span>
</template>
</el-table-column>
<el-table-column label="比例" align="center" prop="rate" width="80">
<template slot-scope="scope">{{ scope.row.rate ? scope.row.rate + '%' : '-' }}</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '0'" type="warning" size="small">未结算</el-tag>
<el-tag v-else-if="scope.row.status === '1'" type="success" size="small">已结算</el-tag>
<el-tag v-else-if="scope.row.status === '7'" type="danger" size="small">已退回</el-tag>
<span v-else>{{ scope.row.status }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
</template>
<script>
import { listProfit, delProfit } from "@/api/system/profit";
export default {
name: "Profit",
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
list: [],
queryParams: { pageNum: 1, pageSize: 10, orderId: null, userId: null, roleType: null, status: null }
};
},
created() { this.getList(); },
methods: {
getList() {
this.loading = true;
listProfit(this.queryParams).then(response => {
this.list = response.data;
this.total = response.total;
this.loading = false;
});
},
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
resetQuery() { this.queryParams = { pageNum: 1, pageSize: 10 }; this.getList(); },
handleSelectionChange(selection) { this.ids = selection.map(item => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; },
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除?').then(function() {
return delProfit(ids);
}).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); }).catch(() => {});
}
}
};
</script>

View File

@@ -0,0 +1,151 @@
<template>
<div class="app-container">
<!-- 待派单订单 -->
<el-card class="mb20">
<div slot="header"><span><i class="el-icon-s-order" /> 待派单订单</span><el-button style="float: right; padding: 3px 0" type="text" @click="loadPendingOrders">刷新</el-button></div>
<el-table v-loading="orderLoading" :data="pendingOrders" max-height="350" @row-click="onOrderSelect" highlight-current-row>
<el-table-column label="订单编号" align="center" prop="yuliu1" width="180" :show-overflow-tooltip="true" />
<el-table-column label="医院ID" align="center" prop="hospitalId" width="100" />
<el-table-column label="患者ID" align="center" prop="cId" width="100" />
<el-table-column label="金额" align="center" width="100">
<template slot-scope="scope"><span style="color: #E6A23C;">¥{{ scope.row.yuguMoney }}</span></template>
</el-table-column>
<el-table-column label="服务类型" align="center" prop="yuliu10" width="120" />
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
<el-table-column label="操作" align="center" width="120">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click.stop="showAssignDialog(scope.row)">派单</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 空闲陪诊师 -->
<el-card>
<div slot="header"><span><i class="el-icon-user" /> 空闲陪诊师</span><el-button style="float: right; padding: 3px 0" type="text" @click="loadCaregivers">刷新</el-button></div>
<el-table v-loading="caregiverLoading" :data="caregivers" max-height="350">
<el-table-column label="ID" align="center" prop="userId" width="80" />
<el-table-column label="昵称" align="center" prop="nickName" width="150" />
<el-table-column label="手机号" align="center" prop="phonenumber" width="130" />
<el-table-column label="实名" align="center" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.identityNo" type="success" size="small">已认证</el-tag>
<el-tag v-else type="warning" size="small">未认证</el-tag>
</template>
</el-table-column>
<el-table-column label="注册时间" align="center" prop="createTime" width="160" />
</el-table>
</el-card>
<!-- 派单对话框 -->
<el-dialog title="确认派单" :visible.sync="dialogVisible" width="450px" append-to-body>
<div v-if="selectedOrder">
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="订单编号">{{ selectedOrder.yuliu1 }}</el-descriptions-item>
<el-descriptions-item label="订单金额">¥{{ selectedOrder.yuguMoney }}</el-descriptions-item>
<el-descriptions-item label="患者ID">{{ selectedOrder.cId }}</el-descriptions-item>
</el-descriptions>
</div>
<div style="margin: 20px 0;">
<span style="font-weight: bold;">选择陪诊师:</span>
<el-select v-model="selectedCaregiverId" placeholder="请选择陪诊师" style="width: 100%; margin-top: 8px;">
<el-option v-for="c in caregivers" :key="c.userId" :label="c.nickName + ' (ID:' + c.userId + ')'" :value="c.userId" />
</el-select>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doAssign" :disabled="!selectedCaregiverId">确认派单</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 派单历史 -->
<el-card class="mt20">
<div slot="header"><span><i class="el-icon-time" /> 我的派单记录</span></div>
<el-table v-loading="historyLoading" :data="dispatchHistory" max-height="300">
<el-table-column label="订单编号" align="center" prop="yuliu1" width="180" />
<el-table-column label="陪诊师ID" align="center" prop="bId" width="100" />
<el-table-column label="金额" align="center" width="100">
<template slot-scope="scope"><span style="color: #E6A23C;">¥{{ scope.row.yuguMoney }}</span></template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '1'" type="warning" size="small">已接单</el-tag>
<el-tag v-else-if="scope.row.status === '4'" type="success" size="small">已完成</el-tag>
<el-tag v-else size="small">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column label="派单时间" align="center" prop="updateTime" width="160" />
</el-table>
</el-card>
</div>
</template>
<script>
import { getPendingOrders, getAvailableCaregivers, assignOrder, getDispatchHistory } from "@/api/system/dispatch";
export default {
name: "Dispatch",
data() {
return {
orderLoading: false,
caregiverLoading: false,
historyLoading: false,
pendingOrders: [],
caregivers: [],
dispatchHistory: [],
dialogVisible: false,
selectedOrder: null,
selectedCaregiverId: null
};
},
created() {
this.loadPendingOrders();
this.loadCaregivers();
this.loadHistory();
},
methods: {
loadPendingOrders() {
this.orderLoading = true;
getPendingOrders().then(response => {
this.pendingOrders = response.data || [];
this.orderLoading = false;
}).catch(() => { this.orderLoading = false; });
},
loadCaregivers() {
this.caregiverLoading = true;
getAvailableCaregivers().then(response => {
this.caregivers = response.data || [];
this.caregiverLoading = false;
}).catch(() => { this.caregiverLoading = false; });
},
loadHistory() {
this.historyLoading = true;
getDispatchHistory().then(response => {
this.dispatchHistory = response.data || [];
this.historyLoading = false;
}).catch(() => { this.historyLoading = false; });
},
onOrderSelect(row) { this.selectedOrder = row; },
showAssignDialog(order) {
this.selectedOrder = order;
this.selectedCaregiverId = null;
this.dialogVisible = true;
},
doAssign() {
if (!this.selectedCaregiverId || !this.selectedOrder) return;
assignOrder(this.selectedOrder.orderId, this.selectedCaregiverId).then(() => {
this.$modal.msgSuccess("派单成功");
this.dialogVisible = false;
this.loadPendingOrders();
this.loadCaregivers();
this.loadHistory();
});
}
}
};
</script>
<style scoped>
.mb20 { margin-bottom: 20px; }
.mt20 { margin-top: 20px; }
</style>

View File

@@ -0,0 +1,148 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="推广员ID" prop="promoterId">
<el-input v-model="queryParams.promoterId" placeholder="请输入推广员ID" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="被邀请用户" prop="invitedUserId">
<el-input v-model="queryParams.invitedUserId" placeholder="请输入被邀请用户ID" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" width="80" />
<el-table-column label="推广员ID" align="center" prop="promoterId" width="120" />
<el-table-column label="被邀请用户ID" align="center" prop="invitedUserId" width="140" />
<el-table-column label="层级" align="center" prop="level" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.level === 1" type="success" size="small">一级</el-tag>
<el-tag v-else-if="scope.row.level === 2" type="warning" size="small">二级</el-tag>
<el-tag v-else-if="scope.row.level === 3" type="info" size="small">三级</el-tag>
<span v-else>{{ scope.row.level }}</span>
</template>
</el-table-column>
<el-table-column label="上级推广员ID" align="center" prop="parentPromoterId" width="140" />
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<!-- 新增/修改对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="推广员ID" prop="promoterId">
<el-input v-model="form.promoterId" placeholder="请输入推广员ID" />
</el-form-item>
<el-form-item label="被邀请用户ID" prop="invitedUserId">
<el-input v-model="form.invitedUserId" placeholder="请输入被邀请用户ID" />
</el-form-item>
<el-form-item label="层级" prop="level">
<el-select v-model="form.level" placeholder="请选择层级">
<el-option label="一级" :value="1" />
<el-option label="二级" :value="2" />
<el-option label="三级" :value="3" />
</el-select>
</el-form-item>
<el-form-item label="上级推广员ID" prop="parentPromoterId">
<el-input v-model="form.parentPromoterId" placeholder="请输入上级推广员ID(可选)" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listPromotion, getPromotion, addPromotion, updatePromotion, delPromotion } from "@/api/system/promotion";
export default {
name: "Promotion",
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
list: [],
title: "",
open: false,
queryParams: { pageNum: 1, pageSize: 10, promoterId: null, invitedUserId: null },
form: {},
rules: {
promoterId: [{ required: true, message: "推广员ID不能为空", trigger: "blur" }],
invitedUserId: [{ required: true, message: "被邀请用户ID不能为空", trigger: "blur" }],
level: [{ required: true, message: "层级不能为空", trigger: "change" }]
}
};
},
created() { this.getList(); },
methods: {
getList() {
this.loading = true;
listPromotion(this.queryParams).then(response => {
this.list = response.data;
this.total = response.total;
this.loading = false;
});
},
cancel() { this.open = false; this.reset(); },
reset() { this.form = {}; },
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
resetQuery() { this.queryParams = { pageNum: 1, pageSize: 10 }; this.getList(); },
handleSelectionChange(selection) { this.ids = selection.map(item => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; },
handleAdd() { this.reset(); this.open = true; this.title = "添加推广关系"; },
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getPromotion(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改推广关系";
});
},
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updatePromotion(this.form).then(() => { this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); });
} else {
addPromotion(this.form).then(() => { this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); });
}
}
});
},
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除?').then(function() {
return delPromotion(ids);
}).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); }).catch(() => {});
}
}
};
</script>

View File

@@ -0,0 +1,164 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="区域名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入区域名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="区域状态" clearable>
<el-option label="启用" value="0" />
<el-option label="停用" value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" width="80" />
<el-table-column label="区域名称" align="center" prop="name" width="180" />
<el-table-column label="父级ID" align="center" prop="parentId" width="100" />
<el-table-column label="层级" align="center" prop="level" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.level === 1" size="small">省级</el-tag>
<el-tag v-else-if="scope.row.level === 2" type="success" size="small">市级</el-tag>
<el-tag v-else-if="scope.row.level === 3" type="warning" size="small">区级</el-tag>
<span v-else>{{ scope.row.level }}</span>
</template>
</el-table-column>
<el-table-column label="负责人ID" align="center" prop="managerId" width="120" />
<el-table-column label="状态" align="center" prop="status" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '0'" type="success" size="small">启用</el-tag>
<el-tag v-else type="danger" size="small">停用</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-plus" @click="handleAddChild(scope.row)">添加子区域</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="区域名称" prop="name">
<el-input v-model="form.name" placeholder="请输入区域名称" />
</el-form-item>
<el-form-item label="父级ID" prop="parentId">
<el-input v-model="form.parentId" placeholder="父级区域ID,顶级为0" />
</el-form-item>
<el-form-item label="层级" prop="level">
<el-select v-model="form.level" placeholder="请选择层级">
<el-option label="省级" :value="1" />
<el-option label="市级" :value="2" />
<el-option label="区级" :value="3" />
</el-select>
</el-form-item>
<el-form-item label="负责人ID" prop="managerId">
<el-input v-model="form.managerId" placeholder="请输入运营经理用户ID(可选)" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio label="0">启用</el-radio>
<el-radio label="1">停用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listRegion, getRegion, addRegion, updateRegion, delRegion } from "@/api/system/region";
export default {
name: "Region",
data() {
return {
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
list: [],
title: "",
open: false,
queryParams: { pageNum: 1, pageSize: 10, name: null, status: null },
form: {},
rules: {
name: [{ required: true, message: "区域名称不能为空", trigger: "blur" }],
level: [{ required: true, message: "层级不能为空", trigger: "change" }],
status: [{ required: true, message: "状态不能为空", trigger: "change" }]
}
};
},
created() { this.getList(); },
methods: {
getList() {
this.loading = true;
listRegion(this.queryParams).then(response => {
this.list = response.data;
this.total = response.total;
this.loading = false;
});
},
cancel() { this.open = false; this.reset(); },
reset() { this.form = { status: "0", parentId: 0 }; },
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
resetQuery() { this.queryParams = { pageNum: 1, pageSize: 10 }; this.getList(); },
handleSelectionChange(selection) { this.ids = selection.map(item => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; },
handleAdd() { this.reset(); this.open = true; this.title = "添加区域"; },
handleAddChild(row) { this.reset(); this.form.parentId = row.id; this.form.level = (row.level || 1) + 1; this.open = true; this.title = "添加子区域 - " + row.name; },
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getRegion(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改区域";
});
},
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateRegion(this.form).then(() => { this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); });
} else {
addRegion(this.form).then(() => { this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); });
}
}
});
},
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除?').then(function() {
return delRegion(ids);
}).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); }).catch(() => {});
}
}
};
</script>

View File

@@ -175,7 +175,7 @@ export default {
getList() {
this.loading = true;
listRenzheng(this.queryParams).then(response => {
this.renzhengList = response.rows;
this.renzhengList = response.data;
this.total = response.total;
this.loading = false;
});