MS-IOHQJGHXZHQD\Administrator 2 сар өмнө
parent
commit
93b0c1cc29

+ 17 - 0
src/api/order/recycle.js

@@ -0,0 +1,17 @@
+import request from '@/utils/request'
+
+// 查询回收站订单列表
+export function recycleOrderList(data) {
+  return request({
+    url: '/admin/order/recycle/page',
+    method: 'get',
+    params: data
+  })
+}
+// 恢复订单
+export function restoreOrder(id) {
+  return request({
+    url: `/admin/order/${id}/restore`,
+    method: 'post'
+  })
+}

+ 32 - 0
src/api/order/serviceOrder.js

@@ -32,3 +32,35 @@ export function refundApply(id, data) {
         data
     })
 }
+//根据订单ID查询后台订单详情
+export function getOrderDetail(id) {
+  return request({
+    url: '/admin/order/' + id + '/detail',
+    method: 'get',
+  })
+}
+
+//查询订单派单候选商户列表
+export function getDispatchMerchantList(id,query) {
+  return request({
+    url: '/admin/order/' + id + '/dispatch/merchant/list',
+    method: 'get',
+    params: query
+  })
+}
+//查询城市列表
+export function getCityList(query) {
+  return request({
+    url: '/system/dept/city/list',
+    method: 'get',
+    params: query
+  })
+}
+//派单
+export function dispatchOrder(id,query) {
+  return request({
+    url: '/admin/order/' + id + '/dispatch',
+    method: 'post',
+    data: query
+  })
+}

+ 9 - 1
src/api/system/comment.js

@@ -60,4 +60,12 @@ export function batchAuditComment(data) {
     method: 'post',
     data: data
   })
-}
+}
+
+// 查询评论状态数量
+export function auditStatusCount() {
+  return request({
+    url: '/tCommentUser/auditStatusCount',
+    method: 'get',
+  })
+}

+ 27 - 0
src/api/system/dynamic.js

@@ -25,3 +25,30 @@ export function auditDynamic(data) {
     data
   })
 }
+//更新动态推荐状态
+export function recommendDynamic(query) {
+  return request({
+    url: `/api/moment/v1/manage/${query.id}/recommend`,
+    method: 'put',
+    data:query
+  })
+}
+// 更新动态上架状态
+export function updateListStatus(query) {
+    return request({
+        url: `/api/moment/v1/manage/${query.id}/list-status`,
+        method: 'put',
+        data: query
+    })
+}
+// 查询动态审核状态统计
+export function getAuditStatusCount(data) {
+  return request({
+    url: '/api/moment/v1/manage/audit-status/count',
+    method: 'get',
+    params: data
+  })
+}
+
+
+

+ 18 - 1
src/api/tenant/enterAudit.js

@@ -9,7 +9,7 @@ export function list(query) {
     })
 }
 
-// 审核
+// 商户待入驻审核
 export function audit(id, query) {
     return request({
         url: `/technician/technician/merchant/audit/${id}/submit`,
@@ -17,3 +17,20 @@ export function audit(id, query) {
         data: query
     })
 }
+// 商户申请入驻审核
+export function applySubmit(id, query) {
+    return request({
+        url: `/technician/technician/merchant/audit/${id}/applySubmit`,
+        method: 'put',
+        data: query
+    })
+}
+
+// 查看商户证照
+export function getCertificate(id) {
+    return request({
+        url: `/technician/technician/merchant/${id}/certificate`,
+        method: 'get',
+    })
+}
+

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

@@ -42,3 +42,27 @@ export function upload (id, query) {
         data: query
     })
 }
+// 技能列表
+export function skillList(query) {
+    return request({
+        url: '/technician/technician/getSkillList',
+        method: 'post',
+        data: query
+    })
+}
+// 上架
+export function enable(query) {
+    return request({
+        url: '/massage/project/audit/project/enable',
+        method: 'put',
+        data: query
+    })
+}
+// 后台变更商户管理状态
+export function getStatus(id, query) {
+    return request({
+        url: `/technician/technician/merchant/${id}/status`,
+        method: 'put',
+        data: query
+    })
+}

+ 2 - 0
src/components/ImageUpload/index.vue

@@ -21,6 +21,7 @@
       <i class="el-icon-plus"></i>
     </el-upload>
 
+
     <!-- 上传提示 -->
     <div class="el-upload__tip" slot="tip" v-if="showTip && !readonly">
       请上传
@@ -28,6 +29,7 @@
       <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
       的文件
       <div v-if="tipText">{{ tipText }}</div>
+
     </div>
 
     <el-dialog

+ 3 - 0
src/views/cancelOrder/index.vue

@@ -285,6 +285,9 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+::v-deep .el-input--medium {
+  height: 38px;
+}
 .app-container {
   height: calc(100vh - 84px);
   display: flex;

+ 141 - 89
src/views/comment/auditModal.vue

@@ -1,109 +1,161 @@
 <template>
+
+  <div>
+
     <ModalView ref="mv" cname="ElDialog" :viewProps="{
-        customClass: 'myModal'
+      customClass: 'myModal'
     }">
