| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- <template>
- <div class="page-wrap">
- <div class="crumbs">
- <el-breadcrumb separator="/">
- <i class="el-icon-eleme"></i> 新配送员管理
- </el-breadcrumb>
- </div>
- <div class="background">
- <div class="topbox">
- <div class="topbox-left">
- <span class="page-title">新配送员管理</span>
- </div>
- <div class="topbox-right">
- <el-button type="primary" icon="el-icon-plus" size="mini" @click="openCreate">新增配送员</el-button>
- </div>
- </div>
- <div class="searchbox">
- <div class="filter-group">
- <span>姓名</span>
- <el-input v-model="filters.name" size="small" style="width:150px" clearable placeholder="配送员姓名"></el-input>
- </div>
- <div class="filter-group">
- <span>手机号</span>
- <el-input v-model="filters.phone" size="small" style="width:150px" clearable placeholder="手机号"></el-input>
- </div>
- <div class="filter-group">
- <span>类型</span>
- <el-select v-model="filters.type" size="small" style="width:140px" clearable placeholder="配送员类型">
- <el-option label="平台配送员" :value="1"></el-option>
- <el-option label="商家配送员" :value="2"></el-option>
- </el-select>
- </div>
- <div class="filter-group">
- <span>状态</span>
- <el-select v-model="filters.accountStatus" size="small" style="width:110px" clearable placeholder="账号状态">
- <el-option label="正常" :value="1"></el-option>
- <el-option label="冻结" :value="0"></el-option>
- </el-select>
- </div>
- <span style="flex:1"></span>
- <el-button type="primary" icon="el-icon-search" size="small" @click="search">查询</el-button>
- <el-button size="small" @click="resetSearch">重置</el-button>
- </div>
- <div class="tablebox">
- <dptable
- :columns="columns"
- :dataSource="tableData"
- :options="options"
- :fetch="getDataList"
- :pagination="pagination"
- />
- </div>
- </div>
- <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px" :close-on-click-modal="false">
- <el-form :model="form" label-width="120px">
- <el-form-item label="配送员姓名" required>
- <el-input v-model="form.name" maxlength="50" placeholder="请输入配送员姓名"></el-input>
- </el-form-item>
- <el-form-item label="手机号" required>
- <el-input v-model="form.phone" maxlength="20" placeholder="请输入手机号" autocomplete="off"></el-input>
- </el-form-item>
- <el-form-item label="密码" :required="!form.id">
- <el-input v-model="form.password" maxlength="128" :placeholder="form.id ? '不填写则不修改密码' : '请输入登录密码'" show-password autocomplete="new-password"></el-input>
- </el-form-item>
- <el-form-item label="配送员类型" required>
- <el-radio-group v-model="form.type" @change="handleTypeChange">
- <el-radio :label="1">平台配送员</el-radio>
- <el-radio :label="2">商家配送员</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item v-if="form.type === 2" label="所属商家ID" required>
- <el-select v-model="form.merchantId" filterable placeholder="请选择所属商家" style="width:100%">
- <el-option
- v-for="item in merchantList"
- :key="getStoreId(item)"
- :label="getStoreName(item)"
- :value="getStoreId(item)"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="工作状态">
- <el-radio-group v-model="form.workStatus">
- <el-radio :label="1">可接单</el-radio>
- <el-radio :label="0">暂停接单</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="账号状态">
- <el-radio-group v-model="form.accountStatus">
- <el-radio :label="1">正常</el-radio>
- <el-radio :label="0">冻结</el-radio>
- </el-radio-group>
- </el-form-item>
- <template v-if="form.type === 1">
- <el-form-item label="平台权限">
- <el-checkbox v-model="form.pickup" :true-label="1" :false-label="0">取餐</el-checkbox>
- <el-checkbox v-model="form.delivery" :true-label="1" :false-label="0">配送</el-checkbox>
- <el-checkbox v-model="form.climbStairs" :true-label="1" :false-label="0">爬楼</el-checkbox>
- </el-form-item>
- </template>
- <el-form-item v-if="form.type === 2" label="不能接单时间">
- <el-time-picker v-model="form.noOrderStartTimeStr" value-format="HH:mm" format="HH:mm" placeholder="开始时间" style="width:140px" editable clearable></el-time-picker>
- <span class="time-separator">至</span>
- <el-time-picker v-model="form.noOrderEndTimeStr" value-format="HH:mm" format="HH:mm" placeholder="结束时间" style="width:140px" editable clearable></el-time-picker>
- </el-form-item>
- </el-form>
- <span slot="footer">
- <el-button @click="dialogVisible = false">取消</el-button>
- <el-button type="primary" :loading="saving" @click="save">保存</el-button>
- </span>
- </el-dialog>
- </div>
- </template>
- <script>
- import dptable from '@/components/common/Dptable.vue'
- const baseUrl = '/deliveryRiderManage1'
- export default {
- name: 'DeliveryerManage1',
- components: { dptable },
- data() {
- return {
- filters: this.createFilters(),
- tableData: [],
- pagination: {
- resultCount: 0,
- currentPage: 1,
- pageSize: 20
- },
- options: {
- mutiSelect: false,
- index: false,
- initTable: true,
- height: '520'
- },
- dialogVisible: false,
- dialogTitle: '',
- saving: false,
- form: this.createForm(),
- merchantList: [],
- columns: [
- { prop: 'name', label: '姓名', width: 140 },
- { prop: 'phone', label: '手机号', width: 150 },
- {
- prop: 'type',
- label: '类型',
- width: 130,
- formatter: row => row.type == 1 ? '平台配送员' : '商家配送员'
- },
- {
- prop: 'workStatus',
- label: '工作状态',
- width: 110,
- render: row => row.workStatus == 1
- ? <el-tag size="small" type="success" style="cursor:pointer" onClick={() => this.updateWorkStatus(row)}>可接单</el-tag>
- : <el-tag size="small" type="warning" style="cursor:pointer" onClick={() => this.updateWorkStatus(row)}>暂停接单</el-tag>
- },
- {
- prop: 'accountStatus',
- label: '账号状态',
- width: 100,
- render: row => row.accountStatus == 1
- ? <el-tag size="small" style="cursor:pointer" onClick={() => this.updateAccountStatus(row)}>正常</el-tag>
- : <el-tag size="small" type="danger" style="cursor:pointer" onClick={() => this.updateAccountStatus(row)}>冻结</el-tag>
- },
- {
- prop: 'pickup',
- label: '取餐',
- width: 75,
- switch: true,
- switchHide: (value, row) => row.type == 2,
- onChange: (value, row) => this.updatePermission(row, 'pickup', value)
- },
- {
- prop: 'delivery',
- label: '配送',
- width: 75,
- switch: true,
- switchHide: (value, row) => row.type == 2,
- onChange: (value, row) => this.updatePermission(row, 'delivery', value)
- },
- {
- prop: 'climbStairs',
- label: '爬楼',
- width: 75,
- switch: true,
- switchHide: (value, row) => row.type == 2,
- onChange: (value, row) => this.updatePermission(row, 'climbStairs', value)
- },
- {
- prop: 'noOrderStartTimeStr',
- label: '不能接单时间',
- width: 140,
- formatter: row => row.type == 2 && row.noOrderStartTimeStr && row.noOrderEndTimeStr
- ? row.noOrderStartTimeStr + ' - ' + row.noOrderEndTimeStr
- : row.type == 1 ? '—' : ''
- },
- {
- prop: 'createTime',
- label: '创建时间',
- width: 150,
- formatter: row => row.createTime ? this.$moment(row.createTime).format('YYYY-MM-DD HH:mm:ss') : '—'
- },
- {
- prop: 'updateTime',
- label: '修改时间',
- width: 150,
- formatter: row => row.updateTime ? this.$moment(row.updateTime).format('YYYY-MM-DD HH:mm:ss') : '—'
- },
- {
- label: '操作',
- width: 220,
- fixed: 'right',
- button: true,
- group: [
- {
- name: '编辑',
- type: 'primary',
- plain: true,
- buttonCode: 'edit',
- onClick: row => this.openEdit(row)
- },
- {
- name: '删除',
- type: 'danger',
- plain: true,
- buttonCode: 'delete',
- onClick: row => this.deleteRider(row)
- }
- ]
- }
- ]
- }
- },
- methods: {
- createFilters() {
- return {
- name: '',
- phone: '',
- type: '',
- accountStatus: ''
- }
- },
- createForm() {
- return {
- id: '',
- phone: '',
- password: '',
- name: '',
- type: 1,
- merchantId: '',
- workStatus: 1,
- accountStatus: 1,
- pickup: 1,
- delivery: 1,
- climbStairs: 0,
- noOrderStartTimeStr: '',
- noOrderEndTimeStr: ''
- }
- },
- search() {
- this.pagination.currentPage = 1
- this.getDataList()
- },
- resetSearch() {
- this.filters = this.createFilters()
- this.search()
- },
- getDataList() {
- const querystring = require('querystring')
- this.options.loading = true
- this.$axios.post(baseUrl + '/list', querystring.stringify({
- name: this.filters.name,
- phone: this.filters.phone,
- type: this.filters.type,
- accountStatus: this.filters.accountStatus,
- pageSize: this.pagination.pageSize,
- currentPage: this.pagination.currentPage
- })).then(res => {
- this.tableData = res.data.list || []
- if (res.data.page) {
- this.pagination.resultCount = res.data.page.resultCount
- this.pagination.currentPage = res.data.page.currentPage
- }
- }).finally(() => {
- this.options.loading = false
- })
- },
- openCreate() {
- this.dialogTitle = '新增配送员'
- this.form = this.createForm()
- this.getMerchantList()
- this.dialogVisible = true
- },
- getMerchantList() {
- if (this.merchantList.length > 0) return
- const querystring = require('querystring')
- this.$axios.post('/storeManage/getStoreList', querystring.stringify({})).then(res => {
- this.merchantList = res.data.list || []
- })
- },
- getStoreId(item) {
- return item.storeId || item.STORE_ID
- },
- getStoreName(item) {
- return item.storeName || item.STORE_NAME || item.name || item.NAME
- },
- openEdit(row) {
- this.dialogTitle = '编辑配送员'
- this.form = this.createForm()
- this.form.id = row.id
- this.getMerchantList()
- this.dialogVisible = true
- const querystring = require('querystring')
- this.$axios.post(baseUrl + '/getById', querystring.stringify({ id: row.id })).then(res => {
- if (!this.handleResult(res, false, true)) {
- this.dialogVisible = false
- return
- }
- this.form = Object.assign(this.createForm(), res.data.obj || {})
- this.form.password = ''
- })
- },
- handleTypeChange() {
- if (this.form.type === 1) {
- this.form.merchantId = ''
- this.form.noOrderStartTimeStr = ''
- this.form.noOrderEndTimeStr = ''
- return
- }
- this.form.pickup = 0
- this.form.delivery = 0
- this.form.climbStairs = 0
- },
- updatePermission(row, field, value) {
- if (field === 'pickup' && value == 1 && row.climbStairs == 1) {
- this.$message.error('取餐权限和爬楼权限不能同时存在')
- this.getDataList()
- return
- }
- if (field === 'climbStairs' && value == 1 && row.pickup == 1) {
- this.$message.error('取餐权限和爬楼权限不能同时存在')
- this.getDataList()
- return
- }
- const querystring = require('querystring')
- this.$axios.post(baseUrl + '/updatePermission', querystring.stringify({
- id: row.id,
- field: field,
- value: value
- })).then(res => this.handleResult(res, true))
- },
- updateWorkStatus(row) {
- const querystring = require('querystring')
- this.$axios.post(baseUrl + '/updateWorkStatus', querystring.stringify({
- id: row.id,
- workStatus: row.workStatus == 1 ? 0 : 1
- })).then(res => this.handleResult(res, true))
- },
- deleteRider(row) {
- this.$confirm('确定要删除该配送员吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- const querystring = require('querystring')
- this.$axios.post(baseUrl + '/delete', querystring.stringify({ id: row.id })).then(res => {
- this.handleResult(res, true)
- })
- }).catch(() => {})
- },
- updateAccountStatus(row) {
- const querystring = require('querystring')
- this.$axios.post(baseUrl + '/updateAccountStatus', querystring.stringify({
- id: row.id,
- accountStatus: row.accountStatus == 1 ? 0 : 1
- })).then(res => this.handleResult(res, true))
- },
- save() {
- if (!this.validateForm()) {
- return
- }
- const querystring = require('querystring')
- this.saving = true
- this.$axios.post(baseUrl + '/save', querystring.stringify(this.buildSaveParams())).then(res => {
- if (this.handleResult(res, false)) {
- this.dialogVisible = false
- this.getDataList()
- }
- }).finally(() => {
- this.saving = false
- })
- },
- buildSaveParams() {
- return {
- id: this.form.id,
- phone: this.form.phone,
- password: this.form.password,
- name: this.form.name,
- type: this.form.type,
- merchantId: this.form.type === 2 ? this.form.merchantId : '',
- workStatus: this.form.workStatus,
- accountStatus: this.form.accountStatus,
- pickup: this.form.type === 1 ? this.form.pickup : 0,
- delivery: this.form.type === 1 ? this.form.delivery : 0,
- climbStairs: this.form.type === 1 ? this.form.climbStairs : 0,
- noOrderStartTimeStr: this.form.type === 2 ? this.form.noOrderStartTimeStr : '',
- noOrderEndTimeStr: this.form.type === 2 ? this.form.noOrderEndTimeStr : ''
- }
- },
- validateForm() {
- if (!this.form.name || !this.form.phone) {
- this.$message.error('请填写姓名和手机号')
- return false
- }
- if (!this.form.id && !this.form.password) {
- this.$message.error('新增配送员必须填写密码')
- return false
- }
- if (!/^1\d{10}$/.test(this.form.phone)) {
- this.$message.error('请输入正确的手机号')
- return false
- }
- if (this.form.type === 2 && !this.form.merchantId) {
- this.$message.error('商家配送员必须填写所属商家ID')
- return false
- }
- if (this.form.type === 1 && this.form.pickup == 1 && this.form.climbStairs == 1) {
- this.$message.error('取餐权限和爬楼权限不能同时存在')
- return false
- }
- return true
- },
- handleResult(res, refresh, silent) {
- if (res.data.rtnBean && res.data.rtnBean.rtnCode != 0) {
- this.$message.error(res.data.rtnBean.rtnMsg)
- if (refresh) this.getDataList()
- return false
- }
- if (!silent) this.$message.success('操作成功')
- if (refresh) this.getDataList()
- return true
- }
- }
- }
- </script>
- <style scoped>
- .page-wrap{
- height: 100%;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- }
- .crumbs{
- color: #666;
- flex-shrink: 0;
- }
- .background{
- flex: 1;
- min-height: 0;
- display: flex;
- flex-direction: column;
- gap: 10px;
- padding: 0 10px 10px;
- }
- .topbox{
- background: white;
- box-shadow: 0 12px 20px -8px rgba(22, 50, 62, 0.3);
- border-radius: 10px;
- min-height: 52px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 10px 16px;
- flex-shrink: 0;
- }
- .topbox-left{ flex-shrink: 0; }
- .page-title{
- font-size: 14px;
- color: #409EFF;
- font-weight: 600;
- }
- .topbox-right{
- flex-shrink: 0;
- display: flex;
- gap: 8px;
- }
- .searchbox{
- background: white;
- box-shadow: 0 12px 20px -8px rgba(22, 50, 62, 0.3);
- border-radius: 10px;
- padding: 12px 16px;
- display: flex;
- align-items: center;
- gap: 8px;
- flex-shrink: 0;
- font-size: 13px;
- color: #606266;
- }
- .searchbox > span{ flex: 1; }
- .filter-group{
- display: flex;
- align-items: center;
- gap: 6px;
- }
- .filter-group > span{
- white-space: nowrap;
- color: #606266;
- }
- .tablebox{
- flex: 1;
- min-height: 0;
- background: white;
- box-shadow: 0 12px 20px -8px rgba(22, 50, 62, 0.3);
- border-radius: 10px;
- padding: 16px;
- overflow: hidden;
- }
- .time-separator{ margin: 0 8px; color: #909399; }
- </style>
- <style>
- .tablebox .el-table{ width: 100% !important; table-layout: auto !important; }
- .tablebox .el-table__header-wrapper table,
- .tablebox .el-table__body-wrapper table{ width: 100% !important; }
- .tablebox th{
- background: #409EFF !important;
- color: #fff !important;
- font-weight: 500 !important;
- font-size: 13px !important;
- padding: 10px 8px !important;
- border: none !important;
- }
- .tablebox td{
- padding: 8px !important;
- font-size: 13px;
- border-left: 1px solid #ebeef5 !important;
- }
- .tablebox td:first-child{ border-left: none !important; }
- .tablebox tr:hover td{ background: #f6faff; }
- /* 弹窗样式优化 */
- .el-dialog__title{ font-weight: 600; }
- .el-dialog__footer .el-button{ padding: 8px 24px; }
- </style>
|