Sfoglia il codice sorgente

fix: 开发新需求

wuguojie 3 mesi fa
parent
commit
e7adf1d5b5
39 ha cambiato i file con 6172 aggiunte e 195 eliminazioni
  1. 24 0
      src/api/WxUser/user.js
  2. 49 0
      src/api/operation/carousel.js
  3. 59 0
      src/api/operation/fare.js
  4. 41 0
      src/api/operation/scopeMap.js
  5. 49 0
      src/api/serve/caetgory.js
  6. 48 0
      src/api/serve/project.js
  7. 67 0
      src/api/storedValue/cards.js
  8. 24 0
      src/api/storedValue/records.js
  9. 28 1
      src/api/system/dept.js
  10. 23 0
      src/api/tenant/alert.js
  11. 12 0
      src/api/tenant/attendance.js
  12. 19 0
      src/api/tenant/enterAudit.js
  13. 44 0
      src/api/tenant/list.js
  14. 1 1
      src/components/DictTag/index.vue
  15. 3 4
      src/views/WxUser/index.vue
  16. 403 0
      src/views/WxUser/user.vue
  17. 304 16
      src/views/carousel/index.vue
  18. 21 14
      src/views/comment/index.vue
  19. 131 128
      src/views/fare/index.vue
  20. 144 0
      src/views/finance/splitPaymentSettlement/index.vue
  21. 32 11
      src/views/mapDemo/addScopeMap.vue
  22. 15 7
      src/views/mapDemo/scopeMap.vue
  23. 234 0
      src/views/order/orderDetail/index.vue
  24. 304 0
      src/views/order/recycle/index.vue
  25. 102 0
      src/views/order/rules/index.vue
  26. 381 0
      src/views/order/serviceOrder/index.vue
  27. 259 0
      src/views/scopeMap/index.vue
  28. 280 0
      src/views/serve/category.vue
  29. 400 0
      src/views/serve/project.vue
  30. 363 0
      src/views/storedValue/cards.vue
  31. 172 0
      src/views/storedValue/records.vue
  32. 68 13
      src/views/system/dept/index.vue
  33. 262 0
      src/views/tenant/alert/index.vue
  34. 165 0
      src/views/tenant/attendance/index.vue
  35. 157 0
      src/views/tenant/attendanceRules/index.vue
  36. 217 0
      src/views/tenant/dynamic/index.vue
  37. 271 0
      src/views/tenant/enterAudit/index.vue
  38. 728 0
      src/views/tenant/list/index.vue
  39. 268 0
      src/views/tenant/skillAudit/index.vue

+ 24 - 0
src/api/WxUser/user.js

@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+
+
+/*
+    用户管理
+ */
+
+// 列表
+export function list (query) {
+    return request({
+        url: '/wx/pc/getUserList',
+        method: 'get',
+        params: query
+    })
+}
+
+// 购物金明细
+export function money(query) {
+    return request({
+        url: '/admin/shoppingFunds/getUserShoppingFundsDetail',
+        method: 'get',
+        params: query
+    })
+}

+ 49 - 0
src/api/operation/carousel.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+/*
+    轮播图
+ */
+// 新增
+export function addOrUpdate(query) {
+    return request({
+        url: '/api/lbt/v1/addOrUpdate',
+        method: 'post',
+        data: query
+    })
+}
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/api/lbt/v1/select',
+        method: 'get',
+        params: query
+    })
+}
+
+// 详情
+export function getById(query) {
+    return request({
+        url: '/api/lbt/v1/wx/getByid',
+        method: 'post',
+        data: query
+    })
+}
+
+// 删除
+export function del(query) {
+    return request({
+        url: '/api/lbt/v1/del',
+        method: 'post',
+        data: query
+    })
+}
+
+// 改变现实状态
+export function status(query) {
+    return request({
+        url: '/api/lbt/v1/status',
+        method: 'put',
+        data: query
+    })
+}

+ 59 - 0
src/api/operation/fare.js

@@ -0,0 +1,59 @@
+import request from '@/utils/request'
+
+/*
+    车费设置
+ */
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/tFareSetting/selectAll',
+        method: 'get',
+        params: query
+    })
+}
+
+// 新增
+export function add(query) {
+    return request({
+        url: '/tFareSetting/add',
+        method: 'post',
+        data: query
+    })
+}
+
+// 修改
+export function edit(query) {
+    return request({
+        url: '/tFareSetting/update',
+        method: 'post',
+        data: query
+    })
+}
+
+// 详情
+export function detail(id) {
+    return request({
+        url: `/tFareSetting/${id}`,
+        method: 'get'
+    })
+}
+
+// 城市查询
+export function citys() {
+    return request({
+        url: '/area/select',
+        method: 'get',
+        params: {
+            level: 2
+        }
+    })
+}
+
+// 删除
+export function del(id) {
+    return request({
+        url: `/tFareSetting/delete/${id}`,
+        method: 'delete'
+    })
+}

+ 41 - 0
src/api/operation/scopeMap.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+/*
+    地图围栏
+ */
+
+// 新增
+export function add(query) {
+    return request({
+        url: '/api/geoFence/v1/add',
+        method: 'post',
+        data: query
+    })
+}
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/api/geoFence/v1/select',
+        method: 'get',
+        params: query
+    })
+}
+
+// 编辑
+export function update(query) {
+    return request({
+        url: '/api/geoFence/v1/update',
+        method: 'post',
+        data: query
+    })
+}
+
+// 删除
+export function del(query) {
+    return request({
+        url: '/api/geoFence/v1/del',
+        method: 'post',
+        data: query
+    })
+}

+ 49 - 0
src/api/serve/caetgory.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+/*
+*   服务类目
+ */
+// 添加
+export function add(query) {
+    return request({
+        url: '/serviceCategory/add',
+        method: 'post',
+        data: query
+    })
+}
+
+// 查询
+export function list(query) {
+    return request({
+        url: '/serviceCategory/page',
+        method: 'get',
+        params: query
+    })
+}
+
+// 修改
+export function edit(query) {
+    return request({
+        url: '/serviceCategory/update',
+        method: 'post',
+        data: query
+    })
+}
+
+// 删除
+export function del(query) {
+    return request({
+        url: '/serviceCategory/delete',
+        method: 'post',
+        params: query
+    })
+}
+
+// 详情
+export function detail(query) {
+    return request({
+        url: '/serviceCategory/detail',
+        method: 'get',
+        params:query
+    })
+}

+ 48 - 0
src/api/serve/project.js

@@ -0,0 +1,48 @@
+import request from '@/utils/request'
+
+/*
+    服务项目
+ */
+
+// 列表
+export function lists(query) {
+    return request({
+        url: '/project/page',
+        method: 'get',
+        params: query
+    })
+}
+
+// 新增
+export function add(query) {
+    return request({
+        url: '/project',
+        method: 'post',
+        data: query
+    })
+}
+
+// 编辑
+export function edit(query) {
+    return request({
+        url: '/project',
+        method: 'put',
+        data: query
+    })
+}
+
+// 删除
+export function del(id) {
+    return request({
+        url: `/project/${id}`,
+        method: 'delete'
+    })
+}
+
+// 详情
+export function detail(id) {
+    return request({
+        url: `/project/${id}`,
+        method: 'get'
+    })
+}

+ 67 - 0
src/api/storedValue/cards.js

@@ -0,0 +1,67 @@
+import request from '@/utils/request'
+
+/*
+    购物卡管理
+ */
+
+// 新增
+export function add(query) {
+    return request({
+        url: '/gift/card/manage',
+        method: 'post',
+        data: query
+    })
+}
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/gift/card/manage/page',
+        method: 'get',
+        params: query
+    })
+}
+
+// 详情
+export function detail(id) {
+    return request({
+        url: `/gift/card/manage/${id}`,
+        method: 'get'
+    })
+}
+
+// 编辑
+export function edit(query) {
+    return request({
+        url: '/gift/card/manage',
+        method: 'put',
+        data: query
+    })
+}
+
+// 删除
+export function del(id) {
+    return request({
+        url: `/gift/card/manage/${id}`,
+        method: 'delete'
+    })
+}
+
+// 修改上架状态
+export function publish(query) {
+    return request({
+        url: '/gift/card/manage/publish',
+        method: 'put',
+        data: query
+    })
+}
+
+// 导出
+export function exportData(query) {
+    return request({
+        url: '/gift/card/manage/export',
+        method: 'post',
+        data: query,
+        responseType: 'blob'
+    })
+}

+ 24 - 0
src/api/storedValue/records.js

@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+
+
+/*
+    购物卡明细
+ */
+
+// 列表
+export function list (query) {
+    return request({
+        url: '/gift/card/order/page',
+        method: 'get',
+        params: query
+    })
+}
+
+// 导出
+export function exportData(query) {
+    return request({
+        url: '/gift/card/order/export',
+        method: 'post',
+        data: query
+    })
+}

+ 28 - 1
src/api/system/dept.js

@@ -25,6 +25,15 @@ export function getDept(deptId) {
   })
 }
 
+// 獲取部門
+export function getDeptList(data) {
+  return request({
+    url: '/system/dept/list',
+    method: 'get',
+    data:data
+  })
+}
+
 // 新增部门
 export function addDept(data) {
   return request({
@@ -49,4 +58,22 @@ export function delDept(deptId) {
     url: '/system/dept/' + deptId,
     method: 'delete'
   })
-}
+}
+
+// 部门树
+export function deptTree(query) {
+  return request({
+    url: '/system/user/deptTree',
+    method: 'get',
+    params: query
+  })
+}
+
+// 部门平铺数据
+export function deptList(query) {
+  return request({
+    url: '/system/dept/list',
+    method: 'get',
+    params: query
+  })
+}

+ 23 - 0
src/api/tenant/alert.js

@@ -0,0 +1,23 @@
+import request from '@/utils/request'
+
+/*
+    告警工单
+ */
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/alarm/getAlarmList',
+        method: 'get',
+        params: query
+    })
+}
+
+// 处理
+export function dealAlert(query) {
+    return request({
+        url: '/alarm/handleAlarm',
+        method: 'post',
+        data: query
+    })
+}

+ 12 - 0
src/api/tenant/attendance.js

@@ -0,0 +1,12 @@
+import request from '@/utils/request'
+
+/*
+    考勤配置
+ */
+export function rules(query) {
+    return request({
+        url: '/attendance/config',
+        method: 'post',
+        data: query
+    })
+}

+ 19 - 0
src/api/tenant/enterAudit.js