-        <div style="flex: 1;">
-            <el-form ref="uForm" :model="form" :rules="rules">
-                <el-form-item label="审核状态" prop="auditStatus">
-                    <el-radio-group v-model="form.auditStatus">
-                        <el-radio :label="1">通过</el-radio>
-                        <el-radio :label="2">拒绝</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item label="审核备注" prop="auditReason">
-                    <el-input type="textarea" placeholder="请输入审核备注/拒绝理由,审核拒绝时必填" v-model="form.auditReason"></el-input>
-                </el-form-item>
-            </el-form>
-        </div>
-        <div slot="footer" class="dialog-footer">
-            <el-button type="primary" @click="submitForm('uForm')">确 定</el-button>
-            <el-button @click="resetForm('uForm')">取 消</el-button>
-        </div>
+      <el-table :data="selectCommentList" style="margin-top: 20px;">
+      <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="userIcon" 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=" ">
+        <template #default="{ row }">
+          {{ calculateAvg(row) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="评论时间" align="center" prop="commentTime" width="180" />
+      <el-table-column label="订单号ID" align="center" prop="orderId" width="180" />
+      <el-table-column label="商户姓名" align="center" prop="merchantName" width="180" />
+      <!-- <el-table-column label="图片" align="center" prop="orderId" 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 label="审核状态" align="center" prop="auditStatus">
+        <template slot-scope="scope">
+          <span>{{ dict.label.local_comment_audit[scope.row.auditStatus] }}</span>
+          <!-- <dict-tag :options="dict.type.local_comment_audit" :value="scope.row.auditStatus"/> -->
+        </template>
+      </el-table-column>
+
+    </el-table>
+      <div style="flex: 1;margin-top: 30px;">
+        <el-form ref="uForm" :model="form" :rules="rules">
+          <el-form-item label="审核状态" prop="auditStatus">
+            <el-radio-group v-model="form.auditStatus">
+              <el-radio :label="1">通过</el-radio>
+              <el-radio :label="2">拒绝</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="审核备注" prop="auditReason">
+            <el-input type="textarea" placeholder="请输入审核备注/拒绝理由,审核拒绝时必填" v-model="form.auditReason"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm('uForm')">确 定</el-button>
+        <el-button @click="resetForm('uForm')">取 消</el-button>
+      </div>
     </ModalView>
+  </div>
 </template>
 
 <script>
 import ModalView from '@/components/ZModalView/index.vue';
-import { 
-    auditComment, 
-    batchAuditComment
+import {
+  auditComment,
+  batchAuditComment
 } from "@/api/system/comment";
 
 export default {
-    components: {
-        ModalView
-    },
-    data() {
-        return {
-            title: '审核',
-            form: {},
-            oForm: {},
-            loading: false,
+  dicts: ['local_comment_audit', 'local_status'],
+  components: {
+    ModalView
+  },
+  data() {
+    return {
+      title: '审核',
+      form: {},
+      oForm: {},
+      loading: false,
+      selectCommentList: [],
+    }
+  },
+  computed: {
+    rules() {
+      return {
+        auditStatus: [
+          { required: true, message: '请选择审核状态', trigger: 'change' }
+        ],
+        auditReason: [
+          { required: this.form.auditStatus === 2, message: '请输入拒绝理由', trigger: 'change' }
+        ]
+      }
+    }
+  },
+  methods: {
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          console.log(this.form);
+          let api = auditComment, params = {
+            ...this.form,
+            commentId: this.oForm.id
+          };
+          if (Array.isArray(this.oForm.id)) {
+            api = batchAuditComment;
+            params = {
+              ...this.form,
+              commentIds: this.oForm.id
+            };
+          }
+          api(params).then(res => {
+            this.$modal.msgSuccess(res.msg);
+            this.resetForm('uForm', true);
+          });
+        } else {
+          console.log('error submit!!');
+          return false;
         }
+      });
     },
-    computed: {
-        rules() {
-            return {
-                auditStatus: [
-                    { required: true, message: '请选择审核状态', trigger: 'change' }
-                ],
-                auditReason: [
-                    { required: this.form.auditStatus === 2, message: '请输入拒绝理由', trigger: 'change' }
-                ]
-            }
-        }
+    resetForm(n, f) {
+      this.$refs[n].resetFields();
+      this.close(f);
     },
-    methods: {
-        submitForm(formName) {
-            this.$refs[formName].validate((valid) => {
-                if (valid) {
-                    console.log(this.form);
-                    let api = auditComment, params = { 
-                        ...this.form,
-                        commentId: this.oForm.id
-                    };
-                    if (Array.isArray(this.oForm.id)) {
-                        api = batchAuditComment;
-                        params = { 
-                            ...this.form,
-                            commentIds: this.oForm.id
-                        };
-                    }
-                    api(params).then(res => {
-                        this.$modal.msgSuccess(res.msg);
-                        this.resetForm('uForm', true);
-                    });
-                } else {
-                    console.log('error submit!!');
-                    return false;
-                }
-            });
-        },
-        resetForm(n, f) {
-            this.$refs[n].resetFields();
-            this.close(f);
-        },
-        open(e) {
-            if (e) {
-                this.oForm = e;
-            }
-            this.$refs.mv.open(this.title);
-        },
-        // 关闭弹窗
-        close(f = false) {
-            if (f) this.$emit('close');
-            this.$refs.mv.close();
-        },
-    }
+    // 计算平均评分
+    calculateAvg(row) {
+      if (!row.experienceComment && !row.priceComment && !row.attitudeComment && !row.groomingComment) return '--'
+      const values = [
+        row.experienceComment,
+        row.priceComment,
+        row.attitudeComment,
+        row.groomingComment
+      ].map(v => v ?? 0) // null/undefined 转 0
+      return (values.reduce((a, b) => a + b, 0) / values.length).toFixed(1)
+    },
+    open(e,selectCommentList) {
+      if (e) {
+        this.selectCommentList = selectCommentList;
+        this.oForm = e;
+      }
+      this.$refs.mv.open(this.title);
+    },
+    // 关闭弹窗
+    close(f = false) {
+      if (f) this.$emit('close');
+      this.$refs.mv.close();
+    },
+  }
 };
 </script>
 
 <style lang="scss" scoped>
 ::v-deep .myModal {
-    .el-dialog__body {
-        max-height: 70vh;
-        overflow-y: auto;
-        padding: 10px 20px;
-    }
+  .el-dialog__body {
+    max-height: 70vh;
+    overflow-y: auto;
+    padding: 10px 20px;
+  }
 }
-</style>
+</style>

+ 321 - 284
src/views/comment/index.vue

@@ -2,43 +2,21 @@
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
       <el-form-item label="技师姓名" prop="name">
-        <el-input
-          v-model="queryParams.name"
-          placeholder="请输入技师姓名"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.name" placeholder="请输入技师姓名" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
-      <el-form-item label="是否敏感词" prop="sensitiveWord">
-        <el-select
-          v-model="queryParams.sensitiveWord"
-          placeholder="请选择"
-          clearable
-        >
-          <el-option
-            v-for="item in dict.type.local_status"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          >
+      <!-- <el-form-item label="是否敏感词" prop="sensitiveWord">
+        <el-select v-model="queryParams.sensitiveWord" placeholder="请选择" clearable>
+          <el-option v-for="item in dict.type.local_status" :key="item.value" :label="item.label" :value="item.value">
           </el-option>
         </el-select>
-      </el-form-item>
-      <el-form-item label="审核状态" prop="auditStatus">
-        <el-select
-          v-model="queryParams.auditStatus"
-          placeholder="请选择"
-          clearable
-        >
-          <el-option
-            v-for="item in dict.type.local_comment_audit"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          >
+      </el-form-item> -->
+      <!-- <el-form-item label="审核状态" prop="auditStatus">
+        <el-select v-model="queryParams.auditStatus" placeholder="请选择" clearable>
+          <el-option v-for="item in dict.type.local_comment_audit" :key="item.value" :label="item.label"
+            :value="item.value">
           </el-option>
         </el-select>
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -88,18 +66,17 @@
           v-hasPermi="['system:comment:export']"
         >导出</el-button>
       </el-col> -->
+      <el-col class="btns" :span="4.5">
+        <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)"
+          v-for="(item, index) in typeList">{{ item.label }}
+          <span>({{ item.value === 0 ? pendingCount : item.value === 1 ? approvedCount : rejectedCount }})</span>
+        </span>
+      </el-col>
       <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-bell"
-          size="mini"
-          :disabled="multiple"
-          @click="handleAudit({ id: ids })"
-          v-hasPermi="['system:comment:export']"
-        >批量审核</el-button>
+        <el-button type="warning" plain icon="el-icon-bell" size="mini" :disabled="multiple"
+          @click="handleAudit({ id: ids })" v-hasPermi="['system:comment:export']">批量审核</el-button>
       </el-col>
-<!--      <el-col :span="1.5">
+      <!--      <el-col :span="1.5">
         <el-button
           type="primary"
           plain
@@ -112,20 +89,33 @@
       <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 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 :key="tableKey" v-loading="loading" :data="commentList" @selection-change="handleSelectionChange"
+      style="margin-top: 20px;">
+      <el-table-column v-if="typeList[typeIndex].value === 0" 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="userIcon" 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="订单号ID" align="center" prop="a" width="180" />
-<!--      <el-table-column label="技师姓名" align="center" prop="name" />
+      <el-table-column label="评分" align="center" prop=" ">
+        <template #default="{ row }">
+          {{ calculateAvg(row) }} {{ typeList[typeIndex].value }}
+        </template>
+      </el-table-column>
+      <el-table-column label="评论时间" align="center" prop="commentTime" width="180" />
+      <el-table-column label="订单号ID" align="center" prop="orderId" width="180" />
+      <el-table-column v-if="typeList[typeIndex].value == 1" label="是否上架" align="center" prop="auditStatus" width="180">
+        <template #default="{ row }">
+          <el-switch v-model="row.auditStatus" :active-value="1" :inactive-value="0" disabled
+            @change="handleChange($event, row)"></el-switch>
+        </template>
+      </el-table-column>
+      <el-table-column label="商户姓名" align="center" prop="merchantName" width="180" />
+      <!-- <el-table-column label="图片" align="center" prop="orderId" width="180" /> -->
+      <!--      <el-table-column label="技师姓名" align="center" prop="name" />
       <el-table-column label="敏感词" align="center" prop="sensitiveWord">
         <template slot-scope="scope">
           <span :style="{
@@ -139,7 +129,9 @@
           <!-- <dict-tag :options="dict.type.local_comment_audit" :value="scope.row.auditStatus"/> -->
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" width="200" fixed="right">
+      <el-table-column v-if="typeList[typeIndex].value !== 0" label="审核人" align="center" prop="auditorName" width="180" />
+      <el-table-column v-if="typeList[typeIndex].value != 0" label="审核时间" align="center" prop="auditTime" width="180" />
+      <el-table-column v-if="typeList[typeIndex].value === 0" label="操作" align="center" width="200" fixed="right">
         <template slot-scope="scope">
           <!-- <el-button
             size="mini"
@@ -149,32 +141,15 @@
             v-hasPermi="['system:comment:edit']"
           >修改</el-button>
           -->
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-bell"
-            @click="handleAudit(scope.row)"
-            v-if="scope.row.auditStatus === 0"
-            v-hasPermi="['system:comment:edit']"
-          >审核</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            style="color: #F56C6C"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['system:comment:remove']"
-          >删除</el-button>
+          <el-button size="mini" type="text" icon="el-icon-bell" @click="handleAudit(scope.row)"
+            v-if="scope.row.auditStatus === 0" v-hasPermi="['system:comment:edit']">审核</el-button>
+          <!-- <el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C"
+            @click="handleDelete(scope.row)" v-hasPermi="['system:comment:remove']">删除</el-button> -->
         </template>
       </el-table-column>
     </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      :page.sync="queryParams.current"
-      :limit.sync="queryParams.size"
-      @pagination="getList"
-    />
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.current" :limit.sync="queryParams.size"
+      @pagination="getList" />
 
     <!-- 添加或修改评论对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
@@ -198,11 +173,7 @@
           <el-input v-model="form.nStar" placeholder="请输入评论分数" />
         </el-form-item>
         <el-form-item label="评论时间" prop="dTime">
-          <el-date-picker clearable
-            v-model="form.dTime"
-            type="date"
-            value-format="yyyy-MM-dd"
-            placeholder="请选择评论时间">
+          <el-date-picker clearable v-model="form.dTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择评论时间">
           </el-date-picker>
         </el-form-item>
         <el-form-item label="技师姓名" prop="name">
@@ -216,18 +187,9 @@
     </el-dialog>
     <!-- 导入对话框 -->
     <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
-      <el-upload
-        ref="upload"
-        drag
-        accept=".xlsx, .xls"
-        :limit="1"
-        :action="upload.url"
-        :headers="upload.headers"
-        :auto-upload="false"
-        :disabled="upload.isUploading"
-        :on-success="handleFileSuccess"
-        :on-progress="handleFileUploadProgress"
-      >
+      <el-upload ref="upload" drag accept=".xlsx, .xls" :limit="1" :action="upload.url" :headers="upload.headers"
+        :auto-upload="false" :disabled="upload.isUploading" :on-success="handleFileSuccess"
+        :on-progress="handleFileUploadProgress">
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
         <div class="el-upload__tip text-center" slot="tip">
@@ -235,7 +197,8 @@
             <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的数据
           </div> -->
           <span>仅允许导入xls、xlsx格式文件。</span>
-          <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
+          <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
+            @click="importTemplate">下载模板</el-link>
         </div>
       </el-upload>
       <div slot="footer" class="dialog-footer">
@@ -249,205 +212,279 @@
 </template>
 
 <script>
-  import { getToken } from "@/utils/auth";
-  import { listComment, getComment, delComment, addComment, updateComment } from "@/api/system/comment";
-  import AuditModal from "./auditModal.vue";
+import { getToken } from "@/utils/auth";
+import { listComment, getComment, delComment, addComment, updateComment, auditStatusCount } from "@/api/system/comment";
+import AuditModal from "./auditModal.vue";
 
-  export default {
-    name: "Comment",
-    dicts: ['local_comment_audit', 'local_status'],
-    components: {
-      AuditModal
-    },
-    data() {
-      return {
-        // 遮罩层
-        loading: true,
-        // 选中数组
-        ids: [],
-        // 非单个禁用
-        single: true,
-        // 非多个禁用
-        multiple: true,
-        // 显示搜索条件
-        showSearch: true,
-        // 总条数
-        total: 0,
-        // 评论表格数据
-        commentList: [],
-        // 弹出层标题
-        title: "",
-        // 是否显示弹出层
+export default {
+  name: "Comment",
+  dicts: ['local_comment_audit', 'local_status'],
+  components: {
+    AuditModal
+  },
+  data() {
+    return {
+      tableKey: 0, // 刷新用的key
+      typeList: [
+        { label: "待审核", value: 0 },
+        { label: "审核通过", value: 1 },
+        { label: "审核驳回", value: 2 },
+      ],
+      typeIndex: 0,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 评论表格数据
+      commentList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10,
+        cIcon: null,
+        cNickName: null,
+        cText: null,
+        cJsid: null,
+        cOpenId: null,
+        nStar: null,
+        dTime: null,
+        name: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {},
+
+      // 用户导入参数
+      upload: {
+        // 是否显示弹出层(用户导入)
         open: false,
-        // 查询参数
-        queryParams: {
-          current: 1,
-          size: 10,
-          cIcon: null,
-          cNickName: null,
-          cText: null,
-          cJsid: null,
-          cOpenId: null,
-          nStar: null,
-          dTime: null,
-          name: null
-        },
-        // 表单参数
-        form: {},
-        // 表单校验
-        rules: {},
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/common/importSensitiveWords"
+      },
+      pendingCount: 0,
+      approvedCount: 0,
+      rejectedCount: 0,
+      selectCommentList: [],
+
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询评论列表 */
+    getList() {
+      this.loading = true;
+      auditStatusCount().then(res => {
+        console.log(res)
+        this.pendingCount = res.data.pendingCount
+        this.approvedCount = res.data.approvedCount
+        this.rejectedCount = res.data.rejectedCount
+      })
+      this.queryParams.auditStatus = this.typeList[this.typeIndex].value
+      listComment(this.queryParams).then(res => {
+        this.commentList = res.data.records;
+        this.tableKey += 1
+        this.total = res.data.total;
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    //是否上架
+    handleChange(e, row) {
+      console.log(row)
+      return
+      publish({
+        id: row.id,
+        isPublished: row.isPublished
+      }).then(res => {
+        if (res.code == 200) {
+          this.$message.success(res.msg)
+          this.getList();
+        } else {
+          this.$message.error(res.msg)
+        }
+      })
+    },
 
-        // 用户导入参数
-        upload: {
-          // 是否显示弹出层(用户导入)
-          open: false,
-          // 弹出层标题(用户导入)
-          title: "",
-          // 是否禁用上传
-          isUploading: false,
-          // 设置上传的请求头部
-          headers: { Authorization: "Bearer " + getToken() },
-          // 上传的地址
-          url: process.env.VUE_APP_BASE_API + "/common/importSensitiveWords"
-        },
+    handleTypeIndex(item, index) {
+      this.typeIndex = index
+      this.getList();
+    },
+    // 计算平均评分
+    calculateAvg(row) {
+      if (!row.experienceComment && !row.priceComment && !row.attitudeComment && !row.groomingComment) return '--'
+      const values = [
+        row.experienceComment,
+        row.priceComment,
+        row.attitudeComment,
+        row.groomingComment
+      ].map(v => v ?? 0) // null/undefined 转 0
+      return (values.reduce((a, b) => a + b, 0) / values.length).toFixed(1)
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        cId: null,
+        cIcon: null,
+        cNickName: null,
+        cText: null,
+        cJsid: null,
+        cOpenId: null,
+        nStar: null,
+        dTime: null,
+        name: null
       };
+      this.resetForm("form");
     },
-    created() {
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
       this.getList();
     },
-    methods: {
-      /** 查询评论列表 */
-      getList() {
-        this.loading = true;
-        listComment(this.queryParams).then(res => {
-          this.commentList = res.data.list;
-          this.total = res.data.total;
-        }).finally(() => {
-          this.loading = false;
-        });
-      },
-      // 取消按钮
-      cancel() {
-        this.open = false;
-        this.reset();
-      },
-      // 表单重置
-      reset() {
-        this.form = {
-          cId: null,
-          cIcon: null,
-          cNickName: null,
-          cText: null,
-          cJsid: null,
-          cOpenId: null,
-          nStar: null,
-          dTime: null,
-          name: null
-        };
-        this.resetForm("form");
-      },
-      /** 搜索按钮操作 */
-      handleQuery() {
-        this.queryParams.pageNum = 1;
-        this.getList();
-      },
-      /** 重置按钮操作 */
-      resetQuery() {
-        this.resetForm("queryForm");
-        this.handleQuery();
-      },
-      // 多选框选中数据
-      handleSelectionChange(selection) {
-        this.ids = selection.map(item => item.id)
-        this.single = selection.length!==1
-        this.multiple = !selection.length
-      },
-      /** 新增按钮操作 */
-      handleAdd() {
-        this.reset();
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.selectCommentList = selection
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加评论";
+    },
+    // 审核操作
+    handleAudit(row) {
+      this.$refs.aModal.open(row, this.selectCommentList);
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const cId = row.cId || this.ids
+      getComment(cId).then(response => {
+        this.form = response.data;
         this.open = true;
-        this.title = "添加评论";
-      },
-      // 审核操作
-      handleAudit(row) {
-        this.$refs.aModal.open(row);
-      },
-      /** 修改按钮操作 */
-      handleUpdate(row) {
-        this.reset();
-        const cId = row.cId || this.ids
-        getComment(cId).then(response => {
-          this.form = response.data;
-          this.open = true;
-          this.title = "修改评论";
-        });
-      },
-      /** 提交按钮 */
-      submitForm() {
-        this.$refs["form"].validate(valid => {
-          if (valid) {
-            if (this.form.cId != null) {
-              updateComment(this.form).then(response => {
-                this.$modal.msgSuccess("修改成功");
-                this.open = false;
-                this.getList();
-              });
-            } else {
-              addComment(this.form).then(response => {
-                this.$modal.msgSuccess("新增成功");
-                this.open = false;
-                this.getList();
-              });
-            }
+        this.title = "修改评论";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.cId != null) {
+            updateComment(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addComment(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
           }
-        });
-      },
-      /** 删除按钮操作 */
-      handleDelete(row) {
-        let idList = []
-        idList.push(row.cId)
-        this.$modal.confirm('是否确认删除评论编号为"' + row.cId + '"的数据项?').then(function() {
-          return delComment(idList)
-        }).then(() => {
-          this.getList();
-          this.$modal.msgSuccess("删除成功");
-        }).catch(() => {});
-      },
-      /** 导出按钮操作 */
-      handleExport() {
-        this.download('system/comment/export', {
-          ...this.queryParams
-        }, `comment_${new Date().getTime()}.xlsx`)
-      },
-      /** 导入按钮操作 */
-      handleImport() {
-        this.upload.title = "用户导入";
-        this.upload.open = true;
-      },
-      /** 下载模板操作 */
-      importTemplate() {
-        this.$download.name('敏感词库模板.xls', false);
-      },
-      // 文件上传中处理
-      handleFileUploadProgress(event, file, fileList) {
-        this.upload.isUploading = true;
-      },
-      // 文件上传成功处理
-      handleFileSuccess(response, file, fileList) {
-        this.upload.open = false;
-        this.upload.isUploading = false;
-        this.$refs.upload.clearFiles();
-        this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      let idList = []
+      idList.push(row.cId)
+      this.$modal.confirm('是否确认删除评论编号为"' + row.cId + '"的数据项?').then(function () {
+        return delComment(idList)
+      }).then(() => {
         this.getList();
-      },
-      // 提交上传文件
-      submitFileForm() {
-        this.$refs.upload.submit();
-      }
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => { });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('system/comment/export', {
+        ...this.queryParams
+      }, `comment_${new Date().getTime()}.xlsx`)
+    },
+    /** 导入按钮操作 */
+    handleImport() {
+      this.upload.title = "用户导入";
+      this.upload.open = true;
+    },
+    /** 下载模板操作 */
+    importTemplate() {
+      this.$download.name('敏感词库模板.xls', false);
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
+      this.getList();
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit();
     }
-  };
+  }
+};
 </script>
 
-<style scoped>
+<style scoped lang="scss">
+.btns {
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+
+  .typeItem {
+    padding: 5px 15px;
+    font-size: 14px;
+    margin: 0 10px 0 0;
+    cursor: pointer;
+    background-color: #fff;
+    border: 1px solid #e9e8e8;
+    color: #000;
+    border-radius: 5px;
+  }
 
+  .active {
+    background-color: #1890ff;
+    color: #fff;
+    border-bottom: 1px solid #1890ff;
+  }
+}
 </style>

+ 1 - 0
src/views/dynamic/index.vue

@@ -201,6 +201,7 @@ export default {
     },
     //  搜索
     handleQuery() {
+      console.log('555555')
       this.queryParams.current = 1
       this.getList()
     },

+ 78 - 27
src/views/mapDemo/components/DispatchOrderDialog.vue

@@ -25,14 +25,17 @@
           <el-option
             v-for="item in regionOptions"
             :key="item.value"
-            :label="item.label"
-            :value="item.value"
+            :label="item.cityName"
+            :value="item.cityCode"
           />
         </el-select>
-        <el-select v-model="filterForm.category" placeholder="服务类目" clearable class="filter-item">
+        <el-select placeholder="服务类目" v-model="filterForm.category" clearable  class="filter-item">
+              <el-option v-for="item in serveTypes" :label="item.name" :value="item.id"></el-option>
+            </el-select>
+        <!-- <el-select v-model="filterForm.category" placeholder="服务类目" clearable class="filter-item">
           <el-option label="按摩" value="按摩" />
           <el-option label="陪玩" value="陪玩" />
-        </el-select>
+        </el-select> -->
         <el-input
           v-model="filterForm.keyword"
           placeholder="搜索技师名称或姓名"
@@ -50,26 +53,26 @@
       <div class="panel-body">
         <div class="technician-list">
           <div
-            v-for="item in sortedTechnicians"
+            v-for="item in technicians"
             :key="item.id"
             class="technician-card"
             :class="{ 'is-active': selectedId === item.id }"
             @click="selectTechnician(item)"
           >
-            <span class="technician-radio" :class="{ 'is-checked': selectedId === item.id }">
+            <span class="technician-radio" :class="{ 'is-checked': selectedId === item.merchantId }">
               <span class="technician-radio__inner" />
             </span>
-            <img :src="item.avatar" class="technician-avatar" alt="" />
+            <img :src="item.merchantAvatar" class="technician-avatar" alt="" />
             <div class="technician-info">
               <div class="technician-name-row">
-                <span class="technician-name">{{ item.nickname }}</span>
-                <span class="status-tag" :class="`status-tag--${item.status}`">{{ statusLabel(item.status) }}</span>
-                <span v-if="item.distance != null" class="technician-distance">距用户 {{ formatDistance(item.distance) }}</span>
+                <span class="technician-name">{{ item.merchantNickName }}</span>
+                <span class="status-tag" :class="`status-tag--${item.status}`">{{ statusLabel(item.postStateName) }}</span>
+                <span v-if="item.distance != null" class="technician-distance">距用户 {{ formatDistance(item.distanceShow) }}</span>
               </div>
-              <div class="technician-address">{{ item.address }}</div>
+              <div class="technician-address">{{ item.merchantAddress }}</div>
             </div>
           </div>
-          <div v-if="!sortedTechnicians.length" class="empty-tip">暂无符合条件的技师</div>
+          <div v-if="!technicians.length" class="empty-tip">暂无符合条件的技师</div>
         </div>
 
         <div class="map-wrap">
@@ -89,6 +92,7 @@
 import AMapLoader from '@amap/amap-jsapi-loader'
 import { calcDistance, formatDistance } from '@/utils/geo'
 import userDestIcon from '@/assets/images/map/user.png'
+import { getDispatchMerchantList,getCityList,serviceCategory,dispatchOrder} from '@/api/order/serviceOrder'
 
 const AMAP_KEY = '41bc0f647d4432045d472f554bf03d75'
 const AMAP_SECURITY = '80ba66cc0bba5b07de6a275d7aa02a39'
@@ -132,13 +136,14 @@ export default {
       filterForm: { ...DEFAULT_FILTER },
       searchParams: { ...DEFAULT_FILTER },
       regionOptions: [{ label: '城市运营中心', value: 'city' }],
-      technicians: MOCK_TECHNICIANS,
+      technicians:[],// MOCK_TECHNICIANS,
       selectedId: null,
       orderStatus: 'pending',
       AMap: null,
       map: null,
       markerInstances: [],
-      destMarker: null
+      destMarker: null,
+      serveTypes: []
     }
   },
   computed: {
@@ -192,9 +197,14 @@ export default {
      * @param {Object} order - 订单信息,需含 arrivalLongitude / arrivalLatitude(用户目的地经纬度)
      */
     open(order) {
+      this.serviceCategoryFun()
+      this.getCityListFun()
+      console.log(order,'order9999')
+      console.log(order.region,'order9999')
+
       if (!order) return
-      const lng = Number(order.arrivalLongitude)
-      const lat = Number(order.arrivalLatitude)
+      const lng = Number(order.merchantLongitude)
+      const lat = Number(order.merchantLatitude)
       if (!Number.isFinite(lng) || !Number.isFinite(lat)) {
         this.$message.warning('该订单缺少用户目的地经纬度,无法分配')
         return
@@ -203,14 +213,40 @@ export default {
       this.orderDest = { lng, lat }
       this.orderStatus = order.dispatchStatus || 'pending'
       this.filterForm = {
-        region: order.region || DEFAULT_FILTER.region,
-        category: order.category || '',
+        orderId: order.id,
+        region: order.region,
+        category: order.categoryId,
         keyword: ''
       }
+      console.log(this.filterForm,'this.filterForm')
+
+      this.getDispatchMerchantListFun()
       this.searchParams = { ...this.filterForm }
       this.selectedId = null
       this.dialogVisible = true
     },
+    getDispatchMerchantListFun() {
+      getDispatchMerchantList(this.filterForm.orderId,{
+        region: this.filterForm.region,
+        category: this.filterForm.category,
+        keyword: this.filterForm.keyword
+      }).then(res => {
+        this.technicians = res.data || []
+      })
+    },
+    //获取服务类型
+    serviceCategoryFun() {
+      serviceCategory().then(res => {
+        if (res.code === 200) {
+          this.serveTypes = res.data
+        }
+      })
+    },
+    getCityListFun() {
+      getCityList().then(res => {
+        this.regionOptions = res.data || []
+      })
+    },
 
     onDialogOpened() {
       this.$nextTick(() => {
@@ -228,6 +264,8 @@ export default {
     },
 
     handleSearch() {
+      this.getDispatchMerchantListFun()
+      return
       this.searchParams = { ...this.filterForm }
       if (this.selectedId && !this.sortedTechnicians.some((item) => item.id === this.selectedId)) {
         this.selectedId = null
@@ -238,6 +276,7 @@ export default {
     },
 
     handleClear() {
+
       this.filterForm = { region: '', category: '', keyword: '' }
       this.searchParams = { region: '', category: '', keyword: '' }
       this.selectedId = null
@@ -360,13 +399,13 @@ export default {
     },
 
     selectTechnician(item) {
-      if (this.selectedId === item.id) {
+      if (this.selectedId === item.merchantId) {
         this.selectedId = null
         return
       }
-      this.selectedId = item.id
+      this.selectedId = item.merchantId
       if (this.map) {
-        this.map.setZoomAndCenter(15, [item.lng, item.lat])
+        this.map.setZoomAndCenter(15, [item.merchantLongitude, item.merchantLatitude])
       }
     },
 
@@ -383,13 +422,25 @@ export default {
         this.$message.warning('订单状态已变更,无法派单')
         return
       }
-      const tech = this.technicians.find((t) => t.id === this.selectedId)
-      this.$message.success(`订单 ${this.currentOrder.orderNo} 已成功派单给 ${tech.nickname}`)
-      this.$emit('success', {
-        order: this.currentOrder,
-        technician: tech
+      //const tech = this.technicians.find((t) => t.id === this.selectedId)
+      dispatchOrder(this.filterForm.orderId, {
+        merchantId: this.selectedId
+      }).then(res => {
+        console.log(res)
+
+        if (res.code === 200) {
+          this.$message.success(res.msg)
+          this.$emit('success',this.filterForm.orderId)
+          this.dialogVisible = false
+        }
+      }).catch(err => {
+        this.$message.error(`订单 ${this.currentOrder.orderNo} 已成功派单给 ${tech.nickname}`)
       })
-      this.dialogVisible = false
+      // this.$emit('success', {
+      //   order: this.currentOrder,
+      //   technician: tech
+      // })
+
     },
 
     destroyMap() {

+ 49 - 0
src/views/mapDemo/components/OrderAddressMap.vue

@@ -104,11 +104,60 @@ export default {
         if (this.fitMarkers && this.markers.length) {
           this.fitMarkerView()
         }
+        // 2. 异步加载 逆地理编码 插件
+        this.map.plugin(['AMap.Geocoder'], () => {
+          // 插件加载成功后再实例化
+          this.geocoder = new AMap.Geocoder()
+          console.log('Geocoder 初始化完成')
+        })
       }).catch((err) => {
         console.error('地图加载失败', err)
         this.$message.error('地图加载失败,请检查网络或 Key 配置')
       })
     },
+    getCityByLngLat(lng, lat, orderInfo,type) {
+      console.log('获取城市', lng, lat)
+      if (this.geocoder) {
+          const lngLat = new AMap.LngLat(lng, lat)
+          this.geocoder.getAddress(lngLat, (status, result) => {
+            if (status === 'complete') {
+              const addr = result.regeocode.addressComponent
+              if (type == '1') {
+                const addrStr = this.getFullAddress(addr)
+                this.$emit('virtualAddress', addrStr)
+              } else {
+                this.$emit('region', addr.citycode)
+
+              }
+
+            }
+          })
+        }
+
+
+    },
+    getFullAddress(addr) {
+      const parts = []
+      // 省份
+      if (addr.province) parts.push(addr.province)
+
+      // 城市:为空则使用省份(适配直辖市)
+      const cityName = addr.city || addr.province
+      if (cityName) parts.push(cityName)
+
+      // 区/县
+      if (addr.district) parts.push(addr.district)
+      // 街道/乡镇
+      if (addr.township) parts.push(addr.township)
+      // 道路
+      if (addr.street) parts.push(addr.street)
+      // 门牌号
+      if (addr.streetNumber) parts.push(addr.streetNumber)
+      // 楼栋
+      if (addr.building) parts.push(addr.building)
+
+      return parts.join('')
+    },
 
     renderMarkers() {
       if (!this.map || !this.AMap) return

+ 5 - 2
src/views/mapDemo/dispatchOrder.vue

@@ -2,7 +2,7 @@
   <div class="dispatch-order-page">
     <el-button type="primary" @click="openDispatch">订单分配</el-button>
 
-    <dispatch-order-dialog ref="dispatchDialog" />
+    <dispatch-order-dialog ref="dispatchDialog" @success="handleSuccess" />
   </div>
 </template>
 
@@ -29,7 +29,10 @@ export default {
   methods: {
     openDispatch() {
       this.$refs.dispatchDialog.open(MOCK_ORDER)
-    }
+    },
+    handleSuccess() {
+      this.$emit('success')
+    },
   }
 }
 </script>

+ 397 - 205
src/views/order/orderDetail/index.vue

@@ -1,234 +1,426 @@
 <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 class="app-container">
+    <div class="top">
+      <div class="message">
+        <div class="left">
+          <span>{{ orderInfo.orderNo }}</span>
         </div>
-        <div class="voucher">
-            <el-descriptions title="服务凭证"></el-descriptions>
-            <div class="list">
-                <image-preview src="" :width="180" :height="180" />
-            </div>
+        <div class="right">
+          <el-button v-if="orderInfo.status == 1" type="primary" size="small"
+            @click="handleAllot(orderInfo)">分配</el-button>
+          <el-button
+            v-if="orderInfo.status == 2 || orderInfo.status == 3 || orderInfo.status == 4 || orderInfo.status == 5"
+            @click="handleRefund(orderInfo)" type="primary" size="small">退款</el-button>
+          <el-button v-if="orderInfo.status == 2" type="primary" size="small"
+            @click="handleExchange(orderInfo)">更换商户</el-button>
+          <el-button v-if="orderInfo.status == 0 || orderInfo.status == 1 || orderInfo.status == 6"
+            @click="handleDel(orderInfo)" type="primary" size="small">删除</el-button>
         </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>
+      <!-- 订单状态(0:待付款,1:待派单,2:待接单,3:待服务 4:服务中 5:已完成 6:已取消
+       7:已关闭 8:拒绝接单 9:退款成功)  -->
+      <!-- <div class="status">{{ orderInfo.status }}</div> -->
+
+      <el-steps :active="orderInfo.status" align-center>
+        <el-step title="提交订单" :description="orderInfo.createTime"></el-step>
+        <el-step title="派单" :description="orderInfo.dispatchTime"></el-step>
+        <el-step title="接单" :description="orderInfo.acceptTime"></el-step>
+        <el-step title="服务已开始" :description="orderInfo.startTime"></el-step>
+        <el-step title="服务已完成" :description="orderInfo.completedTime"></el-step>
+      </el-steps>
+    </div>
+    <div class="order">
+      <el-descriptions title="订单信息">
+        <el-descriptions-item label="下单用户">{{ orderInfo.userNickName }}-{{ orderInfo.contactPhoneNumber
+          }}</el-descriptions-item>
+        <el-descriptions-item label="商户信息">{{ orderInfo.merchantNickName }}-{{ orderInfo.merchantPhone
+          }}</el-descriptions-item>
+        <el-descriptions-item label="下单时间">{{ orderInfo.createTime }}</el-descriptions-item>
+        <el-descriptions-item label="联系信息">{{ orderInfo.contactPersonName }}-{{ orderInfo.contactPhoneNumber
+          }}</el-descriptions-item>
+        <el-descriptions-item label="真实地址">{{ orderInfo.contactAddressInfo }}</el-descriptions-item>
+        <el-descriptions-item label="付款时间">{{ orderInfo.paidTime }}</el-descriptions-item>
+        <el-descriptions-item label="联系地址">{{ orderInfo.contactAddressInfo }}</el-descriptions-item>
+        <el-descriptions-item label="虚拟地址">{{ orderInfo.virtualAddress }}</el-descriptions-item>
+        <el-descriptions-item label="支付方式">{{ orderInfo.paymentMethodName }}</el-descriptions-item>
+        <el-descriptions-item label="预约时间">{{ orderInfo.appointmentStartTime }}</el-descriptions-item>
+        <el-descriptions-item label="目标距离">{{ orderInfo.distance }}</el-descriptions-item>
+        <el-descriptions-item label="平台收益">{{ orderInfo.platformIncome }}</el-descriptions-item>
+        <el-descriptions-item label="服务开始">{{ orderInfo.startTime }}</el-descriptions-item>
+        <el-descriptions-item label="服务时长">{{ orderInfo.projectDuration }}分钟</el-descriptions-item>
+        <el-descriptions-item label="商户收益">{{ orderInfo.merchantIncome }}</el-descriptions-item>
+        <el-descriptions-item label="服务结束">{{ orderInfo.completedTime }}</el-descriptions-item>
+      </el-descriptions>
+      <div class="map">
+        <order-address-map ref="orderAddressMap" :markers="markers" :center="center" :zoom="12" height="400px"
+          @marker-click="onMarkerClick" @virtualAddress="onVirtualAddress" @region="onRegion" />
+      </div>
+    </div>
+    <div class="voucher">
+      <el-descriptions title="服务凭证"></el-descriptions>
+      <div class="list">
+        <div v-for="item in serviceVoucherList" :key="item.id">
+          <image-preview :src="item.voucherUrl" :width="180" :height="180" />
         </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 class="order">
+      <el-table :data="orderTable">
+        <el-table-column prop="a" label="项目信息">
+          <template #default="{ row }">
+            <div class="projectMsg">
+              <div class="left">
+                <image-preview :src="row.projectCover" :width="80" :height="80" />
+              </div>
+              <div class="right">
+                <div>{{ row.projectName }}</div>
+                <div>({{ row.standardDuration }}{{ row.unitName }} )</div>
+              </div>
             </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="unitName" label="计费单位"></el-table-column>
+        <el-table-column prop="unitPrice" label="售价"></el-table-column>
+        <el-table-column prop="merchantCommission" label="商户佣金">
+          <template #default="{ row }">
+            {{ row.merchantCommission }}%
+          </template>
+        </el-table-column>
+        <el-table-column prop="finalAmount" label="实付金额"></el-table-column>
+        <el-table-column prop="afterSalesServiceStatus" label="售后信息">
+          <template #default="{ row }">
+            {{ row.afterSalesServiceStatus ? row.afterSalesServiceStatus : '暂无售后订单' }}
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="other">
+        <div class="right">
+          <div class="box">
+            <span>订单应收:</span>
+            <span>¥{{ orderTable[0].unitPrice }}</span>
+          </div>
+          <div class="box">
+            <span>出行车费:</span>
+            <span>¥{{ orderTable[0].trafficFee }}</span>
+          </div>
+          <div class="box">
+            <span>优惠券抵扣:</span>
+            <span>-¥{{ orderTable[0].couponDiscount }}</span>
+          </div>
+          <div class="box">
+            <span>实付金额:</span>
+            <span style="color: #e74c3c">¥{{ orderTable[0].finalAmount }}</span>
+          </div>
         </div>
+      </div>
+    </div>
+    <div class="log">
+      <el-descriptions title="操作日志"></el-descriptions>
+      <div class="table">
+        <el-table :data="logTable">
+          <el-table-column prop="operator" label="操作人"></el-table-column>
+          <el-table-column prop="operationTime" label="操作时间"></el-table-column>
+          <el-table-column prop="operationContent" label="操作内容"></el-table-column>
+        </el-table>
+      </div>
     </div>
+    <DispatchOrderDialog ref="dispatchDialogRefs" @success="getOrderDetail" />
+  </div>
 </template>
 
 <script>
+import DispatchOrderDialog from '@/views/mapDemo/components/DispatchOrderDialog.vue'
+import AMapLoader from '@amap/amap-jsapi-loader'
 import OrderAddressMap from '@/views/mapDemo/components/OrderAddressMap.vue'
+import { getOrderDetail, orderDetail, refundApply } from '@/api/order/serviceOrder'
+const AMAP_KEY = '41bc0f647d4432045d472f554bf03d75'
+const AMAP_SECURITY = '80ba66cc0bba5b07de6a275d7aa02a39'
+let mapInstanceSeed = 0
 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: [
-                {}
-            ]
-        }
+  name: "detail",
+  components: { OrderAddressMap, DispatchOrderDialog },
+  data() {
+    return {
+      center: [116.397428, 39.90923],
+      // 示例:用户下单地址user / 商户真实地址real / 商户虚拟地址virtual
+      markers: [
+        { lng: 116.280892, lat: 39.921234, label: '用户下单地址', type: 'user' },
+        { lng: 116.385621, lat: 39.954812, label: '商户真实地址', type: 'real' },
+        { lng: 116.451328, lat: 39.908765, label: '商户虚拟地址', type: 'virtual' }
+      ],
+      orderTable: [
+        {}
+      ],
+      logTable: [
+        {}
+      ],
+      orderInfo: { virtualAddress: '' },
+      serviceVoucherList: [],
+      geocoder: null,
+      mapId: `order-address-map-${++mapInstanceSeed}`,
+      AMap: null,
+      map: null,
+
+    }
+  },
+  methods: {
+    initMap() {
+      AMapLoader.reset()
+      AMapLoader.load({
+        key: AMAP_KEY,
+        version: '2.0'
+      }).then((AMap) => {
+        this.AMap = AMap
+        this.map = new AMap.Map(this.mapId, {
+          resizeEnable: true,
+          zoom: this.zoom,
+          center: this.center,
+          viewMode: '2D'
+        })
+        // 2. 异步加载 逆地理编码 插件
+        this.map.plugin(['AMap.Geocoder'], () => {
+          // 插件加载成功后再实例化
+          this.geocoder = new AMap.Geocoder()
+          console.log('Geocoder 初始化完成')
+        })
+      }).catch((err) => {
+        console.error('地图加载失败', err)
+        this.$message.error('地图加载失败,请检查网络或 Key 配置')
+      })
     },
-    methods: {
-        onMarkerClick(marker) {
-            this.$message.info(`点击标记:${marker.label}`)
+    // 分配成功
+    getOrderDetail(id) {
+      getOrderDetail(id).then(res => {
+        if (res.code == 200) {
+          this.orderInfo = res.data.orderInfo
+          this.orderInfo.categoryId = Number(this.$route.query.categoryId)
+          // 订单状态(0:待付款,1:待派单,2:待接单,3:待服务 4:服务中 5:已完成 6:已取消
+          //7:已关闭 8:拒绝接单 9:退款成功)
+          //this.orderInfo.status = 9 //guo
+          this.projectInfo = res.data.projectInfo
+          this.serviceVoucherList = res.data.serviceVoucherList
+
+          this.orderTable = [res.data.projectInfo]
+          this.logTable = res.data.operationLogList
+          this.markers = [
+            //  { lng: 116.280892, lat: 39.921234, label: '用户下单地址', type: 'user' },
+            //  { lng: 116.385621, lat: 39.954812, label: '商户真实地址', type: 'real' },
+            //  { lng: 116.451328, lat: 39.908765, label: '商户虚拟地址', type: 'virtual' },
+            { lng: this.orderInfo.userLongitude, lat: this.orderInfo.userLatitude, label: '用户下单地址', type: 'user' },
+            { lng: this.orderInfo.merchantLongitude, lat: this.orderInfo.merchantLatitude, label: '商户真实地址', type: 'real' },
+            { lng: this.orderInfo.virtualLongitude, lat: this.orderInfo.virtualLatitude, label: '商户虚拟地址', type: 'virtual' },
+
+          ]
+          setTimeout(() => {
+            this.$refs.orderAddressMap.getCityByLngLat(this.orderInfo.merchantLongitude, this.orderInfo.merchantLatitude, this.orderInfo, '1')
+            this.$refs.orderAddressMap.getCityByLngLat(this.orderInfo.merchantLongitude, this.orderInfo.merchantLatitude, this.orderInfo, '2')
+          }, 1000)
+
+        } else {
+          this.$message.error(res.msg)
         }
+      })
+    },
+    // 商户虚拟地址
+    onVirtualAddress(virtualAddress) {
+      this.$set(this.orderInfo, 'virtualAddress', virtualAddress)
+    },
+    // 商户区域
+    onRegion(region) {
+      this.$set(this.orderInfo, 'region', region)
+    },
+    // 分配
+    async handleAllot(row) {
+      this.allotDialogShow = true
+      //this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+      setTimeout(() => {
+        this.$refs.dispatchDialogRefs.open(row)
+      }, 600)
+    },
+    // 删除订单
+    handleDel(row) {
+      this.$confirm('被删除的订单可以通过「订单回收站」查找并恢复', '是否确认删除?', {
+        type: 'warning',
+        confirmButtonText: '确认删除'
+      })
+        .then(() => {
+          orderDetail(row.id).then(res => {
+            if (res.code == 200) {
+              this.$message({
+                message: res.msg,
+                type: 'success'
+              });
+              this.initData();
+            } else {
+              this.$message({
+                message: res.msg,
+                type: 'error'
+              });
+            }
+          })
+        })
+        .catch(() => {
+
+        });
+    },
+    // 退款
+    handleRefund(row) {
+      this.$confirm('是否确认退款?', '系统提示', {
+        type: 'warning',
+        confirmButtonText: '确认'
+      })
+        .then(() => {
+          refundApply(row.id).then(res => {
+            if (res.code == 200) {
+              this.$message({
+                message: res.msg,
+                type: 'success'
+              });
+              this.initData();
+            } else {
+              this.$message({
+                message: res.msg,
+                type: 'error'
+              });
+            }
+          })
+        })
+        .catch(() => {
+
+        });
+    },
+    // 更换商户
+    handleExchange(row) {
+      this.allotDialogShow = true
+      //this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+      setTimeout(() => {
+        this.$refs.dispatchDialogRefs.open(row)
+      }, 500)
     },
-    mounted() {
 
+    onMarkerClick(marker) {
+      this.$message.info(`点击标记:${marker.label}`)
     }
+  },
+  mounted() {
+    window._AMapSecurityConfig = { securityJsCode: AMAP_SECURITY }
+    this.getOrderDetail(this.$route.query.id)
+    //this.initMap()
+
+    // getOrderDetail(this.$route.query.id).then(res => {
+    //   if (res.code == 200) {
+    //     this.logTable = res.data.logItems
+    //   } else {
+    //     this.$message.error(res.msg)
+    //   }
+    // })
+
+  }
 }
 </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;
-            }
+::v-deep .el-input--medium {
+  height: 38px;
+}
+
+.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%;
         }
-        .other{
-            display: flex;
-            justify-content: flex-end;
-            .right{
-                width: 200px;
-                .box{
-                    display: flex;
-                    align-items: center;
-                    justify-content: space-between;
-                    margin-top: 10px;
-                }
-            }
+
+        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;
+      }
     }
-    .voucher{
-        background: white;
-        margin: 10px;
-        padding: 10px;
-        .list{
-            display: flex;
-            align-items: center;
-            justify-content: flex-start;
+
+    .other {
+      display: flex;
+      justify-content: flex-end;
+
+      .right {
+        width: 200px;
+
+        .box {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          margin-top: 10px;
         }
+      }
     }
-    .log{
-        background: white;
-        margin: 10px;
-        padding: 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>

+ 332 - 300
src/views/order/recycle/index.vue

@@ -1,335 +1,367 @@
 <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.orderNo" 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.createTime"
-                            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.userKeyword" placeholder="请填写" clearable >
-                            <el-select style="width: 100px" v-model="orderForm.userSearchType" 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.categoryId" 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: 280px" v-model="orderForm.projectName" clearable></el-input>
-                    </el-form-item>
-                </el-col>
-                <el-col :span="6">
-                    <el-form-item label="商户信息">
-                        <el-input style="width: 280px" v-model="orderForm.merchantSearchType" placeholder="请填写" clearable >
-                            <el-select style="width: 100px" v-model="orderForm.merchantKeyword" 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.paymentMethod" clearable>
-                            <el-option label="0购物卡支付" 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: 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>
+  <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.orderNo" 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.createTime" 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.userKeyword" placeholder="请填写" clearable>
+              <el-select style="width: 100px" v-model="orderForm.userSearchType" slot="prepend" placeholder="请选择">
+                <el-option label="手机号" value="phone"></el-option>
+                <el-option label="昵称" value="nickName"></el-option>
+                <el-option label="姓名" value="name"></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.categoryId" 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: 280px" v-model="orderForm.projectName" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="商户信息">
+            <el-input style="width: 280px" v-model="orderForm.merchantKeyword" placeholder="请填写" clearable>
+              <el-select style="width: 100px" v-model="orderForm.merchantSearchType" slot="prepend" placeholder="请选择">
+                <el-option label="手机号" value="phone"></el-option>
+                <el-option label="昵称" value="nickName"></el-option>
+                <el-option label="姓名" value="name"></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.paymentMethod" 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: 280px" v-model="orderForm.e" clearable>
+              <el-option label="1" value="1"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
 
-        <DispatchOrderDialog ref="dispatchDialogRefs" />
+        <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">{{ row.orderNo }}</div>
+          <div class="orderTime">下单时间:{{ row.orderTime }}</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">{{ row.projectName }}</div>
+              <div class="type">{{ row.projectDuration }}分钟</div>
+              <div class="serveTime">服务时间:2025.12.02 12:00-13:00</div>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="单价/数量" width="130">
+        <template #default="{ row }">
+          <div class="orderNum">{{ row.unitPrice }}/{{ row.unitName }}</div>
+          <div class="orderTime">×{{ row.quantity }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="订单金额" width="240">
+        <template #default="{ row }">
+          <div class="orderNum">¥{{ row.orderAmount }}(含出行费:¥{{ row.trafficFee }})</div>
+          <div class="orderTime">{{ row.status == 0 ? '--' : row.paymentMethodName }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="联系信息" width="200">
+        <template #default="{ row }">
+          <div class="connectMsg">用户:{{ row.userNickName }}</div>
+          <div class="connectMsg" v-if="row.contactPersonName">联系人:{{ row.contactPersonName[0] }} 男 {{
+            row.contactPhoneMasked }}</div>
+          <div class="connectMsg connectAddress">地址:{{ row.contactAddressInfo }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态">
+        <template #default="{ row }">
+          <!-- <div class="orderNum">状态</div> -->
+          <div class="orderNum">{{ row.execStatusName }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="服务商户">
+        <template #default="{ row }">
+          <div class="orderNum">姓名:{{ row.merchantName }}</div>
+          <div class="orderNum">手机号:{{ row.merchantPhone }}</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'
-import { serviceCategory, orderPage } from '@/api/order/serviceOrder'
+import { serviceCategory } from '@/api/order/serviceOrder'
+import { recycleOrderList, restoreOrder } from '@/api/order/recycle'
+
 const MOCK_ORDER = {
-    cId: '1',
-    orderNo: 'ORD20260601001',
-    cName: '张三',
-    cPhone: '13800138001',
-    cAddress: '北京市东城区王府井大街88号',
-    category: '按摩',
-    region: 'city',
-    arrivalLongitude: 116.297428,
-    arrivalLatitude: 39.90923,
-    dispatchStatus: 'pending'
+  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 {
-          serveTypes: [],
-            orderForm: {
-                current: 1,
-                size: 10,
-            },
-            total: 1,
-            table: [
-                {}
-            ],
-            allotDialogShow: false
+  name: "serveOrder",
+  components: { DispatchOrderDialog },
+  data() {
+    return {
+      orderStatus: [
+        { value: 0, label: "待支付" },
+        { value: 1, label: "待派单" },
+        { value: 2, label: "待接单" },
+        { value: 3, label: "待服务" },
+        { value: 4, label: "服务中" },
+        { value: 5, label: "已完成" },
+        { value: 6, label: "已取消" },
+      ],
+      serveTypes: [],
+      orderForm: {
+        current: 1,
+        size: 10,
+        userSearchType: 'phone',
+        merchantSearchType: 'nickName',
+      },
+      typeList: [
+        { name: '全部' },
+        { value: 0, name: "待接单" },
+        { value: 1, name: "待派单" },
+        { value: 2, name: "待接单" },
+        { value: 3, name: "待服务" },
+        { value: 4, name: "服务中" },
+        { value: 5, name: "已完成" },
+        { value: 6, name: "已取消" },
+      ],
+      total: 1,
+      table: [
+        {}
+      ],
+      allotDialogShow: false
+    }
+  },
+  methods: {
+    initData() {
+      let params = {
+        current: this.orderForm.current,
+        size: this.orderForm.size,
+        orderNo: this.orderForm.orderNo,
+        projectName: this.orderForm.projectName,
+        merchantSearchType: this.orderForm.merchantSearchType,
+        merchantKeyword: this.orderForm.merchantKeyword,
+        startTime: this.orderForm.createTime?.[0],
+        endTime: this.orderForm.createTime?.[1],
+        userSearchType: this.orderForm.userSearchType,
+        userKeyword: this.orderForm.userKeyword,
+        categoryId: this.orderForm.categoryId,
+        paymentMethod: this.orderForm.paymentMethod,
+        status: this.orderForm.status,
+      }
+      recycleOrderList(params).then(res => {
+        if (res.code === 200) {
+          this.table = res.data.records
+          this.total = res.data.total
+        }
+      })
+
+    },
+    serviceCategoryFun() {
+      serviceCategory().then(res => {
+        if (res.code === 200) {
+          this.serveTypes = res.data
         }
+      })
     },
-    methods: {
-        initData() {
-          let params = {
-                current: this.orderForm.current,
-                size: this.orderForm.size,
-                orderNo: this.orderForm.orderNo,
-                projectName: this.orderForm.projectName,
-                merchantSearchType: this.orderForm.merchantSearchType,
-                merchantKeyword: this.orderForm.merchantKeyword,
-                startTime: this.orderForm.createTime?.[0],
-                endTime: this.orderForm.createTime?.[1],
-                userSearchType: this.orderForm.userSearchType,
-                userKeyword: this.orderForm.userKeyword,
-                categoryId: this.orderForm.categoryId,
-                paymentMethod: this.orderForm.paymentMethod,
-                status: this.orderForm.status,
+    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(() => {
+          restoreOrder(row.id).then(restoreRes => {
+            if (restoreRes.code === 200) {
+              this.initData();
+              this.$message({
+                message: restoreRes.msg,
+                type: 'success'
+              });
+            }else{
+              this.$message({
+                message: restoreRes.msg,
+                type: 'error'
+              });
             }
-          orderPage(params).then(res => {
-                if (res.code === 200) {
-                    this.table = res.data.records
-                    this.total = res.data.total
-                }
           })
+        })
+        .catch(() => {
 
-        },
-        serviceCategoryFun() {
-            serviceCategory().then(res => {
-                if (res.code === 200) {
-                    this.serveTypes = res.data
-                }
-            })
-        },
-        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();
-        this.serviceCategoryFun()
+        });
     }
+  },
+  mounted() {
+    this.initData();
+    this.serviceCategoryFun()
+  }
 }
 </script>
 
 <style scoped lang="scss">
-.btns{
-    margin: 20px 0;
+::v-deep .el-input--medium {
+  height: 38px;
+}
+.btns {
+  margin: 20px 0;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+
+  .type {
     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;
-        }
+
+    .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;
+
+.orderNum {
+  font-size: 14px;
+  color: black;
 }
-.orderTime{
-    font-size: 12px;
+
+.orderTime {
+  font-size: 12px;
 }
-.serveProject{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .photo{
-        margin-right: 10px;
+
+.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;
     }
-    .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;
-        }
+
+    .type {
+      font-size: 14px;
+    }
+
+    .serveTime {
+      font-size: 12px;
     }
+  }
 }
-.connectMsg{
-    width: 100%;
-    color: black;
-    font-size: 14px;
+
+.connectMsg {
+  width: 100%;
+  color: black;
+  font-size: 14px;
 }
-.connectAddress{
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
+
+.connectAddress {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
 }
 
-.pagination{
-    margin-top: 20px;
-    display: flex;
-    align-items: center;
-    justify-content: flex-end;
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
 }
 </style>

+ 119 - 45
src/views/order/serviceOrder/index.vue

@@ -91,7 +91,7 @@
             <div class="message">
               <div class="title">{{ row.projectName }}</div>
               <div class="type">{{ row.projectDuration }}分钟</div>
-              <div class="serveTime">服务时间:2025.12.02 12:00-13:00</div>
+              <div class="serveTime">服务时间:{{ row.startTime }}</div>
             </div>
           </div>
         </template>
@@ -111,7 +111,7 @@
       <el-table-column label="联系信息" width="200">
         <template #default="{ row }">
           <div class="connectMsg">用户:{{ row.userNickName }}</div>
-          <div class="connectMsg" v-if="row.contactPersonName">联系人:{{ row.contactPersonName[0] }} 男 {{
+          <div class="connectMsg" v-if="row.contactPersonName">联系人:{{ row.contactPersonName[0] }} {{ row.sec == 0 ? '女' : '' }} {{
             row.contactPhoneMasked }}</div>
           <div class="connectMsg connectAddress">地址:{{ row.contactAddressInfo }}</div>
         </template>
@@ -124,7 +124,7 @@
       </el-table-column>
       <el-table-column label="服务商户">
         <template #default="{ row }">
-          <div class="orderNum">姓名:{{ row.merchantName }}</div>
+          <div class="orderNum">姓名:{{ row.merchantNickName }}</div>
           <div class="orderNum">手机号:{{ row.merchantPhone }}</div>
         </template>
       </el-table-column>
@@ -139,7 +139,8 @@
               <el-dropdown-item command="allot" v-if="row.status == 1" @click="handleAllot(row)">分配</el-dropdown-item>
               <el-dropdown-item command="del" v-if="row.status == 0 || row.status == 1 || row.status == 6"
                 @click="handleDel(row)">删除</el-dropdown-item>
-              <el-dropdown-item command="refund" v-if="row.status == 2 || row.status == 3 || row.status == 4 || row.status == 5"
+              <el-dropdown-item command="refund"
+                v-if="row.status == 2 || row.status == 3 || row.status == 4 || row.status == 5"
                 @click="handleRefund(row)">退款</el-dropdown-item>
               <el-dropdown-item command="exchange" v-if="row.status == 2"
                 @click="handleExchange(row)">更换商户</el-dropdown-item>
@@ -154,13 +155,18 @@
         :total="total" />
     </div>
 
-    <DispatchOrderDialog ref="dispatchDialogRefs" />
+    <DispatchOrderDialog ref="dispatchDialogRefs" @success="initData" />
+    <div :id="mapId" class="map-container" style="height: 0;"></div>
   </div>
 </template>
 
 <script>
+
+const AMAP_KEY = '41bc0f647d4432045d472f554bf03d75'
+const AMAP_SECURITY = '80ba66cc0bba5b07de6a275d7aa02a39'
+import AMapLoader from '@amap/amap-jsapi-loader'
 import DispatchOrderDialog from '@/views/mapDemo/components/DispatchOrderDialog.vue'
-import { serviceCategory, orderPage, orderDetail } from '@/api/order/serviceOrder'
+import { serviceCategory, orderPage, orderDetail,refundApply, getDispatchMerchantList } from '@/api/order/serviceOrder'
 const MOCK_ORDER = {
   cId: '1',
   orderNo: 'ORD20260601001',
@@ -173,6 +179,7 @@ const MOCK_ORDER = {
   arrivalLatitude: 39.90923,
   dispatchStatus: 'pending'
 }
+let mapInstanceSeed = 0
 export default {
   name: "serveOrder",
   components: { DispatchOrderDialog },
@@ -185,19 +192,10 @@ export default {
         userSearchType: 'phone',
         merchantSearchType: 'nickName',
       },
-      orderStatus: [
-        { value: 0, label: "待支付" },
-        { value: 1, label: "待派单" },
-        { value: 2, label: "待接单" },
-        { value: 3, label: "待服务" },
-        { value: 4, label: "服务中" },
-        { value: 5, label: "已完成" },
-        { value: 6, label: "已取消" },
-      ],
       total: 1,
       typeIndex: 0,
       typeList: [
-        { name: '全部' },
+        { value: null, name: '全部' },
         { value: 0, name: "待接单" },
         { value: 1, name: "待派单" },
         { value: 2, name: "待接单" },
@@ -209,7 +207,11 @@ export default {
       table: [
         {}
       ],
-      allotDialogShow: false
+      allotDialogShow: false,
+      geocoder: null,
+      mapId: `order-address-map-${++mapInstanceSeed}`,
+      AMap: null,
+      map: null,
     }
   },
   methods: {
@@ -228,7 +230,7 @@ export default {
         userKeyword: this.orderForm.userKeyword,
         categoryId: this.orderForm.categoryId,
         paymentMethod: this.orderForm.paymentMethod,
-        status: this.typeList[this.typeIndex].value || null,
+        status: this.typeList[this.typeIndex].value,
       }
       orderPage(params).then(res => {
         if (res.code === 200) {
@@ -238,23 +240,7 @@ export default {
       })
 
     },
-    //删除服务订单
-    handleDel(row) {
-      orderDetail(row.id).then(res => {
-        if (res.code == 200) {
-          this.$message({
-            message: res.msg,
-            type: 'success'
-          });
-          this.initData();
-        } else {
-          this.$message({
-            message: res.msg,
-            type: 'error'
-          });
-        }
-      })
-    },
+
     //获取服务类型
     serviceCategoryFun() {
       serviceCategory().then(res => {
@@ -275,6 +261,7 @@ export default {
     },
     handleTypeIndex(item, index) {
       this.typeIndex = index
+      this.initData();
     },
     handleSizeChange(size) {
       this.orderForm.size = size
@@ -288,15 +275,19 @@ export default {
       this.$router.push({
         path: '/order/orderDetail',
         query: {
-          id: row.id
+          id: row.id,
+          categoryId: row.categoryId
         }
       })
     },
-    handleAllot(row) {
+    async handleAllot(row) {
+      //row.category = 1
+      this.getCityByLngLat(row.merchantLongitude, row.merchantLatitude,row)
       this.allotDialogShow = true
-      this.$nextTick(() => {
-        this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
-      })
+      //this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+      setTimeout(() => {
+        this.$refs.dispatchDialogRefs.open(row)
+      }, 500)
     },
     handleDel(row) {
       this.$confirm('被删除的订单可以通过「订单回收站」查找并恢复', '是否确认删除?', {
@@ -304,7 +295,20 @@ export default {
         confirmButtonText: '确认删除'
       })
         .then(() => {
-          this.$modal.msgSuccess("删除成功");
+          orderDetail(row.id).then(res => {
+            if (res.code == 200) {
+              this.$message({
+                message: res.msg,
+                type: 'success'
+              });
+              this.initData();
+            } else {
+              this.$message({
+                message: res.msg,
+                type: 'error'
+              });
+            }
+          })
         })
         .catch(() => {
 
@@ -336,10 +340,17 @@ export default {
         });
     },
     handleExchange(row) {
+
+      this.getCityByLngLat(row.merchantLongitude, row.merchantLatitude,row)
       this.allotDialogShow = true
-      this.$nextTick(() => {
-        this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
-      })
+      //this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+      setTimeout(() => {
+        this.$refs.dispatchDialogRefs.open(row)
+      }, 500)
+      // this.allotDialogShow = true
+      // this.$nextTick(() => {
+      //   this.$refs.dispatchDialogRefs.open(MOCK_ORDER)
+      // })
     },
     clickMenuItem(command, row) {
       switch (command) {
@@ -359,9 +370,72 @@ export default {
           this.handleExchange(row)
           break;
       }
-    }
+    },
+    initMap() {
+      AMapLoader.reset()
+      AMapLoader.load({
+        key: AMAP_KEY,
+        version: '2.0'
+      }).then((AMap) => {
+        this.AMap = AMap
+        this.map = new AMap.Map(this.mapId, {
+          resizeEnable: true,
+          zoom: this.zoom,
+          center: this.center,
+          viewMode: '2D'
+        })
+        //2. 异步加载 逆地理编码 插件
+        this.map.plugin(['AMap.Geocoder'], () => {
+          // 插件加载成功后再实例化
+          this.geocoder = new AMap.Geocoder()
+          console.log('Geocoder 初始化完成')
+        })
+
+      }).catch((err) => {
+        console.error('地图加载失败', err)
+        this.$message.error('地图加载失败,请检查网络或 Key 配置')
+      })
+    },
+
+    async getCityByLngLat(lng, lat, row) {
+      console.log('获取城市', lng, lat)
+      if (this.geocoder) {
+        const lngLat = new AMap.LngLat(lng, lat)
+        await this.geocoder.getAddress(lngLat, (status, result) => {
+          if (status === 'complete') {
+            const addr = result.regeocode.addressComponent
+            row.region = addr.citycode
+
+          }
+        })
+      }
+    },
+    getFullAddress(addr) {
+      const parts = []
+      // 省份
+      if (addr.province) parts.push(addr.province)
+
+      // 城市:为空则使用省份(适配直辖市)
+      const cityName = addr.city || addr.province
+      if (cityName) parts.push(cityName)
+
+      // 区/县
+      if (addr.district) parts.push(addr.district)
+      // 街道/乡镇
+      if (addr.township) parts.push(addr.township)
+      // 道路
+      if (addr.street) parts.push(addr.street)
+      // 门牌号
+      if (addr.streetNumber) parts.push(addr.streetNumber)
+      // 楼栋
+      if (addr.building) parts.push(addr.building)
+
+      return parts.join('')
+    },
   },
   mounted() {
+    window._AMapSecurityConfig = { securityJsCode: AMAP_SECURITY }
+    this.initMap()
     this.initData();
     this.serviceCategoryFun();
   }

+ 4 - 4
src/views/serve/project.vue

@@ -52,22 +52,22 @@
             </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>
+                    <el-switch v-model="row.isRecommended" disabled :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>
+                    <el-switch v-model="row.isPriceCustom" disabled :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>
+                    <el-switch v-model="row.isTimeCustom" disabled :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>
+                    <el-switch v-model="row.status" disabled :active-value="1" :inactive-value="0"></el-switch>
                 </template>
             </el-table-column>
             <el-table-column prop="highlightIds" label="亮点" width="150">

+ 1 - 1
src/views/storedValue/cards.vue

@@ -36,7 +36,7 @@
                 <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-button type="primary" @click="handleExport">导出</el-button> -->
                 </el-col>
             </el-row>
         </el-form>

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

@@ -229,6 +229,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
+::v-deep .el-input--medium {
+  height: 38px;
+}
 .btns{
     margin-bottom: 20px;
     display: flex;

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

@@ -163,6 +163,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
+::v-deep .el-input--medium {
+  height: 38px;
+}
 .btns{
     margin-bottom: 20px;
     display: flex;

+ 219 - 0
src/views/tenant/dynamic/dynamicAudit.vue

@@ -0,0 +1,219 @@
+<template>
+  <ModalView
+    ref="mv"
+    cname="ElDialog"
+    :title="title"
+    :viewProps="{
+      width: '45%',
+      customClass: 'auditModal',
+    }"
+    @onClose="close"
+  >
+    <div class="dynamic-info">
+      <div class="dynamic-title">{{ auditForm.title }}</div>
+      <div class="dynamic-content">
+        {{ auditForm.content }}
+      </div>
+      <!-- 图片 -->
+      <div class="media-section" v-if="auditForm.mediaType === 1">
+        <ImageUpload
+          v-model="auditForm.mediaUrls"
+          :limit="9"
+          :readonly="true"
+        />
+      </div>
+      <!-- 视频 -->
+      <div class="media-section" v-if="auditForm.mediaType === 2">
+        <div class="video-container">
+          <video
+            class="video-preview"
+            v-if="auditForm.videoUrl"
+            :src="getVideoUrl(auditForm.videoUrl)"
+            controls
+          ></video>
+        </div>
+      </div>
+    </div>
+
+    <!-- 审核表单 -->
+    <el-form ref="uForm" :model="form" :rules="rules" label-width="80px">
+      <el-form-item label="审核状态" prop="auditStatus">
+        <el-radio-group
+          v-model="form.auditStatus"
+          :disabled="params.status !== 1"
+        >
+          <el-radio :label="2">通过</el-radio>
+          <el-radio :label="3">拒绝</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="审核备注" prop="rejectReason">
+        <el-input
+          type="textarea"
+          placeholder="请输入审核备注/拒绝理由,审核拒绝时必填"
+          v-model="form.rejectReason"
+          maxlength="50"
+          show-word-limit
+          :disabled="params.status !== 1"
+        >
+        </el-input>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button
+        v-if="params.status === 1"
+        type="primary"
+        @click="submitForm('uForm')"
+        >确 定</el-button
+      >
+      <el-button @click="close">取 消</el-button>
+    </div>
+  </ModalView>
+</template>
+
+<script>
+import ModalView from '@/components/ZModalView/index.vue'
+import { getDynamicDetail, auditDynamic } from '@/api/system/dynamic'
+
+export default {
+  components: {
+    ModalView,
+  },
+  data() {
+    return {
+      title: '审核动态',
+      form: {},
+      params: {},
+      auditForm: {
+        title: '',
+        content: '',
+        mediaType: 1,
+        mediaUrls: [],
+        videoUrl: '',
+        auditStatus: 0,
+        rejectReason: '',
+      },
+    }
+  },
+  computed: {
+    rules() {
+      return {
+        auditStatus: [
+          { required: true, message: '请选择审核状态', trigger: 'change' },
+        ],
+        rejectReason: [
+          {
+            required: this.form.auditStatus === 3,
+            message: '请输入拒绝理由',
+            trigger: 'change',
+          },
+        ],
+      }
+    },
+  },
+  methods: {
+    getDetails(id) {
+      getDynamicDetail(id).then(res => {
+        if (res.code === 200) {
+          this.auditForm = res.data
+          if (this.auditForm.mediaType == 2) {
+            this.auditForm.videoUrl = this.auditForm.mediaUrls[0]
+          }
+          // 回显审核状态和原因(1待审核)
+          if (res.data.auditStatus !== 1) {
+            this.form.auditStatus = res.data.auditStatus
+            this.form.rejectReason = res.data.rejectReason
+          }
+          this.$nextTick(() => {
+            if (this.$refs.uForm) {
+              this.$refs.uForm.clearValidate()
+            }
+          })
+        }
+      })
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          const params = {
+            ...this.form,
+            momentId: this.params.momentId,
+          }
+          auditDynamic(params).then(res => {
+            if (res.code === 200) {
+              this.$modal.msgSuccess(res.msg)
+              this.$emit('refreshList')
+              this.close()
+            }
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    resetForm(n, f) {
+      this.$refs[n].resetFields()
+      this.close(f)
+    },
+    open(e) {
+      if (e) this.params = { ...e }
+      this.form = {}
+      this.getDetails(e.momentId)
+      this.$refs.mv.open(this.params.status === 1 ? '审核动态' : '查看详情')
+    },
+    close() {
+      this.form = {}
+      this.$refs.mv.close()
+    },
+    /** 辅助函数:处理视频URL回显(如果是相对路径则加上base_api) */
+    getVideoUrl(url) {
+      if (!url) return ''
+      if (url.indexOf('http') === 0) return url
+      return process.env.VUE_APP_BASE_API + url
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .myModal {
+  .el-dialog__body {
+    max-height: 70vh;
+    overflow-y: auto;
+  }
+}
+
+.dynamic-info {
+  margin-bottom: 10px;
+  border-bottom: 1px solid #e5e5e5;
+
+  .dynamic-title {
+    font-size: 22px;
+    font-weight: bold;
+    margin-bottom: 10px;
+    padding-bottom: 5px;
+    color: #333;
+    border-bottom: 1px solid #e5e5e5;
+  }
+
+  .dynamic-content {
+    font-size: 16px;
+    line-height: 1.5;
+    color: #666;
+    margin-bottom: 20px;
+    white-space: pre-wrap;
+  }
+
+  .media-section {
+    margin-bottom: 20px;
+  }
+
+  .video-container {
+    .video-preview {
+      width: 240px;
+      height: 180px;
+      object-fit: contain;
+    }
+  }
+}
+</style>

+ 267 - 193
src/views/tenant/dynamic/index.vue

@@ -1,217 +1,291 @@
 <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 class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="技师姓名">
+        <el-input v-model="queryParams.technicianName" placeholder="请输入技师姓名" clearable
+          @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="发布时间">
+        <el-date-picker 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="审核状态">
+        <el-select v-model="queryParams.auditStatus" placeholder="请选择" clearable>
+          <el-option v-for="item in dict.type.local_dynamic_audit" :key="item.value" :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item> -->
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button type="primary" size="mini" @click="">导出</el-button>
+      </el-form-item>
+    </el-form>
+
+
+    <el-row :gutter="10" class="mb8">
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <div style="flex: 1">
+      <div class="btns">
+        <div class="type">
+          <span class="typeItem" :class="{ 'active': typeIndex === index }" @click="handleTypeIndex(item, index)"
+            v-for="(item, index) in typeList">{{ item.label }}
+            <span>({{ item.type == 1 ? pendingCount : item.type == 2 ? approvedCount : rejectedCount }})</span>
+          </span>
         </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>
+      <el-table v-loading="loading" :data="dynamicList" height="calc(100% - 68px)">
+        <el-table-column label="序号" type="index" align="center" fixed="left">
+          <template slot-scope="scope">
+            <span>{{
+              (queryParams.current - 1) * queryParams.size + scope.$index + 1
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="姓名" align="center" prop="technicianName" />
+        <el-table-column label="昵称" align="center" prop="technicianNickname" />
+        <el-table-column label="缩略图" align="center" width="60px">
+          <template slot-scope="scope">
+            <el-image fit="contain" :src="scope.row.coverUrl" lazy :preview-src-list="[scope.row.coverUrl]"
+              style="width: 50px; height: 50px"></el-image>
+          </template>
+        </el-table-column>
+        <el-table-column label="动态标题" align="center" prop="title" />
+        <el-table-column label="动态内容" align="center" width="400" prop="content" />
+        <el-table-column key="col-cert1" v-if="typeList[typeIndex].type == 2" label="是否推荐" align="center" prop=""
+          width="180">
+          <template #default="{ row }">
+            <el-switch v-model="row.isRecommend" :active-value="1" :inactive-value="0"
+              @change="handleChange($event, row,'isRecommend')"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column key="col-cert2" v-if="typeList[typeIndex].type == 2" label="是否上架" align="center" prop=""
+          width="180">
+          <template #default="{ row }">
+            <el-switch v-model="row.isList" :active-value="1" :inactive-value="0"
+              @change="handleChange($event, row,'isList')"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column label="发布时间" align="center" prop="publishTime" width="180">
+          <template slot-scope="scope">
+            <span>{{
+              parseTime(scope.row.publishTime, '{y}-{m}-{d} {h}:{i}')
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column key="col-cert3" v-if="typeList[typeIndex].type == 2" label="浏览量" align="center" prop="viewCount" />
+        <el-table-column key="col-cert4" v-if="typeList[typeIndex].type == 2" label="收藏量" align="center" prop="saveCount" />
+        <el-table-column key="col-cert5" label="审核状态" align="center" prop="auditStatus">
+          <template slot-scope="scope">
+            <span>{{scope.row.auditStatus==1?'待审核':scope.row.auditStatus==2?'审核通过':'审核驳回'}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column key="col-cert6" v-if="typeList[typeIndex].type != 1" label="操作人" align="center" prop="updateBy" />
+         <el-table-column key="col-cert7" v-if="typeList[typeIndex].type == 2" label="审核时间" align="center" prop="auditTime" width="180">
+          <template slot-scope="scope">
+            <span>{{
+              parseTime(scope.row.auditTime, '{y}-{m}-{d} {h}:{i}')
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column key="col-cert8" v-if="typeList[typeIndex].type == 1" label="操作" align="center" width="200" fixed="right">
+          <template slot-scope="scope">
+            <el-button size="mini" type="text" :icon="scope.row.auditStatus == 1 ? 'el-icon-bell' : 'el-icon-document'
+              " @click="handleAudit(scope.row)">{{ scope.row.auditStatus == 1 ? '审核' : '详情' }}</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="total > 0" :total="total" :page.sync="queryParams.current" :limit.sync="queryParams.size"
+        @pagination="getList" />
     </div>
+    <!-- 退单审核 -->
+    <DynamicAudit ref="dModal" @close="getList" @refreshList="getList" />
+  </div>
 </template>
 
 <script>
+import { getDynamicList, recommendDynamic, updateListStatus,getAuditStatusCount } from '@/api/system/dynamic'
+import DynamicAudit from './dynamicAudit.vue'
+
 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'
-                    }
-                ]
-            }
+  name: 'Dynamic',
+  dicts: ['local_dynamic_audit'],
+  components: {
+    DynamicAudit,
+  },
+  data() {
+    return {
+      pendingCount: 0,
+      approvedCount: 0,
+      rejectedCount: 0,
+      typeIndex: 0,
+      typeList: [ //1-待审核 2-审核通过 3-审核驳回
+        {
+          label: '待审核',
+          type: '1'
+        }, {
+          label: '审核通过',
+          type: '2'
+        }, {
+          label: '审核驳回',
+          type: '3'
+        },
+      ],
+      loading: true,
+      showSearch: true,
+      total: 0,
+      dynamicList: [],
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10,
+        technicianName: null,
+        auditStatus: 1,
+        dateRange: null,
+      },
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    // 查询动态审核状态统计
+    getAuditStatusCount() {
+      getAuditStatusCount().then(res => {
+        if (res.code == 200) {
+          this.pendingCount = res.data.pendingCount
+          this.approvedCount = res.data.approvedCount
+          this.rejectedCount = res.data.rejectedCount
+        } else {
+          this.$message.error(res.msg)
         }
+      })
     },
-    methods: {
-        initData() {
+    // 动态列表
+    getList() {
+      this.getAuditStatusCount()
+      this.loading = true
+      // 处理日期区间
+      const params = { ...this.queryParams }
+      if (params.dateRange && params.dateRange.length === 2) {
+        params.startTime = params.dateRange[0]
+        params.endTime = params.dateRange[1]
+      }
+      delete params.dateRange
 
-        },
-        handleSizeChange(size) {
-            this.auditForm.size = size
-            this.initData();
-        },
-        handleCurrentChange(page) {
-            this.auditForm.current = page
-            this.initData();
-        },
-        handleSearch() {
-            this.initData();
-        },
-        handleReset() {
-            this.initData();
-        },
-        handleExport() {
+      getDynamicList(params)
+        .then(res => {
+          this.dynamicList = res.data.records
+          this.total = res.data.total
+        })
+        .finally(() => {
+          this.loading = false
+        })
+    },
+    //  搜索
+    handleQuery() {
+      console.log('555555')
+      this.queryParams.current = 1
+      this.getList()
+    },
+    //是否上架
+    handleChange(e, row,type) {
+      console.log(row)
+      let api = updateListStatus
+      let params={
+        id: row.id
+      }
+      if (type == 'isList') {
+        api=updateListStatus
+        params.isList = row.isList ? 1 : 0
+      } else {
+        api=recommendDynamic
+        params.isRecommend = row.isRecommend ? 1 : 0
+      }
 
-        },
-        handleTypeIndex(item, index) {
-            this.typeIndex = index
-        },
-        handleAudit(row) {
-            this.dialogShow = true
-        },
-        handleCancel() {
-            this.dialogShow = false
-        },
-        handleSave() {
-            this.dialogShow = false
+
+      api(params).then(res => {
+        if (res.code == 200) {
+          this.$message.success(res.msg)
+          this.getList();
+        } else {
+          this.$message.error(res.msg)
         }
+      })
     },
-    mounted() {
-
-    }
+    // 切换审核状态
+    handleTypeIndex(item, index) {
+      this.typeIndex = index
+      this.queryParams.auditStatus = item.type
+      this.getList();
+    },
+    // 重置查询
+    resetQuery() {
+      this.reset()
+      this.handleQuery()
+    },
+    // 重置
+    reset() {
+      this.queryParams = {
+        current: 1,
+        size: 10,
+        technicianName: null,
+        auditStatus: null,
+        dateRange: null,
+      }
+      // this.resetForm("form");
+    },
+    // 审核
+    handleAudit(row) {
+      this.$refs.dModal.open({ momentId: row.id, status: row.auditStatus })
+    },
+  },
 }
 </script>
 
-<style scoped lang="scss">
-.btns{
-    margin-bottom: 20px;
+<style lang="scss" scoped>
+::v-deep .el-input--medium {
+  height: 38px;
+}
+.btns {
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+
+  .type {
     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;
-        }
+
+    .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;
+
+.app-container {
+  height: calc(100vh - 84px);
+  display: flex;
+  flex-direction: column;
 }
-.pagination{
-    margin-top: 20px;
-    display: flex;
-    align-items: center;
-    justify-content: flex-end;
+
+.el-pagination {
+  float: right;
+  padding: 30px 0;
 }
 </style>

+ 552 - 249
src/views/tenant/enterAudit/index.vue

@@ -1,271 +1,574 @@
 <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.teSex}`"/>
-                </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 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="teSexName" label="性别">
+      </el-table-column>
+      <el-table-column prop="tePhone" label="电话"></el-table-column>
+      <el-table-column prop="teNickName" label="昵称" width="150"></el-table-column>
+
+
+      <el-table-column key="col-cert1" v-if="auditForm.auditStatus != 1" prop="avatar" label="形象照">
+        <template #default="{ row }">
+          <image-preview :src="row.avatar" :width="120" :height="120" />
+        </template>
+      </el-table-column>
+      <el-table-column key="col-cert2" v-if="auditForm.auditStatus == 0 || auditForm.auditStatus == 1" prop="teAddress"
+        :label="auditForm.auditStatus == 0 ? '意向城市' : '入驻城市'"></el-table-column>
+      <el-table-column key="col-cert5" v-if="auditForm.auditStatus != 0" prop="teBrief" label="简介"></el-table-column>
+
+      <el-table-column key="col-cert3" v-if="auditForm.auditStatus == 0 || auditForm.auditStatus == 1"
+        prop="openServiceName" label="开通服务"></el-table-column>
+
+      <el-table-column key="col-cert4" v-if="auditForm.auditStatus != 0" prop="openServiceName" label="证照管理">
+        <template #default="{ row }">
+          <el-button size="small" type="text" @click="handleAuditLook(row)">查看</el-button>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="applyTime" label="申请时间"></el-table-column>
+
+
+      <el-table-column v-if="auditForm.auditStatus == 2 || auditForm.auditStatus == 3" prop="auditStatusName"
+        label="审批结果"></el-table-column>
+      <el-table-column v-if="auditForm.auditStatus == 2 || auditForm.auditStatus == 3" prop="auditRemark"
+        label="备注"></el-table-column>
+      <el-table-column v-if="auditForm.auditStatus == 2 || auditForm.auditStatus == 3" prop="approveTime"
+        label="审批时间"></el-table-column>
+      <el-table-column v-if="auditForm.auditStatus == 1 || auditForm.auditStatus == 0" label="操作" fixed="right"
+        width="120">
+        <template v-if="auditForm.auditStatus == 1 || auditForm.auditStatus == 0" #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="60%">
+
+      <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 v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="身份证加密" prop="idCardFront"
+          :show-message="false">
+          <div style="display: flex;gap: 40px;">
+            <div>
+              <ImageUpload v-model="addForm.idCardFront" :limit="1" :file-size="2" :isShowTip="false" />
+              <span>身份证正面</span>
+            </div>
+            <div>
+              <ImageUpload v-model="addForm.idCardBack" :limit="1" :file-size="2" :isShowTip="false" />
+              <span>身份证反面</span>
+            </div>
+            <div>
+              <ImageUpload v-model="addForm.idCardHandheld" :limit="1" :file-size="2" :isShowTip="false" />
+              <span>手持身份证</span>
+            </div>
+            <div>
+              <el-button v-if="addForm1.idCardFrout && addForm1.idCardBack && addForm1.idCardHandheld" type="text"
+                @click="handleLookImg([addForm1.idCardFrout[0], addForm1.idCardBack[0], addForm1.idCardHandheld[0]])">查看原件</el-button>
+            </div>
+
+          </div>
+
+        </el-form-item>
+        <el-form-item v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="健康证加密" prop="healthCard"
+          :show-message="false">
+          <div style="display: flex;gap: 20px;">
+            <ImageUpload v-model="addForm.healthCard" :limit="9" @input="onUpload($event, 'healthCard')" :file-size="2"
+              :isShowTip="false" />
+            <div>
+              <el-button type="text" @click="handleLookImg(addForm1.healthCertificate)">查看原件</el-button>
+            </div>
+
+          </div>
+        </el-form-item>
+        <el-form-item v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="资格证加密" :show-message="false"
+          prop="qualificationCard">
+          <div style="display: flex;gap: 20px;">
+
+            <ImageUpload v-model="addForm.qualificationCard" :limit="9" @input="onUpload($event, 'qualificationCard')"
+              :file-size="2" :isShowTip="false" />
+            <div>
+              <el-button type="text" @click="handleLookImg(addForm1.qualificationCertificate)">查看原件</el-button>
+            </div>
+
+          </div>
+
+        </el-form-item>
+        <el-form-item v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="身份证到期时间"
+          prop="idCardExpireTime" :show-message="false">
+          <el-date-picker v-model="addForm.idCardExpireTime" type="date" value-format="yyyy-MM-dd" placeholder="选择日期">
+          </el-date-picker>
+
+        </el-form-item>
+        <el-form-item v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="健康证到期时间"
+          prop="healthCardExpireTime" :show-message="false">
+          <el-date-picker v-model="addForm.healthCardExpireTime" type="date" value-format="yyyy-MM-dd"
+            placeholder="选择日期">
+          </el-date-picker>
+
+        </el-form-item>
+        <el-form-item v-if="auditForm.auditStatus == 1 && addForm.auditStatus == 2" label="资格证到期时间"
+          prop="qualificationCardExpireTime" :show-message="false">
+          <el-date-picker v-model="addForm.qualificationCardExpireTime" type="date" value-format="yyyy-MM-dd"
+            placeholder="选择日期">
+          </el-date-picker>
+
+        </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>
+    <!-- 查看原件弹窗 -->
+    <el-dialog title="预览" width="800" append-to-body :visible.sync="dialogVisibleImg">
+      <div style="display: flex;flex-wrap: wrap;gap: 20px;">
+        <img v-if="imgList.length > 0" v-for="(item, index) in imgList" :key="index" :src="item"
+          style="display: block; max-width: 100%; margin: 0 0 20px 0;text-align: center;" />
+      </div>
+
+    </el-dialog>
+    <!-- 证照管理弹窗 -->
+    <el-dialog title="证照管理" :visible.sync="dialogShow1" width="60%" append-to-body @close="dialogShow1 = false">
+      <el-form v-loading="certLoading" :model="addForm1" ref="addFormRefs" label-width="120px"
+        element-loading-text="加载中..." element-loading-spinner="el-icon-loading">
+
+        <el-form-item label="形象照" prop="avatar" v-if="addForm1.avatar">
+          <el-image v-for="(item, index) in addForm1.avatar" :key="index" fit="fill" style="width: 100px; height: 100px"
+            :src="item" :preview-src-list="addForm1.avatar">
+          </el-image>
+
+        </el-form-item>
+        <el-form-item label="生活照" prop="lifePhotos" v-if="addForm1.lifePhotos">
+          <div style="display: flex;gap: 20px;flex-wrap: wrap;">
+            <el-image v-for="(item, index) in addForm1.lifePhotos" :key="index" style="width: 100px; height: 100px"
+              :src="item" :preview-src-list="addForm1.lifePhotos">
+            </el-image>
+          </div>
+
+        </el-form-item>
+        <el-form-item label="身份证" v-if="addForm1.idCardFrout && addForm1.idCardBack && addForm1.idCardHandheld">
+          <div style="display: flex;gap: 20px;">
+            <el-image style="width: 100px; height: 100px" :src="addForm1.idCardFrout[0]"
+              :preview-src-list="[addForm1.idCardFrout[0], addForm1.idCardBack[0], addForm1.idCardHandheld[0]]">
+            </el-image>
+            <el-image style="width: 100px; height: 100px" :src="addForm1.idCardBack[0]"
+              :preview-src-list="[addForm1.idCardFrout[0], addForm1.idCardBack[0], addForm1.idCardBack[0]]">
+            </el-image>
+            <el-image style="width: 100px; height: 100px" :src="addForm1.idCardHandheld[0]"
+              :preview-src-list="[addForm1.idCardFrout[0], addForm1.idCardBack[0], addForm1.idCardHandheld[0]]">
+            </el-image>
+          </div>
+
+
+        </el-form-item>
+        <el-form-item label="健康证" prop="healthCertificate" v-if="addForm1.healthCertificate">
+          <div style="display: flex;gap: 20px;flex-wrap: wrap;">
+            <el-image v-for="(item, index) in addForm1.healthCertificate" :key="index"
+              style="width: 100px; height: 100px" :src="item" :preview-src-list="addForm1.healthCertificate">
+            </el-image>
+          </div>
+
+
+        </el-form-item>
+        <el-form-item label="从业资格证" prop="qualificationCertificate" v-if="addForm1.qualificationCertificate">
+          <div style="display: flex;gap: 20px;flex-wrap: wrap;">
+            <el-image v-for="(item, index) in addForm1.qualificationCertificate" :key="index"
+              style="width: 100px; height: 100px" :src="item" :preview-src-list="addForm1.qualificationCertificate">
+            </el-image>
+          </div>
+
+        </el-form-item>
+        <el-form-item label="无犯罪记录证明" prop="noCrimeRecord" v-if="addForm1.noCrimeRecord">
+          <div style="display: flex;gap: 20px;flex-wrap: wrap;">
+            <el-image v-for="(item, index) in addForm1.noCrimeRecord" :key="index" style="width: 100px; height: 100px"
+              :src="item" :preview-src-list="addForm1.noCrimeRecord">
+            </el-image>
+          </div>
+
+
+        </el-form-item>
+        <el-form-item label="承诺书" prop="commitmentPdf" v-if="addForm1.commitmentPdf">
+          <div style="display: flex;gap: 20px;flex-wrap: wrap;">
+            <el-image v-for="(item, index) in addForm1.commitmentPdf" :key="index" style="width: 100px; height: 100px"
+              :src="item" :preview-src-list="addForm1.commitmentPdf">
+            </el-image>
+          </div>
+
+
+        </el-form-item>
+        <el-form-item label="承诺视频" prop="commitmentVideo" v-if="addForm1.commitmentVideo">
+          <div class="custom-video">
+            <video ref="video" :src="addForm1.commitmentVideo[0]" height="300px" controls playsinline></video>
+
+          </div>
+
+        </el-form-item>
+        <!-- 音频改用audio标签,不能用el-image -->
+        <el-form-item label="承诺录音" prop="commitmentAudio" v-if="addForm1.commitmentAudio">
+          <audio controls :src="addForm1.commitmentAudio[0]" style="width:300px;"></audio>
+        </el-form-item>
+      </el-form>
+
+    </el-dialog>
+
+  </div>
 </template>
 
 <script>
-import { list, audit } from '@/api/tenant/enterAudit'
+import { list, audit, getCertificate, applySubmit } from '@/api/tenant/enterAudit'
+import C from 'highlight.js/lib/languages/1c';
 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: ''
+  name: "audit",
+  dicts: ['sys_user_sex'],
+  data() {
+    return {
+      imgList: [],
+      dialogVisibleImg: false,
+      certLoading: false,
+      dialogShow1: false,
+      srcList: [],
+      auditForm: {
+        current: 1,
+        size: 10,
+        auditStatus: '0',
+      },
+      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: {
+        auditStatus: '',
+        auditRemark: '',
+        idCardFront: '',
+        idCardBack: '',
+        idCardHandheld: '',
+        healthCard: '',
+        qualificationCard: '',
+
+      },
+      addForm1: {
+        avatar: [],
+        lifePhotos: [],
+        idCardFrout: [],
+        idCardBack: [],
+        idCardHandheld: [],
+        healthCertificate: [],
+        qualificationCertificate: [],
+        noCrimeRecord: [],
+        commitmentPdf: [],
+        commitmentVideo: [],
+        commitmentAudio: [],
+      },
+      addRules: {
+        auditStatus: [
+          { required: true, message: '请选择', trigger: 'change' }
+        ],
+        idCardFront: [
+          { required: true, message: '请上传身份证正面', trigger: 'change' }
+        ],
+        idCardBack: [
+          { required: true, message: '请上传身份证反面', trigger: 'change' }
+        ],
+        idCardHandheld: [
+          { required: true, message: '请上传身份证手持', trigger: 'change' }
+        ],
+        healthCard: [
+          { required: true, message: '请上传健康证', trigger: 'change' }
+        ],
+        qualificationCard: [
+          { required: true, message: '请上传从业资格证', trigger: 'change' }
+        ],
+        idCardExpireTime: [
+          { required: true, message: '请选择身份证到期时间', trigger: 'change' }
+        ],
+        qualificationCardExpireTime: [
+          { required: true, message: '请选择从业资格证到期时间', trigger: 'change' }
+        ],
+        healthCardExpireTime: [
+          { required: true, message: '请选择健康证到期时间', trigger: 'change' }
+        ],
+      },
+      auditId: ''
+    }
+  },
+  watch: {
+
+  },
+  methods: {
+    initData() {
+      this.$set(this.table, 'table', [])
+      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)
         }
+      })
     },
-    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)
-                }
-            })
+    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
+      this.initData();
+    },
+    // 上传事件
+    onUpload(e, k) {
+      console.log(e, k, 'e, k')
+      this.addForm[k] = e;
+    },
+    // 查看原件
+    handleLookImg(imgList) {
+      this.imgList = imgList
+      this.dialogVisibleImg = true
+
+    },
+    //审核
+    handleAudit(row) {
+      this.dialogShow = true
+      this.auditId = row.merchantId
+
+
+      this.$nextTick(() => {
+        this.$refs.addFormRefs.resetFields();
+      })
+      getCertificate(row.merchantId).then(res => {
+
+        if (res.code == 200) {
+          this.addForm1 = res.data
+        }
+      }).finally(() => {
+      })
+    },
+    //查看
+    handleAuditLook(row) {
+      this.addForm1 = {}
+      this.certLoading = true
+      this.dialogShow1 = true
+      getCertificate(row.merchantId).then(res => {
+
+        if (res.code == 200) {
+          this.addForm1 = res.data
         }
+      }).finally(() => {
+        this.certLoading = false
+      })
     },
-    mounted() {
-        this.initData();
+    handleCancel() {
+      this.dialogShow = false
+    },
+    //审核提交
+    handleSave() {
+      this.$refs.addFormRefs.validate((valid) => {
+
+        if (valid) {
+          if (this.addForm.auditStatus == '3') {
+            if (!this.addForm.auditRemark) {
+              this.$message.error('请输入审核备注')
+              return
+            }
+          }
+          if (!this.addForm.idCardHandheld || !this.addForm.idCardFront || !this.addForm.idCardBack) {
+            this.$message.error('请上传身份证')
+            return
+          }
+          let api = audit
+          let params = {
+            auditStatus: this.addForm.auditStatus,
+            auditRemark: this.addForm.auditRemark,
+          }
+          if (this.auditForm.auditStatus == '1') {//待入驻审核
+            api = applySubmit
+            if (this.addForm.auditStatus == '2') {
+              params.idCardExpirationDate = this.addForm.idCardExpireTime
+              params.healthCertificateExpirationDate = this.addForm.healthCardExpireTime
+              params.qualificationCertificateExpirationDate = this.addForm.qualificationCardExpireTime
+            }
+          }
+
+          api(this.auditId, params).then(res => {
+            if (res.code == 200) {
+              this.dialogShow = false
+              this.$message.success(res.msg)
+              this.initData();
+            } else {
+              this.dialogShow = false
+              this.$message.error(res.msg)
+            }
+          })
+        } else {
+          this.$message.error('请填写完整信息')
+        }
+      })
+
+
     }
+  },
+  mounted() {
+    this.initData();
+  }
 }
 </script>
 
 <style scoped lang="scss">
-.btns{
-    margin-bottom: 20px;
+::v-deep .el-input--medium {
+  height: 38px;
+}
+.video-control {
+  display: flex;
+  align-items: center;
+  margin-top: 6px;
+}
+
+.btns {
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+
+  .type {
     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;
-        }
+
+    .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;
+
+// ::v-deep .el-upload-list--picture-card .el-upload-list__item {
+//   width: 120px;
+//   height: 120px;
+// }
+
+// ::v-deep .el-upload--picture-card {
+//   width: 120px !important;
+//   height: 120px !important;
+// }
+
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
 }
 </style>

+ 103 - 35
src/views/tenant/list/index.vue

@@ -80,10 +80,7 @@
             <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 prop="teSexName" label="性别" width="80">
             </el-table-column>
             <el-table-column prop="teAvatar" label="头像" width="150">
                 <template #default="{ row }">
@@ -102,12 +99,12 @@
             <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>
+                    <el-switch v-model="row.postState" disabled :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>
+                    <el-switch v-model="row.isRecommend" disabled :active-value="1" :inactive-value="0"></el-switch>
                 </template>
             </el-table-column>
             <el-table-column prop="techTypeName" label="用户类型" width="150"></el-table-column>
@@ -130,7 +127,7 @@
                             <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-item command="commission" @click="handleCommission(row)">佣金</el-dropdown-item> -->
                         </el-dropdown-menu>
                     </el-dropdown>
                 </template>
@@ -248,25 +245,43 @@
             <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="图片">
+                <el-table-column prop="serviceTag" label="服务类目">
+                    <template #default="{ row }">
+                        {{ row.serviceTag === 1 ? '按摩' : '陪玩' }}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="projectName" label="项目名称"></el-table-column>
+                <el-table-column prop="cover" label="图片">
+                    <template #default="{ row }">
+                        <image-preview :src="row.cover" :width="120" :height="120" />
+                    </template>
+                </el-table-column>
+                <el-table-column prop="projectOriginalPrice" label="价格">
                     <template #default="{ row }">
-                        <image-preview :src="row.icon" :width="120" :height="120" />
+                        {{ row.projectOriginalPrice }}
                     </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="是否上架">
+                <el-table-column prop="projectDuration" label="时间"></el-table-column>
+                <el-table-column prop="unitType" label="计费单位">
                     <template #default="{ row }">
-                        <el-switch v-model="row.isOnline"></el-switch>
+                        {{row.unitType === 0 ? '分钟' : row.unitType === 1 ? '小时' :
+									'次'}}
                     </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="auditStatus" label="状态">
+                    <template #default="{ row }">
+                        {{ row.auditStatus === 0 ? '待审核' : row.auditStatus === 1 ? '已审核' : '已拒绝' }}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="projectIsEnable" label="是否上架">
+                    <template #default="{ row }">
+                      <el-switch v-model="row.projectIsEnable" :active-value="1" :inactive-value="0"
+              @change="handleChange($event, row)"></el-switch>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="highlight" label="亮点"></el-table-column>
+                <el-table-column prop="targetAudience" label="适用人群"></el-table-column>
+                <el-table-column prop="applyTime" label="申请时间"></el-table-column>
             </el-table>
         </el-dialog>
         <el-dialog
@@ -304,16 +319,16 @@
                 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-form-item label="商户状态" prop="merchantStatus">
+                    <el-radio-group v-model="manageForm.merchantStatus">
+                        <el-radio label="0">正常</el-radio>
+                        <el-radio label="1">限制接单</el-radio>
+                        <el-radio label="2">冻结</el-radio>
+                        <el-radio label="3">注销</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 label="变更原因" prop="reasonChange">
+                    <el-input type="textarea" show-word-limit maxlength="200" v-model="manageForm.reasonChange" clearable></el-input>
                 </el-form-item>
             </el-form>
             <template #footer>
@@ -355,7 +370,7 @@
 <script>
 import { list } from '@/api/serve/caetgory'
 import { lists } from '@/api/serve/project'
-import { tenantList, add, detail, edit, upload } from '@/api/tenant/list'
+import { tenantList, add, detail, edit, upload, skillList, enable, getStatus } from '@/api/tenant/list'
 
 export default {
     dicts: ['sys_user_sex'],
@@ -416,12 +431,15 @@ export default {
                 ]
             },
             manageDialogShow: false,
-            manageForm: {},
+            manageForm: {
+              merchantStatus: '',
+              reasonChange: '',
+            },
             manageRules: {
-                a: [
+                merchantStatus: [
                     { required: true, message:'请选择', trigger: "change"}
                 ],
-                b: [
+                reasonChange: [
                     { required: true, message:'请填写', trigger: "blur"}
                 ]
             },
@@ -436,6 +454,22 @@ export default {
         }
     },
     methods: {
+        // 切换状态
+        handleChange(val, row) {
+          console.log(row.projectIsEnable)
+          console.log(row.projectIsEnable ? 1 : 0)
+          enable({
+            merchantId: row.merchantId,
+            projectId: row.projectId,
+            projectIsEnable: row.projectIsEnable ? 1 : 0
+            }).then(res => {
+                if (res.code == 200) {
+                  this.$message.success(res.msg)
+                } else {
+                  this.$message.error(res.msg)
+                }
+           })
+        },
         // 服务类目
         initServeTypes() {
             list({
@@ -490,6 +524,7 @@ export default {
                     this.projectForm.techType = '0'
                     break;
             }
+            this.initData()
         },
         initData() {
             let params = {
@@ -588,10 +623,21 @@ export default {
             }
         },
         handleOpen(row) {
-            this.openDialogShow = true
+            skillList({
+                merchantId: row.merchantId,
+                auditStatus: '1', //审核状态:0-待审核,1-审核通过,2-审核驳回
+            }).then(res => {
+              console.log(res)
+                if(res.code == 200) {
+                  this.openDialogShow = true
+                    this.openTable = res.data
+                }
+            })
+
         },
         handleContract(row) {
             this.contractDialogShow = true
+            this.contractForm = {}
             this.idForContract = row.merchantId
         },
         handleContractCancel() {
@@ -612,8 +658,14 @@ export default {
                 }
             })
         },
+        // 变更商户管理状态
         handleStatus(row) {
-            this.manageDialogShow = true
+          console.log(row)
+           this.manageDialogShow = true
+           this.manageForm.merchantStatus = row.merchantStatus
+           this.manageForm.merchantId = row.merchantId
+           this.manageForm.reasonChange = ''
+
         },
         handleDel(row) {
             this.$modal.confirm('是否确认删除?')
@@ -674,10 +726,23 @@ export default {
             this.dialogShow = false
         },
         handleManageCancel() {
+            this.manageForm = {}
             this.manageDialogShow = false
         },
         handleManageSave() {
-            this.manageDialogShow = false
+          getStatus(this.manageForm.merchantId, {
+                merchantStatus: this.manageForm.merchantStatus, //商户管理状态:0-正常,1-限制接单,2-冻结,3-注销,
+                reasonChange: this.manageForm.reasonChange
+            }).then(res => {
+            if(res.code == 200) {
+               this.initData()
+                this.$message.success(res.msg)
+                this.manageDialogShow = false
+            } else {
+                this.$message.error(res.msg)
+                this.manageDialogShow = false
+            }
+          })
         },
         handleMoneySizeChange(size) {
             this.moneySize = size
@@ -695,6 +760,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
+::v-deep .el-input--medium {
+  height: 38px;
+}
 .btns{
     margin-bottom: 20px;
     display: flex;

+ 269 - 286
src/views/tenant/skillAudit/index.vue

@@ -1,56 +1,44 @@
 <template>
-    <div class="app-container">
-        <el-form
-            :model="auditForm"
-            label-width="68px"
-            :inline="true"
-        >
-            <el-row :gutter="10">
-                <el-col :span="6">
-                    <el-form-item label="姓名">
-                        <el-input style="width: 240px" v-model="auditForm.merchantName" clearable></el-input>
-                    </el-form-item>
-                </el-col>
-                <el-col :span="6">
-                    <el-form-item label="昵称">
-                        <el-input style="width: 240px" v-model="auditForm.merchantNickName" 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.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="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.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">
+  <div class="app-container">
+    <el-form :model="auditForm" label-width="68px" :inline="true">
+      <el-row :gutter="10">
+        <el-col :span="6">
+          <el-form-item label="姓名">
+            <el-input style="width: 240px" v-model="auditForm.merchantName" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="昵称">
+            <el-input style="width: 240px" v-model="auditForm.merchantNickName" 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.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="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.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-date-picker
                             style="width: 240px"
@@ -64,260 +52,255 @@
                         ></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="merchantId" label="商户ID" 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="merchantPhone" label="电话"></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="techTypeName" label="用户类型"></el-table-column>
-            <el-table-column prop="applyTime" label="申请时间"></el-table-column>
-            <el-table-column prop="registerTime" 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="projectName" label="项目名称"></el-table-column>
-                <el-table-column prop="applyReason" label="开通理由"></el-table-column>
-                <el-table-column prop="applyTime" label="申请时间"></el-table-column>
-                <el-table-column prop="auditStatusName" label="审核结果"></el-table-column>
-                <el-table-column prop="remark" label="备注"></el-table-column>
-                <el-table-column  label="操作" width="80">
-                    <template #default="{ row }">
-                        <el-button type="text" v-if="row.auditStatus != 1" @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="auditStatus">
-                    <el-radio-group v-model="addForm.auditStatus">
-                        <el-radio label="1">审核通过</el-radio>
-                        <el-radio label="2">审核驳回</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>
+        <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="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 }">
+          {{ row.merchantSexName }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="merchantPhone" label="电话"></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="techTypeName" label="用户类型"></el-table-column>
+      <el-table-column prop="applyTime" label="申请时间"></el-table-column>
+      <el-table-column prop="registerTime" 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" v-if="row.auditStatus == 0"
+            @click="handleAudit(row)">审核</el-button>
+          <el-button type="text" v-if="row.auditStatus != 0" @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="projectName" label="项目名称"></el-table-column>
+        <el-table-column prop="applyReason" label="开通理由"></el-table-column>
+        <el-table-column prop="applyTime" label="申请时间"></el-table-column>
+        <el-table-column prop="auditStatusName" label="审核结果"></el-table-column>
+        <el-table-column prop="remark" label="备注"></el-table-column>
+        <el-table-column v-if="auditStatusGroup == 0" label="操作" width="80">
+          <template #default="{ row }">
+            <el-button type="text" v-if="row.auditStatus != 1" @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="auditStatus">
+          <el-radio-group v-model="addForm.auditStatus">
+            <el-radio label="1">审核通过</el-radio>
+            <el-radio label="2">审核驳回</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, projects,submit } from '@/api/tenant/skillAudit'
+import { list, projects, submit } from '@/api/tenant/skillAudit'
 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' }
-                ]
-            }
+  name: "audit",
+  dicts: ['sys_user_sex'],
+  data() {
+    return {
+      auditStatusGroup: 0,
+      auditForm: {
+        current: 1,
+        size: 10,
+      },
+      typeList: [
+        {
+          name: '待审核',
+          value: 0
+        },
+        {
+          name: '审核结果',
+          value: 1
         }
-    },
-    methods: {
-        initData() {
-          let params = {
-                current: this.auditForm.current,
-                size: this.auditForm.size,
-                merchantName: this.auditForm.merchantName,
-                techType: this.auditForm.techType,
-                merchantPhone: this.auditForm.merchantPhone,
-                techType: this.auditForm.techType,
-                merchantSex: this.auditForm.merchantSex,
+      ],
+      typeIndex: 0,
+      table: [
+        {
+          sex: 1
+        }
+      ],
+      total: 0,
+      dialogProjectShow: false,
+      projectTable: [],
+      dialogShow: false,
+      addForm: {},
+      addRules: {
+        a: [
+          { required: true, message: '请选择', trigger: 'change' }
+        ]
+      }
+    }
+  },
+  methods: {
+    initData() {
+      let params = {
+        current: this.auditForm.current,
+        size: this.auditForm.size,
+        merchantNickName: this.auditForm.merchantNickName,
+        techType: this.auditForm.techType,
+        merchantPhone: this.auditForm.merchantPhone,
+        techType: this.auditForm.techType,
+        merchantSex: this.auditForm.merchantSex,
+        auditStatusGroup: this.auditStatusGroup,
 
-                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)
-                }
-            })
+        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
-        },
-        handleAudit(row) {
-            this.dialogProjectShow = true
-            projects(row.merchantId).then(res => {
-                if(res.code == 200) {
-                    this.projectTable = res.data
-                } else {
-                    this.$message.error(res.msg)
-                }
-            })
-        },
-        handleProjectAudit(row) {
-            this.dialogShow = true
-            this.addForm={}
-            this.addForm.projectAuditId = row.projectAuditId
+    },
+    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 //审核页签:0-待审核 1-审核结果
+      this.auditStatusGroup = item.value
+      this.initData();
+    },
+    handleAudit(row) {
+      this.dialogProjectShow = true
+      projects(row.merchantId).then(res => {
+        if (res.code == 200) {
+          this.projectTable = res.data
+        } else {
+          this.$message.error(res.msg)
+        }
+      })
+    },
+    handleProjectAudit(row) {
+      this.dialogShow = true
+      this.addForm = {}
+      this.addForm.projectAuditId = row.projectAuditId
 
-        },
-        handleCancel() {
-            this.dialogShow = false
-        },
-        handleSave() {
-            if(!this.addForm.auditStatus) {
-                this.$message.error('请选择审核意见')
-                return
-            }
-            if(!this.addForm.auditRemark) {
-                this.$message.error('请输入审核备注')
-                return
-            }
+    },
+    handleCancel() {
+      this.dialogShow = false
+    },
+    handleSave() {
+      if (!this.addForm.auditStatus) {
+        this.$message.error('请选择审核意见')
+        return
+      }
+      if (!this.addForm.auditRemark) {
+        this.$message.error('请输入审核备注')
+        return
+      }
 
-            submit(this.addForm.projectAuditId,{
-              auditStatus: this.addForm.auditStatus,
-              auditRemark: this.addForm.auditRemark
-            }).then(res => {
-                if(res.code == 200) {
-                  this.dialogShow = false
-                    this.$message.success(res.msg)
-                    this.initData();
-                } else {
-                    this.$message.error(res.msg)
-                }
-            })
+      submit(this.addForm.projectAuditId, {
+        auditStatus: this.addForm.auditStatus,
+        auditRemark: this.addForm.auditRemark
+      }).then(res => {
+        if (res.code == 200) {
+          this.dialogShow = false
+          this.$message.success(res.msg)
+          this.initData();
+        } else {
+          this.$message.error(res.msg)
         }
-    },
-    mounted() {
-        this.initData();
+      })
     }
+  },
+  mounted() {
+    this.initData();
+  }
 }
 </script>
 
 <style scoped lang="scss">
-.btns{
-    margin-bottom: 20px;
+::v-deep .el-input--medium {
+  height: 38px;
+}
+.btns {
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+
+  .type {
     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;
-        }
+
+    .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;
+
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
 }
 </style>