chengziding 10 часов назад
Родитель
Сommit
498ebc7d01

+ 21 - 0
src/api/home.js

@@ -27,4 +27,25 @@ export function userStatistics (data) {
     url: '/system/home/user-statistics',
     method: 'get',
   })
+}
+// 服务分类下服务分布
+export function serviceCategorizeStatistics (data) {
+  return request({
+    url: '/system/home/service-categorize-statistics',
+    method: 'get',
+  })
+}
+// 医院订单数
+export function hospitalOrderStatistics (data) {
+  return request({
+    url: '/system/home/hospital-order-statistics',
+    method: 'get',
+  })
+}
+// 运营端首页
+export function homeQuantity (data) {
+  return request({
+    url: '/system/home/homeQuantity',
+    method: 'get',
+  })
 }

+ 131 - 0
src/api/hospital.js

@@ -0,0 +1,131 @@
+import request from '@/utils/request'
+
+// 查询医院信息列表
+export function hospitalPage (query) {
+  return request({
+    url: '/info/hospital/page',
+    method: 'get',
+    params: query
+  })
+}
+// 获得省市区三级数据
+export function cnAreaTree (query) {
+  return request({
+    url: `/base/cnArea/tree-lbs`,
+    method: 'get',
+    params: query
+  })
+}
+// 新增医院信息
+export function hospitalAdd (data) {
+  return request({
+    url: `/info/hospital/add`,
+    method: 'post',
+    data
+  })
+}
+// 修改医院信息
+export function hospitalEdit (data) {
+  return request({
+    url: `/info/hospital/edit`,
+    method: 'post',
+    data
+  })
+}
+// 获取医院信息详细信息
+export function hospitalInfo (id) {
+  return request({
+    url: `/info/hospital/info/${id}`,
+    method: 'get',
+  })
+}
+// 根据坐标获取位置详情信息
+export function getLocation (location) {
+  return request({
+    url: `/base/cnArea/get-address/${location}`,
+    method: 'get',
+  })
+}
+export function getAddress (address) {
+  return request({
+    url: `/base/cnArea/get-address/${address}`,
+    method: 'get',
+  })
+}
+// 修改医院上下架状态
+export function updateRackStatus (data) {
+  return request({
+    url: `/info/hospital/updateRackStatus`,
+    method: 'post',
+    data
+  })
+}
+// 删除医院信息
+export function hospitalDel (ids) {
+  return request({
+    url: `/info/hospital/del/${ids}`,
+    method: 'post',
+  })
+}
+// 查询医院科室信息列表
+export function hospitalDepartmentPage (query) {
+  return request({
+    url: `/info/hospitalDepartment/page`,
+    method: 'get',
+    params: query
+  })
+}
+// 新增医院科室信息
+export function hospitalDepartmentAdd (data) {
+  return request({
+    url: `/info/hospitalDepartment/add`,
+    method: 'post',
+    data
+  })
+}
+// 获取医院科室信息详细信息
+export function hospitalDepartmentInfo (id) {
+  return request({
+    url: `/info/hospitalDepartment/info/${id}`,
+    method: 'get',
+  })
+}
+// 修改医院科室信息
+export function hospitalDepartmentEdit (data) {
+  return request({
+    url: `/info/hospitalDepartment/edit`,
+    method: 'post',
+    data
+  })
+}
+// 修改医院科室上下架状态
+export function hospitalDepartmentUpdateRackStatus (data) {
+  return request({
+    url: `/info/hospitalDepartment/updateRackStatus`,
+    method: 'post',
+    data
+  })
+}
+// 删除医院科室信息
+export function hospitalDepartmentDel (ids) {
+  return request({
+    url: `/info/hospitalDepartment/del/${ids}`,
+    method: 'post',
+  })
+}
+// 查询医院信息下拉列表
+export function hospitalSimpleList (query) {
+  return request({
+    url: `/info/hospital/simpleList`,
+    method: 'get',
+    params: query
+  })
+}
+// 获取二维码
+export function getQrCode (data) {
+  return request({
+    url: `/info/hospital/getQrCode`,
+    method: 'post',
+    data
+  })
+}

+ 24 - 0
src/api/hospitalOrder.js

@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+
+// 查询订单列表
+export function orderPage (query) {
+  return request({
+    url: '/order/order/page',
+    method: 'get',
+    params: query
+  })
+}
+// 订单状态枚举
+export function orderEnum () {
+  return request({
+    url: `/order/order/enum`,
+    method: 'get',
+  })
+}
+// 获取订单详细信息
+export function orderInfo (id) {
+  return request({
+    url: `/order/order/info/${id}`,
+    method: 'get',
+  })
+}

+ 2 - 1
src/api/order.js

@@ -68,4 +68,5 @@ export function reservation (businessProductId) {
     url: `/ticket/businessProduct/info/reservation/${businessProductId}`,
     method: 'get',
   })
-}
+}
+// 2025/9/23

+ 107 - 0
src/api/service.js

@@ -0,0 +1,107 @@
+import request from '@/utils/request'
+
+// 查询服务分类列表
+export function serviceCategorizePage (query) {
+  return request({
+    url: '/service/serviceCategorize/page',
+    method: 'get',
+    params: query
+  })
+}
+// 新增服务分类
+export function serviceCategorizeAdd (data) {
+  return request({
+    url: '/service/serviceCategorize/add',
+    method: 'post',
+    data: data
+  })
+}
+// 获取服务分类详细信息
+export function serviceCategorizeInfo (id) {
+  return request({
+    url: `/service/serviceCategorize/info/${id}`,
+    method: 'get',
+  })
+}
+// 修改服务分类
+export function serviceCategorizeEdit (data) {
+  return request({
+    url: '/service/serviceCategorize/edit',
+    method: 'post',
+    data: data
+  })
+}
+// 修改服务分类状态
+export function serviceCategorizeSetStatus (id) {
+  return request({
+    url: `/service/serviceCategorize/setStatus/${id}`,
+    method: 'post',
+  })
+}
+// 删除服务分类
+export function serviceCategorizeDel (id) {
+  return request({
+    url: `/service/serviceCategorize/del/${id}`,
+    method: 'post',
+  })
+}
+// 查询服务列表
+export function serviceProductPage (query) {
+  return request({
+    url: '/service/serviceProduct/page',
+    method: 'get',
+    params: query
+  })
+}
+// 新增服务
+export function serviceProductAdd (data) {
+  return request({
+    url: '/service/serviceProduct/add',
+    method: 'post',
+    data: data
+  })
+}
+// 查询服务分类列表 用于下拉
+export function serviceCategorizeList (query) {
+  return request({
+    url: '/service/serviceCategorize/list',
+    method: 'get',
+    params: query
+  })
+}
+// 服务单位
+export function serviceProductEnum () {
+  return request({
+    url: '/service/serviceProduct/enum',
+    method: 'get',
+  })
+}
+// 获取服务详细信息
+export function serviceProductInfo (id) {
+  return request({
+    url: `/service/serviceProduct/info/${id}`,
+    method: 'get',
+  })
+}
+// 修改服务
+export function serviceProductEdit (data) {
+  return request({
+    url: '/service/serviceProduct/edit',
+    method: 'post',
+    data: data
+  })
+}
+// 修改服务状态
+export function serviceProductSetStatus (id) {
+  return request({
+    url: `/service/serviceProduct/setStatus/${id}`,
+    method: 'post',
+  })
+}
+// 删除服务
+export function serviceProductDel (id) {
+  return request({
+    url: `/service/serviceProduct/del/${id}`,
+    method: 'post',
+  })
+}

+ 16 - 3
src/components/Editor/index.vue

