Browse Source

客户管理页面添加

sunlupeng 7 months ago
parent
commit
90e22fc63c

+ 49 - 0
src/api/business.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function listExpress(query) {
+  return request({
+    url: '/customer-business/page',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createExpress(data) {
+  return request({
+    url: '/customer-business/add',
+    method: 'post',
+    data
+  })
+}
+
+export function readExpress(data) {
+  return request({
+    url: '/customer-business/info',
+    method: 'get',
+    data
+  })
+}
+
+export function updateExpress(data) {
+  return request({
+    url: '/customer-business/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteExpress(query) {
+  return request({
+    url: '/customer-business/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function setState(query) {
+  return request({
+    url: '/customer-business/updateStatus',
+    method: 'post',
+    params:query
+  })
+}

+ 49 - 0
src/api/distributor.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function listExpress(query) {
+  return request({
+    url: '/customer-distributor/page',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createExpress(data) {
+  return request({
+    url: '/customer-distributor/add',
+    method: 'post',
+    data
+  })
+}
+
+export function readExpress(data) {
+  return request({
+    url: '/customer-distributor/info',
+    method: 'get',
+    data
+  })
+}
+
+export function updateExpress(data) {
+  return request({
+    url: '/customer-distributor/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteExpress(query) {
+  return request({
+    url: '/customer-distributor/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function setState(query) {
+  return request({
+    url: '/customer-distributor/updateStatus',
+    method: 'post',
+    params:query
+  })
+}

+ 49 - 0
src/api/guest.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function listExpress(query) {
+  return request({
+    url: '/customer-guest/page',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createExpress(data) {
+  return request({
+    url: '/customer-guest/add',
+    method: 'post',
+    data
+  })
+}
+
+export function readExpress(data) {
+  return request({
+    url: '/customer-guest/info',
+    method: 'get',
+    data
+  })
+}
+
+export function updateExpress(data) {
+  return request({
+    url: '/customer-guest/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteExpress(query) {
+  return request({
+    url: '/customer-guest/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function setState(query) {
+  return request({
+    url: '/customer-guest/updateStatus',
+    method: 'post',
+    params:query
+  })
+}

+ 49 - 0
src/api/vip.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+export function listExpress(query) {
+  return request({
+    url: '/customer-vip/page',
+    method: 'get',
+    params: query
+  })
+}
+
+export function createExpress(data) {
+  return request({
+    url: '/customer-vip/add',
+    method: 'post',
+    data
+  })
+}
+
+export function readExpress(data) {
+  return request({
+    url: '/customer-vip/info',
+    method: 'get',
+    data
+  })
+}
+
+export function updateExpress(data) {
+  return request({
+    url: '/customer-vip/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteExpress(query) {
+  return request({
+    url: '/customer-vip/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function setState(query) {
+  return request({
+    url: '/customer-vip/updateStatus',
+    method: 'post',
+    params:query
+  })
+}

+ 7 - 0
src/permission.js

@@ -157,6 +157,13 @@ const myRoles = [
   'stockCountEdit',
   'stockCountEdit',
   'stockCountDetail',
   'stockCountDetail',
 
 
+  // 客户管理
+  'customer',
+  'distributor',
+  'business',
+  'vip',
+  'guest',
+
   'dictManage', 
   'dictManage', 
   'dictList', 
   'dictList', 
   'dictDataList', 
   'dictDataList', 

+ 44 - 29
src/router/index.js

@@ -133,37 +133,52 @@ export const asyncRouterMap = [
         { path: 'stockCountDetail/:id', component: _import('stock/stockCount/stockCountAdd'), name: 'stockCountDetail', meta: { title: '盘点单详情', noCache: false, hideTag: true, hidden: true }},
         { path: 'stockCountDetail/:id', component: _import('stock/stockCount/stockCountAdd'), name: 'stockCountDetail', meta: { title: '盘点单详情', noCache: false, hideTag: true, hidden: true }},
       ]
       ]
     },
     },
-  
-  {
-    path: '/dictManage',
-    component: Layout,
-    redirect: 'noredirect',
-    name: 'dictManage',
-    meta: {
-      title: '字典管理',
-      icon: 'zidian'
+    {
+      path: '/customer',
+      component: Layout,
+      redirect: 'noredirect',
+      name: 'customer',
+      meta: {
+        title: '客户管理',
+        icon: 'shangpin'
+      },
+      children: [
+        { path: 'distributor', component: _import('customer/distributor'), name: 'distributor', meta: { title: '分销商管理', noCache: true }},
+        { path: 'business', component: _import('customer/business'), name: 'business', meta: { title: '企业客户管理', noCache: true }},
+        { path: 'vip', component: _import('customer/vip'), name: 'vip', meta: { title: '会员管理', noCache: true }},
+        { path: 'guest', component: _import('customer/guest'), name: 'guest', meta: { title: '散客管理', noCache: true }},
+      ]
+    },
+    {
+      path: '/dictManage',
+      component: Layout,
+      redirect: 'noredirect',
+      name: 'dictManage',
+      meta: {
+        title: '字典管理',
+        icon: 'zidian'
+      },
+      children: [
+        { path: 'dictList', component: _import('dictManage/dictList'), name: 'dictList', meta: { title: '字典列表', noCache: true }},
+        { path: 'dictDataList/:id', component: _import('dictManage/dictDataList'), name: 'dictDataList', meta: { title: '字典数据', noCache: false, hideTag: true, hidden: true }},
+      ]
     },
     },
-    children: [
-      { path: 'dictList', component: _import('dictManage/dictList'), name: 'dictList', meta: { title: '字典列表', noCache: true }},
-      { path: 'dictDataList/:id', component: _import('dictManage/dictDataList'), name: 'dictDataList', meta: { title: '字典数据', noCache: false, hideTag: true, hidden: true }},
-    ]
-  },
 
 
-  {
-    path: '/sys',
-    component: Layout,
-    redirect: 'noredirect',
-    name: 'sysManage',
-    meta: {
-      title: '系统管理',
-      icon: 'chart'
+    {
+      path: '/sys',
+      component: Layout,
+      redirect: 'noredirect',
+      name: 'sysManage',
+      meta: {
+        title: '系统管理',
+        icon: 'chart'
+      },
+      children: [
+        { path: 'admin', component: _import('sys/admin'), name: 'admin', meta: { title: '用户管理', noCache: true }},
+        { path: 'dept', component: _import('sys/dept'), name: 'dept', meta: { title: '部门管理', noCache: true }},
+        { path: 'role', component: _import('sys/role'), name: 'role', meta: { title: '角色管理', noCache: true }},
+      ]
     },
     },
-    children: [
-      { path: 'admin', component: _import('sys/admin'), name: 'admin', meta: { title: '用户管理', noCache: true }},
-      { path: 'dept', component: _import('sys/dept'), name: 'dept', meta: { title: '部门管理', noCache: true }},
-      { path: 'role', component: _import('sys/role'), name: 'role', meta: { title: '角色管理', noCache: true }},
-    ]
-  },
 
 
-  { path: '*', redirect: '/404', hidden: true }
+    { path: '*', redirect: '/404', hidden: true }
 ]
 ]

+ 273 - 0
src/views/customer/business.vue

@@ -0,0 +1,273 @@
+rookieCode<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="物流公司名称" v-model="listQuery.logisticsName">
+      </el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px;">
+                <el-option :key="item.type" v-for="item in statusList" :label="item.name" :value="item.type">
+                </el-option>
+            </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleQuery">查找</el-button>
+      <el-button class="filter-item" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleCreate">添加</el-button>
+      <!-- <el-button class="filter-item" v-waves icon="el-icon-download" @click="handleDownload">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="物流公司名称" prop="logisticsName">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="快递查询代码" prop="queryCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="菜鸟代码" prop="rookieCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="50px" label="状态">
+          <template slot-scope="props">
+            <span v-if="props.row.status == 0" style="color: #67C23A;font-weight: bold;">启用</span>
+            <span v-if="props.row.status == 1" style="color: #E6A23C;font-weight: bold;">停用</span>
+          </template>
+      </el-table-column>
+      <!-- <el-table-column align="center" min-width="150px" label="备注" prop="remarks">
+      </el-table-column> -->
+
+      <el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.status == 1" type="success" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">启用</el-button>
+          <el-button v-if="scope.row.status == 0" type="warning" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">停用</el-button>
+          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="600px">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="110px">
+        <el-form-item label="物流公司名称" prop="logisticsName">
+          <el-input v-model="dataForm.logisticsName"></el-input>
+        </el-form-item>
+        <el-form-item label="快递查询代码" prop="queryCode">
+          <el-input v-model="dataForm.queryCode"></el-input>
+        </el-form-item>
+        <el-form-item label="菜鸟代码" prop="rookieCode">
+          <el-input v-model="dataForm.rookieCode"></el-input>
+        </el-form-item>
+        <!-- <el-form-item label="备注" prop="remarks">
+          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入"
+            v-model="dataForm.remarks">
+          </el-input>
+        </el-form-item> -->
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+<script>
+import { listExpress, createExpress, updateExpress, deleteExpress, setState } from '@/api/express'
+import waves from '@/directive/waves' // 水波纹指令
+
+export default {
+  directives: { waves },
+  data() {
+    return {
+      list: undefined,
+      total: undefined,
+      listLoading: true,
+      statusList: [
+                {
+                    type: 0,
+                    name: '启用'
+                },
+                {
+                    type: 1,
+                    name: '停用'
+                },
+            ],
+      listQuery: {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      },
+      dataForm: {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: '编辑',
+        create: '创建'
+      },
+      rules: {
+        logisticsName: [{ required: true, message: '物流公司名称不能为空', trigger: 'blur' }],
+        queryCode: [{ required: true, message: '快递查询代码不能为空', trigger: 'blur' }],
+        rookieCode: [{ required: true, message: '菜鸟代码不能为空', trigger: 'blur' }],
+      },
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.listQuery = {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      };
+      this.handleQuery();
+    },
+    getList() {
+      this.listLoading = true
+      listExpress(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+    handleQuery() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+    resetForm() {
+      this.dataForm = {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      }
+    },
+    handleCreate() {
+      this.resetForm()
+      this.dialogStatus = 'create'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    createData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          createExpress(this.dataForm).then(response => {
+            this.list.unshift(response.data.data)
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '创建成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row)
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateExpress(this.dataForm).then(() => {
+            for (const v of this.list) {
+              if (v.id === this.dataForm.id) {
+                const index = this.list.indexOf(v)
+                this.list.splice(index, 1, this.dataForm)
+                break
+              }
+            }
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '更新成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          deleteExpress({id:row.id}).then(response => {
+            this.$notify({
+              title: '成功',
+              message: '删除成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }).catch(() => {
+  
+        })
+    },
+    handleDownload() {
+      window.location.href = process.env.BASE_API + '/product/export';
+    },
+    changeState(id, status) {
+            setState({ id: id, status: status }).then(response => {
+                this.$notify({
+                    title: '成功',
+                    message: '状态修改成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+  }
+}
+</script>

+ 273 - 0
src/views/customer/distributor.vue

@@ -0,0 +1,273 @@
+rookieCode<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="物流公司名称" v-model="listQuery.logisticsName">
+      </el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px;">
+                <el-option :key="item.type" v-for="item in statusList" :label="item.name" :value="item.type">
+                </el-option>
+            </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleQuery">查找</el-button>
+      <el-button class="filter-item" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleCreate">添加</el-button>
+      <!-- <el-button class="filter-item" v-waves icon="el-icon-download" @click="handleDownload">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="物流公司名称" prop="logisticsName">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="快递查询代码" prop="queryCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="菜鸟代码" prop="rookieCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="50px" label="状态">
+          <template slot-scope="props">
+            <span v-if="props.row.status == 0" style="color: #67C23A;font-weight: bold;">启用</span>
+            <span v-if="props.row.status == 1" style="color: #E6A23C;font-weight: bold;">停用</span>
+          </template>
+      </el-table-column>
+      <!-- <el-table-column align="center" min-width="150px" label="备注" prop="remarks">
+      </el-table-column> -->
+
+      <el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.status == 1" type="success" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">启用</el-button>
+          <el-button v-if="scope.row.status == 0" type="warning" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">停用</el-button>
+          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="600px">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="110px">
+        <el-form-item label="物流公司名称" prop="logisticsName">
+          <el-input v-model="dataForm.logisticsName"></el-input>
+        </el-form-item>
+        <el-form-item label="快递查询代码" prop="queryCode">
+          <el-input v-model="dataForm.queryCode"></el-input>
+        </el-form-item>
+        <el-form-item label="菜鸟代码" prop="rookieCode">
+          <el-input v-model="dataForm.rookieCode"></el-input>
+        </el-form-item>
+        <!-- <el-form-item label="备注" prop="remarks">
+          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入"
+            v-model="dataForm.remarks">
+          </el-input>
+        </el-form-item> -->
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+<script>
+import { listExpress, createExpress, updateExpress, deleteExpress, setState } from '@/api/express'
+import waves from '@/directive/waves' // 水波纹指令
+
+export default {
+  directives: { waves },
+  data() {
+    return {
+      list: undefined,
+      total: undefined,
+      listLoading: true,
+      statusList: [
+                {
+                    type: 0,
+                    name: '启用'
+                },
+                {
+                    type: 1,
+                    name: '停用'
+                },
+            ],
+      listQuery: {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      },
+      dataForm: {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: '编辑',
+        create: '创建'
+      },
+      rules: {
+        logisticsName: [{ required: true, message: '物流公司名称不能为空', trigger: 'blur' }],
+        queryCode: [{ required: true, message: '快递查询代码不能为空', trigger: 'blur' }],
+        rookieCode: [{ required: true, message: '菜鸟代码不能为空', trigger: 'blur' }],
+      },
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.listQuery = {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      };
+      this.handleQuery();
+    },
+    getList() {
+      this.listLoading = true
+      listExpress(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+    handleQuery() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+    resetForm() {
+      this.dataForm = {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      }
+    },
+    handleCreate() {
+      this.resetForm()
+      this.dialogStatus = 'create'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    createData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          createExpress(this.dataForm).then(response => {
+            this.list.unshift(response.data.data)
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '创建成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row)
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateExpress(this.dataForm).then(() => {
+            for (const v of this.list) {
+              if (v.id === this.dataForm.id) {
+                const index = this.list.indexOf(v)
+                this.list.splice(index, 1, this.dataForm)
+                break
+              }
+            }
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '更新成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          deleteExpress({id:row.id}).then(response => {
+            this.$notify({
+              title: '成功',
+              message: '删除成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }).catch(() => {
+  
+        })
+    },
+    handleDownload() {
+      window.location.href = process.env.BASE_API + '/product/export';
+    },
+    changeState(id, status) {
+            setState({ id: id, status: status }).then(response => {
+                this.$notify({
+                    title: '成功',
+                    message: '状态修改成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+  }
+}
+</script>

+ 273 - 0
src/views/customer/guest.vue

@@ -0,0 +1,273 @@
+rookieCode<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="物流公司名称" v-model="listQuery.logisticsName">
+      </el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px;">
+                <el-option :key="item.type" v-for="item in statusList" :label="item.name" :value="item.type">
+                </el-option>
+            </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleQuery">查找</el-button>
+      <el-button class="filter-item" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleCreate">添加</el-button>
+      <!-- <el-button class="filter-item" v-waves icon="el-icon-download" @click="handleDownload">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="物流公司名称" prop="logisticsName">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="快递查询代码" prop="queryCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="菜鸟代码" prop="rookieCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="50px" label="状态">
+          <template slot-scope="props">
+            <span v-if="props.row.status == 0" style="color: #67C23A;font-weight: bold;">启用</span>
+            <span v-if="props.row.status == 1" style="color: #E6A23C;font-weight: bold;">停用</span>
+          </template>
+      </el-table-column>
+      <!-- <el-table-column align="center" min-width="150px" label="备注" prop="remarks">
+      </el-table-column> -->
+
+      <el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.status == 1" type="success" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">启用</el-button>
+          <el-button v-if="scope.row.status == 0" type="warning" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">停用</el-button>
+          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="600px">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="110px">
+        <el-form-item label="物流公司名称" prop="logisticsName">
+          <el-input v-model="dataForm.logisticsName"></el-input>
+        </el-form-item>
+        <el-form-item label="快递查询代码" prop="queryCode">
+          <el-input v-model="dataForm.queryCode"></el-input>
+        </el-form-item>
+        <el-form-item label="菜鸟代码" prop="rookieCode">
+          <el-input v-model="dataForm.rookieCode"></el-input>
+        </el-form-item>
+        <!-- <el-form-item label="备注" prop="remarks">
+          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入"
+            v-model="dataForm.remarks">
+          </el-input>
+        </el-form-item> -->
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+<script>
+import { listExpress, createExpress, updateExpress, deleteExpress, setState } from '@/api/express'
+import waves from '@/directive/waves' // 水波纹指令
+
+export default {
+  directives: { waves },
+  data() {
+    return {
+      list: undefined,
+      total: undefined,
+      listLoading: true,
+      statusList: [
+                {
+                    type: 0,
+                    name: '启用'
+                },
+                {
+                    type: 1,
+                    name: '停用'
+                },
+            ],
+      listQuery: {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      },
+      dataForm: {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: '编辑',
+        create: '创建'
+      },
+      rules: {
+        logisticsName: [{ required: true, message: '物流公司名称不能为空', trigger: 'blur' }],
+        queryCode: [{ required: true, message: '快递查询代码不能为空', trigger: 'blur' }],
+        rookieCode: [{ required: true, message: '菜鸟代码不能为空', trigger: 'blur' }],
+      },
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.listQuery = {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      };
+      this.handleQuery();
+    },
+    getList() {
+      this.listLoading = true
+      listExpress(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+    handleQuery() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+    resetForm() {
+      this.dataForm = {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      }
+    },
+    handleCreate() {
+      this.resetForm()
+      this.dialogStatus = 'create'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    createData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          createExpress(this.dataForm).then(response => {
+            this.list.unshift(response.data.data)
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '创建成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row)
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateExpress(this.dataForm).then(() => {
+            for (const v of this.list) {
+              if (v.id === this.dataForm.id) {
+                const index = this.list.indexOf(v)
+                this.list.splice(index, 1, this.dataForm)
+                break
+              }
+            }
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '更新成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          deleteExpress({id:row.id}).then(response => {
+            this.$notify({
+              title: '成功',
+              message: '删除成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }).catch(() => {
+  
+        })
+    },
+    handleDownload() {
+      window.location.href = process.env.BASE_API + '/product/export';
+    },
+    changeState(id, status) {
+            setState({ id: id, status: status }).then(response => {
+                this.$notify({
+                    title: '成功',
+                    message: '状态修改成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+  }
+}
+</script>

+ 273 - 0
src/views/customer/vip.vue

@@ -0,0 +1,273 @@
+rookieCode<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="物流公司名称" v-model="listQuery.logisticsName">
+      </el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px;">
+                <el-option :key="item.type" v-for="item in statusList" :label="item.name" :value="item.type">
+                </el-option>
+            </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleQuery">查找</el-button>
+      <el-button class="filter-item" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleCreate">添加</el-button>
+      <!-- <el-button class="filter-item" v-waves icon="el-icon-download" @click="handleDownload">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="物流公司名称" prop="logisticsName">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="快递查询代码" prop="queryCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="80px" label="菜鸟代码" prop="rookieCode">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="50px" label="状态">
+          <template slot-scope="props">
+            <span v-if="props.row.status == 0" style="color: #67C23A;font-weight: bold;">启用</span>
+            <span v-if="props.row.status == 1" style="color: #E6A23C;font-weight: bold;">停用</span>
+          </template>
+      </el-table-column>
+      <!-- <el-table-column align="center" min-width="150px" label="备注" prop="remarks">
+      </el-table-column> -->
+
+      <el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.status == 1" type="success" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">启用</el-button>
+          <el-button v-if="scope.row.status == 0" type="warning" size="small"
+                        @click="changeState(scope.row.id, scope.row.status)">停用</el-button>
+          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="600px">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="110px">
+        <el-form-item label="物流公司名称" prop="logisticsName">
+          <el-input v-model="dataForm.logisticsName"></el-input>
+        </el-form-item>
+        <el-form-item label="快递查询代码" prop="queryCode">
+          <el-input v-model="dataForm.queryCode"></el-input>
+        </el-form-item>
+        <el-form-item label="菜鸟代码" prop="rookieCode">
+          <el-input v-model="dataForm.rookieCode"></el-input>
+        </el-form-item>
+        <!-- <el-form-item label="备注" prop="remarks">
+          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入"
+            v-model="dataForm.remarks">
+          </el-input>
+        </el-form-item> -->
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+<script>
+import { listExpress, createExpress, updateExpress, deleteExpress, setState } from '@/api/express'
+import waves from '@/directive/waves' // 水波纹指令
+
+export default {
+  directives: { waves },
+  data() {
+    return {
+      list: undefined,
+      total: undefined,
+      listLoading: true,
+      statusList: [
+                {
+                    type: 0,
+                    name: '启用'
+                },
+                {
+                    type: 1,
+                    name: '停用'
+                },
+            ],
+      listQuery: {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      },
+      dataForm: {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: '编辑',
+        create: '创建'
+      },
+      rules: {
+        logisticsName: [{ required: true, message: '物流公司名称不能为空', trigger: 'blur' }],
+        queryCode: [{ required: true, message: '快递查询代码不能为空', trigger: 'blur' }],
+        rookieCode: [{ required: true, message: '菜鸟代码不能为空', trigger: 'blur' }],
+      },
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.listQuery = {
+        page: 1,
+        limit: 10,
+        logisticsName: undefined,
+        status: undefined,
+      };
+      this.handleQuery();
+    },
+    getList() {
+      this.listLoading = true
+      listExpress(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+    handleQuery() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+    resetForm() {
+      this.dataForm = {
+        logisticsName: undefined,
+        queryCode: undefined,
+        rookieCode: undefined,
+        remarks: undefined,
+      }
+    },
+    handleCreate() {
+      this.resetForm()
+      this.dialogStatus = 'create'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    createData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          createExpress(this.dataForm).then(response => {
+            this.list.unshift(response.data.data)
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '创建成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row)
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateExpress(this.dataForm).then(() => {
+            for (const v of this.list) {
+              if (v.id === this.dataForm.id) {
+                const index = this.list.indexOf(v)
+                this.list.splice(index, 1, this.dataForm)
+                break
+              }
+            }
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '更新成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }
+      })
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          deleteExpress({id:row.id}).then(response => {
+            this.$notify({
+              title: '成功',
+              message: '删除成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+        }).catch(() => {
+  
+        })
+    },
+    handleDownload() {
+      window.location.href = process.env.BASE_API + '/product/export';
+    },
+    changeState(id, status) {
+            setState({ id: id, status: status }).then(response => {
+                this.$notify({
+                    title: '成功',
+                    message: '状态修改成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+  }
+}
+</script>