@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+// 列表
+export function list(query) {
+    return request({
+        url: '/technician/technician/merchant/audit/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 审核
+export function audit(id, query) {
+    return request({
+        url: `/technician/technician/merchant/audit/${id}/submit`,
+        method: 'put',
+        data: query
+    })
+}

+ 44 - 0
src/api/tenant/list.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+/*
+*   商户管理
+ */
+// 列表
+export function tenantList(query) {
+    return request({
+        url: '/technician/technician/merchant/list',
+        method: 'get',
+        params: query
+    })
+}
+// 添加
+export function add(query) {
+    return request({
+        url: '/technician/technician/merchant',
+        method: 'post',
+        data: query
+    })
+}
+// 详情
+export function detail (query) {
+    return request({
+        url: `/technician/technician/merchant/detail/${query}`,
+        method: 'get',
+    })
+}
+// 编辑
+export function edit (id, query) {
+    return request({
+        url: `/technician/technician/merchant/${id}`,
+        method: 'put',
+        data: query
+    })
+}
+// 上传合同
+export function upload (id, query) {
+    return request({
+        url: `/technician/technician/merchant/${id}/contract`,
+        method: 'post',
+        data: query
+    })
+}

+ 1 - 1
src/components/DictTag/index.vue

@@ -3,7 +3,7 @@
     <template v-for="(item, index) in options">
       <template v-if="values.includes(item.value)">
         <span
-          v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)"
+          v-if="(item.raw.listClass == 'default') && (item.raw.cssClass == '' || item.raw.cssClass == null)"
           :key="item.value"
           :index="index"
           :class="item.raw.cssClass"

+ 3 - 4
src/views/WxUser/index.vue

@@ -31,7 +31,7 @@
             clearable
             @keyup.enter.native="handleQuery"
           />
-        </el-form-item> 
+        </el-form-item>
         <el-form-item label="下单次数" prop="nNum">
           <el-input
             v-model="queryParams.nNum"
@@ -259,7 +259,7 @@
     </el-dialog>
   </div>
 </template>
-  
+
   <script>
 import {
   listUser,
@@ -292,7 +292,7 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
-      
+
       // 查询参数
       queryParams: {
         current: 1,
@@ -472,4 +472,3 @@ export default {
   padding: 30px 0;
 }
 </style>
-  

+ 403 - 0
src/views/WxUser/user.vue

@@ -0,0 +1,403 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="queryParams"
+            :inline="true"
+            label-width="100px"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="昵称:">
+                        <el-input style="width: 240px" v-model="queryParams.cNickName" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="电话:">
+                        <el-input style="width: 240px" v-model="queryParams.cPhone" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="创建时间:">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="queryParams.createTime"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="用户ID"></el-table-column>
+            <el-table-column prop="cIcon" label="图片">
+                <template #default="{ row }">
+                    <image-preview :src="row.cIcon" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="cNickName" label="昵称"></el-table-column>
+            <el-table-column prop="cPhone" label="电话"></el-table-column>
+            <el-table-column prop="a" label="地址">
+                <template #default="{ row }">
+                    <el-button type="text" @click="handleViewAddress(row)">查看</el-button>
+                </template>
+            </el-table-column>
+            <el-table-column prop="dMoney" label="消费金额"></el-table-column>
+            <el-table-column prop="nNum" label="下单次数"></el-table-column>
+            <el-table-column prop="dBalance" label="购物金"></el-table-column>
+            <el-table-column prop="dAllMoney" label="总收益"></el-table-column>
+            <el-table-column prop="currentPoints" label="当前积分"></el-table-column>
+            <el-table-column prop="totalPoints" label="累计积分"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间"></el-table-column>
+            <el-table-column label="操作" width="120">
+                <template #default="{ row }">
+                    <el-button type="text" @click="handlePoints(row)">积分</el-button>
+                    <el-button type="text" @click="handleShop(row)">购物金</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="queryParams.current"
+                :page-size="queryParams.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :visible.sync="dialogShow"
+            title="用户地址"
+        >
+            <el-table :data="addressTable">
+                <el-table-column type="index" label="序号" width="80"></el-table-column>
+                <el-table-column prop="a" label="地址"></el-table-column>
+                <el-table-column prop="a" label="姓名"></el-table-column>
+                <el-table-column prop="a" label="电话"></el-table-column>
+                <el-table-column prop="a" label="添加时间"></el-table-column>
+            </el-table>
+        </el-dialog>
+        <el-dialog
+            :visible.sync="drawerPointsShow"
+            title="用户积分详情"
+            width="1000px"
+        >
+            <el-form
+                :model="pointForm"
+                :inline="true"
+                label-width="90px"
+            >
+                <el-row :gutter="20">
+                    <el-col :span="8">
+                        <el-form-item label="积分项目:">
+                            <el-select style="width: 200px" v-model="pointForm.a" placeholder="请选择" clearable>
+                                <el-option label="1" value="1"></el-option>
+                            </el-select>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-form-item label="时间:">
+                            <el-date-picker
+                                style="width: 200px"
+                                v-model="pointForm.e"
+                                type="daterange"
+                                range-separator="至"
+                                start-placeholder="开始日期"
+                                end-placeholder="结束日期"
+                                value-format="yyyy-MM-dd"
+                                clearable
+                            />
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-button type="primary" @click="handlePointSearch">搜索</el-button>
+                        <el-button @click="handlePointReset">重置</el-button>
+                    </el-col>
+                </el-row>
+            </el-form>
+            <el-table
+                :data="pointTable"
+            >
+                <el-table-column prop="a" label="积分项目"></el-table-column>
+                <el-table-column prop="a" label="积分变化"></el-table-column>
+                <el-table-column prop="a" label="时间"></el-table-column>
+            </el-table>
+        </el-dialog>
+        <el-dialog
+            :visible.sync="drawerMoneyShow"
+            title="购物金明细"
+            width="1000px"
+        >
+            <div>
+                <h3 style="margin-top: 0">购物金:{{ shoppFunds.shoppingFundsBalance }}</h3>
+            </div>
+            <el-form
+                :model="moneyForm"
+                :inline="true"
+                label-width="90px"
+            >
+                <el-row :gutter="20">
+                    <el-col :span="10">
+                        <el-form-item label="时间:">
+                            <el-date-picker
+                                style="width: 240px"
+                                v-model="moneyForm.moneyTime"
+                                type="daterange"
+                                range-separator="至"
+                                start-placeholder="开始日期"
+                                end-placeholder="结束日期"
+                                value-format="yyyy-MM-dd"
+                                clearable
+                            />
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-button type="primary" @click="handleMoneySearch">搜索</el-button>
+                        <el-button @click="handleMoneyReset">重置</el-button>
+                    </el-col>
+                </el-row>
+            </el-form>
+            <div class="btns">
+                <div class="type">
+                    <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeindex(item, index)" v-for="(item, index) in typeList">{{ item }}</span>
+                </div>
+            </div>
+            <div class="sum">
+                <h3>总计:{{ shoppFunds.totalCount }}笔</h3>
+                <h3>合计:¥{{ shoppFunds.totalAmount }}</h3>
+            </div>
+            <el-table
+                :data="moneyTable"
+            >
+                <el-table-column prop="orderNo" label="订单号"></el-table-column>
+                <el-table-column v-if="typeIndex == 0" prop="giftCardName" label="购物卡名称"></el-table-column>
+                <el-table-column v-if="typeIndex == 0" prop="orderAmount" label="订单金额"></el-table-column>
+                <el-table-column v-if="typeIndex == 1" prop="orderAmount" label="支出金额"></el-table-column>
+                <el-table-column v-if="typeIndex == 0" prop="orderTime" label="购买时间"></el-table-column>
+                <el-table-column v-if="typeIndex == 1" prop="orderTime" label="支出时间"></el-table-column>
+            </el-table>
+            <div class="pagination">
+                <el-pagination
+                    v-show="moneyTotal > 0"
+                    small
+                    background
+                    @size-change="handleMoneySizeChange"
+                    @current-change="handleMoneyCurrentChange"
+                    :current-page="moneyForm.current"
+                    :page-size="moneyForm.size"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="total"
+                />
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { list, money } from '@/api/WxUser/user'
+import tab from "@/plugins/tab";
+
+export default {
+    name: "cards",
+    data() {
+        return {
+            queryParams: {
+                current: 1,
+                size: 10
+            },
+            total: 1,
+            table: [
+                {}
+            ],
+            dialogShow: false,
+            addressTable: [
+                {}
+            ],
+            drawerPointsShow: false,
+            pointForm: {},
+            pointTable: [
+                {}
+            ],
+            drawerMoneyShow: false,
+            typeList: [ '购买', '支出' ],
+            typeIndex: 0,
+            moneyForm: {
+                current: 1,
+                size: 10,
+                type: 0
+            },
+            moneyTable: [
+                {}
+            ],
+            moneyTotal: 1,
+            userId: '',
+            shoppFunds: {
+                shoppingFundsBalance: 0,
+                totalAmount: 0,
+                totalCount: 0
+            }
+        }
+    },
+    methods: {
+        initData() {
+            let obj = {
+                cNickName: this.queryParams.cNickName,
+                cPhone: this.queryParams.cPhone,
+                startTime: this.queryParams.createTime?.[0],
+                endTime: this.queryParams.createTime?.[1],
+            }
+            list({
+                ...obj
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.date.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleSizeChange(size) {
+            this.queryParams.size = size
+            this.initData()
+        },
+        handleCurrentChange(page) {
+            this.queryParams.current = page
+            this.initData()
+        },
+        handleViewAddress(row) {
+            this.dialogShow = true
+        },
+        handlePoints(row) {
+
+        },
+        handleShop(row) {
+            this.drawerMoneyShow = true
+            this.userId = row.id
+            this.initMoney();
+        },
+        initMoney() {
+            let obj = {
+                userId: this.userId,
+                detailType: this.moneyForm.type,
+                startTime: this.moneyForm.moneyTime?.[0],
+                endTime: this.moneyForm.moneyTime?.[1]
+            }
+            money({
+                ...obj
+            }).then(res => {
+                if(res.code == 200) {
+                    this.moneyTable = res.data.page.records
+                    this.moneyTotal = res.data.page.total
+                    this.shoppFunds.shoppingFundsBalance = res.data.shoppingFundsBalance
+                    this.shoppFunds.totalAmount = res.data.totalAmount
+                    this.shoppFunds.totalCount = res.data.totalCount
+                }
+            })
+        },
+        handlePointSearch() {
+
+        },
+        handlePointReset() {
+
+        },
+        handleMoneySearch() {
+            this.moneyForm.current = 1
+            this.moneyForm.size = 10
+            this.initMoney();
+        },
+        handleMoneyReset() {
+            this.moneyForm = {
+                current: 1,
+                size: 10,
+                type: 0
+            }
+            this.initMoney();
+        },
+        handleTypeindex(item, index) {
+            this.typeIndex = index
+            switch (item) {
+                case '购买':
+                    this.moneyForm.type = 0
+                    break;
+                case '支出':
+                    this.moneyForm.type = 1
+                    break;
+            }
+            this.initMoney();
+        },
+        handleMoneyCurrentChange(page) {
+            this.moneyForm.current = page
+            this.initMoney();
+        },
+        handleMoneySizeChange(size) {
+            this.moneyForm.size = size
+            this.initMoney();
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.sum{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 304 - 16
src/views/carousel/index.vue

@@ -1,14 +1,15 @@
+<!--
 <template>
     <div class="app-container">
       <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-        <!-- <el-form-item label="是否删除0否1是" prop="nDel">
+        &lt;!&ndash; <el-form-item label="是否删除0否1是" prop="nDel">
           <el-input
             v-model="queryParams.nDel"
             placeholder="请输入是否删除0否1是"
             clearable
             @keyup.enter.native="handleQuery"
           />
-        </el-form-item> -->
+        </el-form-item> &ndash;&gt;
         <el-form-item label="标题" prop="cSort">
           <el-input
             v-model="queryParams.cDescribe"
@@ -33,7 +34,7 @@
             @click="handleAdd"
           >新增</el-button>
         </el-col>
-        <!-- <el-col :span="1.5">
+        &lt;!&ndash; <el-col :span="1.5">
           <el-button
             type="success"
             plain
@@ -64,24 +65,24 @@
             @click="handleExport"
             v-hasPermi="['system:lbt:export']"
           >导出</el-button>
-        </el-col>-->
-        <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
+        </el-col>&ndash;&gt;
+        &lt;!&ndash; <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> &ndash;&gt;
       </el-row>
 
       <el-table v-loading="loading" :data="lbtList" @selection-change="handleSelectionChange">
 
-        <!-- <el-table-column type="selection" width="55" align="center" /> -->
+        &lt;!&ndash; <el-table-column type="selection" width="55" align="center" /> &ndash;&gt;
         <el-table-column label="序号" align="center" prop="cSort" />
-        <!-- <el-table-column label="主键" align="center" prop="cId" /> -->
-        <!-- <el-table-column label="图片地址" align="center" prop="cImgUrl" /> -->
+        &lt;!&ndash; <el-table-column label="主键" align="center" prop="cId" /> &ndash;&gt;
+        &lt;!&ndash; <el-table-column label="图片地址" align="center" prop="cImgUrl" /> &ndash;&gt;
         <el-table-column label="图片" align="center" prop="cImgUrl" width="100">
           <template slot-scope="scope">
             <image-preview :src="scope.row.cImgUrl" :width="50" :height="50"/>
           </template>
         </el-table-column>
-        <!-- <el-table-column label="是否删除0否1是" align="center" prop="nDel" /> -->
+        &lt;!&ndash; <el-table-column label="是否删除0否1是" align="center" prop="nDel" /> &ndash;&gt;
         <el-table-column label="标题" align="center" prop="cDescribe" />
-        <!-- <el-table-column label="文本内容" align="center" prop="cContent" /> -->
+        &lt;!&ndash; <el-table-column label="文本内容" align="center" prop="cContent" /> &ndash;&gt;
         <el-table-column label="内容" align="center" >
             <template slot-scope="scope">
                 <div class="contentClass" v-html="scope.row.cContent"></div>
@@ -115,14 +116,14 @@
         layout="total, sizes, prev, pager, next, jumper"
         :total="total">
       </el-pagination>
-      <!-- 添加或修改轮播图对话框 -->
+      &lt;!&ndash; 添加或修改轮播图对话框 &ndash;&gt;
       <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
         <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-          <!-- <el-form-item label="图片地址" prop="cImgUrl">
+          &lt;!&ndash; <el-form-item label="图片地址" prop="cImgUrl">
             <el-input v-model="form.cImgUrl" type="textarea" placeholder="请输入内容" />
-          </el-form-item> -->
+          </el-form-item> &ndash;&gt;
           <el-form-item label="上传图片" prop="cImgUrl">
-            <!-- <el-input v-model="form.cImgUrl" type="textarea" placeholder="请输入内容" /> -->
+            &lt;!&ndash; <el-input v-model="form.cImgUrl" type="textarea" placeholder="请输入内容" /> &ndash;&gt;
             <el-upload
                 action="#"
                 class="avatar-uploader"
@@ -134,9 +135,9 @@
                 <i v-else class="el-icon-plus avatar-uploader-icon"></i>
             </el-upload>
           </el-form-item>
-          <!-- <el-form-item label="是否删除0否1是" prop="nDel">
+          &lt;!&ndash; <el-form-item label="是否删除0否1是" prop="nDel">
             <el-input v-model="form.nDel" placeholder="请输入是否删除0否1是" />
-          </el-form-item> -->
+          </el-form-item> &ndash;&gt;
           <el-form-item label="标题" prop="cDescribe">
             <el-input v-model="form.cDescribe" type="textarea" placeholder="请输入内容" />
           </el-form-item>
@@ -375,3 +376,290 @@
     padding: 30px 0;
   }
 </style>
+-->
+
+<template>
+    <div class="app-container">
+        <el-form
+                :model="auditForm"
+                label-width="68px"
+                :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="轮播标题">
+                        <el-input style="width: 240px" v-model="auditForm.title" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="显示状态">
+                        <el-select style="width: 240px" v-model="auditForm.status" clearable>
+                            <el-option label="隐藏" value="0"></el-option>
+                            <el-option label="显示" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+<!--                <el-col :span="6">
+                    <el-form-item label="类型">
+                        <el-select style="width: 240px" v-model="auditForm.type" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>-->
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button size="small" icon="el-icon-plus" type="primary" @click="handleAdd">新增</el-button>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="sort" label="序号" width="80"></el-table-column>
+            <el-table-column prop="title" label="标题"></el-table-column>
+            <el-table-column prop="imgUrl" label="图像">
+                <template #default="{ row }">
+                    <image-preview :src="row.imgUrl" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="jumpUrl" label="跳转地址"></el-table-column>
+            <el-table-column prop="status" label="显示">
+                <template #default="{ row }">
+                    <el-switch v-model="row.status" :active-value="1" :inactive-value="0" @change="handleStatus(row)"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="createTime" label="创建时间"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-button size="small" type="text" icon="el-icon-delete" @click="handleDel(row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                    v-show="total > 0"
+                    background
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                    :current-page="auditForm.current"
+                    :page-size="auditForm.size"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="total"
+            />
+        </div>
+        <el-dialog
+                :title="title"
+                :visible.sync="dialogShow"
+                width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="120px"
+                :rules="addRules"
+            >
+                <el-form-item label="标题" prop="title">
+                    <el-input style="width: 240px" v-model="addForm.title" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="图像" prop="imgUrl">
+                    <ImageUpload v-model="addForm.imgUrl" :file-size="3" :limit="1" />
+                </el-form-item>
+                <el-form-item label="跳转的地址" prop="jumpUrl">
+                    <el-input style="width: 240px" v-model="addForm.jumpUrl" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="排序" prop="sort">
+                    <el-input-number style="width: 240px" v-model="addForm.sort" placeholder="请填写" clearable />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <el-button @click="handleCancel">取消</el-button>
+                <el-button type="primary" @click="handleSave">确定</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { addOrUpdate, list, getById, del, status } from '@/api/operation/carousel'
+export default {
+    name: "audit",
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            auditForm: {
+                current: 1,
+                size: 10
+            },
+            table: [],
+            total: 0,
+            dialogProjectShow: false,
+            projectTable: [],
+            title: '新增',
+            dialogShow: false,
+            addForm: {},
+            addRules: {
+                title: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                imgUrl: [
+                    { required: true, message: '请上传', trigger: 'change' }
+                ],
+            },
+            editId: ''
+        }
+    },
+    methods: {
+        initData() {
+            list({
+                ...this.auditForm
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSizeChange(size) {
+            this.auditForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.auditForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.initData();
+        },
+        handleReset() {
+            this.initData();
+        },
+        handleAdd() {
+            this.title = '新增'
+            this.dialogShow = true
+        },
+        handleEdit(row) {
+            this.title = '编辑'
+            this.dialogShow = true
+            this.editId = row.id
+            getById({
+                id: this.editId
+            }).then(res => {
+                if(res.code == 200) {
+                    this.addForm = res.data
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    del({
+                        id: row.id
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.initData();
+                            this.$message.success(res.msg)
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                })
+                .catch(() => {});
+        },
+        handleCancel() {
+            this.dialogShow = false
+            this.addForm = {}
+        },
+        handleSave() {
+            this.$refs.addFormRefs.validate((valid) => {
+                if(!valid) return
+                if(this.editId) {
+                    addOrUpdate({
+                        id: this.editId,
+                        ...this.addForm
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.$message.success(res.msg)
+                            this.dialogShow = false
+                            this.addForm = {}
+                            this.initData();
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                } else {
+                    addOrUpdate({
+                        ...this.addForm
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.$message.success(res.msg)
+                            this.dialogShow = false
+                            this.addForm = {}
+                            this.initData();
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                }
+            })
+        },
+        handleStatus(row) {
+            status({
+                id: row.id,
+                status: row.status
+            }).then(res => {
+                if(res.code == 200) {
+                    this.initData();
+                    this.$message.success(res.msg)
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  .type{
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .typeItem{
+      padding: 5px 15px;
+      border-radius: 4px;
+      font-size: 14px;
+      margin: 0 10px 0 0;
+      cursor: pointer;
+      border: 1px solid #ccc;
+    }
+    .active{
+      background: #1890ff;
+      color: white;
+      border-color: #1890ff;
+    }
+  }
+}
+.pagination{
+  margin-top: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+}
+</style>
+

+ 21 - 14
src/views/comment/index.vue

@@ -13,7 +13,7 @@
         <el-select
           v-model="queryParams.sensitiveWord"
           placeholder="请选择"
-          clearable 
+          clearable
         >
           <el-option
             v-for="item in dict.type.local_status"
@@ -28,7 +28,7 @@
         <el-select
           v-model="queryParams.auditStatus"
           placeholder="请选择"
-          clearable 
+          clearable
         >
           <el-option
             v-for="item in dict.type.local_comment_audit"
@@ -99,7 +99,7 @@
           v-hasPermi="['system:comment:export']"
         >批量审核</el-button>
       </el-col>
-      <el-col :span="1.5">
+<!--      <el-col :span="1.5">
         <el-button
           type="primary"
           plain
@@ -108,24 +108,31 @@
           @click="handleImport"
           v-hasPermi="['system:comment:export']"
         >敏感词库维护</el-button>
-      </el-col>
+      </el-col>-->
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <el-table v-loading="loading" :data="commentList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="评论人昵称" align="left" prop="nickName" width="100" />
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column type="index" label="序号" width="55" align="center" />
+        <el-table-column label="评论人昵称" align="left" prop="nickName" width="100" />
+        <el-table-column label="用户头像" align="left" prop="nickName" width="100" >
+            <template #default="{ row }">
+                <image-preview :src="row.icon" :width="80" :height="80" />
+            </template>
+        </el-table-column>
       <el-table-column label="评论内容" align="left" prop="text" width="400" show-overflow-tooltip />
       <el-table-column label="评论分数" align="center" prop="star" />
-      <el-table-column label="评论时间" align="center" prop="commentTime" width="180" />
-      <el-table-column label="技师姓名" align="center" prop="name" />
+        <el-table-column label="评论时间" align="center" prop="commentTime" width="180" />
+        <el-table-column label="订单号ID" align="center" prop="a" width="180" />
+<!--      <el-table-column label="技师姓名" align="center" prop="name" />
       <el-table-column label="敏感词" align="center" prop="sensitiveWord">
         <template slot-scope="scope">
           <span :style="{
             color: scope.row.sensitiveWord == 1 ? '#F56C6C' : '#606266'
           }">{{ dict.label.local_status[scope.row.sensitiveWord] }}</span>
         </template>
-      </el-table-column>
+      </el-table-column>-->
       <el-table-column label="审核状态" align="center" prop="auditStatus">
         <template slot-scope="scope">
           <span>{{ dict.label.local_comment_audit[scope.row.auditStatus] }}</span>
@@ -159,7 +166,7 @@
             v-hasPermi="['system:comment:remove']"
           >删除</el-button>
         </template>
-      </el-table-column> 
+      </el-table-column>
     </el-table>
     <pagination
       v-show="total > 0"
@@ -240,12 +247,12 @@
     <AuditModal ref="aModal" @close="getList" />
   </div>
 </template>
-  
+
 <script>
   import { getToken } from "@/utils/auth";
   import { listComment, getComment, delComment, addComment, updateComment } from "@/api/system/comment";
   import AuditModal from "./auditModal.vue";
-  
+
   export default {
     name: "Comment",
     dicts: ['local_comment_audit', 'local_status'],
@@ -289,7 +296,7 @@
         form: {},
         // 表单校验
         rules: {},
-        
+
         // 用户导入参数
         upload: {
           // 是否显示弹出层(用户导入)
@@ -443,4 +450,4 @@
 
 <style scoped>
 
-</style>
+</style>

+ 131 - 128
src/views/fare/index.vue

@@ -42,16 +42,17 @@
       </el-form-item> -->
       <el-form-item label="城市:">
         <el-select
-          v-model="queryParams.deptName"
+          v-model="queryParams.cityCode"
           placeholder="请选择"
           @change="handleSelection"
           clearable
+          filterable
         >
           <el-option
             v-for="item in options"
-            :key="item.deptId"
-            :label="item.deptName"
-            :value="item.deptName"
+            :key="item.code"
+            :label="item.name"
+            :value="item.code"
           >
           </el-option>
         </el-select>
@@ -121,31 +122,20 @@
     </el-row>
 
     <el-table v-loading="loading" :data="settingList">
-      <!-- <el-table-column type="selection" width="55" align="center" /> -->
-      <el-table-column label="编号" align="center" prop="id" />
-      <el-table-column label="部门名称" align="center" prop="deptName" />
-      <el-table-column label="起步价" align="center" prop="baseFare" />
-      <el-table-column label="起步距离" align="center" prop="baseDistance" />
-      <el-table-column
-        label="超出起步价后每公里费用"
-        align="center"
-        prop="additionalFarePer"
-      />
-      <el-table-column label="是否启用" align="center" prop="enable">
-        <template slot-scope="scope">
-          {{ scope.row.enable === 0 ? "已停用" : "已启用 " }}
-          <!-- <el-switch
-            v-model="scope.row.enable"
-            inline-prompt
-            :active-value="1"
-            :inactive-value="0"
-            @change="changeStatus(scope.row)"
-          ></el-switch> -->
-        </template>
-      </el-table-column>
-      <!-- <el-table-column label="部门id" align="center" prop="deptId" /> -->
-
-      <!-- <el-table-column label="是否删除0否1是" align="center" prop="isDelete" /> -->
+        <el-table-column type="index" label="序号" width="55" align="center" />
+        <el-table-column label="编号" align="center" prop="id" width="180" />
+        <el-table-column label="城市" align="center" prop="cityName" />
+        <el-table-column label="日间起步价" align="center" prop="daytimeBaseFare" />
+        <el-table-column label="日间起步距离" align="center" prop="daytimeBaseDistance" />
+        <el-table-column label="日间超出起步每公里费用" align="center" prop="daytimeAdditionalFarePer" width="180" />
+        <el-table-column label="夜间起步价" align="center" prop="nightBaseFare" />
+        <el-table-column label="夜间起步距离" align="center" prop="nightBaseDistance" />
+        <el-table-column label="夜间超出起步每公里费用" align="center" prop="nightAdditionalFarePer" width="180" />
+        <el-table-column label="是否启用" align="center" prop="enable">
+          <template slot-scope="scope">
+            {{ scope.row.enable === 0 ? "已停用" : "已启用 " }}
+          </template>
+        </el-table-column>
       <el-table-column
         label="操作"
         align="center"
@@ -175,34 +165,46 @@
     <pagination
       v-show="total > 0"
       :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
+      :page.sync="queryParams.current"
+      :limit.sync="queryParams.size"
       @pagination="getList"
     />
 
     <!-- 添加或修改车费设置对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="180px">
-        <el-form-item label="起步价" prop="baseFare">
-          <el-input v-model="form.baseFare" placeholder="请输入起步价" />
-        </el-form-item>
-        <el-form-item label="起步距离" prop="baseDistance">
-          <el-input v-model="form.baseDistance" placeholder="请输入起步距离" />
-        </el-form-item>
-        <el-form-item label="超出起步价后每公里费用" prop="additionalFarePer">
-          <el-input
-            v-model="form.additionalFarePer"
-            placeholder="请输入超出起步价后每公里费用"
-          />
-        </el-form-item>
+      <el-form ref="form" :model="form" :rules="rules" label-width="200px">
+          <el-form-item label="日间起步价" prop="daytimeBaseFare">
+              <el-input v-model="form.daytimeBaseFare" placeholder="请输入起步价" />
+          </el-form-item>
+          <el-form-item label="日间起步距离" prop="daytimeBaseDistance">
+              <el-input v-model="form.daytimeBaseDistance" placeholder="请输入起步距离" />
+          </el-form-item>
+          <el-form-item label="日间超出起步价后每公里费用" prop="daytimeAdditionalFarePer">
+              <el-input
+                      v-model="form.daytimeAdditionalFarePer"
+                      placeholder="请输入超出起步价后每公里费用"
+              />
+          </el-form-item>
+          <el-form-item label="夜间起步价" prop="nightBaseFare">
+              <el-input v-model="form.nightBaseFare" placeholder="请输入起步价" />
+          </el-form-item>
+          <el-form-item label="夜间起步距离" prop="nightBaseDistance">
+              <el-input v-model="form.nightBaseDistance" placeholder="请输入起步距离" />
+          </el-form-item>
+          <el-form-item label="夜间超出起步价后每公里费用" prop="nightAdditionalFarePer">
+              <el-input
+                      v-model="form.nightAdditionalFarePer"
+                      placeholder="请输入超出起步价后每公里费用"
+              />
+          </el-form-item>
         <el-form-item label="城市:">
-          <el-select v-model="form.deptName" placeholder="请选择">
+          <el-select v-model="form.cityCode" placeholder="请选择" filterable clearable>
             <el-option
               @click.native="handleSelectTeam(item)"
               v-for="item in options"
-              :key="item.deptId"
-              :label="item.deptName"
-              :value="item.deptName"
+              :key="item.code"
+              :label="item.name"
+              :value="item.code"
             >
             </el-option>
           </el-select>
@@ -212,7 +214,8 @@
             v-model="enable"
             active-text="启用"
             inactive-text="关闭"
-            change
+            :active-value="1"
+            :inactive-value="0"
           >
           </el-switch>
         </el-form-item>
@@ -233,15 +236,16 @@
     </el-dialog>
   </div>
 </template>
-  
+
   <script>
-import {
-  farelist,
-  getSetting,
-  delSetting,
-  addSetting,
-  updateSetting,
-} from "@/api/system/setting";
+// import {
+//   farelist,
+//   getSetting,
+//   delSetting,
+//   addSetting,
+//   updateSetting,
+// } from "@/api/system/setting";
+import { list, add, edit, detail, citys, del } from '@/api/operation/fare'
 import { getDept } from "@/api/system/js";
 
 export default {
@@ -268,15 +272,8 @@ export default {
       open: false,
       // 查询参数
       queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        baseFare: null,
-        baseDistance: null,
-        additionalFarePer: null,
-        enable: null,
-        deptId: null,
-        deptName: null,
-        isDelete: null,
+        current: 1,
+        size: 10,
       },
       // 表单参数
       form: {},
@@ -295,35 +292,42 @@ export default {
   methods: {
     //选择部门
     handleSelectTeam(item) {
-      this.form.deptId = item.deptId;
-      this.form.deptName = item.deptName;
-    },
-    changeStatus(row) {
-      this.form.additionalFarePer = row.additionalFarePer;
-      this.form.baseDistance = row.baseDistance;
-      this.form.baseFare = row.baseFare;
-      this.form.enable = row.enable;
-      this.form.deptId = row.deptId;
-      this.form.deptName = row.deptName;
-      this.form.id = row.id;
-      updateSetting(this.form).then((res) => {
-        if (res.code == 200) {
-          this.$modal.msgSuccess("修改成功");
-          this.resetQuery();
-          return true;
-        } else {
-          this.$modal.msgError(res.msg);
-          this.resetQuery();
-          return false;
-        }
-      });
+      this.form.cityCode = item.code;
+      this.form.cityName = item.name;
     },
+    // changeStatus(row) {
+    //   this.form.additionalFarePer = row.additionalFarePer;
+    //   this.form.baseDistance = row.baseDistance;
+    //   this.form.baseFare = row.baseFare;
+    //   this.form.enable = row.enable;
+    //   this.form.deptId = row.deptId;
+    //   this.form.cityName = row.cityName;
+    //   this.form.id = row.id;
+    //   updateSetting(this.form).then((res) => {
+    //     if (res.code == 200) {
+    //       this.$modal.msgSuccess("修改成功");
+    //       this.resetQuery();
+    //       return true;
+    //     } else {
+    //       this.$modal.msgError(res.msg);
+    //       this.resetQuery();
+    //       return false;
+    //     }
+    //   });
+    // },
     change(row) {},
     // 获取部门
     getDeptList() {
-      getDept().then((res) => {
-        this.options = res.data;
-      });
+      // getDept().then((res) => {
+      //   this.options = res.data;
+      // });
+        citys().then(res => {
+            if(res.code == 200) {
+                this.options = res.data
+            } else {
+                this.$message.error(res.msg)
+            }
+        })
     },
     /** 提交按钮 */
     submitForm() {
@@ -342,14 +346,14 @@ export default {
       //   if (valid) {
       if (this.form.id != null) {
         this.enable == true ? (this.form.enable = 1) : (this.form.enable = 0);
-        updateSetting(this.form).then((response) => {
+        edit(this.form).then((response) => {
           this.$modal.msgSuccess("修改成功");
           this.open = false;
           this.getList();
         });
       } else {
         this.enable == true ? (this.form.enable = 1) : (this.form.enable = 0);
-        addSetting(this.form).then((response) => {
+        add(this.form).then((response) => {
           this.$modal.msgSuccess("新增成功");
           this.open = false;
           this.getList();
@@ -361,7 +365,7 @@ export default {
     /** 查询车费设置列表 */
     getList() {
       this.loading = true;
-      farelist(this.queryParams).then((response) => {
+        list(this.queryParams).then((response) => {
         this.settingList = response.data.records;
         this.total = response.data.total;
         this.loading = false;
@@ -381,7 +385,7 @@ export default {
         additionalFarePer: null,
         enable: null,
         deptId: null,
-        deptName: null,
+        cityName: null,
         createTime: null,
         updateTime: null,
         isDelete: null,
@@ -390,23 +394,16 @@ export default {
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.queryParams.pageSize = 10;
+      this.queryParams.current = 1;
+      this.queryParams.size = 10;
       this.getList();
     },
     /** 重置按钮操作 */
     resetQuery() {
       this.queryParams = {
-        id: null,
-        baseFare: null,
-        baseDistance: null,
-        additionalFarePer: null,
-        enable: null,
-        deptId: null,
-        deptName: null,
-        createTime: null,
-        updateTime: null,
-        isDelete: null,
+          current: 1,
+          size: 10,
+          cityName: ''
       };
       this.handleQuery();
     },
@@ -427,31 +424,38 @@ export default {
     handleUpdate(row) {
       this.reset();
       this.open = true;
-      this.form.additionalFarePer = row.additionalFarePer;
-      this.form.baseDistance = row.baseDistance;
-      this.form.baseFare = row.baseFare;
-      row.enable == 0 ? (this.enable = false) : (this.enable = true);
-      this.form.deptId = row.deptId;
-      this.form.deptName = row.deptName;
-      this.form.id = row.id;
+      // this.form.additionalFarePer = row.additionalFarePer;
+      // this.form.baseDistance = row.baseDistance;
+      // this.form.baseFare = row.baseFare;
+      // row.enable == 0 ? (this.enable = false) : (this.enable = true);
+      // this.form.deptId = row.deptId;
+      // this.form.cityName = row.cityName;
+      // this.form.id = row.id;
       this.title = "修改车费设置";
+      detail(row.id).then(res => {
+          if(res.code ==200) {
+              this.form = res.data
+              this.form.enable = `${res.data.enable}`
+          } else {
+              this.$message.error(res.msg)
+          }
+      })
     },
 
     /** 删除按钮操作 */
     handleDelete(row) {
-      //   const ids = row.id || this.ids;
-      let idList = [];
-      idList.push(row.id);
-      this.$modal
-        .confirm('是否确认删除车费设置编号为"' + row.id + '"的数据项?')
-        .then(function () {
-          return delSetting(idList);
-        })
-        .then(() => {
-          this.getList();
-          this.$modal.msgSuccess("删除成功");
-        })
-        .catch(() => {});
+        this.$modal.confirm('是否确认删除?')
+            .then(() => {
+                del(row.id).then(res => {
+                    if(res.code == 200) {
+                        this.getList()
+                        this.$message.success(res,msg)
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                })
+            })
+            .catch(() => {});
     },
     /** 导出按钮操作 */
     handleExport() {
@@ -466,4 +470,3 @@ export default {
   },
 };
 </script>
-  

+ 144 - 0
src/views/finance/splitPaymentSettlement/index.vue

@@ -0,0 +1,144 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="queryParams"
+            :inline="true"
+            label-width="100px"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="商户姓名:">
+                        <el-input style="width: 240px" v-model="queryParams.a" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="下单时间:">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="queryParams.e"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="订单ID:">
+                        <el-input style="width: 240px" v-model="queryParams.a" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                    <el-button type="primary" @click="handleExport">导出</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="a" label="订单ID"></el-table-column>
+            <el-table-column prop="a" label="项目名称"></el-table-column>
+            <el-table-column prop="a" label="订单总金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.a }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="优惠券抵扣金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.a }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="实付金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.a }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="商户应收金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.a }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="平台应收金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.a }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="商户姓名"></el-table-column>
+            <el-table-column prop="a" label="商户账户"></el-table-column>
+            <el-table-column prop="a" label="优惠券平台成本"></el-table-column>
+            <el-table-column prop="a" label="优惠券商家成本"></el-table-column>
+            <el-table-column prop="a" label="结算时间"></el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="queryParams.current"
+                :page-size="queryParams.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+    </div>
+</template>
+
+<script>
+import {del, detail} from "@/api/serve/caetgory";
+
+export default {
+    name: "cards",
+    data() {
+        return {
+            queryParams: {
+                current: 1,
+                size: 10
+            },
+            total: 1,
+            table: [
+                {}
+            ],
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSearch() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleExport() {
+
+        },
+        handleSizeChange(size) {
+            this.queryParams.size = size
+            this.initData()
+        },
+        handleCurrentChange(page) {
+            this.queryParams.current = page
+            this.initData()
+        },
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 32 - 11
src/views/mapDemo/addScopeMap.vue

@@ -53,7 +53,7 @@
     <!-- 底部按钮 -->
     <div class="footer-btns">
       <el-button @click="handleCancel">取消</el-button>
-      <el-button @click="handleSave">保存</el-button>
+      <el-button @click="handleSave" type="primary">保存</el-button>
     </div>
   </div>
 </template>
@@ -63,11 +63,26 @@ import AMapLoader from '@amap/amap-jsapi-loader'
 
 const AMAP_KEY = '41bc0f647d4432045d472f554bf03d75'
 const AMAP_SECURITY = '80ba66cc0bba5b07de6a275d7aa02a39'
-const DEFAULT_CENTER = [116.397428, 39.90923]
-const DEFAULT_RADIUS_KM = 1
+// const DEFAULT_CENTER = [116.397428, 39.90923]
+// const DEFAULT_RADIUS_KM = 1
 
 export default {
   name: 'AddScopeMap',
+  props: {
+    center: {
+        type: Array,
+        default: [116.397428, 39.90923]
+    },
+    point: {
+      type: Object,
+      default: {
+          name: '',
+          intro: '',
+          radius: 1,
+          riskLevel: ''
+      }
+    }
+  },
   data() {
     const validateRadius = (rule, value, callback) => {
       if (value === '' || value === null || value === undefined) {
@@ -88,7 +103,7 @@ export default {
       form: {
         name: '',
         intro: '',
-        radius: String(DEFAULT_RADIUS_KM),
+        radius: String(this.point.radius),
         riskLevel: ''
       },
       rules: {
@@ -102,6 +117,7 @@ export default {
         lat: null,
         province: '',
         city: '',
+        cityCode: '',
         district: '',
         address: ''
       },
@@ -115,6 +131,7 @@ export default {
   },
   mounted() {
     this.initMap()
+      this.form = this.point
   },
   beforeDestroy() {
     this.destroyMap()
@@ -131,7 +148,7 @@ export default {
         this.map = new AMap.Map(this.mapId, {
           resizeEnable: true,
           zoom: 14,
-          center: DEFAULT_CENTER,
+          center: this.center,
           viewMode: '2D'
         })
         this.placeSearch = new AMap.PlaceSearch({
@@ -142,7 +159,7 @@ export default {
           radius: 1000,
           extensions: 'all'
         })
-        this.setMapPoint(DEFAULT_CENTER[0], DEFAULT_CENTER[1], '默认位置')
+        this.setMapPoint(this.center[0], this.center[1], this.point.name)
       }).catch((err) => {
         console.error('地图加载失败', err)
         this.$message.error('地图加载失败,请检查网络或 Key 配置')
@@ -151,7 +168,7 @@ export default {
 
     getRadiusMeters() {
       const km = Number(this.form.radius)
-      if (Number.isNaN(km) || km <= 0) return DEFAULT_RADIUS_KM * 1000
+      if (Number.isNaN(km) || km <= 0) return km * 1000
       return km * 1000
     },
 
@@ -217,6 +234,7 @@ export default {
               lat,
               province: comp.province || '',
               city: comp.city || comp.province || '',
+              cityCode: comp.adcode,
               district: comp.district || '',
               address: result.regeocode.formattedAddress || ''
             }
@@ -308,7 +326,7 @@ export default {
       this.form = {
         name: '',
         intro: '',
-        radius: String(DEFAULT_RADIUS_KM),
+        radius: String(this.point.radius),
         riskLevel: ''
       }
       this.locationInfo = {
@@ -316,11 +334,13 @@ export default {
         lat: null,
         province: '',
         city: '',
+        cityCode: '',
         district: '',
         address: ''
       }
       this.$refs.form && this.$refs.form.resetFields()
-      this.setMapPoint(DEFAULT_CENTER[0], DEFAULT_CENTER[1], '默认位置')
+      this.setMapPoint(this.center[0], this.center[1], '默认位置')
+        this.$emit('scopeMapCancel')
     },
 
     handleSave() {
@@ -340,6 +360,7 @@ export default {
           address: this.locationInfo.address,
           province: this.locationInfo.province,
           city: this.locationInfo.city,
+          cityCode: this.locationInfo.cityCode,
           district: this.locationInfo.district
         }
 
@@ -349,7 +370,7 @@ export default {
           city: this.locationInfo.city,
           district: this.locationInfo.district
         })
-
+        this.$emit('scopeMapSave', saveData)
         this.$message.success('保存成功,省市区已打印到控制台')
       })
     },
@@ -419,7 +440,7 @@ export default {
 
 .map-container {
   width: 100%;
-  height: 420px;
+  height: 380px;
   margin-bottom: 20px;
   background: #eef1f5;
 }

+ 15 - 7
src/views/mapDemo/scopeMap.vue

@@ -26,21 +26,29 @@ const AMAP_SECURITY = '80ba66cc0bba5b07de6a275d7aa02a39'
 const DEFAULT_RADIUS = 1000
 
 /** 不同位置区域:每个位置一个标记 + 一个圈 */
-const DEFAULT_POINT_LIST = [
-  { lng: 116.397428, lat: 39.90923, label: '位置一', radius: 500 },
-  { lng: 116.451328, lat: 39.908765, label: '位置二', radius: 800 },
-  { lng: 116.280892, lat: 39.921234, label: '位置三', radius: 600 }
-]
+// const DEFAULT_POINT_LIST = [
+//   { lng: 116.397428, lat: 39.90923, label: '位置一', radius: 500 },
+//   { lng: 116.451328, lat: 39.908765, label: '位置二', radius: 800 },
+//   { lng: 116.280892, lat: 39.921234, label: '位置三', radius: 600 }
+// ]
 
 const POINT_COLORS = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C']
 
 export default {
   name: 'ScopeMap',
+  props: {
+    points: {
+        type: Array,
+        default: [
+            { lng: 112.55, lat: 37.87, label: '站位点1', radius: 500 }
+        ]
+    }
+  },
   data() {
     return {
       mapId: 'scope-map-demo',
       searchKeyword: '',
-      pointList: DEFAULT_POINT_LIST.map((item) => ({ ...item })),
+      pointList: this.points.map((item) => ({ ...item })),
       activeIndex: -1,
       AMap: null,
       map: null,
@@ -297,7 +305,7 @@ export default {
 
 .scope-map-container {
   width: 100%;
-  height: 520px;
+  height: 600px;
   background: #eef1f5;
 }
 </style>

+ 234 - 0
src/views/order/orderDetail/index.vue

@@ -0,0 +1,234 @@
+<template>
+    <div class="app-container">
+        <div class="top">
+            <div class="message">
+                <div class="left">
+                    <img src="" />
+                    <span>订单号</span>
+                </div>
+                <div class="right">
+                    <el-button type="primary" size="small">操作按钮</el-button>
+                    <el-button type="primary" size="small">操作按钮</el-button>
+                </div>
+            </div>
+            <el-steps :active="3" align-center>
+                <el-step title="提交订单" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="派单" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="待接单" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="商户已接单" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="待服务" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="开始服务" description="2025.12.02 12:02:25"></el-step>
+                <el-step title="服务完成" description="2025.12.02 12:02:25"></el-step>
+            </el-steps>
+        </div>
+        <div class="order">
+            <el-descriptions title="订单信息">
+                <el-descriptions-item label="下单用户">昵称-手机号</el-descriptions-item>
+                <el-descriptions-item label="商户信息">昵称-手机号</el-descriptions-item>
+                <el-descriptions-item label="下单时间">时间</el-descriptions-item>
+                <el-descriptions-item label="联系信息">姓名-手机号</el-descriptions-item>
+                <el-descriptions-item label="真实地址">真实地址</el-descriptions-item>
+                <el-descriptions-item label="付款时间">时间</el-descriptions-item>
+                <el-descriptions-item label="联系地址">联系地址</el-descriptions-item>
+                <el-descriptions-item label="虚拟地址">虚拟地址</el-descriptions-item>
+                <el-descriptions-item label="支付方式">支付方式</el-descriptions-item>
+                <el-descriptions-item label="预约时间">预约时间</el-descriptions-item>
+                <el-descriptions-item label="目标距离">目标距离</el-descriptions-item>
+                <el-descriptions-item label="平台收益">平台收益</el-descriptions-item>
+                <el-descriptions-item label="服务开始">服务开始时间</el-descriptions-item>
+                <el-descriptions-item label="服务时长">服务时长</el-descriptions-item>
+                <el-descriptions-item label="商户收益">商户收益</el-descriptions-item>
+                <el-descriptions-item label="服务结束">服务结束时间</el-descriptions-item>
+            </el-descriptions>
+            <div class="map">
+                <order-address-map
+                    :markers="markers"
+                    :center="center"
+                    :zoom="12"
+                    height="400px"
+                    @marker-click="onMarkerClick"
+                />
+            </div>
+        </div>
+        <div class="voucher">
+            <el-descriptions title="服务凭证"></el-descriptions>
+            <div class="list">
+                <image-preview src="" :width="180" :height="180" />
+            </div>
+        </div>
+        <div class="order">
+            <el-table
+                :data="orderTable"
+            >
+                <el-table-column prop="a" label="项目信息">
+                    <template #default="{ row }">
+                        <div class="projectMsg">
+                            <div class="left">
+                                <image-preview src="" :width="80" :height="80" />
+                            </div>
+                            <div class="right">
+                                <div>斯诺克技术指导-个性化</div>
+                                <div>陪练(120分钟)</div>
+                            </div>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="a" label="计费单位"></el-table-column>
+                <el-table-column prop="a" label="售价"></el-table-column>
+                <el-table-column prop="a" label="商户佣金"></el-table-column>
+                <el-table-column prop="a" label="实付金额"></el-table-column>
+                <el-table-column prop="a" label="售后信息"></el-table-column>
+            </el-table>
+            <div class="other">
+                <div class="right">
+                    <div class="box">
+                        <span>订单应收:</span>
+                        <span>123</span>
+                    </div>
+                    <div class="box">
+                        <span>出行车费:</span>
+                        <span>123</span>
+                    </div>
+                    <div class="box">
+                        <span>优惠券抵扣:</span>
+                        <span>123</span>
+                    </div>
+                    <div class="box">
+                        <span>实付金额:</span>
+                        <span style="color: #e74c3c">实付金额</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="log">
+            <el-descriptions title="操作日志"></el-descriptions>
+            <div class="table">
+                <el-table
+                    :data="logTable"
+                >
+                    <el-table-column prop="a" label="操作人"></el-table-column>
+                    <el-table-column prop="a" label="操作时间"></el-table-column>
+                    <el-table-column prop="a" label="操作内容"></el-table-column>
+                </el-table>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import OrderAddressMap from '@/views/mapDemo/components/OrderAddressMap.vue'
+export default {
+    name: "detail",
+    components: { OrderAddressMap },
+    data() {
+        return {
+            center: [116.397428, 39.90923],
+            // 示例:用户下单地址user / 商户真实地址real / 商户虚拟地址virtual
+            markers: [
+                { lng: 116.280892, lat: 39.921234, label: '用户下单地址1', type: 'user' },
+                { lng: 116.385621, lat: 39.954812, label: '商户真实地址2', type: 'real' },
+                { lng: 116.451328, lat: 39.908765, label: '商户虚拟地址3', type: 'virtual' }
+            ],
+            orderTable: [
+                {}
+            ],
+            logTable: [
+                {}
+            ]
+        }
+    },
+    methods: {
+        onMarkerClick(marker) {
+            this.$message.info(`点击标记:${marker.label}`)
+        }
+    },
+    mounted() {
+
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.app-container{
+    background: #f1f2f5;
+    padding: 0;
+    overflow: hidden;
+    .top{
+        background: white;
+        margin: 10px;
+        padding: 10px;
+        .message{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            margin-bottom: 20px;
+            .left{
+                display: flex;
+                align-items: center;
+                justify-content: flex-start;
+                img{
+                    width: 40px;
+                    height: 40px;
+                    border-radius: 50%;
+                }
+                span{
+                    font-size: 14px;
+                    margin-left: 10px;
+                }
+            }
+            .right{
+                display: flex;
+                align-items: center;
+                justify-content: flex-end;
+            }
+        }
+    }
+    .order{
+        background: white;
+        margin: 10px;
+        padding: 10px;
+        .map{
+            margin-top: 10px;
+        }
+        .projectMsg{
+            display: flex;
+            align-items: center;
+            justify-content: flex-start;
+            .left{
+                margin-right: 10px;
+            }
+            .right{
+                font-size: 16px;
+            }
+        }
+        .other{
+            display: flex;
+            justify-content: flex-end;
+            .right{
+                width: 200px;
+                .box{
+                    display: flex;
+                    align-items: center;
+                    justify-content: space-between;
+                    margin-top: 10px;
+                }
+            }
+        }
+    }
+    .voucher{
+        background: white;
+        margin: 10px;
+        padding: 10px;
+        .list{
+            display: flex;
+            align-items: center;
+            justify-content: flex-start;
+        }
+    }
+    .log{
+        background: white;
+        margin: 10px;
+        padding: 10px;
+    }
+}
+</style>

+ 304 - 0
src/views/order/recycle/index.vue

@@ -0,0 +1,304 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="orderForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="订单号">
+                        <el-input style="width: 280px" v-model="orderForm.a" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="下单时间">
+                        <el-date-picker
+                            style="width: 280px"
+                            v-model="orderForm.b"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="用户信息">
+                        <el-input style="width: 280px" v-model="orderForm.d" placeholder="请填写" clearable >
+                            <el-select style="width: 100px" v-model="orderForm.c" slot="prepend" placeholder="请选择">
+                                <el-option label="手机号" value="1"></el-option>
+                                <el-option label="昵称" value="2"></el-option>
+                                <el-option label="姓名" value="3"></el-option>
+                            </el-select>
+                        </el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="服务分类">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="项目名称">
+                        <el-input style="width: 280px" v-model="orderForm.f" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户信息">
+                        <el-input style="width: 280px" v-model="orderForm.d" placeholder="请填写" clearable >
+                            <el-select style="width: 100px" v-model="orderForm.c" slot="prepend" placeholder="请选择">
+                                <el-option label="手机号" value="1"></el-option>
+                                <el-option label="昵称" value="2"></el-option>
+                                <el-option label="姓名" value="3"></el-option>
+                            </el-select>
+                        </el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="支付方式">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="订单归属">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <el-table
+            :data="table"
+            style="margin-top: 20px"
+        >
+            <el-table-column label="订单信息" width="200">
+                <template #default="{ row }">
+                    <div class="orderNum">订单号:20251201103742</div>
+                    <div class="orderTime">下单时间:2025.12.02 12:00:01</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="服务项目" width="340">
+                <template #default="{ row }">
+                    <div class="serveProject">
+                        <div class="photo">
+                            <image-preview :src="row.ccover" :width="80" :height="80" />
+                        </div>
+                        <div class="message">
+                            <div class="title">斯诺克技术指导-个性化斯诺克技术指导-个性化</div>
+                            <div class="type">陪练(120分钟)</div>
+                            <div class="serveTime">服务时间:2025.12.02 12:00-13:00</div>
+                        </div>
+                    </div>
+                </template>
+            </el-table-column>
+            <el-table-column label="单价/数量" width="150">
+                <template #default="{ row }">
+                    <div class="orderNum">188.00/次</div>
+                    <div class="orderTime">×12</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="订单金额" width="240">
+                <template #default="{ row }">
+                    <div class="orderNum">¥362(含出行费:¥0.00)</div>
+                    <div class="orderTime">余额支付</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="联系信息">
+                <template #default="{ row }">
+                    <div class="connectMsg">用户:用户709514</div>
+                    <div class="connectMsg">联系人:好 178 **** 0334</div>
+                    <div class="connectMsg connectAddress">地址:云南省昆明市官渡区彩云辅路</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="状态">
+                <template #default="{ row }">
+                    <div class="orderNum">状态</div>
+                    <div class="orderNum">关联的售后状态</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="服务商户">
+                <template #default="{ row }">
+                    <div class="orderNum">姓名</div>
+                    <div class="orderNum">手机号</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button type="text" icon="el-icon-refresh" @click="handleRecover(row)">恢复</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="orderForm.current"
+                :page-size="orderForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+
+        <DispatchOrderDialog ref="dispatchDialogRefs" />
+    </div>
+</template>
+
+<script>
+import DispatchOrderDialog from '@/views/mapDemo/components/DispatchOrderDialog.vue'
+
+const MOCK_ORDER = {
+    cId: '1',
+    orderNo: 'ORD20260601001',
+    cName: '张三',
+    cPhone: '13800138001',
+    cAddress: '北京市东城区王府井大街88号',
+    category: '按摩',
+    region: 'city',
+    arrivalLongitude: 116.297428,
+    arrivalLatitude: 39.90923,
+    dispatchStatus: 'pending'
+}
+export default {
+    name: "serveOrder",
+    components: { DispatchOrderDialog },
+    data() {
+        return {
+            orderForm: {
+                current: 1,
+                size: 10,
+            },
+            total: 1,
+            table: [
+                {}
+            ],
+            allotDialogShow: false
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSearch() {
+            this.orderForm.current = 1
+            this.orderForm.size = 10
+            this.initData();
+        },
+        handleReset() {
+            this.orderForm.current = 1
+            this.orderForm.size = 10
+            this.initData();
+        },
+        handleSizeChange(size) {
+            this.orderForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.orderForm.current = page
+            this.initData();
+        },
+        handleRecover(row) {
+            this.$confirm('确定恢复当前订单?', '系统提示', {
+                type: 'warning',
+                confirmButtonText: '确认',
+                cancelButtonText: '取消'
+            })
+                .then(() => {
+                    this.$modal.msgSuccess("恢复成功");
+                })
+                .catch(() => {
+
+                });
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin: 20px 0;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border-bottom: 1px solid #ffffff;
+        }
+        .active{
+            border-bottom: 1px solid #1890ff;
+        }
+    }
+}
+.orderNum{
+    font-size: 14px;
+    color: black;
+}
+.orderTime{
+    font-size: 12px;
+}
+.serveProject{
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .photo{
+        margin-right: 10px;
+    }
+    .message{
+        width: calc(100% - 90px);
+        color: black;
+        .title{
+            width: 100%;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            font-size: 14px;
+        }
+        .type{
+            font-size: 14px;
+        }
+        .serveTime{
+            font-size: 12px;
+        }
+    }
+}
+.connectMsg{
+    width: 100%;
+    color: black;
+    font-size: 14px;
+}
+.connectAddress{
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 102 - 0
src/views/order/rules/index.vue

@@ -0,0 +1,102 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="rulesForm"
+            label-width="150px"
+            :rules="rules"
+        >
+            <el-descriptions title="订单流转规则" :column="1"></el-descriptions>
+            <el-form-item prop="autoFlowEnabled" label="系统流转">
+                <el-switch v-model="rulesForm.autoFlowEnabled"></el-switch>
+            </el-form-item>
+            <el-form-item prop="timeoutHours" label="自动流转时间">
+                用户下单超
+                <el-input style="width: 200px" placeholder="请填写" v-model="rulesForm.timeoutHours" :disabled="!rulesForm.autoFlowEnabled" clearable>
+                    <template #append>小时</template>
+                </el-input>
+                商户未接单
+            </el-form-item>
+            <el-form-item prop="defaultAction" label="系统自动处理流转">
+                <el-select style="width: 200px" v-model="rulesForm.defaultAction" placeholder="请选择" :disabled="!rulesForm.autoFlowEnabled" clearable>
+                    <el-option value="1" label="自动退款"></el-option>
+                    <el-option value="2" label="转为待指派订单"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-descriptions title="退款规则" :column="1"></el-descriptions>
+            <el-form-item prop="d" label="商户为出发前">
+                <el-radio-group v-model="rulesForm.preDepartureStrategy">
+                    <el-radio :label="0">全额退款</el-radio>
+                    <el-radio :label="1">部分退款</el-radio>
+                </el-radio-group>
+                <div class="list">
+                    <div class="item" v-for="item in rulesForm.list">
+                        商户未出发前
+                        <el-input :disabled="rulesForm.preDepartureStrategy == 0" style="width: 200px" v-model="item.timeStartHours">
+                            <template #append>小时</template>
+                        </el-input>
+                        至
+                        <el-input :disabled="rulesForm.preDepartureStrategy == 0" style="width: 200px" v-model="item.timeEndHours">
+                            <template #append>小时</template>
+                        </el-input>
+                        ,
+                        退款订单金额的
+                        <el-input :disabled="rulesForm.preDepartureStrategy == 0" style="width: 200px" v-model="item.refundPercent">
+                            <template #append>%</template>
+                        </el-input>
+                    </div>
+                </div>
+            </el-form-item>
+            <el-form-item prop="refundType" label="商户已出发">
+                <el-radio-group v-model="rulesForm.refundType1">
+                    <el-radio :label="0">全额退款</el-radio>
+                    <el-radio :label="1">部分退款</el-radio>
+                </el-radio-group>
+                <el-input style="width: 200px" v-model="rulesForm.refundPercent1" placeholder="请填写" clearable>
+                    <template #append>%</template>
+                </el-input>
+            </el-form-item>
+            <el-form-item prop="g" label="服务中订单">
+                <el-radio-group v-model="rulesForm.refundType2">
+                    <el-radio :label="0">全额退款</el-radio>
+                    <el-radio :label="1">部分退款</el-radio>
+                </el-radio-group>
+                <el-input style="width: 200px" v-model="rulesForm.refundPercent2" placeholder="请填写" clearable>
+                    <template #append>%</template>
+                </el-input>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "rules",
+    data() {
+        return {
+            rulesForm: {
+                autoFlowEnabled: false,
+                list: [
+                    {}
+                ]
+            },
+            rules: {
+                autoFlowEnabled: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                b: [
+                    { required: true, message: '请选择', trigger: 'change' },
+                    {
+                        pattern: /^(?:[1-9]|[1-9]\d|[1-6]\d{2}|7[01]\d|720)$/,
+                        message: '请输入1~720之间正整数',
+                        trigger: 'blur'
+                    }
+                ]
+            }
+        }
+    }
+}
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 381 - 0
src/views/order/serviceOrder/index.vue

@@ -0,0 +1,381 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="orderForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="订单号">
+                        <el-input style="width: 280px" v-model="orderForm.a" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="下单时间">
+                        <el-date-picker
+                            style="width: 280px"
+                            v-model="orderForm.b"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="用户信息">
+                        <el-input style="width: 280px" v-model="orderForm.d" placeholder="请填写" clearable >
+                            <el-select style="width: 100px" v-model="orderForm.c" slot="prepend" placeholder="请选择">
+                                <el-option label="手机号" value="1"></el-option>
+                                <el-option label="昵称" value="2"></el-option>
+                                <el-option label="姓名" value="3"></el-option>
+                            </el-select>
+                        </el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="服务分类">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="项目名称">
+                        <el-input style="width: 280px" v-model="orderForm.f" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户信息">
+                        <el-input style="width: 280px" v-model="orderForm.d" placeholder="请填写" clearable >
+                            <el-select style="width: 100px" v-model="orderForm.c" slot="prepend" placeholder="请选择">
+                                <el-option label="手机号" value="1"></el-option>
+                                <el-option label="昵称" value="2"></el-option>
+                                <el-option label="姓名" value="3"></el-option>
+                            </el-select>
+                        </el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="支付方式">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="订单归属">
+                        <el-select style="width: 280px" v-model="orderForm.e" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)" v-for="(item, index) in typeList">{{ item.name }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column label="订单信息" width="200">
+                <template #default="{ row }">
+                    <div class="orderNum">订单号:20251201103742</div>
+                    <div class="orderTime">下单时间:2025.12.02 12:00:01</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="服务项目" width="340">
+                <template #default="{ row }">
+                    <div class="serveProject">
+                        <div class="photo">
+                            <image-preview :src="row.ccover" :width="80" :height="80" />
+                        </div>
+                        <div class="message">
+                            <div class="title">斯诺克技术指导-个性化斯诺克技术指导-个性化</div>
+                            <div class="type">陪练(120分钟)</div>
+                            <div class="serveTime">服务时间:2025.12.02 12:00-13:00</div>
+                        </div>
+                    </div>
+                </template>
+            </el-table-column>
+            <el-table-column label="单价/数量" width="150">
+                <template #default="{ row }">
+                    <div class="orderNum">188.00/次</div>
+                    <div class="orderTime">×12</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="订单金额" width="240">
+                <template #default="{ row }">
+                    <div class="orderNum">¥362(含出行费:¥0.00)</div>
+                    <div class="orderTime">余额支付</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="联系信息">
+                <template #default="{ row }">
+                    <div class="connectMsg">用户:用户709514</div>
+                    <div class="connectMsg">联系人:好 178 **** 0334</div>
+                    <div class="connectMsg connectAddress">地址:云南省昆明市官渡区彩云辅路</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="状态">
+                <template #default="{ row }">
+                    <div class="orderNum">状态</div>
+                    <div class="orderNum">关联的售后状态</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="服务商户">
+                <template #default="{ row }">
+                    <div class="orderNum">姓名</div>
+                    <div class="orderNum">手机号</div>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-dropdown @command="(command) => clickMenuItem(command, row)">
+                        <span class="el-dropdown-link">
+                            <el-button size="small" type="text">操作<i class="el-icon-arrow-down el-icon--right"></i></el-button>
+                        </span>
+                        <el-dropdown-menu slot="dropdown">
+                            <el-dropdown-item command="view" @click="handleView(row)">详情</el-dropdown-item>
+                            <el-dropdown-item command="allot" @click="handleAllot(row)">分配</el-dropdown-item>
+                            <el-dropdown-item command="del" @click="handleDel(row)">删除</el-dropdown-item>
+                            <el-dropdown-item command="refund" @click="handleRefund(row)">退款</el-dropdown-item>
+                            <el-dropdown-item command="exchange" @click="handleExchange(row)">更换商户</el-dropdown-item>
+                        </el-dropdown-menu>
+                    </el-dropdown>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="orderForm.current"
+                :page-size="orderForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+
+        <DispatchOrderDialog ref="dispatchDialogRefs" />
+    </div>
+</template>
+
+<script>
+import DispatchOrderDialog from '@/views/mapDemo/components/DispatchOrderDialog.vue'
+
+const MOCK_ORDER = {
+    cId: '1',
+    orderNo: 'ORD20260601001',
+    cName: '张三',
+    cPhone: '13800138001',
+    cAddress: '北京市东城区王府井大街88号',
+    category: '按摩',
+    region: 'city',
+    arrivalLongitude: 116.297428,
+    arrivalLatitude: 39.90923,
+    dispatchStatus: 'pending'
+}
+export default {
+    name: "serveOrder",
+    components: { DispatchOrderDialog },
+    data() {
+        return {
+            orderForm: {
+                current: 1,
+                size: 10,
+            },
+            total: 1,
+            typeIndex: 0,
+            typeList: [
+                {
+                    name: '全部'
+                },
+                {
+                    name: '待派单'
+                }
+            ],
+            table: [
+                {}
+            ],
+            allotDialogShow: false
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSearch() {
+            this.orderForm.current = 1
+            this.orderForm.size = 10
+            this.initData();
+        },
+        handleReset() {
+            this.orderForm.current = 1
+            this.orderForm.size = 10
+            this.initData();
+        },
+        handleTypeIndex(item, index) {
+            this.typeIndex = index
+        },
+        handleSizeChange(size) {
+            this.orderForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.orderForm.current = page
+            this.initData();
+        },
+        handleView(row) {
+            this.$router.push({
+                path: '/order/orderDetail',
+                query: {
+                    id: row.id
+                }
+            })
+        },
+        handleAllot(row) {
+            this.allotDialogShow = true
+            this.$nextTick(() => {
+                this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+            })
+        },
+        handleDel(row) {
+            this.$confirm('被删除的订单可以通过「订单回收站」查找并恢复', '是否确认删除?', {
+                type: 'warning',
+                confirmButtonText: '确认删除'
+            })
+                .then(() => {
+                    this.$modal.msgSuccess("删除成功");
+                })
+                .catch(() => {
+
+                });
+        },
+        handleRefund(row) {
+            this.$confirm('是否确认退款?', '系统提示', {
+                type: 'warning',
+                confirmButtonText: '确认'
+            })
+                .then(() => {
+                    this.$modal.msgSuccess("申请退款中...");
+                })
+                .catch(() => {
+
+                });
+        },
+        handleExchange(row) {
+            this.allotDialogShow = true
+            this.$nextTick(() => {
+                this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+            })
+        },
+        clickMenuItem(command, row) {
+            switch (command) {
+                case 'view':
+                    this.handleView(row)
+                    break;
+                case 'allot':
+                    this.handleAllot(row)
+                    break;
+                case 'del':
+                    this.handleDel(row)
+                    break;
+                case 'refund':
+                    this.handleRefund(row)
+                    break;
+                case 'exchange':
+                    this.handleExchange(row)
+                    break;
+            }
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin: 20px 0;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border-bottom: 1px solid #ffffff;
+        }
+        .active{
+            border-bottom: 1px solid #1890ff;
+        }
+    }
+}
+.orderNum{
+    font-size: 14px;
+    color: black;
+}
+.orderTime{
+    font-size: 12px;
+}
+.serveProject{
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .photo{
+        margin-right: 10px;
+    }
+    .message{
+        width: calc(100% - 90px);
+        color: black;
+        .title{
+            width: 100%;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            font-size: 14px;
+        }
+        .type{
+            font-size: 14px;
+        }
+        .serveTime{
+            font-size: 12px;
+        }
+    }
+}
+.connectMsg{
+    width: 100%;
+    color: black;
+    font-size: 14px;
+}
+.connectAddress{
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 259 - 0
src/views/scopeMap/index.vue

@@ -0,0 +1,259 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="queryParams"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="城市:">
+                        <el-select
+                            v-model="queryParams.cityCode"
+                            placeholder="请选择"
+                            clearable
+                        >
+                            <el-option
+                                v-for="item in options"
+                                :key="item.code"
+                                :label="item.name"
+                                :value="item.code"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button type="primary" @click="addScopeMap">新增围栏</el-button>
+            <el-button type="primary" @click="viewScopeMap">查看地图</el-button>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="围栏ID"></el-table-column>
+            <el-table-column prop="cityName" label="城市"></el-table-column>
+            <el-table-column prop="fenceName" label="围栏名称"></el-table-column>
+            <el-table-column prop="fenceIntro" label="围栏介绍"></el-table-column>
+            <el-table-column prop="riskLevel" label="风险等级">
+                <template #default="{ row }">
+                    {{ row.riskLevel == 1?'低风险':row.riskLevel == 2?'中风险':row.riskLevel == 3?'高风险':'' }}
+                </template>
+            </el-table-column>
+            <el-table-column prop="createTime" label="创建时间"></el-table-column>
+            <el-table-column label="操作">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-button size="small" type="text" icon="el-icon-delete" @click="handleDel(row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="queryParams.current"
+                :page-size="queryParams.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :title="title"
+            :visible.sync="drawerShow"
+            size="50%"
+            style="height: 900px"
+            :wrapper-closable="false"
+        >
+            <AddScopeMap :center="center" :point="point" @scopeMapSave="handleScopeMapSave" @scopeMapCancel="handleScopeMapCancel"></AddScopeMap>
+        </el-dialog>
+        <el-dialog
+            title="查看围栏"
+            :visible.sync="drawerViewShow"
+            size="50%"
+            style="height: 900px"
+            :wrapper-closable="false"
+        >
+            <ViewScopeMap :points="pointList"></ViewScopeMap>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { citys } from '@/api/operation/fare'
+import { add, list, update, del } from '@/api/operation/scopeMap'
+import AddScopeMap from '@/views/mapDemo/addScopeMap.vue'
+import ViewScopeMap from '@/views/mapDemo/scopeMap.vue'
+
+export default {
+    name: "scopeMap",
+    components: {
+        AddScopeMap,
+        ViewScopeMap
+    },
+    data() {
+        return {
+            queryParams: {
+                current: 1,
+                size: 10
+            },
+            total: 1,
+            options: [],
+            table: [],
+            drawerShow: false,
+            drawerViewShow: false,
+            pointList: [],
+            title: '新增围栏',
+            center: [116.397428, 39.90923],
+            point: {
+                name: '',
+                intro: '',
+                radius: 1,
+                riskLevel: '1'
+            },
+            editId: ''
+        }
+    },
+    methods: {
+        getDeptList() {
+            citys().then((res) => {
+                this.options = res.data;
+            });
+        },
+        addScopeMap() {
+            this.drawerShow = true
+            this.title = '新增围栏'
+            this.editId = ''
+        },
+        viewScopeMap() {
+            this.pointList = this.table.map(item => {
+                return {
+                    lng: item.longitude,
+                    lat: item.latitude,
+                    label: item.fenceName,
+                    radius: item.radiusKm
+                }
+            })
+            this.drawerViewShow = true
+        },
+        initData() {
+            list({
+                ...this.queryParams
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.queryParams = {
+                current: 1,
+                size: 10
+            }
+            this.initData()
+        },
+        handleSizeChange(size) {
+            this.queryParams.size = size
+        },
+        handleCurrentChange(page) {
+            this.queryParams.current = page
+        },
+        handleScopeMapSave(data) {
+            this.drawerShow = false
+            let obj = {
+                cityCode: data.cityCode,
+                cityName: data.district,
+                address: data.address,
+                fenceName: data.name,
+                fenceIntro: data.intro,
+                radiusKm: data.radiusKm,
+                riskLevel: data.riskLevel,
+                longitude: data.lng,
+                latitude: data.lat
+            }
+            if(this.editId) {
+                update({
+                    id: this.editId,
+                    ...obj
+                }).then(res => {
+                    if(res.code == 200 ) {
+                        this.initData();
+                        this.$message.success(res.msg)
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                })
+            } else {
+                add({
+                    ...obj
+                }).then(res => {
+                    if(res.code == 200 ) {
+                        this.initData();
+                        this.$message.success(res.msg)
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                })
+            }
+        },
+        handleScopeMapCancel() {
+            this.drawerShow = false
+        },
+        handleEdit(row) {
+            this.drawerShow = true
+            this.title = '编辑围栏'
+            this.center = [ row.longitude, row.latitude ]
+            this.point = { name: row.fenceName, intro: row.fenceIntro, radius: row.radiusKm, riskLevel: `${row.riskLevel}` }
+            this.editId = row.id
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    del({
+                        id: row.id
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.initData()
+                            this.$message.success(res.msg)
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                })
+                .catch(() => {});
+        }
+    },
+    mounted() {
+        this.getDeptList();
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 280 - 0
src/views/serve/category.vue

@@ -0,0 +1,280 @@
+<template>
+    <div class="app-container category">
+        <el-form
+            :model="categoryForm"
+            label-width="68"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="服务名称">
+                        <el-input style="width: 240px" v-model="categoryForm.name" placeholder="请填写" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="是否首页展示">
+                        <el-select style="width: 240px" v-model="categoryForm.isHomeDisplay" clearable>
+                            <el-option label="是" value="1"></el-option>
+                            <el-option label="否" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="是否上架">
+                        <el-select style="width: 240px" v-model="categoryForm.isOnline" clearable>
+                            <el-option label="是" value="1"></el-option>
+                            <el-option label="否" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button icon="el-icon-plus" type="primary" @click="handleAdd">新增</el-button>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="sort" label="序号" width="50"></el-table-column>
+            <el-table-column prop="name" label="服务名称"></el-table-column>
+            <el-table-column prop="icon" label="图标">
+                <template #default="{ row }">
+                    <image-preview :src="row.icon" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="a" label="服务标签">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.service_tag" :value="`${row.serviceTag}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isHomeDisplay" label="是否首页展示">
+                <template #default="{ row }">
+                    <el-switch disabled v-model="row.isHomeDisplay" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isOnline" label="是否上架">
+                <template #default="{ row }">
+                    <el-switch disabled v-model="row.isOnline" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" width="120">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-button size="small" type="text" icon="el-icon-delete" @click="handleDel(row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="categoryForm.current"
+                :page-size="categoryForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :title="title"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="80px"
+                :rules="addRules"
+            >
+                <el-form-item label="服务标签" prop="serviceTag">
+                    <el-select style="width: 240px" v-model="addForm.serviceTag" clearable>
+                        <el-option v-for="item in dict.type.service_tag" :label="item.label" :value="item.value"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="服务名称" prop="name">
+                    <el-input style="width: 240px" v-model="addForm.name" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="图标" prop="icon">
+                    <ImageUpload v-model="addForm.icon" :file-size="3" :limit="1" />
+                </el-form-item>
+                <el-form-item label="首页展示" prop="isHomeDisplay">
+                    <el-switch v-model="addForm.isHomeDisplay" :active-value="1" :inactive-value="0"></el-switch>
+                </el-form-item>
+                <el-form-item label="上架" prop="isOnline">
+                    <el-switch v-model="addForm.isOnline" :active-value="1" :inactive-value="0"></el-switch>
+                </el-form-item>
+                <el-form-item label="序号" prop="sort">
+                    <el-input-number v-model="addForm.sort" placeholder="请填写" clearable />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="footer">
+                    <el-button @click="handleCancel">取消</el-button>
+                    <el-button type="primary" @click="handleSave">确定</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { add, list, edit, del, detail } from '@/api/serve/caetgory'
+export default {
+    dicts: ['service_tag'],
+    data() {
+        return {
+            categoryForm: {
+                name: '',
+                isHomeDisplay: '', // 0-否 1-是
+                isOnline: '', // 0-否 1-是
+                current: 1,
+                size: 10
+            },
+            total: 0,
+            table: [],
+            title: '新增',
+            dialogShow: false,
+            addRules: {
+                serviceTag: [
+                    { required: true, message:'请选择', trigger: "change"}
+                ],
+                name: [
+                    { required: true, message:'请填写', trigger: "blur",}
+                ]
+            },
+            addForm: {},
+            editId: ''
+        }
+    },
+    methods: {
+        initData() {
+            list({
+                ...this.categoryForm
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.categoryForm.current = 1
+            this.categoryForm.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.categoryForm = {}
+            this.categoryForm.current = 1
+            this.categoryForm.size = 10
+            this.initData()
+        },
+        handleAdd() {
+            this.title = '新增'
+            this.dialogShow = true
+        },
+        handleEdit(row) {
+            this.title = '编辑'
+            this.editId = row.id
+            this.dialogShow = true
+            detail({
+                id: row.id
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.addForm = res.data
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    del({
+                        id: row.id
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.$message.success(res.msg)
+                            this.initData()
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                })
+                .catch(() => {
+
+                });
+        },
+        handleSizeChange(size) {
+            this.categoryForm.size = size
+            this.initData()
+        },
+        handleCurrentChange(current) {
+            this.categoryForm.current = current
+            this.initData()
+        },
+        handleSave() {
+            let params = {
+                serviceTag: this.addForm.serviceTag,
+                name: this.addForm.name,
+                icon: this.addForm.icon,
+                isHomeDisplay: this.addForm.isHomeDisplay?'1':'0',
+                isOnline: this.addForm.isOnline?'1':'0',
+                sort: this.addForm.sort
+            }
+            if(this.editId) {
+                edit({
+                    id: this.editId,
+                    ...params
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData()
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                    this.dialogShow = false
+                })
+            } else {
+                add({
+                    ...params
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData()
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                    this.dialogShow = false
+                })
+            }
+        },
+        handleCancel() {
+            this.dialogShow = false
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 400 - 0
src/views/serve/project.vue

@@ -0,0 +1,400 @@
+<template>
+    <div class="app-container project">
+        <el-form
+            :model="projectForm"
+            label-width="68"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="标题">
+                        <el-input style="width: 240px" v-model="projectForm.title" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="上架状态">
+                        <el-select style="width: 240px" v-model="projectForm.status" clearable>
+                            <el-option label="已上架" value="1"></el-option>
+                            <el-option label="未上架" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button size="small" icon="el-icon-plus" type="primary" @click="handleAdd">新增</el-button>
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeindex(item, index)" v-for="(item, index) in typeList">{{ item.name }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="项目编号" width="150"></el-table-column>
+            <el-table-column prop="ctitle" label="标题" width="150"></el-table-column>
+            <el-table-column prop="ccover" label="图片" width="150">
+                <template #default="{ row }">
+                    <image-preview :src="row.ccover" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="priceMin" label="最低价" width="80"></el-table-column>
+            <el-table-column prop="priceMax" label="最高价" width="80"></el-table-column>
+            <el-table-column prop="dprice" label="标价" width="80"></el-table-column>
+            <el-table-column prop="standardDuration" label="标时" width="80"></el-table-column>
+            <el-table-column prop="unitType" label="计费单位" width="80">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.unit_type" :value="`${row.unitType}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isRecommended" label="是否推荐" width="100">
+                <template #default="{ row }">
+                    <el-switch v-model="row.isRecommended" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isPriceCustom" label="价格是否自定义" width="120">
+                <template #default="{ row }">
+                    <el-switch v-model="row.isPriceCustom" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isTimeCustom" label="标时是否自定义" width="120">
+                <template #default="{ row }">
+                    <el-switch v-model="row.isTimeCustom" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="status" label="是否上架" width="100">
+                <template #default="{ row }">
+                    <el-switch v-model="row.status" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="highlightIds" label="亮点" width="150">
+                <template #default="{ row }">
+                    <template v-for="item in returnArr(row.highlightIds)">
+                        <dict-tag style="margin-bottom: 5px" :options="dict.type.highlight_type" :value="`${item}`"/>
+                    </template>
+                </template>
+            </el-table-column>
+            <el-table-column prop="targetAudience" label="适用人群" width="150"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="150"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleView(row)">详情</el-button>
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-button size="small" type="text" icon="el-icon-delete" @click="handleDel(row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="projectForm.current"
+                :page-size="projectForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :title="title"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="120px"
+                :rules="addRules"
+                style="height: 660px; overflow-y: auto"
+            >
+                <el-form-item label="服务类目" prop="categoryId">
+                    <el-select style="width: 240px" v-model="addForm.categoryId" placeholder="请选择" clearable>
+                        <el-option v-for="(item, index) in typeLists" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="图片" prop="cover">
+                    <ImageUpload v-model="addForm.cover" :file-size="3" :limit="1" />
+                </el-form-item>
+                <el-form-item label="项目标题" prop="title">
+                    <el-input style="width: 240px" v-model="addForm.title" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="最低价" prop="priceMin">
+                    <el-input style="width: 240px" v-model="addForm.priceMin" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="最高价" prop="priceMax">
+                    <el-input style="width: 240px" v-model="addForm.priceMax" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="标价" prop="price">
+                    <el-input style="width: 240px" v-model="addForm.price" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="标时" prop="standardDuration">
+                    <el-input style="width: 240px" v-model="addForm.standardDuration" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="计费单位" prop="unitType">
+                    <el-select style="width: 240px" v-model="addForm.unitType" placeholder="请选择" clearable>
+                        <el-option v-for="item in dict.type.unit_type" :label="item.label" :value="item.value"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="商户分佣比" prop="merchantShareRatio">
+                    <el-input-number v-model="addForm.merchantShareRatio" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="是否推荐" prop="isRecommended">
+                    <el-radio-group v-model="addForm.isRecommended">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="价格是否自定义" prop="isPriceCustom">
+                    <el-radio-group v-model="addForm.isPriceCustom">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+<!--                <el-form-item label="标时是否自定义" prop="isTimeCustom">
+                    <el-radio-group v-model="addForm.isTimeCustom">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>-->
+                <el-form-item label="是否上架" prop="status">
+                    <el-radio-group v-model="addForm.status">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="项目亮点" prop="highlightIds">
+                    <el-select style="width: 240px" multiple v-model="addForm.highlightIds" placeholder="请选择" clearable>
+                        <el-option v-for="item in dict.type.highlight_type" :label="item.label" :value="item.value"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="适用人群" prop="targetAudience">
+                    <el-input style="width: 240px" show-word-limit maxlength="200" type="textarea" v-model="addForm.targetAudience" placeholder="请填写" clearable />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="footer">
+                    <el-button @click="handleCancel">取消</el-button>
+                    <el-button type="primary" @click="handleSave">确定</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { lists, edit, add, del, detail } from '@/api/serve/project'
+import { list } from '@/api/serve/caetgory'
+
+export default {
+    dicts: ['unit_type', 'highlight_type'],
+    data() {
+        return {
+            projectForm: {
+                current: 1,
+                size: 10
+            },
+            total: 11,
+            table: [],
+            typeList: [
+                {
+                    name: '全部'
+                }
+            ],
+            typeLists: [], // 新增、编辑使用
+            typeIndex: 0,
+            title: '新增',
+            dialogShow: false,
+            editId: '',
+            addRules: {
+                a: [
+                    { required: true, message:'请填写', trigger: "blur",}
+                ]
+            },
+            addForm: {}
+        }
+    },
+    methods: {
+        returnArr(str) {
+            if(str) {
+                return str.split(',')
+            }
+        },
+        initType() {
+            list({
+                current: 1,
+                size: 1000
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.typeList = this.typeList.concat(res.data.records)
+                    this.typeLists = res.data.records
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleTypeindex(item, index)  {
+            this.typeIndex = index
+            if(item.name == '全部') {
+                this.projectForm.type = ''
+            } else {
+                this.projectForm.type = item.id
+            }
+        },
+        initData() {
+            lists({
+                ...this.projectForm
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.projectForm.current = 1
+            this.projectForm.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.projectForm = {}
+            this.projectForm.current = 1
+            this.projectForm.size = 10
+            this.initData()
+        },
+        handleAdd() {
+            this.title = '新增'
+            this.dialogShow = true
+        },
+        handleView(row) {
+            this.dialogShow = true
+            this.editId = row.id
+            detail(row.id).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.addForm = {
+                        type: res.data.type,
+                        cover: res.data.cover,
+                        title: res.data.title,
+                        priceMin: res.data.priceMin,
+                        priceMax: res.data.priceMax,
+                        price: res.data.price,
+                        standardDuration: res.data.standardDuration,
+                        merchantShareRatio: res.data.merchantShareRatio,
+                        targetAudience: res.data.targetAudience,
+                        unitType: `${res.data.unitType}`,
+                        isRecommended: `${res.data.isRecommended}`,
+                        isPriceCustom: `${res.data.isPriceCustom}`,
+                        // isTimeCustom: `${res.data.isTimeCustom}`,
+                        status: `${res.data.status}`,
+                        highlightIds: res.data.highlightIds.split(',')
+                    }
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleEdit(row) {
+            this.dialogShow = true
+            this.editId = row.id
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    del(row.id).then(res => {
+                        if(res.code == 200) {
+                            this.$message.success(res.msg)
+                            this.initData()
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                })
+                .catch(() => {});
+        },
+        handleSizeChange(size) {
+            this.project.size = size
+        },
+        handleCurrentChange(current) {
+            this.project.current = current
+        },
+        handleSave() {
+            if(this.editId) {
+                edit({
+                    id: this.editId,
+                    ...this.addForm,
+                    highlightIds: this.addForm?.highlightIds.join(',')
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData()
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                    this.dialogShow = false
+                })
+            } else {
+                add({
+                    ...this.addForm,
+                    highlightIds: this.addForm?.highlightIds.join(',')
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData()
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                    this.dialogShow = false
+                })
+            }
+        },
+        handleCancel() {
+            this.dialogShow = false
+        }
+    },
+    mounted() {
+        this.initType();
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 363 - 0
src/views/storedValue/cards.vue

@@ -0,0 +1,363 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="queryParams"
+            :inline="true"
+            label-width="100px"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="购物卡名称:">
+                        <el-input style="width: 240px" v-model="queryParams.name" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="创建时间:">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="queryParams.createDate"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="上架状态:">
+                        <el-select style="width: 240px" v-model="queryParams.isPublished">
+                            <el-option label="上架" value="1"></el-option>
+                            <el-option label="下架" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                    <el-button type="primary" @click="handleExport">导出</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button type="primary" @click="handleAdd">新增</el-button>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="购物卡ID"></el-table-column>
+            <el-table-column prop="name" label="购物卡名称"></el-table-column>
+            <el-table-column prop="amount" label="金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.amount }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="imageUrl" label="缩略图">
+                <template #default="{ row }">
+                    <image-preview :src="row.imageUrl" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="stock" label="库存"></el-table-column>
+            <el-table-column prop="sales" label="销量"></el-table-column>
+            <el-table-column prop="isPublished" label="是否上架">
+                <template #default="{ row }">
+                    <el-switch v-model="row.isPublished" :active-value="1" :inactive-value="0" @change="handleChange($event, row)"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="createTime" label="发布时间"></el-table-column>
+            <el-table-column prop="commissionRate" label="商户提成比例">
+                <template #default="{ row }">
+                    <span>{{ row.commissionRate }}%</span>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-button size="small" type="text" icon="el-icon-delete" @click="handleDel(row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="queryParams.current"
+                :page-size="queryParams.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :title="title"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="100px"
+                :rules="addRules"
+            >
+                <el-form-item label="购物卡名称" prop="name">
+                    <el-input style="width: 340px" v-model="addForm.name" maxlength="20" placeholder="请填写" clearable show-word-limit />
+                </el-form-item>
+                <el-form-item label="图片" prop="imageUrl">
+                    <ImageUpload v-model="addForm.imageUrl" :file-size="3" :limit="1" />
+                </el-form-item>
+                <el-form-item label="购物卡金额" prop="amount">
+                    <el-input style="width: 340px" v-model="addForm.amount" placeholder="请填写" >
+                        <template #append>¥</template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="商户提成比" prop="commissionRate">
+                    <el-input style="width: 340px" v-model="addForm.commissionRate" placeholder="请填写" >
+                        <template #append>%</template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="库存" prop="stock">
+                    <el-input style="width: 340px" v-model="addForm.stock" placeholder="请填写" clearable/>
+                </el-form-item>
+<!--                <el-form-item label="上架" prop="isOnline">
+                    <el-switch v-model="addForm.isOnline" :active-value="1" :inactive-value="0"></el-switch>
+                </el-form-item>-->
+                <el-form-item label="有效期" prop="validDate">
+                    <el-date-picker
+                        style="width: 340px"
+                        v-model="addForm.validDate"
+                        type="daterange"
+                        range-separator="至"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期"
+                        value-format="yyyy-MM-dd"
+                        clearable
+                    />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="footer">
+                    <el-button @click="handleCancel">取消</el-button>
+                    <el-button type="primary" @click="handleSave">确定</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { add, list, detail, edit, del, publish, exportData } from '@/api/storedValue/cards'
+
+export default {
+    name: "cards",
+    data() {
+        return {
+            queryParams: {
+                current: 1,
+                size: 10
+            },
+            total: 0,
+            table: [],
+            title: '新增',
+            dialogShow: false,
+            addForm: {},
+            addRules: {
+                name: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                imageUrl: [
+                    { required: true, message: '请上传', trigger: 'change' }
+                ],
+                amount: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                commissionRate: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                stock: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ],
+                validDate: [
+                    { required: true, message: '请选择', trigger: 'change' }
+                ]
+            },
+            editId: ''
+        }
+    },
+    methods: {
+        initData() {
+            let obj = {
+                current: this.queryParams.current,
+                size: this.queryParams.size,
+                name: this.queryParams.name,
+                beginCreateDate: this.queryParams.createDate?.[0],
+                endCreateDate: this.queryParams.createDate?.[1],
+                isPublished: this.queryParams.isPublished,
+            }
+            list({
+                ...obj
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.queryParams = {
+                current: 1,
+                size: 10
+            }
+            this.initData()
+        },
+        handleExport() {
+            let obj = {
+                current: this.queryParams.current,
+                size: this.queryParams.size,
+                name: this.queryParams.name,
+                beginCreateDate: this.queryParams.createDate?.[0],
+                endCreateDate: this.queryParams.createDate?.[1],
+                isPublished: this.queryParams.isPublished,
+            }
+            exportData({
+                ...obj
+            }).then(res => {
+                const blob = new Blob([res.data])
+                const blobUrl = URL.createObjectURL(blob)
+                const aLink = document.createElement('a')
+                aLink.href = blobUrl
+                aLink.download = `购物卡_${new Date().getTime()}.xls` // 下载文件名
+                document.body.appendChild(aLink)
+                aLink.click()
+                document.body.removeChild(aLink)
+                URL.revokeObjectURL(blobUrl)
+            })
+        },
+        handleSizeChange(size) {
+            this.queryParams.size = size
+            this.initData()
+        },
+        handleCurrentChange(page) {
+            this.queryParams.current = page
+            this.initData()
+        },
+        handleAdd() {
+            this.title = '新增'
+            this.dialogShow = true
+            this.addForm = {}
+        },
+        handleDetail() {
+            detail(this.editId).then(res => {
+                if(res.code == 200) {
+                    this.addForm = res.data
+                    this.addForm.validDate  = [res.data.validStartDate, res.data.validEndDate]
+                }
+            })
+        },
+        handleEdit(row) {
+            this.title = '编辑'
+            this.editId = row.id
+            this.dialogShow = true
+            this.handleDetail();
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    del(row.id).then(res => {
+                        if(res.code == 200) {
+                            this.$message.success(res.msg)
+                            this.initData();
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                    })
+                })
+                .catch(() => {
+
+                });
+        },
+        handleChange(e, row) {
+            publish({
+                id: row.id,
+                isPublished: row.isPublished
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.initData();
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleCancel() {
+            this.dialogShow = false
+        },
+        handleSave() {
+            let obj = {
+                name: this.addForm.name,
+                imageUrl: this.addForm.imageUrl,
+                amount: this.addForm.amount,
+                commissionRate: this.addForm.commissionRate,
+                stock: this.addForm.stock,
+                validStartDate: this.addForm.validDate?.[0],
+                validEndDate: this.addForm.validDate?.[1],
+            }
+            this.$refs.addFormRefs.validate((valid) => {
+                if(!valid) return
+                if(this.editId) {
+                    edit({
+                        id: this.editId,
+                        ...obj
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.initData();
+                            this.$message.success(res.msg)
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                        this.dialogShow = false
+                    })
+                } else {
+                    add({
+                        ...obj
+                    }).then(res => {
+                        if(res.code == 200) {
+                            this.initData();
+                            this.$message.success(res.msg)
+                        } else {
+                            this.$message.error(res.msg)
+                        }
+                        this.dialogShow = false
+                    })
+                }
+            })
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 172 - 0
src/views/storedValue/records.vue

@@ -0,0 +1,172 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="queryParams"
+            :inline="true"
+            label-width="100px"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="用户姓名:">
+                        <el-input style="width: 240px" v-model="queryParams.userName" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="下单时间:">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="queryParams.orderTime"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户姓名:">
+                        <el-input style="width: 240px" v-model="queryParams.merchantName" placeholder="请填写" clearable />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                    <el-button type="primary" @click="handleExport">导出</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="订单ID"></el-table-column>
+            <el-table-column prop="giftCardName" label="购物卡名称"></el-table-column>
+            <el-table-column prop="payAmount" label="金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.payAmount }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="userName" label="用户姓名"></el-table-column>
+            <el-table-column prop="userPhone" label="用户电话"></el-table-column>
+            <el-table-column prop="orderTime" label="下单时间"></el-table-column>
+            <el-table-column prop="commissionAmount" label="商户提成金额">
+                <template #default="{ row }">
+                    <span>¥{{ row.commissionAmount }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="merchantAccount" label="商户账户"></el-table-column>
+            <el-table-column prop="merchantName" label="商户姓名"></el-table-column>
+            <el-table-column prop="merchantNickName" label="商户昵称"></el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="queryParams.current"
+                :page-size="queryParams.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+    </div>
+</template>
+
+<script>
+import { list, exportData } from '@/api/storedValue/records'
+
+export default {
+    name: "cards",
+    data() {
+        return {
+            queryParams: {
+                current: 1,
+                size: 10
+            },
+            total: 1,
+            table: [
+                {}
+            ],
+        }
+    },
+    methods: {
+        initData() {
+            let obj = {
+                userName: this.queryParams.userName,
+                merchantName: this.queryParams.merchantName,
+                startTime: this.queryParams.orderTime?.[0],
+                endTime: this.queryParams.orderTime?.[1],
+                current: this.queryParams.current,
+                size: this.queryParams.size
+            }
+            list({
+                ...obj
+            }).then(res => {
+                if(res.code == 200){
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.queryParams.current = 1
+            this.queryParams.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.queryParams = {
+                current: 1,
+                size: 10
+            }
+            this.initData()
+        },
+        handleExport() {
+            let obj = {
+                userName: this.queryParams.userName,
+                merchantName: this.queryParams.merchantName,
+                startTime: this.queryParams.orderTime?.[0],
+                endTime: this.queryParams.orderTime?.[1],
+                current: this.queryParams.current,
+                size: this.queryParams.size
+            }
+            exportData({
+                ...obj
+            }).then(res => {
+                const blob = new Blob([res.data])
+                const blobUrl = URL.createObjectURL(blob)
+                const aLink = document.createElement('a')
+                aLink.href = blobUrl
+                aLink.download = `购物卡明细_${new Date().getTime()}.xls` // 下载文件名
+                document.body.appendChild(aLink)
+                aLink.click()
+                document.body.removeChild(aLink)
+                URL.revokeObjectURL(blobUrl)
+            })
+        },
+        handleSizeChange(size) {
+            this.queryParams.size = size
+            this.initData()
+        },
+        handleCurrentChange(page) {
+            this.queryParams.current = page
+            this.initData()
+        },
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 68 - 13
src/views/system/dept/index.vue

@@ -1,14 +1,26 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
-      <el-form-item label="部门名称" prop="deptName">
-        <el-input
-          v-model="queryParams.deptName"
-          placeholder="请输入部门名称"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+        <el-form-item label="部门名称" prop="deptName">
+            <el-input
+                    v-model="queryParams.deptName"
+                    placeholder="请输入部门名称"
+                    clearable
+                    @keyup.enter.native="handleQuery"
+            />
+        </el-form-item>
+        <el-form-item label="创建时间" prop="createTime">
+            <el-date-picker
+                style="width: 240px"
+                v-model="queryParams.dateRange"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="yyyy-MM-dd"
+                clearable
+            ></el-date-picker>
+        </el-form-item>
       <el-form-item label="状态" prop="status">
         <el-select v-model="queryParams.status" placeholder="部门状态" clearable>
           <el-option
@@ -57,7 +69,11 @@
       :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
     >
       <el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
-      <el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
+        <el-table-column prop="cityName" label="部门城市" width="100"></el-table-column>
+        <el-table-column prop="leader" label="负责人" width="100"></el-table-column>
+        <el-table-column prop="phone" label="负责人电话" width="120"></el-table-column>
+        <el-table-column prop="email" label="负责人邮箱" width="200"></el-table-column>
+        <el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
       <el-table-column prop="status" label="状态" width="100">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
@@ -99,6 +115,28 @@
     <!-- 添加或修改部门对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-row>
+              <el-col :span="24">
+                  <el-form-item label="部门城市" prop="parentId">
+                      <el-select
+                          style="width: 100%"
+                          v-model="queryParams.cityCode"
+                          placeholder="请选择"
+                          clearable
+                          filterable
+                          @change="handleDeptCity"
+                      >
+                          <el-option
+                              v-for="item in cityOptions"
+                              :key="item.code"
+                              :label="item.name"
+                              :value="item.code"
+                          >
+                          </el-option>
+                      </el-select>
+                  </el-form-item>
+              </el-col>
+          </el-row>
         <el-row>
           <el-col :span="24" v-if="form.parentId !== 0">
             <el-form-item label="上级部门" prop="parentId">
@@ -158,9 +196,10 @@
 </template>
 
 <script>
-import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept";
+import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild, getDeptList } from "@/api/system/dept";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { citys } from '@/api/operation/fare'
 
 export default {
   name: "Dept",
@@ -168,6 +207,8 @@ export default {
   components: { Treeselect },
   data() {
     return {
+        //城市
+        cityOptions: [],
       // 遮罩层
       loading: true,
       // 显示搜索条件
@@ -223,11 +264,22 @@ export default {
     this.getList();
   },
   methods: {
+      // 部门城市选择
+      handleDeptCity(e) {
+          let item = this.cityOptions.filter(item => item.code === e)
+          this.form.cityName = item?.[0].name
+      },
+      // 获取部门
+      getDeptLists() {
+          citys().then((res) => {
+              this.cityOptions = res.data;
+          });
+      },
     /** 查询部门列表 */
     getList() {
       this.loading = true;
       listDept(this.queryParams).then(response => {
-        this.deptList = this.handleTree(response.data, "deptId");
+        this.deptList = this.handleTree(response.data.records, "deptId");
         this.loading = false;
       });
     },
@@ -279,7 +331,7 @@ export default {
       this.open = true;
       this.title = "添加部门";
       listDept().then(response => {
-        this.deptOptions = this.handleTree(response.data, "deptId");
+        this.deptOptions = this.handleTree(response.data.records, "deptId");
       });
     },
     /** 展开/折叠操作 */
@@ -335,6 +387,9 @@ export default {
         this.$modal.msgSuccess("删除成功");
       }).catch(() => {});
     }
-  }
+  },
+    mounted() {
+        this.getDeptLists();
+    }
 };
 </script>

+ 262 - 0
src/views/tenant/alert/index.vue

@@ -0,0 +1,262 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="alertForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="姓名">
+                        <el-input style="width: 240px" v-model="alertForm.merchantName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="昵称">
+                        <el-input style="width: 240px" v-model="alertForm.merchantNickName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="性别">
+                        <el-select style="width: 240px" v-model="alertForm.merchantSex" clearable>
+                            <el-option v-for="item in dict.type.sys_user_sex" :label="item.label" :value="item.value"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户电话">
+                        <el-input style="width: 240px" v-model="alertForm.merchantPhone" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="申请时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="alertForm.applyTime"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)" v-for="(item, index) in typeList">{{ item }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="订单号" width="150"></el-table-column>
+            <el-table-column prop="merchantName" label="商户姓名" width="150"></el-table-column>
+            <el-table-column prop="merchantNickName" label="商户昵称" width="150"></el-table-column>
+            <el-table-column prop="merchantSex" label="商户性别">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.sys_user_sex" :value="`${row.merchantSex}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="merchantAvatar" label="形象照">
+                <template #default="{ row }">
+                    <image-preview :src="row.merchantAvatar" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="merchantPhone" label="电话"></el-table-column>
+            <el-table-column prop="address" label="位置"></el-table-column>
+            <el-table-column prop="beginTime" label="发起时间"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button v-if="row.alarmStatus == 0" size="small" type="text" icon="el-icon-finished" @click="handleAudit(row)">处理</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="alertForm.current"
+                :page-size="alertForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            title="处理"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="120px"
+                :rules="addRules"
+            >
+                <el-form-item label="处理过程及结果" prop="note">
+                    <el-input type="textarea" show-word-limit maxlength="200" v-model="addForm.note" clearable />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <el-button @click="handleCancel">取消</el-button>
+                <el-button type="primary" @click="handleSave">确定</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { list, dealAlert } from '@/api/tenant/alert'
+
+export default {
+    name: "audit",
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            alertForm: {
+                current: 1,
+                size: 10,
+                alarmStatus: 0
+            },
+            typeList: ['待处理','已处理'],
+            typeIndex: 0,
+            table: [
+                {
+                    sex: 1
+                }
+            ],
+            total: 1,
+            dialogShow: false,
+            addForm: {},
+            addRules: {
+                note: [
+                    { required: true, message: '请填写', trigger: 'blur' }
+                ]
+            },
+            alertId: ''
+        }
+    },
+    methods: {
+        initData() {
+            let obj = {
+                merchantName: this.alertForm.merchantName,
+                merchantNickName: this.alertForm.merchantNickName,
+                merchantSex: this.alertForm.merchantSex,
+                merchantPhone: this.alertForm.merchantPhone,
+                startTime: this.alertForm.applyTime?.[0],
+                endTime: this.alertForm.applyTime?.[1],
+                alarmStatus: this.alertForm.alarmStatus
+            }
+            list({
+                ...obj
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSizeChange(size) {
+            this.alertForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.alertForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.alertForm.current = 1
+            this.alertForm.size = 10
+            this.initData();
+        },
+        handleReset() {
+            this.alertForm = {
+                current: 1,
+                size: 10
+            }
+            this.initData();
+        },
+        handleTypeIndex(item, index) {
+            this.typeIndex = index
+            switch (item) {
+                case '待处理':
+                    this.alertForm.alarmStatus = 0
+                    break;
+                case '已处理':
+                    this.alertForm.alarmStatus = 1
+                    break;
+            }
+        },
+        handleAudit(row) {
+            this.dialogShow = true
+            this.alertId = row.id
+            this.addForm.note = ''
+        },
+        handleCancel() {
+            this.alertId = ''
+            this.addForm.note = ''
+            this.dialogShow = false
+        },
+        handleSave() {
+            dealAlert({
+                id: this.alertId,
+                note: this.addForm.note
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.initData();
+                    this.dialogShow = false
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 165 - 0
src/views/tenant/attendance/index.vue

@@ -0,0 +1,165 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="attendanceForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="商户姓名">
+                        <el-input style="width: 240px" v-model="attendanceForm.name" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="attendanceForm.dateRange"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="考勤状态">
+                        <el-select style="width: 240px" v-model="attendanceForm.sex" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="日期"></el-table-column>
+            <el-table-column prop="ctitle" label="商户姓名"></el-table-column>
+            <el-table-column prop="ctitle" label="工作时间">
+                <template #default="{ row }">
+                    <el-button type="text" @click="handleView(row)">查看</el-button>
+                </template>
+            </el-table-column>
+            <el-table-column prop="priceMin" label="考勤状态">
+                <template #default="{ row }">
+
+                </template>
+            </el-table-column>
+            <el-table-column prop="dprice" label="日累计工作时长"></el-table-column>
+            <el-table-column prop="dprice" label="扣款金额"></el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="attendanceForm.current"
+                :page-size="attendanceForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            title="工作时间"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-table
+                :data="workTable"
+            >
+                <el-table-column prop="a" label="上班时间"></el-table-column>
+                <el-table-column prop="a" label="下班时间"></el-table-column>
+                <el-table-column prop="a" label="工作时长"></el-table-column>
+            </el-table>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "attendance",
+    data() {
+        return {
+            attendanceForm: {
+                current: 1,
+                size: 10
+            },
+            table: [
+                {}
+            ],
+            total: 0,
+            dialogShow: false,
+            workTable: [
+                {}
+            ]
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSizeChange(size) {
+            this.attendanceForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.attendanceForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.initData();
+        },
+        handleReset() {
+            this.initData();
+        },
+        handleView(row) {
+            this.dialogShow = true
+        },
+    },
+    mounted() {
+
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 157 - 0
src/views/tenant/attendanceRules/index.vue

@@ -0,0 +1,157 @@
+<template>
+    <div class="app-container">
+        <el-form
+            ref="ruleRefs"
+            :model="ruleRorm"
+            :rules="rules"
+            label-width="120px"
+            style="height: calc(100vh - 185px); background: white; padding: 10px; overflow-y: auto"
+        >
+            <el-form-item prop="basicWorkHours" label="基本工作时长">
+                <el-input style="width: 200px" v-model="ruleRorm.basicWorkHours" placeholder="请填写" clearable>
+                    <template slot="append">时</template>
+                </el-input>
+            </el-form-item>
+            <el-form-item prop="workDurationRuleEnabled" label="工作时长规则">
+                <el-radio-group v-model="ruleRorm.workDurationRuleEnabled">
+                    <el-radio label="1">有</el-radio>
+                    <el-radio label="0">无</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <div class="durationRules">
+                <div v-for="(item, index) in list" class="list">
+                    <div class="ruleItem">
+                        <span style="margin-right: 10px">早退时长</span>
+                        <el-input style="width: 180px" :disabled="ruleRorm.workDurationRuleEnabled !='1'" v-model="item.startMinutes" placeholder="请填写" clearable @change="handleStart($event, item, index)">
+                            <template slot="append">分钟</template>
+                        </el-input>
+                        <span style="margin: 0 10px">至</span>
+                        <el-input style="width: 180px" :disabled="ruleRorm.workDurationRuleEnabled !='1'" v-model="item.endMinutes" placeholder="请填写" clearable @change="handleEnd($event, item, index)">
+                            <template slot="append">分钟</template>
+                        </el-input>
+                        <span style="margin-right: 10px">,扣款</span>
+                        <el-input style="width: 180px" :disabled="ruleRorm.workDurationRuleEnabled !='1'" v-model="item.deductAmount" placeholder="请填写" clearable>
+                            <template slot="append">元</template>
+                        </el-input>
+                    </div>
+                    <el-button v-if="list.length > 1" style="margin-left: 20px" type="text" @click="delRules(item, index)">删除</el-button>
+                </div>
+                <el-button style="margin-left: 20px" type="text" @click="addRules">添加</el-button>
+            </div>
+        </el-form>
+        <div class="btns">
+            <el-button type="primary" @click="handleSave">保存</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+import { rules } from '@/api/tenant/attendance'
+export default {
+    name: "attendanceRules",
+    data() {
+        return {
+            ruleRorm: {
+
+            },
+            rules: {
+                basicWorkHours: [
+                    { required: true, message: '请填写', trigger: 'change' }
+                ],
+                workDurationRuleEnabled: [
+                    { required: true, message: '请选择', trigger: 'change' }
+                ]
+            },
+            list: [
+                {
+                    ruleType: 1,
+                    startMinutes: null,
+                    endMinutes: null,
+                    deductAmount: null
+                }
+            ]
+        }
+    },
+    methods: {
+        addRules() {
+            this.list.push({
+                ruleType: 1,
+                startMinutes: null,
+                endMinutes: null,
+                deductAmount: null
+            })
+            if(this.list[this.list.length - 2].endMinutes){
+                this.list[this.list.length - 1].startMinutes = Number(this.list[this.list.length - 2].endMinutes) + 1
+            }
+        },
+        delRules(item, index) {
+            this.list.splice(index, 1)
+        },
+        handleStart(event, item, index) {
+            if(this.list[index].endMinutes && this.list[index].startMinutes >= this.list[index].endMinutes) {
+                this.$message.error('结束时间需大于开始时间,请重新填写!')
+            }
+        },
+        handleEnd(event, item, index) {
+            if(this.list[index].endMinutes <= this.list[index].startMinutes) {
+                this.$message.error('结束时间需大于开始时间,请重新填写!')
+            }
+            if(this.list[index + 1]) {
+                this.list[index + 1].startMinutes = Number(this.list[index].endMinutes) + 1
+            }
+        },
+        handleSave() {
+            this.$refs.ruleRefs.validate((valid) => {
+                if(!valid) return
+                rules({
+                    ...this.ruleRorm,
+                    deductionRules: this.ruleRorm.workDurationRuleEnabled == '1'?[...this.list]:[]
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.$router.push({
+                            path: '/tenant/attendance'
+                        })
+                    } else {
+                        this.$message.error(res.msg)
+                    }
+                })
+            })
+        }
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.app-container{
+    background: #f2f2f2;
+    padding-bottom: 0;
+    overflow: hidden;
+    .durationRules{
+        display: flex;
+        width: 800px;
+        flex-wrap: wrap;
+        .list{
+            display: flex;
+            align-items: center;
+            justify-content: flex-start;
+            margin: 10px 0;
+            .ruleItem{
+                display: flex;
+                align-items: center;
+                justify-content: flex-start;
+                font-size: 14px;
+                margin-left: 16px;
+            }
+        }
+    }
+    .btns{
+        height: 60px;
+        background: white;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin: 10px 0;
+    }
+}
+</style>

+ 217 - 0
src/views/tenant/dynamic/index.vue

@@ -0,0 +1,217 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="auditForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="技师姓名">
+                        <el-input style="width: 240px" v-model="auditForm.name" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="发布时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="auditForm.dateRange"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="审核状态">
+                        <el-select style="width: 240px" v-model="auditForm.sex" clearable>
+                            <el-option label="男" value="1"></el-option>
+                            <el-option label="nv" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                    <el-button type="primary" @click="handleExport">导出</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)" v-for="(item, index) in typeList">{{ item.name }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="商户ID" width="150"></el-table-column>
+            <el-table-column prop="ctitle" label="姓名" width="150"></el-table-column>
+            <el-table-column prop="ctitle" label="昵称" width="150"></el-table-column>
+            <el-table-column prop="ccover" label="性别">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.sys_user_sex" :value="`${row.sex}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="priceMin" label="电话"></el-table-column>
+            <el-table-column prop="priceMax" label="形象照">
+                <template #default="{ row }">
+                    <image-preview :src="row.ccover" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="dprice" label="意向城市"></el-table-column>
+            <el-table-column prop="createTime" label="申请时间"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-document-checked" @click="handleAudit(row)">审核</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="auditForm.current"
+                :page-size="auditForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            title="审核动态"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <h2>标题</h2>
+            <p>内容</p>
+            <div class="media">
+                <div v-for="(item, index) in dynamicObj.list" style="margin-right: 10px">
+                    <image-preview v-if="item.type == 'img'" :src="item.cover" :width="120" :height="120" />
+                    <video style="width: 160px; height: 120px;" v-if="item.type == 'video'" controls :src="item.src"></video>
+                </div>
+            </div>
+            <el-input style="width: 100%; margin-top: 20px" type="textarea" maxlength="50" show-word-limit></el-input>
+            <template #footer>
+                <el-button @click="handleCancel">审核不通过</el-button>
+                <el-button type="primary" @click="handleSave">审核通过</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "audit",
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            auditForm: {
+                current: 1,
+                size: 10
+            },
+            typeList: [
+                {
+                    name: '待入驻'
+                }
+            ],
+            typeIndex: 0,
+            table: [
+                {
+                    sex: 1
+                }
+            ],
+            total: 0,
+            dialogShow: false,
+            dynamicObj: {
+                list: [
+                    {
+                        type: 'img'
+                    },{
+                        type: 'video'
+                    }
+                ]
+            }
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSizeChange(size) {
+            this.auditForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.auditForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.initData();
+        },
+        handleReset() {
+            this.initData();
+        },
+        handleExport() {
+
+        },
+        handleTypeIndex(item, index) {
+            this.typeIndex = index
+        },
+        handleAudit(row) {
+            this.dialogShow = true
+        },
+        handleCancel() {
+            this.dialogShow = false
+        },
+        handleSave() {
+            this.dialogShow = false
+        }
+    },
+    mounted() {
+
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.media{
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 271 - 0
src/views/tenant/enterAudit/index.vue

@@ -0,0 +1,271 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="auditForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="姓名">
+                        <el-input style="width: 240px" v-model="auditForm.teName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="昵称">
+                        <el-input style="width: 240px" v-model="auditForm.teNickName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="用户类型">
+                        <el-select style="width: 240px" v-model="auditForm.techType" clearable>
+                            <el-option label="虚拟用户" value="1"></el-option>
+                            <el-option label="正式用户" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户电话">
+                        <el-input style="width: 240px" v-model="auditForm.tePhone" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="申请时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="auditForm.applyTime"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="性别">
+                        <el-select style="width: 240px" v-model="auditForm.teSex" clearable>
+                            <el-option v-for="item in dict.type.sys_user_sex" :label="item.label" :value="item.value"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)" v-for="(item, index) in typeList">{{ item.name }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="merchantId" label="商户ID" width="150"></el-table-column>
+            <el-table-column prop="teName" label="姓名" width="150"></el-table-column>
+            <el-table-column prop="teNickName" label="昵称" width="150"></el-table-column>
+            <el-table-column prop="teSex" label="性别">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.sys_user_sex" :value="`${row.sex}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="tePhone" label="电话"></el-table-column>
+            <el-table-column prop="avatar" label="形象照">
+                <template #default="{ row }">
+                    <image-preview :src="row.avatar" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="teAddress" label="意向城市"></el-table-column>
+            <el-table-column prop="openServiceName" label="开通服务"></el-table-column>
+            <el-table-column prop="applyTime" label="申请时间"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button v-if="row.auditStatus == 1" size="small" type="text" icon="el-icon-document-checked" @click="handleAudit(row)">审核</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="auditForm.current"
+                :page-size="auditForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            title="商户审核"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="120px"
+                :rules="addRules"
+            >
+                <el-form-item label="审核意见" prop="auditStatus">
+                    <el-radio-group v-model="addForm.auditStatus">
+                        <el-radio label="2">审核通过</el-radio>
+                        <el-radio label="3">审核驳回</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="审核备注" prop="auditRemark">
+                    <el-input type="textarea" show-word-limit maxlength="200" v-model="addForm.auditRemark" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <el-button @click="handleCancel">取消</el-button>
+                <el-button type="primary" @click="handleSave">确定</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { list, audit } from '@/api/tenant/enterAudit'
+export default {
+    name: "audit",
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            auditForm: {
+                current: 1,
+                size: 10
+            },
+            typeList: [ // 0-待入驻 1-待审核 2-审核通过 3-审核驳回
+                {
+                    name: '待入驻',
+                    type: '0'
+                },{
+                    name: '待审核',
+                    type: '1'
+                },{
+                    name: '审核通过',
+                    type: '2'
+                },{
+                    name: '审核驳回',
+                    type: '3'
+                },
+            ],
+            typeIndex: 0,
+            table: [],
+            total: 0,
+            dialogShow: false,
+            addForm: {},
+            addRules: {
+                auditStatus: [
+                    { required: true, message: '请选择', trigger: 'change' }
+                ]
+            },
+            auditId: ''
+        }
+    },
+    methods: {
+        initData() {
+            let params = {
+                current: this.auditForm.current,
+                size: this.auditForm.size,
+                auditStatus: this.auditForm.auditStatus,
+                teName: this.auditForm.teName,
+                teNickName: this.auditForm.teNickName,
+                techType: this.auditForm.techType,
+                tePhone: this.auditForm.tePhone,
+                beginApplyTime: this.auditForm.applyTime?.[0],
+                endApplyTime: this.auditForm.applyTime?.[1],
+                teSex: this.auditForm.teSex,
+            }
+            list({
+                ...params
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSizeChange(size) {
+            this.auditForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.auditForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.initData();
+        },
+        handleReset() {
+            this.initData();
+        },
+        handleTypeIndex(item, index) {
+            this.typeIndex = index
+            this.auditForm.auditStatus = item.type
+        },
+        handleAudit(row) {
+            this.dialogShow = true
+            this.auditId = row.merchantId
+        },
+        handleCancel() {
+            this.dialogShow = false
+        },
+        handleSave() {
+            this.dialogShow = false
+            audit(this.auditId, {
+                ...this.addForm
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.initData();
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        }
+    },
+    mounted() {
+        this.initData();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 728 - 0
src/views/tenant/list/index.vue

@@ -0,0 +1,728 @@
+<template>
+    <div class="app-container project">
+        <el-form
+            :model="projectForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="姓名">
+                        <el-input style="width: 240px" v-model="projectForm.teName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="昵称">
+                        <el-input style="width: 240px" v-model="projectForm.teNickName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="服务类目">
+                        <el-select style="width: 240px" v-model="projectForm.openService" clearable>
+                            <el-option v-for="item in serveTypes" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户电话">
+                        <el-input style="width: 240px" v-model="projectForm.tePhone" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="注册时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="projectForm.createTime"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        />
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="上架状态">
+                        <el-select style="width: 240px" v-model="projectForm.postState">
+                            <el-option label="上架" value="1"></el-option>
+                            <el-option label="下架" value="0"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="性别">
+                        <el-select style="width: 240px" v-model="projectForm.g" clearable>
+                            <el-option
+                                v-for="dict in dict.type.sys_user_sex"
+                                :key="dict.value"
+                                :label="dict.label"
+                                :value="dict.value"
+                            ></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <el-button size="small" icon="el-icon-plus" type="primary" @click="handleAdd">新增</el-button>
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndexChange(item, index)" v-for="(item, index) in typeList">{{ item.text }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="merchantId" label="商户ID" width="150"></el-table-column>
+            <el-table-column prop="teName" label="姓名" width="150"></el-table-column>
+            <el-table-column prop="teNickName" label="昵称" width="80"></el-table-column>
+            <el-table-column prop="teSex" label="性别" width="80">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.sys_user_sex" :value="`${row.teSex}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="teAvatar" label="头像" width="150">
+                <template #default="{ row }">
+                    <image-preview :src="row.teAvatar" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="tePhone" label="电话" width="80"></el-table-column>
+            <el-table-column prop="nstar" label="评分" width="80"></el-table-column>
+            <el-table-column prop="serviceState" label="服务状态" width="80">
+                <template #default="{ row }">
+                    {{ row.serviceState == 0?'服务中':row.serviceState == 1?'可服务':row.serviceState == 2?'休息中':'' }}
+                </template>
+            </el-table-column>
+            <el-table-column prop="nnum" label="已服务数量" width="100"></el-table-column>
+            <el-table-column prop="onlineTime" label="累计在线时长" width="100"></el-table-column>
+            <el-table-column prop="teProject" label="服务类目" width="80"></el-table-column>
+            <el-table-column prop="postState" label="上架状态" width="120">
+                <template #default="{ row }">
+                    <el-switch v-model="row.postState" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="isRecommend" label="是否推荐" width="100">
+                <template #default="{ row }">
+                    <el-switch v-model="row.isRecommend" :active-value="1" :inactive-value="0"></el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column prop="techTypeName" label="用户类型" width="150"></el-table-column>
+            <el-table-column prop="merchantStatusName" label="管理状态" width="150">
+                <template #default="{ row }">
+                    <el-button type="text" @click="handleViewManageStatus(row)">{{ row.merchantStatusName }}</el-button>
+                </template>
+            </el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="150"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="180">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-view" @click="handleView(row)">详情</el-button>
+                    <el-button size="small" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
+                    <el-dropdown @command="clickMenuItem($event, row)">
+                        <span class="el-dropdown-link">
+                            <el-button size="small" type="text">更多<i class="el-icon-arrow-down el-icon--right"></i></el-button>
+                        </span>
+                        <el-dropdown-menu slot="dropdown">
+                            <el-dropdown-item command="open" @click="handleOpen(row)">开通项目</el-dropdown-item>
+                            <el-dropdown-item command="contract" @click="handleContract(row)">合同</el-dropdown-item>
+                            <el-dropdown-item command="status" @click="handleStatus(row)">状态管理</el-dropdown-item>
+<!--                            <el-dropdown-item command="del" @click="handleDel(row)">删除</el-dropdown-item>-->
+                            <el-dropdown-item command="commission" @click="handleCommission(row)">佣金</el-dropdown-item>
+                        </el-dropdown-menu>
+                    </el-dropdown>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="projectForm.current"
+                :page-size="projectForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            :title="title"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="80px"
+                :rules="addRules"
+                :disabled="title == '详情'"
+            >
+                <el-form-item label="姓名" prop="teName">
+                    <el-input style="width: 240px" v-model="addForm.teName" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="服务类目" prop="openService">
+                    <el-select style="width: 240px" multiple v-model="addForm.openService" clearable>
+                        <el-option v-for="item in serveTypes" :label="item.name" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="昵称" prop="teNickName">
+                    <el-input style="width: 240px" v-model="addForm.teNickName" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="服务项目" prop="projectIds">
+                    <el-select style="width: 240px" v-model="addForm.projectIds" multiple clearable>
+                        <el-option v-for="item in serveProjects" :label="item.title" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="性别" prop="teSex">
+                    <el-select style="width: 240px" v-model="addForm.teSex" clearable>
+                        <el-option
+                            v-for="dict in dict.type.sys_user_sex"
+                            :key="dict.value"
+                            :label="dict.label"
+                            :value="dict.value"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="商户类型" prop="techType">
+                    <el-select style="width: 240px" v-model="addForm.techType" clearable>
+                        <el-option label="真实商户" value="1"></el-option>
+                        <el-option label="虚拟商户" value="0"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="电话" prop="tePhone">
+                    <el-input style="width: 240px" v-model="addForm.tePhone" placeholder="请填写" clearable />
+                </el-form-item>
+                <el-form-item label="是否推荐" prop="isRecommend">
+                    <el-radio-group v-model="addForm.isRecommend">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="footer" v-if="title == '详情'">
+                    <el-button @click="handleCancel">关闭</el-button>
+                </div>
+                <div class="footer" v-else>
+                    <el-button @click="handleCancel">取消</el-button>
+                    <el-button type="primary" @click="handleSave">确定</el-button>
+                </div>
+            </template>
+        </el-dialog>
+        <el-dialog
+            title="商户状态记录"
+            :visible.sync="statusDialogShow"
+            width="30%"
+        >
+            <el-table
+                :data="statusTable"
+            >
+                <el-table-column type="index" label="序号" width="50"></el-table-column>
+                <el-table-column prop="" label="管理状态"></el-table-column>
+                <el-table-column prop="" label="变更原因"></el-table-column>
+                <el-table-column prop="" label="操作人"></el-table-column>
+                <el-table-column prop="" label="变更时间"></el-table-column>
+            </el-table>
+            <div class="pagination">
+                <el-pagination
+                    small
+                    v-show="statusTotal > 0"
+                    background
+                    @size-change="handleStatusSizeChange"
+                    @current-change="handleStatusCurrentChange"
+                    :current-page="statusCurrent"
+                    :page-size="statusSize"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="statusTotal"
+                />
+            </div>
+        </el-dialog>
+        <el-dialog
+            title="开通项目"
+            :visible.sync="openDialogShow"
+            width="60%"
+        >
+            <el-table
+                :data="openTable"
+            >
+                <el-table-column prop="" label="服务类目"></el-table-column>
+                <el-table-column prop="" label="项目名称"></el-table-column>
+                <el-table-column prop="" label="图片">
+                    <template #default="{ row }">
+                        <image-preview :src="row.icon" :width="120" :height="120" />
+                    </template>
+                </el-table-column>
+                <el-table-column prop="" label="价格"></el-table-column>
+                <el-table-column prop="" label="时间"></el-table-column>
+                <el-table-column prop="" label="计费单位"></el-table-column>
+                <el-table-column prop="" label="状态"></el-table-column>
+                <el-table-column prop="" label="是否上架">
+                    <template #default="{ row }">
+                        <el-switch v-model="row.isOnline"></el-switch>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="" label="亮点"></el-table-column>
+                <el-table-column prop="" label="适用人群"></el-table-column>
+                <el-table-column prop="" label="申请时间"></el-table-column>
+            </el-table>
+        </el-dialog>
+        <el-dialog
+            title="合同"
+            :visible.sync="contractDialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="contractForm"
+                label-width="80px"
+                :rules="contractRules"
+            >
+                <el-form-item label="合同" prop="contract">
+                    <FileUpload
+                        :fileSize="10"
+                        :fileType="['pdf', 'jpg', 'jpeg', 'png']"
+                        v-model="contractForm.contract"
+                    />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="footer">
+                    <el-button @click="handleContractCancel">取消</el-button>
+                    <el-button type="primary" @click="handleContractSave">确定</el-button>
+                </div>
+            </template>
+        </el-dialog>
+        <el-dialog
+            title="状态管理"
+            :visible.sync="manageDialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="manageForm"
+                label-width="80px"
+                :rules="manageRules"
+            >
+                <el-form-item label="商户状态" prop="a">
+                    <el-radio-group v-model="manageForm.a">
+                        <el-radio label="1">正常</el-radio>
+                        <el-radio label="2">限制接单</el-radio>
+                        <el-radio label="3">冻结</el-radio>
+                        <el-radio label="4">注销</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="变更原因" prop="b">
+                    <el-input type="textarea" show-word-limit maxlength="200" v-model="manageForm.b" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <el-button @click="handleManageCancel">取消</el-button>
+                <el-button type="primary" @click="handleManageSave">确定</el-button>
+            </template>
+        </el-dialog>
+        <el-dialog
+            title="佣金明细"
+            :visible.sync="moneyDialogShow"
+            width="30%"
+        >
+            <el-table
+                :data="moneyTable"
+            >
+                <el-table-column type="index" label="序号" width="50"></el-table-column>
+                <el-table-column prop="" label="管理状态"></el-table-column>
+                <el-table-column prop="" label="变更原因"></el-table-column>
+                <el-table-column prop="" label="操作人"></el-table-column>
+                <el-table-column prop="" label="变更时间"></el-table-column>
+            </el-table>
+            <div class="pagination">
+                <el-pagination
+                    small
+                    v-show="moneyTotal > 0"
+                    background
+                    @size-change="handleMoneySizeChange"
+                    @current-change="handleMoneyCurrentChange"
+                    :current-page="moneyCurrent"
+                    :page-size="moneySize"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="moneyTotal"
+                />
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { list } from '@/api/serve/caetgory'
+import { lists } from '@/api/serve/project'
+import { tenantList, add, detail, edit, upload } from '@/api/tenant/list'
+
+export default {
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            projectForm: {
+                current: 1,
+                size: 10
+            },
+            total: 11,
+            table: [],
+            typeList: [
+                {
+                    type: '0',
+                    text: '全部'
+                },{
+                    type: '1',
+                    text: '可服务'
+                },{
+                    type: '0',
+                    text: '服务中'
+                },{
+                    type: '2',
+                    text: '休息中'
+                },{
+                    type: '1',
+                    text: '虚拟用户'
+                },{
+                    type: '0',
+                    text: '正式用户'
+                },
+            ],
+            typeIndex: 0,
+            title: '新增',
+            dialogShow: false,
+            addRules: {
+                a: [
+                    { required: true, message:'请选择', trigger: "change"}
+                ],
+                name: [
+                    { required: true, message:'请填写', trigger: "blur",}
+                ]
+            },
+            addForm: {},
+            editId: '',
+            statusDialogShow: false,
+            statusTable: [],
+            statusTotal: 0,
+            statusCurrent: 1,
+            statusSize: 10,
+            openDialogShow: false,
+            openTable: [],
+            contractDialogShow: false,
+            contractForm: {},
+            contractRules: {
+                contract: [
+                    { required: true, message:'请上传', trigger: "change"}
+                ]
+            },
+            manageDialogShow: false,
+            manageForm: {},
+            manageRules: {
+                a: [
+                    { required: true, message:'请选择', trigger: "change"}
+                ],
+                b: [
+                    { required: true, message:'请填写', trigger: "blur"}
+                ]
+            },
+            moneyDialogShow: false,
+            moneyTable: [],
+            moneyTotal: 0,
+            moneyCurrent: 1,
+            moneySize: 10,
+            serveTypes: [], // 服务类目
+            serveProjects: [], // 服务项目
+            idForContract : '',
+        }
+    },
+    methods: {
+        // 服务类目
+        initServeTypes() {
+            list({
+                current: 1,
+                size: 1000
+            }).then(res => {
+                if(res.code == 200) {
+                    this.serveTypes = res.data.records
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        // 服务项目
+        initServeProjects() {
+            lists({
+                current: 1,
+                size: 1000
+            }).then(res => {
+                if(res.code == 200) {
+                    this.serveProjects = res.data.records
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleTypeIndexChange(item, index) {
+            this.typeIndex = index
+            switch (item.text) {
+                case '全部':
+                    this.projectForm.serviceState = ''
+                    this.projectForm.techType = ''
+                    break;
+                case '可服务':
+                    this.projectForm.serviceState = '1'
+                    this.projectForm.techType = ''
+                    break;
+                case '服务中':
+                    this.projectForm.serviceState = '0'
+                    this.projectForm.techType = ''
+                    break;
+                case '休息中':
+                    this.projectForm.serviceState = '2'
+                    this.projectForm.techType = ''
+                    break;
+                case '虚拟用户':
+                    this.projectForm.serviceState = ''
+                    this.projectForm.techType = '1'
+                    break;
+                case '正式用户':
+                    this.projectForm.serviceState = ''
+                    this.projectForm.techType = '0'
+                    break;
+            }
+        },
+        initData() {
+            let params = {
+                current: this.projectForm.current,
+                size: this.projectForm.size,
+                teName: this.projectForm.teName,
+                teNickName: this.projectForm.teNickName,
+                openService: this.projectForm.openService,
+                tePhone: this.projectForm.tePhone,
+                beginCreateTime: this.projectForm.createTime?.[0],
+                endCreateTime: this.projectForm.createTime?.[1],
+                postState: this.projectForm.postState,
+                teSex: this.projectForm.teSex,
+                serviceState: this.projectForm.serviceState,
+                techType: this.projectForm.techType
+            }
+            tenantList({
+                ...params
+            }).then(res => {
+                if(res.code == 200) {
+                    this.table = res.data.records
+                    this.total = res.data.total
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleSearch() {
+            this.projectForm.current = 1
+            this.projectForm.size = 10
+            this.initData()
+        },
+        handleReset() {
+            this.projectForm = {}
+            this.projectForm.current = 1
+            this.projectForm.size = 10
+            this.initData()
+        },
+        handleViewManageStatus() {
+            this.statusDialogShow = true
+            this.initStatus()
+        },
+        initStatus() {
+
+        },
+        initDetail(id) {
+            detail(id).then(res => {
+                if(res.code == 200) {
+                    this.addForm = {
+                        teName: res.data.teName,
+                        openService: res.data.openService?.split(',').map(Number),
+                        teNickName: res.data.teNickName,
+                        projectIds: res.data.projectIds?.split(',').map(Number),
+                        teSex: `${res.data.teSex}`,
+                        techType: `${res.data.techType}`,
+                        tePhone: res.data.tePhone,
+                        isRecommend: `${res.data.isRecommend}`
+                    }
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleAdd() {
+            this.dialogShow = true
+            this.title = '新增'
+        },
+        handleView(row) {
+            this.dialogShow = true
+            this.title = '详情'
+            this.initDetail(row.merchantId)
+        },
+        handleEdit(row) {
+            this.dialogShow = true
+            this.title = '编辑'
+            this.editId = row.merchantId
+            this.initDetail(row.merchantId)
+        },
+        clickMenuItem(command, row) {
+            switch (command) {
+                case 'open':
+                    this.handleOpen(row)
+                    break;
+                case 'del':
+                    this.handleDel(row)
+                    break;
+                case 'contract':
+                    this.handleContract(row)
+                    break;
+                case 'status':
+                    this.handleStatus(row)
+                    break;
+                case 'commission':
+                    this.handleCommission(row)
+                    break;
+            }
+        },
+        handleOpen(row) {
+            this.openDialogShow = true
+        },
+        handleContract(row) {
+            this.contractDialogShow = true
+            this.idForContract = row.merchantId
+        },
+        handleContractCancel() {
+            this.contractDialogShow = false
+            this.contractForm.contract = ''
+        },
+        handleContractSave() {
+            let emu = this.contractForm.contract.split('/')[this.contractForm.contract.split('/').length - 1]
+            upload(this.idForContract, {
+                contractName: emu?emu.split('.')[0]:'我的合同',
+                url: this.contractForm.contract
+            }).then(res => {
+                if(res.code == 200) {
+                    this.$message.success(res.msg)
+                    this.contractDialogShow = false
+                } else {
+                    this.$message.error(res.msg)
+                }
+            })
+        },
+        handleStatus(row) {
+            this.manageDialogShow = true
+        },
+        handleDel(row) {
+            this.$modal.confirm('是否确认删除?')
+                .then(() => {
+                    this.$modal.msgSuccess("删除成功");
+                })
+                .catch(() => {});
+        },
+        handleCommission(row) {
+            this.moneyDialogShow = true
+        },
+        handleSizeChange(size) {
+            this.projectForm.size = size
+            this.initData()
+        },
+        handleCurrentChange(current) {
+            this.projectForm.current = current
+            this.initData()
+        },
+        handleStatusSizeChange(size) {
+            this.statusSize = size
+            this.initStatus()
+        },
+        handleStatusCurrentChange(page) {
+            this.statusCurrent = page
+            this.initStatus()
+        },
+        handleSave() {
+            if(this.editId) {
+                edit(this.editId, {
+                    ...this.addForm
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData();
+                        this.dialogShow = false
+                    } else {
+                        this.$message.error(res.msg)
+                        this.dialogShow = false
+                    }
+                })
+            } else {
+                add({
+                    ...this.addForm
+                }).then(res => {
+                    if(res.code == 200) {
+                        this.$message.success(res.msg)
+                        this.initData();
+                        this.dialogShow = false
+                    } else {
+                        this.$message.error(res.msg)
+                        this.dialogShow = false
+                    }
+                })
+            }
+        },
+        handleCancel() {
+            this.dialogShow = false
+        },
+        handleManageCancel() {
+            this.manageDialogShow = false
+        },
+        handleManageSave() {
+            this.manageDialogShow = false
+        },
+        handleMoneySizeChange(size) {
+            this.moneySize = size
+        },
+        handleMoneyCurrentChange(page) {
+            this.moneyCurrent = 1
+        }
+    },
+    mounted() {
+        this.initData();
+        this.initServeTypes();
+        this.initServeProjects();
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>

+ 268 - 0
src/views/tenant/skillAudit/index.vue

@@ -0,0 +1,268 @@
+<template>
+    <div class="app-container">
+        <el-form
+            :model="auditForm"
+            label-width="68px"
+            :inline="true"
+        >
+            <el-row :gutter="20">
+                <el-col :span="6">
+                    <el-form-item label="姓名">
+                        <el-input style="width: 240px" v-model="auditForm.name" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="昵称">
+                        <el-input style="width: 240px" v-model="auditForm.nickName" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="用户类型">
+                        <el-select style="width: 240px" v-model="auditForm.type" clearable>
+                            <el-option label="1" value="1"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="商户电话">
+                        <el-input style="width: 240px" v-model="auditForm.phone" clearable></el-input>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="申请时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="auditForm.dateRange"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="性别">
+                        <el-select style="width: 240px" v-model="auditForm.sex" clearable>
+                            <el-option v-for="item in dict.type.sys_user_sex" :label="item.label" :value="item.value"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-form-item label="审批时间">
+                        <el-date-picker
+                            style="width: 240px"
+                            v-model="auditForm.dateRange"
+                            type="daterange"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            value-format="yyyy-MM-dd"
+                            clearable
+                        ></el-date-picker>
+                    </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                    <el-button type="primary" @click="handleSearch">搜索</el-button>
+                    <el-button @click="handleReset">重置</el-button>
+                </el-col>
+            </el-row>
+        </el-form>
+        <div class="btns">
+            <div class="type">
+                <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)" v-for="(item, index) in typeList">{{ item.name }}</span>
+            </div>
+        </div>
+        <el-table
+            :data="table"
+        >
+            <el-table-column prop="id" label="商户ID" width="150"></el-table-column>
+            <el-table-column prop="ctitle" label="姓名" width="150"></el-table-column>
+            <el-table-column prop="ctitle" label="昵称" width="150"></el-table-column>
+            <el-table-column prop="ccover" label="性别">
+                <template #default="{ row }">
+                    <dict-tag :options="dict.type.sys_user_sex" :value="`${row.sex}`"/>
+                </template>
+            </el-table-column>
+            <el-table-column prop="priceMin" label="电话"></el-table-column>
+            <el-table-column prop="priceMax" label="形象照">
+                <template #default="{ row }">
+                    <image-preview :src="row.ccover" :width="120" :height="120" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="dprice" label="用户类型"></el-table-column>
+            <el-table-column prop="createTime" label="申请时间"></el-table-column>
+            <el-table-column prop="createTime" label="注册时间"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="120">
+                <template #default="{ row }">
+                    <el-button size="small" type="text" icon="el-icon-document-checked" @click="handleAudit(row)">审核</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination">
+            <el-pagination
+                v-show="total > 0"
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="auditForm.current"
+                :page-size="auditForm.size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+            />
+        </div>
+        <el-dialog
+            title="申请开通服务"
+            :visible.sync="dialogProjectShow"
+            width="50%"
+        >
+            <el-table
+                :data="projectTable"
+            >
+                <el-table-column prop="a" label="项目名称"></el-table-column>
+                <el-table-column prop="a" label="开通理由"></el-table-column>
+                <el-table-column prop="a" label="申请时间"></el-table-column>
+                <el-table-column prop="a" label="审核结果"></el-table-column>
+                <el-table-column prop="a" label="备注"></el-table-column>
+                <el-table-column prop="a" label="操作" width="80">
+                    <template #default="{ row }">
+                        <el-button type="text" @click="handleProjectAudit(row)">审核</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </el-dialog>
+        <el-dialog
+            title="商户审核"
+            :visible.sync="dialogShow"
+            width="30%"
+        >
+            <el-form
+                :model="addForm"
+                ref="addFormRefs"
+                label-width="120px"
+                :rules="addRules"
+            >
+                <el-form-item label="审核意见" prop="a">
+                    <el-radio-group v-model="addForm.a">
+                        <el-radio label="1">审核通过</el-radio>
+                        <el-radio label="2">审核驳回</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="审核备注" prop="b">
+                    <el-input type="textarea" show-word-limit maxlength="200" v-model="addForm.b" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <el-button @click="handleCancel">取消</el-button>
+                <el-button type="primary" @click="handleSave">确定</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "audit",
+    dicts: ['sys_user_sex'],
+    data() {
+        return {
+            auditForm: {
+                current: 1,
+                size: 10
+            },
+            typeList: [
+                {
+                    name: '待审核'
+                }
+            ],
+            typeIndex: 0,
+            table: [
+                {
+                    sex: 1
+                }
+            ],
+            total: 0,
+            dialogProjectShow: false,
+            projectTable: [],
+            dialogShow: false,
+            addForm: {},
+            addRules: {
+                a: [
+                    { required: true, message: '请选择', trigger: 'change' }
+                ]
+            }
+        }
+    },
+    methods: {
+        initData() {
+
+        },
+        handleSizeChange(size) {
+            this.auditForm.size = size
+            this.initData();
+        },
+        handleCurrentChange(page) {
+            this.auditForm.current = page
+            this.initData();
+        },
+        handleSearch() {
+            this.initData();
+        },
+        handleReset() {
+            this.initData();
+        },
+        handleTypeIndex(item, index) {
+            this.typeIndex = index
+        },
+        handleAudit(row) {
+            this.dialogProjectShow = true
+        },
+        handleProjectAudit(row) {
+            this.dialogShow = true
+        },
+        handleCancel() {
+            this.dialogShow = false
+        },
+        handleSave() {
+            this.dialogShow = false
+        }
+    },
+    mounted() {
+
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.btns{
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .type{
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        .typeItem{
+            padding: 5px 15px;
+            border-radius: 4px;
+            font-size: 14px;
+            margin: 0 10px 0 0;
+            cursor: pointer;
+            border: 1px solid #ccc;
+        }
+        .active{
+            background: #1890ff;
+            color: white;
+            border-color: #1890ff;
+        }
+    }
+}
+.pagination{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+</style>