@@ -39,7 +39,7 @@ export default {
     // 上传文件大小限制(MB)
     fileSize: {
       type: Number,
-      default: 5,
+      default: 500,
     },
     /* 类型(base64格式、url格式) */
     type: {
@@ -49,7 +49,7 @@ export default {
   },
   data () {
     return {
-      uploadUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
+      uploadUrl: process.env.VUE_APP_BASE_API + "/system/oss/local-upload", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken()
       },
@@ -125,6 +125,14 @@ export default {
             this.quill.format("image", false);
           }
         });
+        toolbar.addHandler("video", (value) => {
+          this.uploadType = "video";
+          if (value) {
+            this.$refs.upload.$children[0].$refs.input.click();
+          } else {
+            this.quill.format("video", false);
+          }
+        });
       }
       this.Quill.pasteHTML(this.currentValue);
       this.Quill.on("text-change", (delta, oldDelta, source) => {
@@ -165,7 +173,12 @@ export default {
         // 获取光标所在位置
         let length = quill.getSelection().index;
         // 插入图片  res.url为服务器返回的图片地址
-        quill.insertEmbed(length, "image", res.data.url);
+        if (this.uploadType == 'image') {
+          quill.insertEmbed(length, "image", res.data.url);
+        }
+        if (this.uploadType == 'video') {
+          quill.insertEmbed(length, "video", res.data.url);
+        }
         // 调整光标到最后
         quill.setSelection(length + 1);
       } else {

+ 12 - 25
src/components/FileUpload/index.vue

@@ -1,19 +1,6 @@
 <template>
   <div class="upload-file">
-    <el-upload
-      multiple
-      :action="uploadFileUrl"
-      :before-upload="handleBeforeUpload"
-      :file-list="fileList"
-      :limit="limit"
-      :on-error="handleUploadError"
-      :on-exceed="handleExceed"
-      :on-success="handleUploadSuccess"
-      :show-file-list="false"
-      :headers="headers"
-      class="upload-file-uploader"
-      ref="upload"
-    >
+    <el-upload multiple :action="uploadFileUrl" :before-upload="handleBeforeUpload" :file-list="fileList" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" :on-success="handleUploadSuccess" :show-file-list="false" :headers="headers" class="upload-file-uploader" ref="upload">
       <!-- 上传按钮 -->
       <el-button size="mini" type="primary">选取文件</el-button>
       <!-- 上传提示 -->
@@ -68,12 +55,12 @@ export default {
       default: true
     }
   },
-  data() {
+  data () {
     return {
       number: 0,
       uploadList: [],
       baseUrl: process.env.VUE_APP_BASE_API,
-      uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/local-upload", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
       },
@@ -82,7 +69,7 @@ export default {
   },
   watch: {
     value: {
-      handler(val) {
+      handler (val) {
         if (val) {
           let temp = 1;
           // 首先将值转为数组
@@ -106,13 +93,13 @@ export default {
   },
   computed: {
     // 是否显示提示
-    showTip() {
+    showTip () {
       return this.isShowTip && (this.fileType || this.fileSize);
     },
   },
   methods: {
     // 上传前校检格式和大小
-    handleBeforeUpload(file) {
+    handleBeforeUpload (file) {
       // 校检文件类型
       if (this.fileType) {
         let fileExtension = "";
@@ -142,16 +129,16 @@ export default {
       return true;
     },
     // 文件个数超出
-    handleExceed() {
+    handleExceed () {
       this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
     },
     // 上传失败
-    handleUploadError(err) {
+    handleUploadError (err) {
       this.$modal.msgError("上传图片失败,请重试");
       this.$modal.closeLoading()
     },
     // 上传成功回调
-    handleUploadSuccess(res, file) {
+    handleUploadSuccess (res, file) {
       if (res.code === 200) {
         this.uploadList.push({ name: res.data.fileName, url: res.data.url });
         if (this.uploadList.length === this.number) {
@@ -167,12 +154,12 @@ export default {
       }
     },
     // 删除文件
-    handleDelete(index) {
+    handleDelete (index) {
       this.fileList.splice(index, 1);
       this.$emit("input", this.listToString(this.fileList));
     },
     // 获取文件名称
-    getFileName(name) {
+    getFileName (name) {
       if (name.lastIndexOf("/") > -1) {
         return name.slice(name.lastIndexOf("/") + 1);
       } else {
@@ -180,7 +167,7 @@ export default {
       }
     },
     // 对象转成指定字符串分隔
-    listToString(list, separator) {
+    listToString (list, separator) {
       let strs = "";
       separator = separator || ",";
       for (let i in list) {

+ 8 - 4
src/components/ImageUpload/index.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="component-upload-image" :class="'upload'+unique">
-    <el-upload ref="upload" multiple :action="uploadImgUrl" list-type="picture-card" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" name="file" :on-remove="handleRemove" :show-file-list="true" :headers="headers" :file-list="fileList" :on-preview="handlePictureCardPreview" :class="{hide: this.fileList.length >= this.limit}" style="display: none;">
+  <div class="component-upload-image" :class="'upload'+unique" v-if="!(fileList.length <=0&&disabled)">
+    <el-upload ref="upload" multiple :action="uploadImgUrl" :disabled="disabled" list-type="picture-card" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" name="file" :on-remove="handleRemove" :show-file-list="true" :headers="headers" :file-list="fileList" :on-preview="handlePictureCardPreview" :class="{hide: this.fileList.length >= this.limit}" style="display: none;">
       <i class="el-icon-plus"></i>
     </el-upload>
     <!-- 拖拽排序区域 -->
@@ -16,7 +16,7 @@
               <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                 <i class="el-icon-zoom-in"></i>
               </span>
-              <span class="el-upload-list__item-delete" @click="handleRemove(file)">
+              <span class="el-upload-list__item-delete" v-if="!disabled" @click="handleRemove(file)">
                 <i class="el-icon-delete"></i>
               </span>
             </span>
@@ -75,6 +75,10 @@ export default {
     unique: {
       type: Number | String,
       default: 0,
+    },
+    disabled: {
+      type: Boolean,
+      default: false
     }
   },
   data () {
@@ -85,7 +89,7 @@ export default {
       dialogVisible: false,
       hideUpload: false,
       baseUrl: process.env.VUE_APP_BASE_API,
-      uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/local-upload", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
       },

+ 48 - 14
src/router/index.js

@@ -94,38 +94,72 @@ export const constantRoutes = [
       }
     ]
   },
+  // {
+  //   path: '/shop',
+  //   component: Layout,
+  //   hidden: true,
+  //   redirect: 'noredirect',
+  //   children: [
+  //     {
+  //       path: 'details',
+  //       component: () => import('@/views/shop/details'),
+  //       name: 'shopDetails',
+  //       meta: { title: '商铺新增/修改', icon: 'user' }
+  //     }
+  //   ]
+  // },
   {
-    path: '/shop',
+    path: '/hospital',
     component: Layout,
     hidden: true,
     redirect: 'noredirect',
     children: [
       {
         path: 'details',
-        component: () => import('@/views/shop/details'),
-        name: 'shopDetails',
-        meta: { title: '商铺新增/修改', icon: 'user' }
+        component: () => import('@/views/hospital/details'),
+        name: 'hospitalDetails',
+        meta: { title: '医院新增/修改', icon: 'user' }
       }
     ]
   },
+  // {
+  //   path: '/goods',
+  //   component: Layout,
+  //   hidden: true,
+  //   redirect: 'noredirect',
+  //   children: [
+  //     {
+  //       path: 'details',
+  //       component: () => import('@/views/goods/details'),
+  //       name: 'goodsDetails',
+  //       meta: { title: '商品新增/修改', icon: 'user' }
+  //     },
+  //     {
+  //       path: 'couponCodeDatabase',
+  //       component: () => import('@/views/goods/couponCodeDatabase'),
+  //       name: 'couponCodeDatabase',
+  //       meta: { title: '券码库', icon: 'user' }
+  //     }
+  //   ]
+  // },
   {
-    path: '/goods',
+    path: '/service',
     component: Layout,
     hidden: true,
     redirect: 'noredirect',
     children: [
       {
         path: 'details',
-        component: () => import('@/views/goods/details'),
-        name: 'goodsDetails',
-        meta: { title: '商品新增/修改', icon: 'user' }
+        component: () => import('@/views/service/details'),
+        name: 'serviceDetails',
+        meta: { title: '服务新增/修改', icon: 'user' }
       },
-      {
-        path: 'couponCodeDatabase',
-        component: () => import('@/views/goods/couponCodeDatabase'),
-        name: 'couponCodeDatabase',
-        meta: { title: '券码库', icon: 'user' }
-      }
+      // {
+      //   path: 'couponCodeDatabase',
+      //   component: () => import('@/views/service/couponCodeDatabase'),
+      //   name: 'couponCodeDatabase',
+      //   meta: { title: '券码库', icon: 'user' }
+      // }
     ]
   },
   {

+ 1 - 1
src/views/banner/index.vue

@@ -239,7 +239,7 @@ export default {
       jumpTypeList: [
         { label: "内部页面", value: 0 },
         { label: "外部链接", value: 1 },
-        { label: "内部资源", value: 2 },
+        // { label: "内部资源", value: 2 },
       ],
       resourceModelList: [
         // { label: '无', value: 0 },

+ 18 - 0
src/views/finance/index.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="app-container">
+    👏就这...
+  </div>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+
+    }
+  },
+}
+</script>
+
+<style lang='scss' scoped>
+</style>

+ 289 - 0
src/views/hospital/department.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="科室名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入名称" clearable size="small" @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="daterangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+      </el-form-item>
+      <el-form-item label="状态" prop="rackStatus">
+        <el-select v-model="queryParams.rackStatus" placeholder="请选择状态" clearable size="small" style="width: 240px">
+          <el-option v-for="dict in dict.type.hospital_rack_status" :key="dict.value" :label="dict.label" :value="dict.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 @click="close()" size="mini">返回</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
+      <el-table-column type="index" width="55" label="序号" align="center">
+        <template slot-scope="scope">
+          <div>
+            {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="科室名称" align="center" prop="name" />
+      <el-table-column label="排序" align="center" prop="sortOrder" />
+      <el-table-column label="上架状态" align="center" prop="rackStatus">
+        <template slot-scope="{row}">
+          <el-tag v-for="(v,i) in dict.type.hospital_rack_status" :type="v.raw.cssClass" :key="i" v-if="v.value===row.rackStatus">{{v.label}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime,'{y}-{m}-{d} {h}:{i}')}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
+          <el-button size="mini" type="text" @click="setStatus(scope.row)">{{scope.row.rackStatus==0?'下架':'上架'}}</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+
+    <!-- 添加或修改测试单表对话框 -->
+    <el-drawer :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="科室名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入名称" />
+        </el-form-item>
+        <el-form-item label="排序" prop="sortOrder">
+          <el-input-number v-model="form.sortOrder" :min="1" label="排序" :precision="0"></el-input-number>
+        </el-form-item>
+        <el-form-item label="上架状态" prop="rackStatus">
+          <el-select v-model="form.rackStatus" placeholder="请选择上架状态" clearable style="width: 100%">
+            <el-option v-for="dict in dict.type.hospital_rack_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div class="demo-drawer__footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-drawer>
+    <!-- 用户导入对话框 -->
+  </div>
+</template>
+
+<script>
+import { hospitalDepartmentPage, hospitalDepartmentAdd, hospitalDepartmentInfo, hospitalDepartmentEdit, hospitalDepartmentUpdateRackStatus, hospitalDepartmentDel } from "@/api/hospital.js";
+
+export default {
+  dicts: ['hospital_rack_status'],
+  components: {
+  },
+  data () {
+    return {
+      //按钮loading
+      buttonLoading: false,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 测试单表表格数据
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 创建时间时间范围
+      daterangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalId: undefined,
+        name: undefined,
+        rackStatus: undefined,
+      },
+      // 表单参数
+      form: {
+        name: undefined,
+        rackStatus: undefined,
+        sortOrder: 1
+      },
+      // 表单校验
+      rules: {
+        name: [
+          { required: true, message: "请输入分类名称", trigger: "blur" }
+        ],
+        rackStatus: [
+          { required: true, message: "请选择状态", trigger: "blur" }
+        ],
+        sortOrder: [{ required: true, message: "请输入排序", trigger: "change" }],
+      },
+    };
+  },
+  created () {
+    if (this.$route.query.hospitalId) {
+      this.queryParams.hospitalId = this.$route.query.hospitalId * 1
+    }
+    this.getList();
+  },
+  methods: {
+    close () {
+      this.$router.back();
+    },
+    /** 查询测试单表列表 */
+    getList () {
+      this.loading = true;
+      this.queryParams["createTimeStart"] = undefined;
+      this.queryParams["createTimeEnd"] = undefined;
+      if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
+        this.queryParams["createTimeStart"] = this.daterangeCreateTime[0];
+        this.queryParams["createTimeEnd"] = this.daterangeCreateTime[1];
+      }
+      hospitalDepartmentPage(this.queryParams).then(response => {
+        this.list = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel () {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset () {
+      this.form = {
+        name: undefined,
+        rackStatus: undefined,
+        sortOrder: 1
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery () {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery () {
+      this.daterangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange (selection) {
+      this.ids = selection.map(item => item.categoryId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd () {
+      this.reset();
+      this.open = true;
+      this.title = "添加科室";
+    },
+    /** 修改按钮操作 */
+    handleUpdate (row) {
+      this.loading = true;
+      this.reset();
+      const id = row.id
+      hospitalDepartmentInfo(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改科室";
+      });
+    },
+    /** 提交按钮 */
+    submitForm () {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.buttonLoading = true;
+          if (this.form.id != null) {
+            hospitalDepartmentEdit(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            this.form.hospitalId = this.$route.query.hospitalId * 1
+            hospitalDepartmentAdd(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete (row) {
+      const ids = row.id;
+      this.$modal.confirm('是否确认删除名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return hospitalDepartmentDel(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    /** 上下架按钮操作 */
+    setStatus (row) {
+      const ids = row.categoryId || this.ids;
+      let statusText = row.rackStatus == 0 ? '下架' : '上架';
+      let param = {
+        id: row.id,
+        rackStatus: row.rackStatus == 1 ? '0' : '1'
+      }
+      this.$modal.confirm('是否确认' + statusText + '名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return hospitalDepartmentUpdateRackStatus(param);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess(statusText + "成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+  }
+};
+</script>
+<style lang="scss">
+.el-drawer__body {
+  padding: 0 20px !important;
+}
+</style>
+<style lang="scss" scoped>
+.flex {
+  display: flex;
+}
+.demo-drawer__footer {
+  margin-left: 120px;
+}
+</style>

+ 313 - 0
src/views/hospital/details.vue

@@ -0,0 +1,313 @@
+<template>
+  <div class="app-container">
+    <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+      <h3>基础信息</h3>
+      <el-form-item label="医院名称" prop="name">
+        <el-input v-model="form.name" placeholder="请输入医院名称" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="医院等级" prop="level">
+        <el-select v-model="form.level" placeholder="请选择医院等级" clearable style="width: 100%">
+          <el-option v-for="dict in dict.type.hospital_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="医院标签" prop="label">
+        <el-input v-model="form.label" placeholder="请输入医院标签" maxlength="150" clearable @keyup.enter.native="handleQuery" />
+        <div class="hint">*例如:中医院,综合医院等</div>
+      </el-form-item>
+      <el-form-item label="所在城市" prop="provinces">
+        <!-- <el-input v-model="form.name" placeholder="请输入商户名称" clearable  @keyup.enter.native="handleQuery" /> -->
+        <el-cascader ref="refSubCat" v-model="form.provinces" placeholder="请选择所在城市" :options="areaTrea" :props="{ expandTrigger: 'hover' }" @change="handleChange" style="width: 100%"></el-cascader>
+      </el-form-item>
+      <el-form-item label="详细地址" prop="address">
+        <el-input v-model="form.address" placeholder="请输入详细地址" maxlength="100" clearable @keyup.enter.native="getgetAddressFun" />
+      </el-form-item>
+      <el-form-item label="经纬度" prop="coordinates">
+        <el-input v-model="form.coordinates" disabled placeholder="请输入经纬度" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <!-- <div id="container1" class="map-box"></div> -->
+      <GDMap ref="gdMapRef" :defaultMarker="defaultMarker" @change="mapchange" />
+      <el-form-item label="负责人" prop="responsiblePerson">
+        <el-input v-model="form.responsiblePerson" placeholder="请输入负责人" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="联系电话" prop="contactMobile">
+        <el-input v-model="form.contactMobile" placeholder="请输入联系电话" maxlength="11" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="客服电话" prop="serviceMobile">
+        <el-input v-model="form.serviceMobile" placeholder="请输入客服电话" maxlength="11" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="医院介绍" prop="introduction">
+        <editor v-model="form.introduction" :min-height="192" />
+      </el-form-item>
+      <h3>医院图片</h3>
+      <el-form-item label="医院logo" prop="logoUrl">
+        <imageUpload v-model="form.logoUrl" :limit="1" unique="logoUrl" />
+      </el-form-item>
+      <h3>运营配置</h3>
+      <el-form-item label="营业时间" prop="businessHours">
+        <el-input v-model="form.businessHours" placeholder="请输入营业时间" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="医院序号" prop="sortOrder">
+        <el-input-number v-model="form.sortOrder" :min="1" label="排序" :precision="0"></el-input-number>
+        <div class="hint">*数字越大在越前面,排序优先需要,其次是创建时间</div>
+      </el-form-item>
+      <el-form-item label="营业状态" prop="businessStatus">
+        <el-select v-model="form.businessStatus" placeholder="请输入状态" clearable style="width: 240px">
+          <el-option v-for="dict in dict.type.hospital_business_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import GDMap from '@/components/gdMap/index'
+import { cnAreaTree, hospitalAdd, getLocation, hospitalInfo, hospitalEdit } from '@/api/hospital'
+import qqmapPlus from 'qqmap-plus';
+import draggable from 'vuedraggable';
+export default {
+  dicts: ['hospital_level', 'hospital_business_status'],
+  components: {
+    draggable,
+    GDMap
+  },
+  data () {
+    return {
+      form: {
+        name: undefined,
+        level: undefined,
+        label: undefined,
+        provinces: undefined,
+        address: undefined,
+        coordinates: undefined,
+        responsiblePerson: undefined,
+        contactMobile: undefined,
+        serviceMobile: undefined,
+        introduction: undefined,
+        logoUrl: undefined,
+        businessHours: undefined,
+        sortOrder: undefined,
+        businessStatus: undefined,
+      },
+      rules: {
+        name: [
+          { required: true, message: '请输入医院名称', trigger: 'change' }
+        ],
+        level: [
+          { required: true, message: '请选择医院等级', trigger: 'change' }
+        ],
+        label: [
+          { required: true, message: '请输入医院标签', trigger: 'change' }
+        ],
+        provinces: [
+          { required: true, message: '请选择所在城市', trigger: 'change' }
+        ],
+        address: [
+          { required: true, message: '请输入详细地址', trigger: 'change' }
+        ],
+        coordinates: [
+          { required: true, message: '请选择经纬度', trigger: 'change' }
+        ],
+        responsiblePerson: [
+          { required: true, message: '请输入负责人', trigger: 'change' }
+        ],
+        contactMobile: [
+          { required: true, message: '请输入联系电话', trigger: 'change' }
+        ],
+        serviceMobile: [
+          { required: true, message: '请输入客服电话', trigger: 'change' }
+        ],
+        // introduction: [
+        //   { required: true, message: '请输入医院介绍', trigger: 'change' }
+        // ],
+        logoUrl: [
+          { required: true, message: '请上传医院logo', trigger: 'change' }
+        ],
+        // businessHours: [
+        //   { required: true, message: '请输入营业时间', trigger: 'change' }
+        // ],
+        sortOrder: [
+          { required: true, message: '请输入医院序号', trigger: 'change' }
+        ],
+        businessStatus: [
+          { required: true, message: '请选择营业状态', trigger: 'change' }
+        ],
+      },
+      areaTrea: [],
+      shopTypeList: [],
+      map: null,
+      markers: [],
+      lnglat: [],
+      geocoder: null,
+      buttonLoading: false,
+      // 地图回显
+      defaultMarker: {
+        location: {}
+      }
+    }
+  },
+  mounted () {
+    this.getCnAreaTree();
+    if (this.$route.query.id) {
+      this.getDetails(this.$route.query.id)
+    } else {
+      this.$refs.gdMapRef.initAMap();
+    }
+    document.documentElement.scrollTop = 0
+  },
+  methods: {
+    getCnAreaTree () {
+      cnAreaTree().then(res => {
+        this.areaTrea = res.data?.children
+      })
+    },
+    addBusinessProductCategory () {
+      this.form.businessProductCategoryList.push({})
+    },
+    deleteBusinessProductCategory (index) {
+      this.form.businessProductCategoryList.splice(index, 1)
+    },
+    // 省市区选择
+    handleChange (value) {
+      this.form.provinces = value;
+      this.form.provinceId = value[0];
+      this.form.provinceName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[0];
+      this.form.cityId = value[1];
+      this.form.cityName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[1];
+      this.form.areaId = value[2];
+      this.form.areaName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[2];
+    },
+    getDetails (id) {
+      hospitalInfo(id).then(res => {
+        res.data.provinces = [res.data.provinceId, res.data.cityId, res.data.areaId];
+        let arr = res.data.coordinates.split(',');
+        this.defaultMarker = {
+          location: {
+            lng: arr[0],
+            lat: arr[1]
+          },
+          address: res.data.address,
+        }
+        this.form = res.data;
+        this.$refs.gdMapRef.initAMap()
+      })
+    },
+    /** 提交按钮 */
+    submitForm () {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          let formCopy = JSON.parse(JSON.stringify(this.form))
+          this.buttonLoading = true;
+          if (this.form.id != null) {
+            hospitalEdit(formCopy).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.cancel()
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            hospitalAdd(formCopy).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.cancel()
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    // 取消按钮
+    cancel () {
+      this.$router.go(-1)
+    },
+    mapchange (e) {
+      console.log(e);
+      this.form.address = e.address;
+      this.form.coordinates = e.location.lng + ',' + e.location.lat;
+      this.form.latitude = e.location.lat;
+      this.form.longitude = e.location.lng;
+
+    },
+    //地图
+    initMap (obj = {}) {
+      var that = this;
+      let key = "KNZBZ-YSB3S-QGNOH-6UN4N-LVGUZ-OJFPQ"
+      qqmapPlus.init(key, () => {
+        if (obj.lat) {
+          that.form.longitude = obj.long;
+          that.form.latitude = obj.lat;
+        } else {
+          obj.long = that.form.longitude = 114.30656433105469;
+          obj.lat = that.form.latitude = 30.588281906904278;
+        }
+        var myLatlng = new qq.maps.LatLng(obj.lat, obj.long);
+        var myOptions = {
+          zoom: 16,
+          center: myLatlng,
+          mapTypeId: qq.maps.MapTypeId.ROADMAP
+        };
+        that.map = new qq.maps.Map(document.getElementById('container1'), myOptions);
+        var marker = new qq.maps.Marker({
+          position: myLatlng,
+          map: that.map
+        });
+        // 获取点击后的地址
+        qq.maps.event.addListener(that.map, 'click', function (event) {
+          if (marker) {
+            marker.setMap(null);
+            marker = null;
+          }
+          // that.$refs.formRef.clearValidate();
+          // 获取点击后的地图坐标
+          that.form.longitude = event.latLng.getLng();
+          that.form.latitude = event.latLng.getLat();
+          that.$set(that.form, 'coordinates', event.latLng.getLng() + ',' + event.latLng.getLat());
+          marker = new qq.maps.Marker({
+            position: new qq.maps.LatLng(event.latLng.getLat(), event.latLng.getLng()),
+            map: that.map
+          });
+          getLocation(event.latLng.getLat() + ',' + event.latLng.getLng()).then(res => {
+            that.form.address = res.data.address + res.data.formatted_addresses.rough
+          })
+        });
+      });
+    },
+  }
+}
+</script>
+
+<style lang='scss' scoped>
+.el-form {
+  width: 800px;
+}
+.hint {
+  font-size: 12px;
+  color: red;
+}
+.map-box {
+  width: calc(100% - 120px);
+  height: 300px;
+  margin-bottom: 30px;
+  box-sizing: border-box;
+  margin-left: 120px;
+}
+.flex {
+  display: flex;
+  margin-bottom: 10px;
+  .el-button {
+    margin-left: 10px;
+  }
+}
+h3 {
+  width: 120px;
+  font-weight: 700;
+  text-align: right;
+}
+.flex-bet {
+  display: flex;
+  justify-content: space-between;
+}
+</style>

+ 270 - 0
src/views/hospital/list.vue

@@ -0,0 +1,270 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="医院名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入医院名称" clearable size="small" @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="负责人姓名" prop="responsiblePerson">
+        <el-input v-model="queryParams.responsiblePerson" placeholder="请输入负责人姓名" clearable size="small" @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="营业状态" prop="businessStatus">
+        <el-select v-model="queryParams.businessStatus" placeholder="请选择营业状态" clearable size="small" style="width: 240px">
+          <el-option v-for="dict in dict.type.hospital_business_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="医院等级" prop="level">
+        <el-select v-model="queryParams.level" placeholder="请选择医院等级" clearable size="small" style="width: 240px">
+          <el-option v-for="dict in dict.type.hospital_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="daterangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+      </el-form-item>
+      <el-form-item label="上架状态" prop="rackStatus">
+        <el-select v-model="queryParams.rackStatus" placeholder="请选择上架状态" clearable size="small" style="width: 240px">
+          <el-option v-for="dict in dict.type.hospital_rack_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="所在城市" prop="provinces">
+        <el-cascader ref="refSubCat" size="small" v-model="queryParams.provinces" placeholder="请选择所在城市" :options="areaTrea" :props="{ expandTrigger: 'hover' }" @change="handleChange" style="width: 100%"></el-cascader>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
+      <el-table-column type="index" width="55" label="序号" align="center">
+        <template slot-scope="scope">
+          <div>
+            {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="医院ID" align="center" prop="id" width="100" />
+      <el-table-column label="医院logo" align="center" prop="logoUrl">
+        <template slot-scope="scope">
+          <el-image style="width: 50px; height: 50px" :src="scope.row.logoUrl" :preview-src-list="scope.row.logoUrl ? [scope.row.logoUrl] : []"></el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="医院名称" align="center" prop="name" />
+      <el-table-column label="负责人" align="center" prop="responsiblePerson" />
+      <el-table-column label="联系方式" align="center" prop="contactMobile" />
+      <el-table-column label="医院地址" align="center" prop="address" />
+      <el-table-column label="营业状态" align="center" prop="businessStatus">
+        <template slot-scope="{row}">
+          <!-- <el-tag type="success" v-if="row.businessStatus">正常</el-tag>
+          <el-tag type="danger" v-if="!row.businessStatus">停业</el-tag> -->
+          <el-tag v-for="(v,i) in dict.type.hospital_business_status" :type="v.raw.cssClass" :key="i" v-if="v.value===row.businessStatus">{{v.label}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="上架状态" align="center" prop="rackStatus">
+        <template slot-scope="{row}">
+          <el-tag v-for="(v,i) in dict.type.hospital_rack_status" :type="v.raw.cssClass" :key="i" v-if="v.value===row.rackStatus">{{v.label}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="等级" align="center" prop="level">
+        <template slot-scope="{row}">
+          <div v-for="(v,i) in dict.type.hospital_level" :key="i" v-if="v.value==row.level">{{v.label}}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime,'{y}-{m}-{d} {h}:{i}')}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
+          <el-button size="mini" type="text" @click="setStatus(scope.row)">{{scope.row.rackStatus==0?'下架':'上架'}}</el-button>
+          <el-button size="mini" type="text" @click="getQrCode(scope.row)">二维码</el-button>
+          <el-button size="mini" type="text" @click="goDepartment(scope.row)">科室管理</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+  </div>
+</template>
+
+<script>
+import { hospitalPage, cnAreaTree, updateRackStatus, hospitalDel, getQrCode } from '@/api/hospital'
+export default {
+  dicts: ['hospital_level', 'hospital_rack_status', 'hospital_business_status'],
+  data () {
+    return {
+      //按钮loading
+      buttonLoading: false,
+      // 遮罩层
+      loading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 测试单表表格数据
+      list: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: undefined,
+        contactPerson: undefined,
+        businessStatus: undefined,
+        level: undefined,
+        rackStatus: undefined,
+        provinces: undefined
+      },
+      areaTrea: [],
+      daterangeCreateTime: [],
+    }
+  },
+  created () {
+    this.getCnAreaTree();
+    this.getList()
+  },
+  methods: {
+
+    getCnAreaTree () {
+      cnAreaTree().then(res => {
+        this.areaTrea = res.data?.children
+      })
+    },
+    // 获取二维码
+    getQrCode (row) {
+      let param = {
+        entityValue: "",
+        hospitalId: row.id,
+        path: "pages/order/placeAnOrder",
+        sceneType: 0
+      }
+      getQrCode(param).then(res => {
+        // this.$download(res.data.url, '二维码.png')
+        window.open(res.data.url, '_blank')
+      })
+    },
+    getList () {
+      this.loading = true;
+      this.queryParams["startTime"] = undefined;
+      this.queryParams["endTime"] = undefined;
+      if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
+        this.queryParams["startTime"] = this.daterangeCreateTime[0];
+        this.queryParams["endTime"] = this.daterangeCreateTime[1];
+      }
+      hospitalPage(this.queryParams).then(response => {
+        // response.rows.map(v => {
+        //   let arr = []
+        //   v.businessCategoryList.map(k => {
+        //     arr.push(k.categoryName)
+        //   })
+        //   v.categoryNames = arr.join(",")
+        // })
+        this.list = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete (row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除医院名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return hospitalDel(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    // 多选框选中数据
+    handleSelectionChange (selection) {
+      this.ids = selection.map(item => item.businessId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    // 省市区选择
+    handleChange (value) {
+      this.queryParams.provinces = value;
+      this.queryParams.provinceId = value[0];
+      this.queryParams.provinceName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[0];
+      this.queryParams.cityId = value[1];
+      this.queryParams.cityName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[1];
+      this.queryParams.areaId = value[2];
+      this.queryParams.areaName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[2];
+    },
+    /** 搜索按钮操作 */
+    handleQuery () {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery () {
+      this.daterangeCreateTime = [];
+      this.queryParams.provinceId = undefined;
+      this.queryParams.provinceName = undefined;
+      this.queryParams.cityId = undefined;
+      this.queryParams.cityName = undefined;
+      this.queryParams.areaId = undefined;
+      this.queryParams.areaName = undefined;
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    handleAdd () {
+      this.$router.push({
+        path: '/hospital/details'
+      })
+    },
+    handleUpdate (row) {
+      this.$router.push({
+        path: '/hospital/details',
+        query: {
+          id: row.id
+        }
+      })
+    },
+    /** 上下架按钮操作 */
+    setStatus (row) {
+      let statusText = row.rackStatus == 0 ? '下架' : '上架';
+      this.$modal.confirm('是否确认' + statusText + '医院名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        let param = {
+          id: row.id,
+          rackStatus: row.rackStatus == 1 ? '0' : '1'
+        }
+        return updateRackStatus(param);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess(statusText + "成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    goDepartment (row) {
+      this.$router.push({
+        path: '/hospital/department',
+        query: {
+          hospitalId: row.id
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang='scss' scoped>
+</style>

+ 29 - 29
src/views/index.vue

@@ -8,34 +8,34 @@
             <div class="top_l_list_item">
               <img src="@/assets/images/icon1.png" alt="">
               <div>
-                <div class="top_l_list_item_lab">待处理售后</div>
-                <div class="top_l_list_item_val">{{homeTopObj.waitSum}}</div>
-                <div class="top_l_list_item_btn" @click="goAfterSaleOrder()">查看详情</div>
+                <div class="top_l_list_item_lab">用户数</div>
+                <div class="top_l_list_item_val">{{homeTopObj.userSum}}</div>
+                <!-- <div class="top_l_list_item_btn" @click="goAfterSaleOrder()">查看详情</div> -->
               </div>
             </div>
             <div class="top_l_list_item">
               <img src="@/assets/images/icon2.png" alt="">
               <div>
-                <div class="top_l_list_item_lab">待处理发货</div>
-                <div class="top_l_list_item_val">{{homeTopObj.waitShip}}</div>
-                <div class="top_l_list_item_btn" @click="goPointsMallOrder()">查看详情</div>
+                <div class="top_l_list_item_lab">医院数</div>
+                <div class="top_l_list_item_val">{{homeTopObj.hospitalSum}}</div>
+                <!-- <div class="top_l_list_item_btn" @click="goPointsMallOrder()">查看详情</div> -->
               </div>
             </div>
             <div class="top_l_list_item">
-              <img src="@/assets/images/icon1.png" alt="">
+              <img src="@/assets/images/icon3.png" alt="">
               <div>
-                <div class="top_l_list_item_lab">用户数</div>
-                <div class="top_l_list_item_val">{{homeTopObj.userSum}}</div>
+                <div class="top_l_list_item_lab">订单数</div>
+                <div class="top_l_list_item_val">{{homeTopObj.orderSum}}</div>
               </div>
             </div>
             <div class="top_l_list_item">
-              <img src="@/assets/images/icon2.png" alt="">
+              <img src="@/assets/images/icon4.png" alt="">
               <div>
-                <div class="top_l_list_item_lab">商家数</div>
-                <div class="top_l_list_item_val">{{homeTopObj.businessSum}}</div>
+                <div class="top_l_list_item_lab">护工数</div>
+                <div class="top_l_list_item_val">{{homeTopObj.nurseSum}}</div>
               </div>
             </div>
-            <div class="top_l_list_item">
+            <!-- <div class="top_l_list_item">
               <img src="@/assets/images/icon3.png" alt="">
               <div>
                 <div class="top_l_list_item_lab">订单数</div>
@@ -48,7 +48,7 @@
                 <div class="top_l_list_item_lab">参与PK数</div>
                 <div class="top_l_list_item_val">{{homeTopObj.gameSum}}</div>
               </div>
-            </div>
+            </div> -->
           </div>
           <div class="top_l_chart">
             <div class="top_l_chart_t">
@@ -62,21 +62,21 @@
           <div class="top_r_quick">
             <div class="top_r_quick_title">快捷入口</div>
             <div class="top_r_quick_list">
-              <div class="top_r_quick_item" @click="goPath('/shop/shopList')">
+              <div class="top_r_quick_item" @click="goPath('/hospital/list')">
                 <i class="el-icon-document"></i>
-                <span>商户管理</span>
+                <span>医院管理</span>
               </div>
-              <div class="top_r_quick_item" @click="goPath('/goods/list')">
+              <div class="top_r_quick_item" @click="goPath('/service/list')">
                 <i class="el-icon-shopping-bag-2"></i>
-                <span>商品管理</span>
+                <span>服务管理</span>
               </div>
               <div class="top_r_quick_item" @click="goPath('/order/list')">
                 <i class="el-icon-collection-tag"></i>
                 <span>订单管理</span>
               </div>
-              <div class="top_r_quick_item" @click="goPath('/distribute/distributeOrder')">
+              <div class="top_r_quick_item" @click="goPath('/finance/list')">
                 <i class="el-icon-sell"></i>
-                <span>分销管理</span>
+                <span>财务管理</span>
               </div>
               <div class="top_r_quick_item" @click="goPath('/user/user/index')">
                 <i class="el-icon-user"></i>
@@ -85,14 +85,14 @@
             </div>
           </div>
           <div class="top_r_chart">
-            <div class="top_r_chart_title">商户类型</div>
+            <div class="top_r_chart_title">服务分类</div>
             <div class="top_r_chart_content" ref="pieChart" style="height: 300px;"></div>
           </div>
         </div>
       </div>
       <div class="bottom">
         <div class="bottom_t">
-          <div class="bottom_t_title">商户订单数<span>(top10)</span></div>
+          <div class="bottom_t_title">医院订单数<span>(top10)</span></div>
           <div class="bottom_t_more"></div>
         </div>
         <div class="bottom_b" ref="categoryChart" style="height: 300px;"></div>
@@ -107,7 +107,7 @@
 </template>
 
 <script>
-import { homeTop, userStatistics, businessStatistics, ticketOrderStatistics } from '@/api/home'
+import { homeQuantity, userStatistics, serviceCategorizeStatistics, hospitalOrderStatistics } from '@/api/home'
 import * as echarts from "echarts";
 export default {
   data () {
@@ -172,7 +172,7 @@ export default {
     },
     // 获取头部集合
     getHomeTop () {
-      homeTop().then(res => {
+      homeQuantity().then(res => {
         this.homeTopObj = res.data
       })
     },
@@ -184,12 +184,12 @@ export default {
         this.initChart()
       })
     },
-    // 获取商户类型
+    // 获取服务分类
     getBusinessStatistics () {
-      businessStatistics().then(res => {
+      serviceCategorizeStatistics().then(res => {
         res.data.map(v => {
-          v.name = v.categoryName;
-          v.value = v.businessSum;
+          v.name = v.name;
+          v.value = v.serviceProductNum;
         })
         this.pieData = res.data;
         this.initPieChart();
@@ -338,7 +338,7 @@ export default {
     },
     // 获取商户订单数
     getTicketOrderStatistics () {
-      ticketOrderStatistics().then(res => {
+      hospitalOrderStatistics().then(res => {
         this.shopChartData.xData = res.data.map(v => v.businessName);
         this.shopChartData.yData = res.data.map(v => v.businessOrder);
         this.initCategoryChart()

+ 1 - 1
src/views/operating/agreement.vue

@@ -22,7 +22,7 @@ export default {
   dicts: ['protocol_type'],
   data () {
     return {
-      tabList: ['用户协议', '隐私协议', '关于我们', '活动规则'],
+      tabList: ['隐私协议', '隐私协议', '关于我们', '活动规则'],
       content: '',
       code: 'user_protocol',
       params: {},

+ 1 - 1
src/views/operating/jinGang.vue

@@ -222,7 +222,7 @@ export default {
       jumpTypeList: [
         { label: "内部页面", value: 0 },
         { label: "外部链接", value: 1 },
-        { label: "内部资源", value: 2 },
+        // { label: "内部资源", value: 2 },
       ],
       resourceModelList: [
         // { label: '无', value: 0 },

+ 74 - 123
src/views/order/orderList/details.vue

@@ -2,85 +2,33 @@
   <div class="app-container">
     <el-form :model="form" ref="form" inline>
       <h3>基础信息</h3>
-      <el-form-item label="订单号:" prop="name">{{form.orderNumber}}</el-form-item>
-      <el-form-item label="所属商家:" prop="name">{{form.businessName}}</el-form-item>
-      <el-form-item label="商品名称:" prop="name">{{form.businessProductName}}</el-form-item>
-      <el-form-item label="订单属性:" prop="name"> {{form.orderType==0?"自购":form.orderType==1?"奖励":"--"}}</el-form-item>
-      <el-form-item label="购买数量:" prop="name">{{form.buyQuantity}}(可使用 {{form.waitSum}} )</el-form-item>
-      <el-form-item label="销价格售:" prop="name">{{form.sellingPrice}}</el-form-item>
-      <el-form-item label="应付金额:" prop="name">{{form.orderAmount}}</el-form-item>
+      <el-form-item label="订单号:" prop="name">{{form.orderNo}}</el-form-item>
+      <br>
+      <el-form-item label="下单人姓名:" prop="name">{{form.userName}}</el-form-item>
+      <el-form-item label="下单人手机号:" prop="name">{{form.userMobile}}</el-form-item>
+      <el-form-item label="下单时间:" prop="name">{{ parseTime(form.createTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>
       <el-form-item label="订单状态:" prop="name">
-        <!-- {{dealStatus(form.orderStatus)}} -->
-        <el-tag v-if="form.orderStatus==10">待使用</el-tag>
-        <el-tag v-if="form.orderStatus==20&&form.refundStatus==0" type="success">已完成</el-tag>
-        <el-tag v-if="form.orderStatus==30&&form.refundStatus==2" type="info">已退款</el-tag>
-        <el-tag v-if="form.orderStatus==20&&form.refundStatus==1" type="info">已完成(有退款)</el-tag>
-        <el-tag v-if="form.orderStatus==0" type="danger">待支付</el-tag>
-        <el-tag v-if="form.orderStatus==30&&form.refundStatus!=2" type="info">已取消</el-tag>
+        {{dealStatus(form.status)}}
+      </el-form-item>
+      <h3>服务信息</h3>
+      <el-form-item label="下单医院:" prop="name">{{form.hospitalVo.name}}</el-form-item>
+      <el-form-item label="所在科室:" prop="name">{{form.hospitalDepartmentName}}</el-form-item>
+      <el-form-item label="医院地址:" prop="name">{{form.hospitalVo.address}}</el-form-item>
+      <el-form-item label="期望时间:" prop="name">{{parseTime(form.expectedTime, '{y}-{m}-{d} {h}:{i}')||'-'}}</el-form-item>
+      <el-form-item label="服务名称:" prop="name">{{form.serviceName}}</el-form-item>
+      <el-form-item label="房床号:" prop="name">{{form.roomNumber}}</el-form-item>
+      <el-form-item label="下单数量:" prop="name">{{form.orderNum}}{{dealServiceUnitList(form.serviceUnit)}}</el-form-item>
+      <el-form-item label="销售价格:" prop="name">{{form.sellingPrice}}</el-form-item>
+      <el-form-item label="应付金额:" prop="name">{{form.totalPrice}}</el-form-item>
+      <el-form-item label="特殊需求:" prop="name">{{form.remarks||'-'}}</el-form-item>
+      <h3>就诊人信息</h3>
+      <el-form-item label="就诊人姓名:" prop="name">{{ form.patientVo.name}}</el-form-item>
+      <el-form-item label="电话:" prop="name">{{form.patientVo.mobile}}</el-form-item>
+      <el-form-item label="性别:" prop="name">{{dealGender(form.patientVo.gender)}}</el-form-item>
+      <el-form-item label="年龄:" prop="name">{{form.patientVo.age}}</el-form-item>
+      <el-form-item label="关系:" prop="name">
+        <div v-for="(v,i) in dict.type.patient_relationship" :key="i" v-if="v.value==form.patientVo.relationship">{{v.label}}</div>
       </el-form-item>
-      <el-form-item label="下单人姓名:" prop="name">{{form.userNickname}}</el-form-item>
-      <el-form-item label="下单人手机号:" prop="name">{{form.userPhone}}</el-form-item>
-      <el-form-item label="下单时间:" prop="name">{{ parseTime(form.orderTime, '{y}-{m}-{d} {h}:{i}') }}</el-form-item>
-      <el-form-item label="预约日期:" prop="name" v-if="form.reservationDate">{{form.reservationDate}}</el-form-item>
-      <el-form-item label="预约场次:" prop="name" v-if="form.reservationTime">{{form.reservationTime}}</el-form-item>
-      <h3>游客信息</h3>
-      <el-form-item label="游客姓名:" prop="name">{{form.productVisitor.visitorName}}</el-form-item>
-      <el-form-item label="游客手机号:" prop="name">{{form.productVisitor.visitorPhone}}</el-form-item>
-      <el-form-item label="游客身份证号:" prop="name">{{form.productVisitor.visitorCardNumber}}</el-form-item>
-      <h3>付款信息</h3>
-      <el-form-item label="支付时间:" prop="name">{{ parseTime(form.payTime, '{y}-{m}-{d} {h}:{i}')||'--' }}</el-form-item>
-      <el-form-item label="支付方式:" prop="name">微信支付</el-form-item>
-      <el-form-item label="支付流水号:" prop="name">{{form.payOrder||'--'}}</el-form-item>
-      <el-form-item label="实际支付金额:" prop="name">{{form.payAmount}}</el-form-item>
-      <div v-if="!(form.orderStatus==30&&form.refundStatus!=2)&&form.orderStatus!=0">
-        <h3>券码信息</h3>
-        <el-table :data="couponList" stripe>
-          <el-table-column prop="date" label="序号" width="80">
-            <template slot-scope="scope">
-              <div>
-                {{  scope.$index + 1 }}
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="businessName" align="center" label="所属商家">
-          </el-table-column>
-          <el-table-column prop="businessProductName" align="center" label="商品名称">
-          </el-table-column>
-          <el-table-column prop="couponCode" align="center" label="券码">
-          </el-table-column>
-          <el-table-column prop="couponStatus" align="center" label="状态">
-            <template slot-scope="{row}">
-              <div v-for="(v,i) in couponStatusList" :key="i" :class="{active:row.couponStatus==20||row.couponStatus==21}" v-if="row.couponStatus==v.value" @click="goAfterSaleOrderDetails(row)">{{v.label}}</div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="useTime" align="center" label="使用时间">
-            <template slot-scope="{row}">
-              {{ parseTime(row.useTime, '{y}-{m}-{d} {h}:{i}')||'--' }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="verificationSysUserName" align="center" label="核销人">
-            <template slot-scope="{row}">
-              {{ row.verificationSysUserName||'--' }}
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-            <template slot-scope="scope">
-              <el-button size="mini" v-if="scope.row.couponStatus==0" type="text" @click="confirmWriteOff(scope.row)">确认核销</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-        <div v-if="gameRecord.serialNumber">
-          <h3>游戏信息</h3>
-          <el-form-item label="游戏流水号:" prop="name">{{gameRecord.serialNumber}}</el-form-item>
-          <el-form-item label="游戏时间:" prop="name">{{ parseTime(gameRecord.executeTime, '{y}-{m}-{d} {h}:{i}')||'--' }}</el-form-item>
-          <el-form-item label="游戏结果:" prop="name">{{gameRecord.gameResult?'赢盘':'输盘'}}</el-form-item>
-          <!-- <el-form-item label="累计消费金额:" prop="name">{{gameRecord.serialNumber}}</el-form-item> -->
-        </div>
-      </div>
-      <div v-if="form.orderStatus==30&&form.refundStatus!=2">
-        <h3>取消信息</h3>
-        <el-form-item label="取消原因:" prop="name">{{form.cancelNote||'--'}}</el-form-item>
-      </div>
     </el-form>
     <div class="form-footer">
       <el-button @click="back">返回</el-button>
@@ -90,19 +38,17 @@
 
 <script>
 import { businessProductOrderInfo, orderCouponList, verification } from '@/api/order.js'
-import { gameRecordPage } from '@/api/game.js'
+import { orderInfo, orderEnum } from '@/api/hospitalOrder.js'
+import { serviceProductEnum } from '@/api/service.js'
 
 export default {
+  dicts: ['patient_relationship'],
   data () {
     return {
-      form: {},
-      statusList: [
-        { label: '待使用', value: 10, tag: "" },
-        { label: '已完成', value: 20, tag: "success" },
-        { label: '已退款', value: 3, tag: "info" },
-        { label: '待支付', value: 0, tag: "danger" },
-        { label: '已取消', value: 30, tag: "info" },
-      ],
+      form: {
+        hospitalVo: {},
+        patientVo: {}
+      },
       couponStatusList: [
         { label: '待使用', value: 0 },
         { label: '已使用', value: 10 },
@@ -111,7 +57,14 @@ export default {
         { label: '已过期', value: 30 },
       ],
       couponList: [],
-      gameRecord: {}
+      gameRecord: {},
+      statusList: [],
+      genderList: [
+        { label: '0', value: '未知' },
+        { label: '1', value: '男' },
+        { label: '2', value: '女' }
+      ],
+      serviceUnitList: []
     }
   },
   created () {
@@ -120,55 +73,50 @@ export default {
   methods: {
     init () {
       this.getDetails();
-      this.getOrderCouponList();
+      this.getOrderEnum();
+      this.getServiceUnitList();
+    },
+    // 获取服务单位列表
+    getServiceUnitList () {
+      serviceProductEnum().then(res => {
+        this.serviceUnitList = res.data.serviceUnit
+      })
     },
     dealStatus (status) {
       for (let i = 0; i < this.statusList.length; i++) {
-        if (this.statusList[i].value == status) {
-          return this.statusList[i].label
+        if (this.statusList[i].code == status) {
+          return this.statusList[i].value
+        }
+      }
+    },
+    dealGender (gender) {
+      for (let i = 0; i < this.genderList.length; i++) {
+        if (this.genderList[i].label == gender) {
+          return this.genderList[i].value
+        }
+      }
+    },
+    dealServiceUnitList (val) {
+      for (let i = 0; i < this.serviceUnitList.length; i++) {
+        if (this.serviceUnitList[i].code == val) {
+          return this.serviceUnitList[i].value
         }
       }
     },
     back () {
       this.$router.go(-1)
     },
-    getDetails () {
-      businessProductOrderInfo(this.$route.query.orderId).then(res => {
-        this.form = res.data
-        this.getGameRecordPage(res.data.orderNumber)
-      })
-    },
-    // 获取券码信息
-    getOrderCouponList () {
-      orderCouponList({ orderId: this.$route.query.orderId }).then(res => {
-        this.couponList = res.data
+    getOrderEnum () {
+      orderEnum().then(res => {
+        this.statusList = res.data.orderStatus;
       })
     },
-    // 获取游戏信息
-    getGameRecordPage (relatedOrderNo) {
-      gameRecordPage({ relatedOrderNo: relatedOrderNo }).then(res => {
-        if (res.rows && res.rows.length > 0) {
-          this.gameRecord = res.rows[0]
-        }
+    getDetails () {
+      orderInfo(this.$route.query.id).then(res => {
+        this.form = res.data
+        // this.getGameRecordPage(res.data.orderNumber)
       })
     },
-    confirmWriteOff (item) {
-      this.$modal.confirm('确定核销此券码吗?').then(() => {
-        return verification({ couponId: item.couponId });
-      }).then(() => {
-        this.init();
-        this.$modal.msgSuccess("核销成功");
-      }).finally(() => {
-      });
-    },
-    goAfterSaleOrderDetails (row = {}) {
-      if (row.couponStatus == 20 || row.couponStatus == 21) {
-        this.$router.push({
-          path: '/order/afterSaleOrderDetails',
-          query: { refundOrderId: row.refundOrderId }
-        })
-      }
-    },
   }
 
 }
@@ -189,4 +137,7 @@ h3 {
   margin-top: 20px;
   text-align: center;
 }
+::v-deep .el-form-item__content {
+  width: calc(100% - 120px);
+}
 </style>

+ 66 - 67
src/views/order/orderList/index.vue

@@ -1,26 +1,23 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
-      <el-form-item label="所属商家" prop="businessId">
-        <el-select v-model="queryParams.businessId" filterable placeholder="请选择所属商家" size="small" clearable style="width: 100%">
-          <el-option v-for="(v,i) in shopList" :key="i" :label="v.businessName" :value="v.businessId" />
+      <el-form-item label="下单医院" prop="hospitalId">
+        <el-select v-model="queryParams.hospitalId" filterable placeholder="请选择下单医院" size="small" clearable style="width: 100%">
+          <el-option v-for="(v,i) in shopList" :key="i" :label="v.name" :value="v.id" />
         </el-select>
       </el-form-item>
-      <el-form-item label="订单号" prop="orderNumber">
-        <el-input v-model="queryParams.orderNumber" placeholder="请输入订单号" maxlength="30" clearable size="small" @keyup.enter.native="handleQuery" />
+      <el-form-item label="订单号" prop="orderNo">
+        <el-input v-model="queryParams.orderNo" placeholder="请输入订单号" maxlength="30" clearable size="small" @keyup.enter.native="handleQuery" />
       </el-form-item>
-      <el-form-item label="下单手机号" prop="userPhone">
-        <el-input v-model="queryParams.userPhone" placeholder="请输入下单手机号" maxlength="11" clearable size="small" @keyup.enter.native="handleQuery" />
+      <el-form-item label="下单手机号" prop="userMobile">
+        <el-input v-model="queryParams.userMobile" placeholder="请输入下单手机号" maxlength="11" clearable size="small" @keyup.enter.native="handleQuery" />
       </el-form-item>
-      <el-form-item label="商品名称" prop="businessProductName">
-        <el-input v-model="queryParams.businessProductName" placeholder="请输入商品名称" maxlength="30" clearable size="small" @keyup.enter.native="handleQuery" />
+      <el-form-item label="服务名称" prop="serviceName">
+        <el-input v-model="queryParams.serviceName" placeholder="请输入服务名称" maxlength="30" clearable size="small" @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="下单时间" prop="">
         <el-date-picker v-model="daterangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
       </el-form-item>
-      <el-form-item label="券码核销码" prop="couponCode">
-        <el-input v-model="queryParams.couponCode" placeholder="请输入券码核销码" maxlength="60" clearable size="small" @keyup.enter.native="handleQuery" />
-      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -28,8 +25,8 @@
     </el-form>
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
-        <el-radio-group size="mini" v-model="queryParams.queryStatus" style="margin-bottom: 30px;" @input="handleQuery">
-          <el-radio-button v-for="(v,i) in queryStatusList" :key="i" :label="v.value">{{v.label}}</el-radio-button>
+        <el-radio-group size="mini" v-model="queryParams.status" style="margin-bottom: 30px;" @input="handleQuery">
+          <el-radio-button v-for="(v,i) in queryStatusList" :key="i" :label="v.code">{{v.value}}</el-radio-button>
         </el-radio-group>
       </el-col>
       <el-col :span="1.5">
@@ -46,53 +43,43 @@
         </template>
       </el-table-column>
       <!-- <el-table-column label="商家ID" align="center" prop="businessId" /> -->
-      <el-table-column label="订单编号" align="center" prop="orderNumber" />
-      <el-table-column label="商品名称" align="center" prop="businessProductName" />
+      <el-table-column label="订单编号" align="center" prop="orderNo" />
+      <el-table-column label="服务名称" align="center" prop="serviceName" />
       <el-table-column label="销售价格" align="center" prop="sellingPrice" />
-      <el-table-column label="购买数" align="center" prop="buyQuantity" width="60" />
-      <el-table-column label="可用数" align="center" prop="waitSum" width="60" />
-      <el-table-column label="实付金额" align="center" prop="payAmount">
+      <el-table-column label="下单数量" align="center" prop="orderNum" />
+      <el-table-column label="单位" align="center" prop="serviceUnit" width="60">
         <template slot-scope="{row}">
-          {{row.payAmount||"--"}}
+          <div v-for="(v, i) in serviceUnitList" :key="i" v-if="v.code==row.serviceUnit">{{v.value}}</div>
         </template>
       </el-table-column>
-      <el-table-column label="下单手机号" align="center" prop="userPhone" />
-      <el-table-column label="所属商家" align="center" prop="businessName" />
-      <el-table-column label="订单状态" align="center" prop="orderStatus">
+      <el-table-column label="应付金额" align="center" prop="totalPrice">
         <template slot-scope="{row}">
-          <!-- <el-tag v-for="(v,i) in statusList" :key="i" :type="v.tag" v-if="row.orderStatus==v.value">{{v.label}}</el-tag> -->
-          <el-tag v-if="row.orderStatus==10">待使用</el-tag>
+          {{row.totalPrice||"--"}}
+        </template>
+      </el-table-column>
+      <el-table-column label="下单手机号" align="center" prop="userMobile" />
+      <el-table-column label="下单医院" align="center" prop="hospitalName" />
+      <el-table-column label="所在科室" align="center" prop="hospitalDepartmentName" />
+      <el-table-column label="订单状态" align="center" prop="status">
+        <template slot-scope="{row}">
+          <div v-for="(v,i) in statusList" :key="i" :type="v.tag" v-if="row.status==v.code">{{v.value}}</div>
+          <!-- <el-tag v-if="row.orderStatus==10">待使用</el-tag>
           <el-tag v-if="row.orderStatus==20&&row.refundStatus!=2&&row.refundStatus!=1" type="success">已完成</el-tag>
           <el-tag v-if="row.orderStatus==30&&row.refundStatus==2" type="info">已退款</el-tag>
           <el-tag v-if="row.orderStatus==20&&row.refundStatus==1" type="info">已完成(有退款)</el-tag>
           <el-tag v-if="row.orderStatus==0" type="danger">待支付</el-tag>
-          <el-tag v-if="row.orderStatus==30&&row.refundStatus!=2" type="info">已取消</el-tag>
+          <el-tag v-if="row.orderStatus==30&&row.refundStatus!=2" type="info">已取消</el-tag> -->
         </template>
       </el-table-column>
-      <el-table-column label="订单属性" align="center" prop="orderType">
-        <template slot-scope="{row}">
-          {{row.orderType==0?"自购":row.orderType==1?"奖励":"--"}}
-        </template>
-      </el-table-column>
-      <el-table-column label="下单时间" align="center" prop="orderTime" width="140">
+      <el-table-column label="下单时间" align="center" prop="createTime" width="140">
         <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.orderTime, '{y}-{m}-{d} {h}:{i}') }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="预约日期" align="center" prop="reservationDate">
-        <template slot-scope="scope">
-          <span>{{ scope.row.reservationDate||'--' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="预约场次" align="center" prop="reservationTime">
-        <template slot-scope="scope">
-          <span>{{ scope.row.reservationTime||'--' }}</span>
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button size="mini" type="text" @click="goDetails(scope.row)">查看</el-button>
-          <el-button size="mini" type="text" v-if="scope.row.reservationStatus&&scope.row.orderType==1&&!scope.row.reservationTime" @click="openDialog(scope.row)">配置预约时间</el-button>
+          <!-- <el-button size="mini" type="text" v-if="scope.row.reservationStatus&&scope.row.orderType==1&&!scope.row.reservationTime" @click="openDialog(scope.row)">配置预约时间</el-button> -->
         </template>
       </el-table-column>
     </el-table>
@@ -122,7 +109,9 @@
 
 <script>
 import { businessProductOrderPage, businessProductOrderChange, reservation } from '@/api/order.js'
-import { businessList } from "@/api/shop"
+import { hospitalSimpleList } from "@/api/hospital.js"
+import { orderPage, orderEnum } from "@/api/hospitalOrder.js"
+import { serviceProductEnum } from "@/api/service.js"
 export default {
   data () {
     return {
@@ -155,21 +144,17 @@ export default {
         queryStatus: undefined
       },
       daterangeCreateTime: [],
-      // statusList: [
-      //   { label: '待使用', value: 10, tag: "" },
-      //   { label: '已完成', value: 20, tag: "success" },
-      //   { label: '已退款', value: 3, tag: "info" },
-      //   { label: '待支付', value: 0, tag: "danger" },
-      //   { label: '已取消', value: 30, tag: "info" },
-      // ],
+      statusList: [],
       queryStatusList: [
-        { label: '全部', value: undefined },
-        { label: '待使用', value: 10 },
-        { label: '已完成', value: 20 },
-        { label: '已退款', value: 40 },
-        { label: '待支付', value: 0 },
-        { label: '已取消', value: 30 },
+        { value: '全部', code: undefined },
+        // { label: '待确认', value: 10 },
+        // { label: '待服务', value: 20 },
+        // { label: '服务中', value: 40 },
+        // { label: '已完成', value: 0 },
+        // { label: '已退款', value: 0 },
+        // { label: '已取消', value: 30 },
       ],
+      serviceUnitList: [],
       tabPosition: 0,
       shopList: [],
       dialogVisible: false,
@@ -188,13 +173,15 @@ export default {
   },
   created () {
     this.getList();
+    this.getOrderEnum();
+    this.getServiceUnitList()
     this.getShopList()
   },
   methods: {
     goDetails (row) {
       this.$router.push({
         path: '/order/orderList/details',
-        query: { orderId: row.orderId }
+        query: { id: row.id }
       })
     },
     openDialog (item) {
@@ -204,6 +191,18 @@ export default {
         this.reserveData = res.data;
       })
     },
+    getOrderEnum () {
+      orderEnum().then(res => {
+        this.statusList = res.data.orderStatus;
+        this.queryStatusList.push(...res.data.orderStatus)
+      })
+    },
+    // 获取服务单位列表
+    getServiceUnitList () {
+      serviceProductEnum().then(res => {
+        this.serviceUnitList = res.data.serviceUnit
+      })
+    },
     reservationDateChange (e) {
       this.reserveData.reservationDateList.map((v, i) => {
         if (v.reservationDate == e) {
@@ -250,27 +249,27 @@ export default {
     //  导出订单
     handleExport () {
       // /shoporder/shopOrder/export
-      this.download('/system/businessProductOrder/export', {
+      this.download('/order/order/export', {
         ...this.queryParams
-      }, `门店商品订单_${new Date().getTime()}.xlsx`)
+      }, `订单列表_${new Date().getTime()}.xlsx`)
     },
     dealStatus (val) {
       return this.statusList.find(item => item.value == val).label
     },
     getShopList () {
-      businessList().then(res => {
+      hospitalSimpleList().then(res => {
         this.shopList = res.data
       })
     },
     getList () {
       this.loading = true;
-      this.queryParams["orderTimeStart"] = undefined;
-      this.queryParams["orderTimeEnd"] = undefined;
+      this.queryParams["startTime"] = undefined;
+      this.queryParams["endTime"] = undefined;
       if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
-        this.queryParams["orderTimeStart"] = this.daterangeCreateTime[0];
-        this.queryParams["orderTimeEnd"] = this.daterangeCreateTime[1];
+        this.queryParams["startTime"] = this.daterangeCreateTime[0];
+        this.queryParams["endTime"] = this.daterangeCreateTime[1];
       }
-      businessProductOrderPage(this.queryParams).then(response => {
+      orderPage(this.queryParams).then(response => {
         this.list = response.rows;
         this.total = response.total;
         this.loading = false;

+ 268 - 0
src/views/service/details.vue

@@ -0,0 +1,268 @@
+<template>
+  <div class="app-container">
+    <el-form :model="form" ref="form" :rules="rules" label-width="160px">
+      <el-form-item label="服务名称" prop="name">
+        <el-input v-model="form.name" placeholder="请输入服务名称" :disabled="$route.query.type == 'show'" maxlength="50" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="服务分类" prop="serviceCategorizeId">
+        <el-select v-model="form.serviceCategorizeId" :disabled="$route.query.type == 'show'" placeholder="请选择服务分类" clearable style="width: 100%">
+          <el-option v-for="(v, i) in typeList" :key="i" :label="v.name" :value="v.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="服务图片" prop="image">
+        <imageUpload v-model="form.image" unique="image" :disabled="$route.query.type == 'show'" :limit="1" />
+      </el-form-item>
+      <h3>销售信息</h3>
+      <el-form-item label="销售价" prop="sellingPrice">
+        <el-input-number v-model="form.sellingPrice" :disabled="$route.query.type == 'show'" controls-position="right" :min="0" :max="Number(form.originalPrice)||Infinity" :precision="2"></el-input-number>
+      </el-form-item>
+      <el-form-item label="原价" prop="originalPrice">
+        <el-input-number v-model="form.originalPrice" :disabled="$route.query.type == 'show'" controls-position="right" :min="Number(form.costPrice)||0" :precision="2"></el-input-number>
+      </el-form-item>
+      <el-form-item label="成本价" prop="costPrice">
+        <el-input-number v-model="form.costPrice" :disabled="$route.query.type == 'show'" controls-position="right" :min="0" :precision="2"></el-input-number>
+      </el-form-item>
+      <el-form-item label="服务单位" prop="serviceUnit">
+        <div class="flex">
+          <el-select v-model="form.serviceUnit" :disabled="$route.query.type == 'show'" placeholder="请选择服务单位" clearable style="width: 50%;">
+            <el-option v-for="(v, i) in serviceUnitList" :key="i" :label="v.value" :value="v.code" />
+          </el-select>
+          <el-input-number style="margin-left: 20px;margin-right:10px;" v-model="form.serviceUnitDuration" :disabled="$route.query.type == 'show'" controls-position="right" :min="0" :max="99" :precision="0"></el-input-number> 小时
+        </div>
+      </el-form-item>
+
+      <h3>服务说明</h3>
+      <el-form-item label="服务说明" prop="serviceDescription">
+        <el-input type="textarea" v-model="form.serviceDescription" :disabled="$route.query.type == 'show'" placeholder="请输入服务说明" clearable />
+      </el-form-item>
+      <el-form-item label="服务须知" prop="serviceNotice">
+        <el-input type="textarea" :rows="2" placeholder="请输入服务须知" :disabled="$route.query.type == 'show'" clearable v-model="form.serviceNotice">
+        </el-input>
+      </el-form-item>
+      <el-form-item label="上架状态" prop="status">
+        <el-select v-model="form.status" placeholder="请选择状态" :disabled="$route.query.type == 'show'" style="width: 240px">
+          <el-option label="上架" :value="true" />
+          <el-option label="下架" :value="false" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <el-form label-width="120px">
+      <el-form-item label="">
+        <el-button v-if="$route.query.type != 'show'" :loading="buttonLoading" type="primary" @click="submitForm">保 存</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { businessList, businessProductCategoryList } from "@/api/service";
+import {
+  serviceProductAdd,
+  serviceCategorizeList,
+  serviceProductEnum,
+  serviceProductInfo,
+  serviceProductEdit
+} from "@/api/service";
+import draggable from "vuedraggable";
+export default {
+  components: {
+    draggable,
+  },
+  data () {
+    return {
+      form: {
+        name: undefined,
+        serviceCategorizeId: undefined,
+        image: undefined,
+        sellingPrice: undefined,
+        originalPrice: undefined,
+        costPrice: undefined,
+        serviceUnit: undefined,
+        serviceDescription: undefined,
+        serviceNotice: undefined,
+        status: true
+      },
+      typeList: [],
+      rules: {
+        name: [
+          { required: true, message: "请输入服务名称", trigger: "change" },
+        ],
+        sellingPrice: [
+          { required: true, message: "请输入销售价", trigger: "change" },
+        ],
+        originalPrice: [
+          { required: true, message: "请输入原价", trigger: "change" },
+        ],
+        costPrice: [
+          { required: true, message: "请输入成本价", trigger: "change" },
+        ],
+        serviceUnit: [
+          { required: true, message: "请选择服务单位", trigger: "change" },
+        ],
+        serviceDescription: [{ required: true, message: "请输入服务说明", trigger: "change" }],
+      },
+      buttonLoading: false,
+      currentDate: new Date(),
+      selectedDates: [],
+      serviceUnitList: []
+    };
+  },
+  created () {
+    this.getTypeList();
+    this.getServiceUnitList()
+    if (this.$route.query.id) {
+      this.getDetails(this.$route.query.id);
+    }
+  },
+  methods: {
+    // 判断某个日期是否已被选中
+    isSelected (date) {
+      return this.selectedDates.some(
+        d => d === this.formatDate(date)
+      );
+    },
+    // 获取服务单位列表
+    getServiceUnitList () {
+      serviceProductEnum().then(res => {
+        this.serviceUnitList = res.data.serviceUnit
+      })
+    },
+    // 点击切换选中状态
+    toggleSelection (date) {
+      if (this.$route.query.type == 'show') return
+      let dateString = this.formatDate(date);
+      let index = this.selectedDates.findIndex(
+        d => this.formatDate(d) === dateString
+      );
+      if (index === -1) {
+        this.selectedDates.push(this.formatDate(date));
+      } else {
+        this.selectedDates.splice(index, 1);
+      }
+    },
+    // 格式化日期为 YYYY-MM-DD
+    formatDate (date) {
+      const d = new Date(date);
+      const year = d.getFullYear();
+      const month = (d.getMonth() + 1).toString().padStart(2, '0');
+      const day = d.getDate().toString().padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+    getDetails (id) {
+      serviceProductInfo(id).then((res) => {
+        this.form = res.data;
+      });
+    },
+    getTypeList () {
+      serviceCategorizeList().then((res) => {
+        this.typeList = res.data;
+      });
+    },
+    addBusinessProductCategory () {
+      this.form.businessProductTimeList.push({})
+    },
+    deleteBusinessProductCategory (index) {
+      this.form.businessProductTimeList.splice(index, 1)
+    },
+    cancel () {
+      if (this.$route.query.queryParams) {
+        localStorage.setItem('queryParams', this.$route.query.queryParams)
+      }
+      this.$router.go(-1);
+    },
+    submitForm () {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          if (!this.form.serviceUnitDuration) {
+            this.$message.error('请输入服务单位时长');
+            return
+          }
+          let formCopy = JSON.parse(JSON.stringify(this.form));
+          this.buttonLoading = true;
+          if (this.form.id != null) {
+            serviceProductEdit(formCopy)
+              .then((response) => {
+                this.$modal.msgSuccess("修改成功");
+                this.cancel();
+              })
+              .finally(() => {
+                this.buttonLoading = false;
+              });
+          } else {
+            serviceProductAdd(formCopy)
+              .then((response) => {
+                this.$modal.msgSuccess("新增成功");
+                this.cancel();
+              })
+              .finally(() => {
+                this.buttonLoading = false;
+              });
+          }
+        }
+      });
+    },
+    addItem () {
+      this.form.businessProductNotesList.push({});
+    },
+    deleteItem (index) {
+      this.form.businessProductNotesList.splice(index, 1);
+    },
+  },
+};
+</script>
+
+<style lang='scss' scoped>
+.el-form {
+  width: 1000px;
+}
+.hint {
+  font-size: 12px;
+  color: red;
+}
+.map-box {
+  width: calc(100% - 120px);
+  height: 300px;
+  margin-bottom: 30px;
+  box-sizing: border-box;
+  margin-left: 120px;
+}
+.flex {
+  display: flex;
+  margin-bottom: 10px;
+  .el-button {
+    margin-left: 10px;
+  }
+}
+h3 {
+  width: 160px;
+  font-weight: 700;
+  text-align: right;
+}
+.flex-bet {
+  display: flex;
+  justify-content: space-between;
+}
+.showTip {
+  display: inline-block;
+  margin-left: 20px;
+  font-weight: 700;
+  color: #606266;
+}
+
+// .selected {
+//   background-color: #909399;
+//   color: white;
+//   border-radius: 4px;
+// }
+::v-deep .el-calendar-table .el-calendar-day {
+  height: 47px !important;
+}
+// ::v-deep .el-input.is-disabled .el-input__inner,
+// ::v-deep .el-range-editor.is-disabled,
+// ::v-deep .el-range-editor.is-disabled input,
+// ::v-deep .el-textarea.is-disabled .el-textarea__inner {
+//   background-color: #fff;
+//   color: rgb(96, 98, 102);
+// }
+</style>

+ 245 - 0
src/views/service/index.vue

@@ -0,0 +1,245 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="服务分类" prop="serviceCategorizeId">
+        <el-select v-model="queryParams.serviceCategorizeId" placeholder="请选择服务分类" size="small" clearable style="width: 100%">
+          <el-option v-for="(v,i) in typeList" :key="i" :label="v.name" :value="v.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small" style="width: 240px">
+          <el-option label="上架" :value="true" />
+          <el-option label="下架" :value="false" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="daterangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange" @sort-change="sortChange">
+      <el-table-column type="index" width="55" label="序号" align="center">
+        <template slot-scope="scope">
+          <div>
+            {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="服务ID" align="center" prop="id" width="120" />
+      <el-table-column label="服务分类" align="center" prop="serviceCategorizeName" />
+      <el-table-column label="服务名称" align="center" prop="name" />
+      <el-table-column label="价格(元)" align="center" prop="sellingPrice" />
+      <el-table-column label="单位" align="center" prop="serviceUnit">
+        <template slot-scope="{row}">
+          <div v-for="(v,i) in serviceUnitList" :key="i" v-if="v.code == row.serviceUnit">{{v.value}}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="上架状态" align="center" prop="status">
+        <template slot-scope="{row}">
+          <el-tag type="success" v-if="row.status">上架</el-tag>
+          <el-tag type="danger" v-if="!row.status">下架</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="140">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime,'{y}-{m}-{d} {h}:{i}')}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200px">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" @click="handleUpdate(scope.row,'show')">查看</el-button>
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row,'edit')">修改</el-button>
+          <el-button size="mini" type="text" @click="setStatus(scope.row)">{{scope.row.status?'下架':'上架'}}</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" v-if="!scope.row.status" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+
+  </div>
+</template>
+
+<script>
+import { serviceProductPage, serviceCategorizeList, serviceProductSetStatus, serviceProductDel, serviceProductEnum } from "@/api/service.js";
+export default {
+  data () {
+    return {
+      //按钮loading
+      buttonLoading: false,
+      // 遮罩层
+      loading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 测试单表表格数据
+      list: [1],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        businessName: undefined,
+        businessProductCategoryId: undefined,
+        status: undefined,
+        giftPoints: undefined
+      },
+      daterangeCreateTime: [],
+      typeList: [],
+      serviceUnitList: []
+    }
+  },
+  created () {
+    let queryParams = localStorage.getItem('queryParams');
+    if (queryParams) {
+      this.queryParams = JSON.parse(queryParams);
+      localStorage.setItem('queryParams', '')
+    }
+    this.getList();
+    this.getTypeList();
+    this.getServiceUnitList();
+  },
+  methods: {
+    sortChange (e) {
+      this.queryParams.sortOrder = Boolean(e.order == "ascending");
+      this.handleQuery()
+    },
+    // 获取服务单位列表
+    getServiceUnitList () {
+      serviceProductEnum().then(res => {
+        this.serviceUnitList = res.data.serviceUnit
+      })
+    },
+    // 获取服务分类列表
+    getTypeList () {
+      serviceCategorizeList().then((res) => {
+        this.typeList = res.data;
+      });
+    },
+    /** 上下架按钮操作 */
+    setStatus (row) {
+      const ids = row.id;
+      let statusText = row.status ? '下架' : '上架';
+      this.$modal.confirm('是否确认' + statusText + '服务名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return serviceProductSetStatus(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess(statusText + "成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    getList () {
+      this.loading = true;
+      this.queryParams["startTime"] = undefined;
+      this.queryParams["endTime"] = undefined;
+      if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
+        this.queryParams["startTime"] = this.daterangeCreateTime[0];
+        this.queryParams["endTime"] = this.daterangeCreateTime[1];
+      }
+      serviceProductPage(this.queryParams).then(response => {
+        this.list = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getCnAreaTree () {
+      cnAreaTree().then(res => {
+        this.areaTrea = res.data?.children
+      })
+    },
+    // 省市区选择
+    handleChange (value) {
+      this.queryParams.provinces = value;
+      this.queryParams.provinceCode = value[0];
+      this.queryParams.provinceName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[0];
+      this.queryParams.cityCode = value[1];
+      this.queryParams.cityName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[1];
+      this.queryParams.areaCode = value[2];
+      this.queryParams.areaName = this.$refs['refSubCat'].getCheckedNodes()[0].pathLabels[2];
+    },
+    handleAdd () {
+      this.$router.push({
+        path: '/service/details',
+      })
+    },
+    goCouponCodeDatabase (row) {
+      if (row.codeType == 1) {
+        this.$router.push({
+          path: '/goods/couponCodeDatabase',
+          query: {
+            productId: row.businessProductId,
+            title: row.title,
+            queryParams: JSON.stringify(this.queryParams)
+          }
+        })
+      }
+    },
+    handleUpdate (row, type) {
+      this.$router.push({
+        path: '/service/details',
+        query: {
+          id: row.id,
+          type: type || 'edit',
+          queryParams: JSON.stringify(this.queryParams)
+        }
+      })
+    },
+    /** 搜索按钮操作 */
+    handleQuery () {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery () {
+      this.daterangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange (selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 删除按钮操作 */
+    handleDelete (row) {
+      const ids = row.id;
+      this.$modal.confirm('是否确认删除服务名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return serviceProductDel(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+  }
+}
+</script>
+
+<style lang='scss' scoped>
+.active {
+  color: #1890ff;
+  cursor: pointer;
+}
+</style>

+ 281 - 0
src/views/service/type.vue

@@ -0,0 +1,281 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="分类名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入分类名称" clearable size="small" @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="daterangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small" style="width: 240px">
+          <el-option label="上架" :value="true" />
+          <el-option label="下架" :value="false" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
+      <el-table-column type="index" width="55" label="序号" align="center">
+        <template slot-scope="scope">
+          <div>
+            {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="分类名称" align="center" prop="name" />
+      <el-table-column label="分类排序" align="center" prop="sort" />
+      <el-table-column label="上架状态" align="center" prop="status">
+        <template slot-scope="{row}">
+          <el-tag type="success" v-if="row.status">上架</el-tag>
+          <el-tag type="danger" v-if="!row.status">下架</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime,'{y}-{m}-{d} {h}:{i}')}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
+          <el-button size="mini" type="text" @click="setStatus(scope.row)">{{scope.row.status?'下架':'上架'}}</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" v-if="!scope.row.status" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+
+    <!-- 添加或修改测试单表对话框 -->
+    <el-drawer :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="分类名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入分类名称" />
+        </el-form-item>
+        <el-form-item label="分类排序" prop="sort">
+          <el-input-number v-model="form.sort" :min="1" label="排序" :precision="0"></el-input-number>
+        </el-form-item>
+        <el-form-item label="上架状态" prop="status">
+          <el-select v-model="form.status" placeholder="请选择上架状态" clearable style="width: 100%">
+            <el-option label="上架" :value="true" />
+            <el-option label="下架" :value="false" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div class="demo-drawer__footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-drawer>
+    <!-- 用户导入对话框 -->
+  </div>
+</template>
+
+<script>
+import { serviceCategorizePage, serviceCategorizeAdd, serviceCategorizeInfo, serviceCategorizeEdit, serviceCategorizeSetStatus, serviceCategorizeDel } from "@/api/service.js";
+
+export default {
+  dicts: ['quick_link_location'],
+  components: {
+  },
+  data () {
+    return {
+      //按钮loading
+      buttonLoading: false,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 测试单表表格数据
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 创建时间时间范围
+      daterangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: undefined,
+        status: undefined,
+      },
+      // 表单参数
+      form: {
+        name: undefined,
+        status: undefined,
+        sort: 1
+      },
+      // 表单校验
+      rules: {
+        name: [
+          { required: true, message: "请输入分类名称", trigger: "blur" }
+        ],
+        status: [
+          { required: true, message: "请选择状态", trigger: "blur" }
+        ],
+        sort: [{ required: true, message: "请输入排序", trigger: "change" }],
+      },
+    };
+  },
+  created () {
+    this.getList();
+  },
+  methods: {
+    /** 查询测试单表列表 */
+    getList () {
+      this.loading = true;
+      this.queryParams["startTime"] = undefined;
+      this.queryParams["endTime"] = undefined;
+      if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
+        this.queryParams["startTime"] = this.daterangeCreateTime[0];
+        this.queryParams["endTime"] = this.daterangeCreateTime[1];
+      }
+      serviceCategorizePage(this.queryParams).then(response => {
+        this.list = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel () {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset () {
+      this.form = {
+        name: undefined,
+        status: undefined,
+        sort: 1
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery () {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery () {
+      this.daterangeCreateTime = [];
+      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();
+      this.open = true;
+      this.title = "添加分类";
+    },
+    /** 修改按钮操作 */
+    handleUpdate (row) {
+      this.loading = true;
+      this.reset();
+      const id = row.id || this.ids
+      serviceCategorizeInfo(id).then(response => {
+        this.loading = false;
+        this.form = response.data;
+        this.form.createTime = undefined;
+        this.form.updateTime = undefined;
+        this.open = true;
+        this.title = "修改分类";
+      });
+    },
+    /** 提交按钮 */
+    submitForm () {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.buttonLoading = true;
+          if (this.form.id != null) {
+            serviceCategorizeEdit(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          } else {
+            serviceCategorizeAdd(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            }).finally(() => {
+              this.buttonLoading = false;
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete (row) {
+      const ids = row.id;
+      this.$modal.confirm('是否确认删除名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return serviceCategorizeDel(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+    /** 上下架按钮操作 */
+    setStatus (row) {
+      const ids = row.id;
+      let statusText = row.status ? '下架' : '上架';
+      this.$modal.confirm('是否确认' + statusText + '名称为"' + row.name + '"的数据项?').then(() => {
+        this.loading = true;
+        return serviceCategorizeSetStatus(ids);
+      }).then(() => {
+        this.loading = false;
+        this.getList();
+        this.$modal.msgSuccess(statusText + "成功");
+      }).finally(() => {
+        this.loading = false;
+      });
+    },
+  }
+};
+</script>
+<style lang="scss">
+.el-drawer__body {
+  padding: 0 20px !important;
+}
+</style>
+<style lang="scss" scoped>
+.flex {
+  display: flex;
+}
+.demo-drawer__footer {
+  margin-left: 120px;
+}
+</style>

+ 7 - 10
src/views/user/details.vue

@@ -7,11 +7,11 @@
         <div>{{details.mobile}}</div>
       </div>
     </div>
-    <div class="numBox">
+    <!-- <div class="numBox">
       <div>兑换豆 :{{details.integralAble||0}}</div>
       <div>红包数 :{{details.redEnvelopeTotal||0}}</div>
       <div>PK数 :{{details.gamesSum||0}}</div>
-    </div>
+    </div> -->
 
     <div class="tabsBox">
       <el-tabs v-model="activeName" @tab-click="handleQuery()">
@@ -20,12 +20,12 @@
             <div>用户ID:{{details.id}}</div>
             <div>用户昵称:{{details.nickname}}</div>
             <div>手机号:{{details.mobile}}</div><br />
-            <div>注册时间:{{ parseTime(details.createDay, '{y}-{m}-{d} {h}:{i}') }}</div>
+            <div>注册时间:{{ parseTime(details.createTime, '{y}-{m}-{d} {h}:{i}') }}</div>
             <div>上次登录时间:{{parseTime(details.lastLoginTime, '{y}-{m}-{d} {h}:{i}')}}</div>
-            <div>邀请人:<span v-if="details.managerUser">{{details.managerUser.mobile}}({{details.managerUser.nickname}})</span> </div>
+            <!-- <div>邀请人:<span v-if="details.managerUser">{{details.managerUser.mobile}}({{details.managerUser.nickname}})</span> </div> -->
           </div>
         </el-tab-pane>
-        <el-tab-pane label="兑换豆明细" name="1">
+        <!-- <el-tab-pane label="兑换豆明细" name="1">
           <el-table :data="list" stripe v-loading="loading">
             <el-table-column prop="date" label="序号" width="80">
               <template slot-scope="scope">
@@ -82,8 +82,6 @@
                 </div>
               </template>
             </el-table-column>
-            <!-- <el-table-column prop="address" label="累计消费金额">
-            </el-table-column> -->
             <el-table-column prop="relatedOrderNo" label="关联订单号" align="center">
             </el-table-column>
             <el-table-column prop="amount" label="红包金额" align="center">
@@ -117,8 +115,6 @@
                 </div>
               </template>
             </el-table-column>
-            <!-- <el-table-column prop="" label="累计消费金额">
-            </el-table-column> -->
             <el-table-column prop="relatedOrderNo" label="关联订单号" align="center">
               <template slot-scope="scope">
                 <span>{{ scope.row.relatedOrderNo||'--' }}</span>
@@ -143,7 +139,7 @@
             </el-table-column>
           </el-table>
           <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
-        </el-tab-pane>
+        </el-tab-pane> -->
       </el-tabs>
     </div>
     <div class="form-footer">
@@ -241,6 +237,7 @@ export default {
     display: flex;
     font-size: 14px;
     font-weight: 700;
+    min-height: 100px;
     .head_r {
       margin-left: 20px;
       display: flex;

+ 1 - 3
src/views/user/index.vue

@@ -39,9 +39,7 @@
       </el-table-column>
       <el-table-column label="昵称" align="center" prop="nickname" />
       <el-table-column label="手机号" prop="mobile" align="center" />
-      <el-table-column label="兑换豆数" prop="integralAble" align="center" />
-      <el-table-column label="红包金额" align="center" prop="redEnvelopeTotal" />
-      <el-table-column label="PK数" align="center" prop="gamesSum" />
+      <el-table-column label="订单数" prop="orderNum" align="center" />
       <el-table-column label="注册时间" align="center" prop="createDay" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>