Browse Source

供应商端接口调试完成

喻文俊 3 years ago
parent
commit
623ed46494

+ 10 - 10
.env.development

@@ -4,26 +4,26 @@ NODE_ENV = development
 ENV = 'development'
 
 # 测试地址 API接口
-VUE_APP_BASE_API = 'https://zplma-b.caimei365.com'
-# VUE_APP_BASE_API = 'http://192.168.2.68:8012'
+# VUE_APP_BASE_API = 'https://zplma-b.caimei365.com'
+VUE_APP_BASE_API = 'http://192.168.2.68:8012'
 
 # 文件上传 API接口地址
-VUE_APP_UPLOAD_API='https://zplma-b.caimei365.com'
-# VUE_APP_UPLOAD_API='http://192.168.2.68:8012'
+# VUE_APP_UPLOAD_API='https://zplma-b.caimei365.com'
+VUE_APP_UPLOAD_API='http://192.168.2.68:8012'
 
 # 二维码生成链接location
 VUE_APP_BASE_SERVER = 'https://www-b.caimei365.com'
 
 # 消息接口地址 WebSocket
-# VUE_APP_SOCKET_SERVER = 'wss://zplma-b.caimei365.com/websocket?sessionSource=zplm_admin'
-VUE_APP_SOCKET_SERVER = 'ws://192.168.2.68:8012/websocket?sessionSource=zplm_admin'
+VUE_APP_SOCKET_SERVER = 'wss://zplma-b.caimei365.com/websocket?sessionSource=zplm_admin'
+# VUE_APP_SOCKET_SERVER = 'ws://192.168.2.68:8012/websocket?sessionSource=zplm_admin'
 
 # 网站地址
-# VUE_APP_LOCAL = 'http://192.168.2.81:9527'
-VUE_APP_LOCAL = 'http://zplm-b.caimei365.com'
+VUE_APP_LOCAL = 'http://192.168.2.81:9527'
+# VUE_APP_LOCAL = 'http://zplm-b.caimei365.com'
 
 
 # 支付
-# VUE_APP_PAY_LOCAL = 'http://192.168.2.68:18014'
-VUE_APP_PAY_LOCAL = 'http://zplm-b.caimei365.com
+VUE_APP_PAY_LOCAL = 'http://192.168.2.68:18014'
+# VUE_APP_PAY_LOCAL = 'http://zplm-b.caimei365.com
 

+ 46 - 28
src/api/auth.js

@@ -73,74 +73,92 @@ export function auditAuth(data) {
   })
 }
 
-// 机构用户列表
-export function getAuthUserList(params) {
+// 获取用户反馈信息列表
+export function getFeedbackList(params) {
   return request({
-    url: '/club/user/list',
+    url: '/shop/feedback/list',
     method: 'get',
     params
   })
 }
 
-// 机构生成邀请码
-export function makeGenerate(data) {
+// 获取反馈信息
+export function getFeedbackDetail(params) {
   return request({
-    url: '/club/user/code/generate',
+    url: '/shop/feedback/form/data',
+    method: 'get',
+    params
+  })
+}
+
+// 处理反馈信息
+export function handleFeedback(data) {
+  return request({
+    url: '/shop/feedback/handle',
     method: 'post',
     data
   })
 }
 
-// 更新邀请码
-export function updateGenerate(data) {
+// 一键下载授权牌 / 二维
+export function exportAd(params) {
   return request({
-    url: '/club/user/code/update',
+    url: '/download/shop/image',
+    method: 'get',
+    params
+  })
+}
+
+// 添加机构用户
+export function createClubUser(data) {
+  return request({
+    url: '/club/user/save',
     method: 'post',
     data
   })
 }
 
-// 解绑邀请码
-export function unbindGenerate(data) {
+// 删除机构用户
+export function removeClubUser(data) {
   return request({
-    url: '/club/user/code/unbind',
+    url: '/club/user/delete',
     method: 'post',
     data
   })
 }
 
-// 获取用户反馈信息列表
-export function getFeedbackList(params) {
+// 机构用户列表
+export function getAuthUserList(params) {
   return request({
-    url: '/shop/feedback/list',
+    url: '/club/user/list',
     method: 'get',
     params
   })
 }
 
-// 获取反馈信息
-export function getFeedbackDetail(params) {
+// 机构生成邀请码
+export function makeGenerate(data) {
   return request({
-    url: '/shop/feedback/form/data',
-    method: 'get',
-    params
+    url: '/club/user/code/generate',
+    method: 'post',
+    data
   })
 }
 
-// 处理反馈信息
-export function handleFeedback(data) {
+// 更新邀请码
+export function updateGenerate(data) {
   return request({
-    url: '/shop/feedback/handle',
+    url: '/club/user/code/update',
     method: 'post',
     data
   })
 }
 
-// 一键下载授权牌 / 二维
-export function exportAd(params) {
+// 解绑邀请
+export function unbindGenerate(data) {
   return request({
-    url: '/download/shop/image',
-    method: 'get',
-    params
+    url: '/club/user/code/unbind',
+    method: 'post',
+    data
   })
 }

+ 9 - 0
src/api/doctor.js

@@ -53,3 +53,12 @@ export function doctorAudit(data) {
     data
   })
 }
+
+// 医师机构列表
+export function fetchDoctorClubList(params) {
+  return request({
+    url: '/auth/select',
+    method: 'get',
+    params
+  })
+}

+ 45 - 0
src/api/product.js

@@ -53,3 +53,48 @@ export function auditProduct(data) {
     data
   })
 }
+
+// 添加设备分类
+export function createProductCate(data) {
+  return request({
+    url: '/auth/product/type/save',
+    method: 'post',
+    data
+  })
+}
+
+// 获取设备分类列表
+export function fetchProductCateList(params) {
+  return request({
+    url: '/auth/product/type/list',
+    method: 'get',
+    params
+  })
+}
+
+// 删除设备分类
+export function removeProductCate(data) {
+  return request({
+    url: '/auth/product/type/delete',
+    method: 'post',
+    data
+  })
+}
+
+// 修改设备分类状态
+export function updateProductCateStatus(data) {
+  return request({
+    url: '/auth/product/type/update/status',
+    method: 'post',
+    data
+  })
+}
+
+// 设备选择列表
+export function fetchProductSelectList(params) {
+  return request({
+    url: '/auth/product/type/select',
+    method: 'get',
+    params
+  })
+}

+ 1 - 1
src/styles/index.scss

@@ -24,7 +24,7 @@ html {
 }
 
 #app {
-  height: 100%;
+  min-height: 100vh;
 }
 
 *,

+ 1 - 1
src/views/admin/audit/club/device/index.vue

@@ -74,7 +74,7 @@
             type="primary"
             icon="el-icon-s-check"
             size="mini"
-            @click="$_navigationTo(`club-device-detail?id=${row.productId}&authId=${listQuery.authId}`)"
+            @click="$_navigationTo(`/audit/club/device-detail?id=${row.productId}&authId=${listQuery.authId}`)"
           >审核</el-button>
           <span v-else class="status success el-icon-check">&nbsp;已审核</span>
         </template>

+ 1 - 1
src/views/admin/audit/club/index.vue

@@ -69,7 +69,7 @@
               type="primary"
               icon="el-icon-s-check"
               size="mini"
-              @click="$_navigationTo(`club-list?authUserId=${row.authUserId}`)"
+              @click="$_navigationTo(`/audit/club/club-list?authUserId=${row.authUserId}`)"
             >机构认证审核</el-button>
           </el-badge>
         </template>

+ 2 - 2
src/views/admin/audit/club/list.vue

@@ -87,14 +87,14 @@
             size="mini"
             style="margin-right:5px"
             icon="el-icon-s-check"
-            @click="$_navigationTo(`club-detail?authId=${row.authId}`)"
+            @click="$_navigationTo(`/audit/club/club-detail?authId=${row.authId}`)"
           >审核</el-button>
           <el-badge :hidden="row.lowerAuditStatus === 1" :value="row.waitAuditNum" :max="99">
             <el-button
               icon="el-icon-s-shop"
               type="primary"
               size="mini"
-              @click="$_navigationTo(`club-device-list?authId=${row.authId}`)"
+              @click="$_navigationTo(`/audit/club/device/list?authId=${row.authId}`)"
             >设备认证审核</el-button>
           </el-badge>
         </template>

+ 1 - 1
src/views/common/login/index.vue

@@ -180,7 +180,7 @@ $dark_gray: #889aa4;
 $light_gray: #eee;
 
 .login-container {
-  min-height: 100%;
+  min-height: 100vh;
   width: 100%;
   background-color: $bg;
   overflow: hidden;

+ 1 - 0
src/views/components/CustomItems/index.vue

@@ -11,6 +11,7 @@
 <script>
 export default {
   name: 'CustomItems',
+
   data() {
     return {
       formData: {

+ 7 - 0
src/views/components/DoctorCustomItems/index.vue

@@ -50,6 +50,13 @@ export default {
         content: ''
       })
     },
+    setParamsItem(dataArray) {
+      if (dataArray.length === 0) return
+      this.formDataList = dataArray.map((item, index) => {
+        this.uuid = index + 1
+        return { ...item, uuid: this.uuid }
+      })
+    },
     // 删除一条
     removeOne(formData) {
       const uuid = formData.uuid

+ 164 - 25
src/views/normal/club/device-cate.vue

@@ -2,8 +2,8 @@
   <div class="app-container">
     <div class="filter-container">
       <div class="filter-control">
-        <span>设备管理:</span>
-        <el-input v-model="listQuery.productName" placeholder="设备管理" @keyup.enter.native="handleFilter" />
+        <span>设备名称:</span>
+        <el-input v-model="listQuery.name" placeholder="设备名称" @keyup.enter.native="handleFilter" />
       </div>
       <div class="filter-control">
         <span>审核状态:</span>
@@ -43,7 +43,7 @@
       header-row-class-name="tableHeader"
     >
       <el-table-column label="序号" :index="indexMethod" type="index" align="center" width="80" />
-      <el-table-column label="设备管理" align="center" prop="productName" />
+      <el-table-column label="设备名称" align="center" prop="name" />
 
       <el-table-column label="审核状态" width="220px" align="center">
         <template slot-scope="{ row }">
@@ -87,17 +87,18 @@
           <span>{{ row.createTime | formatTime }}</span>
         </template>
       </el-table-column>
+      <el-table-column label="创建人" align="center" prop="createBy" width="160" />
       <!-- <el-table-column v-if="false" label="创建人" width="180px" align="center" prop="createBy" /> -->
       <el-table-column label="操作" align="center" width="240px" class-name="small-padding fixed-width">
         <template slot-scope="{ row }">
           <permission-button
-            type="default"
+            type="primary"
             size="mini"
-            @click="handleEdit"
+            @click="handleEdit(row)"
           >
             编辑
           </permission-button>
-          <permission-button type="danger" size="mini" @click="handleRemoveProduct(row)">
+          <permission-button type="danger" size="mini" @click="handleRemove(row)">
             删除
           </permission-button>
         </template>
@@ -112,17 +113,56 @@
       :limit.sync="listQuery.pageSize"
       @pagination="getList"
     />
+
+    <!-- 设备添加对话框 -->
+    <el-dialog
+      title="添加设备"
+      :visible.sync="dialogVisible"
+      width="30%"
+      @close="onDialogClose"
+    >
+      <el-form ref="form" :model="formData" :rules="rules" label-width="100px">
+        <el-form-item prop="name" label="设备名称:">
+          <el-input v-model="formData.name" placeholder="请输入设备名称" />
+        </el-form-item>
+        <el-form-item prop="image" label="设备图片:" class="pd-10">
+          <el-input v-show="false" v-model="formData.image" />
+          <upload-image
+            tip="建议尺寸:542px * 542px"
+            :image-list="productImageList"
+            :before-upload="beforeUploadImage"
+            @success="onUploadImageSuccess"
+            @remove="onUploadImageRemove"
+          />
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="onSave">保 存</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import PermissionButton from '@/views/components/PermissionButton'
 import Pagination from '@/components/Pagination' // secondary package based on el-pagination
+import UploadImage from '@/components/UploadImage'
 import { formatDate } from '@/utils'
 import { mapGetters } from 'vuex'
+import { createProductCate, fetchProductCateList, removeProductCate, updateProductCateStatus } from '@/api/product'
+
+const resetFormData = () => ({
+  productTypeId: '',
+  authUserId: '',
+  name: '',
+  image: '',
+  createBy: ''
+})
+
 export default {
   name: 'ComplexTable',
-  components: { Pagination, PermissionButton },
+  components: { Pagination, PermissionButton, UploadImage },
   filters: {
     formatTime(time) {
       if (!time) {
@@ -134,29 +174,32 @@ export default {
 
   data() {
     return {
-      authParty: '',
       tableKey: 0,
       list: null,
       total: 0,
       listLoading: true,
+      dialogVisible: false,
       listQuery: {
-        status: '',
+        authUserId: '',
         auditStatus: '',
-        authId: '',
-        productName: '',
-        snCode: '',
+        listType: 1,
+        name: '',
         pageNum: 1,
-        pageSize: 10
+        pageSize: 10,
+        status: ''
       },
-      showQRcode: false,
       productInfo: {},
-      // 审核未通过
-      auditFailedList: [],
-      auditNoticeFlag: true
+      // 添加分类表单
+      formData: resetFormData(),
+      rules: {
+        name: [{ required: true, message: '请输入设备名称', trigger: ['blur'] }],
+        image: [{ required: true, message: '请上传设备图片', trigger: ['change'] }]
+      },
+      productImageList: []
     }
   },
   computed: {
-    ...mapGetters(['userIdentity'])
+    ...mapGetters(['userIdentity', 'authUserId'])
   },
   created() {
     this.getList()
@@ -166,22 +209,109 @@ export default {
     // 获取列表信息
     getList() {
       this.listLoading = false
+      this.fetchProductList()
     },
     // 过滤列表
     handleFilter() {
-
+      this.formData.pageNum = 1
+      this.fetchProductList()
     },
     // 改变启用状态
-    handleChangeStatus(item) {
-
+    async handleChangeStatus(row) {
+      row.status = row.status ? 0 : 1
+      try {
+        await updateProductCateStatus({
+          productTypeId: row.productTypeId,
+          status: row.status
+        })
+        this.$message.success('修改设备状态成功')
+        this.fetchProductList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 获取设备分类列表
+    async fetchProductList() {
+      this.listQuery.authUserId = this.authUserId
+      try {
+        const res = await fetchProductCateList(this.listQuery)
+        this.total = res.data.total
+        this.list = res.data.list
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 保存
+    async onSave() {
+      try {
+        await this.$refs.form.validate()
+      } catch (error) {
+        console.log(error)
+      }
+      this.formData.authUserId = this.authUserId
+      this.formData.createBy = this.authUserId
+      try {
+        await createProductCate(this.formData)
+        this.$message.success('保存设备分类成功')
+        this.dialogVisible = false
+        this.fetchProductList()
+      } catch (error) {
+        console.log(error)
+      }
     },
     // 添加分类
     handleAdd() {
-
+      this.dialogVisible = true
     },
-    // 添加分类
-    handleEdit() {
+    // 编辑分类
+    handleEdit(row) {
+      this.formData.productTypeId = row.productTypeId
+      this.formData.name = row.name
+      this.formData.image = row.image
+      this.formData.createBy = row.createBy
+      this.productImageList.push({ url: row.image, name: row.name })
+      this.dialogVisible = true
+    },
+    // 删除
+    async handleRemove(row) {
+      let confirmType = ''
+      try {
+        confirmType = await this.$confirm('确认删除改商品分类吗?该操作不可逆!', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+      } catch (error) {
+        console.log(error)
+      }
+
+      if (confirmType !== 'confirm') return
 
+      try {
+        await removeProductCate({
+          productTypeId: row.productTypeId
+        })
+        this.$message.success('删除设备分类成功')
+        this.fetchProductList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    onDialogClose() {
+      this.$refs.form.resetFields()
+      this.formData = resetFormData()
+      this.productImageList = []
+    },
+    beforeUploadImage(file) {
+      return true
+    },
+    onUploadImageSuccess({ response, file, fileList }) {
+      this.formData.image = response.data
+      this.productImageList = fileList
+    },
+    onUploadImageRemove({ file, fileList }) {
+      this.formData.image = ''
+      this.productImageList = []
     },
     // 表格索引
     indexMethod(index) {
@@ -192,5 +322,14 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-
+.app-container{
+  ::v-deep{
+    .el-dialog__body{
+      padding-bottom: 0;
+    }
+  }
+  .pd-10{
+    padding-top: 10px;
+  }
+}
 </style>

+ 50 - 17
src/views/normal/club/device/edit.vue

@@ -1,9 +1,22 @@
 <template>
   <div v-loading="isLoading" class="addProduct">
     <el-form ref="addFormRef" label-width="130px" class="addForm" :model="formData" :rules="rules">
+      <!--
       <el-form-item label="设备名称:" prop="productName">
         <el-input v-model="formData.productName" placeholder="建议输入30个字符效果最佳" show-word-limit maxlength="50" />
       </el-form-item>
+      -->
+
+      <el-form-item label="设备名称:" prop="productTypeId">
+        <el-select v-model="formData.productTypeId" filterable placeholder="选择设备" style="width:100%" @change="onProductTypeIdChange">
+          <el-option
+            v-for="item in deviceList"
+            :key="item.productTypeId"
+            :label="item.name"
+            :value="item.productTypeId"
+          />
+        </el-select>
+      </el-form-item>
 
       <el-form-item label="设备SN码:" prop="snCode">
         <el-input v-model="formData.snCode" placeholder="请输入设备SN码" />
@@ -19,7 +32,7 @@
           <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
       </el-form-item>
-
+      <!-- 暂时移除
       <el-form-item label="设备图片:" prop="productImage">
         <upload-image
           tip="建议尺寸:542px * 542px"
@@ -30,6 +43,7 @@
         />
         <el-input v-model="formData.productImage" class="hiddenInput" />
       </el-form-item>
+       -->
       <el-form-item label="授权牌:" prop="certificateImage">
         <upload-image
           tip="建议尺寸:150px * 112px"
@@ -70,7 +84,7 @@
 
 <script>
 import UploadImage from '@/components/UploadImage'
-import { saveProduct, getProductById } from '@/api/product'
+import { saveProduct, getProductById, fetchProductSelectList } from '@/api/product'
 import { fetchBrandList } from '@/api/brand'
 import { mapGetters } from 'vuex'
 import { isSnCode } from '@/utils/validate'
@@ -96,6 +110,7 @@ export default {
       editType: 'add',
       paramsCount: 4,
       brandList: [],
+      deviceList: [], // 设备列表
       formData: {
         authUserId: '',
         authId: '', //	授权id
@@ -105,24 +120,26 @@ export default {
         paramList: [],
         productId: '', //	授权设备id
         productImage: '', //	设备图片
-        productName: '', //	设备名称
+        // productName: '', //	设备名称
         snCode: '', //	设备SN码
         status: 2, //	上架状态:0下线,1上线 2待审核
         brandId: '',
         addQrCodeFlag: 0,
-        addTemplateType: 1
+        addTemplateType: 1,
+        productTypeId: ''
       },
       paramList: [], // 参数列表
       rules: {
         certificateImage: [{ required: true, message: '授权牌照不能为空' }],
         paramList: [{ required: true, message: '参数不能为空' }],
-        productImage: [{ required: true, message: '设备图片不能为空' }],
+        // productImage: [{ required: true, message: '设备图片不能为空' }], 暂时移除
         snCode: [{ required: true, message: 'SN码不能为空' }, { validator: valideSNcode }],
-        productName: [
-          { required: true, message: '设备名称不能为空' },
-          { max: 50, message: '字数在50字符以内' }
-        ],
-        brandId: [{ required: true, validator: valideBrandId, tigger: 'change' }]
+        // productName: [
+        //   { required: true, message: '设备名称不能为空' },
+        //   { max: 50, message: '字数在50字符以内' }
+        // ],
+        productTypeId: [{ required: true, message: '设备名称不能为空', trigger: 'change' }],
+        brandId: [{ required: true, validator: valideBrandId, trigger: 'change' }]
       },
       // 参数框的提示语
       tipList: ['例如:品牌', '例如:尺寸', '例如:功率', '例如:重量'],
@@ -159,8 +176,14 @@ export default {
     if (this.shopType === 1) {
       this.formData.brandId = this.proxyInfo?.brandId || this.brandId || ''
     }
+    this.fetchDeviceList()
   },
   methods: {
+    // 设备分类修改
+    onProductTypeIdChange(value) {
+      const deviceInfo = this.deviceList.find(item => item.productTypeId === value)
+      this.formData.productImage = deviceInfo.image
+    },
     // 初始化表单数据
     initFormData() {
       if (this.editType !== 'edit') {
@@ -170,7 +193,6 @@ export default {
       this.isLoading = true
       getProductById({ productId: this.formData.productId }).then(res => {
         console.log(res)
-        // const { authId, certificateImage, paramList, productId, productImage, productName, snCode, status } = res.data
         for (const key in res.data) {
           if (Object.hasOwnProperty.call(res.data, key)) {
             if (key !== 'paramList') {
@@ -215,11 +237,11 @@ export default {
     // 初始化上传图片列表
     initImageList() {
       setTimeout(() => {
-        const productImage = this.formData.productImage
+        // const productImage = this.formData.productImage // 暂时移除
         const certificateImage = this.formData.certificateImage
-        if (productImage) {
-          this.productImageList.push({ name: 'productImage', url: productImage })
-        }
+        // if (productImage) { // 暂时移除
+        //   this.productImageList.push({ name: 'productImage', url: productImage })
+        // }
         if (certificateImage) {
           this.certificateImageList.push({ name: 'certificateImage', url: certificateImage })
         }
@@ -276,11 +298,22 @@ export default {
     getBrandList() {
       fetchBrandList({ type: 3, authUserId: this.formData.authUserId }).then(res => {
         console.log(res)
-
         this.brandList = res.data
       })
     },
 
+    // 获取设备列表
+    async fetchDeviceList() {
+      try {
+        const res = await fetchProductSelectList({
+          authUserId: this.authUserId
+        })
+        this.deviceList = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
     // 添加一栏参数
     handleAddParam() {
       this.paramsCount += 1
@@ -359,7 +392,7 @@ export default {
   }
 }
 .addForm {
-  width: 800px;
+  width: 640px;
   margin: 0 auto;
   margin-top: 80px;
 }

+ 72 - 58
src/views/normal/club/edit.vue

@@ -4,6 +4,7 @@
       <el-form-item label="机构名称:" prop="name">
         <el-input v-model="formData.name" placeholder="请输入机构名称" clearable />
       </el-form-item>
+
       <el-form-item label="所在地区:" prop="address">
         <el-cascader
           ref="cascader"
@@ -20,7 +21,11 @@
         <el-input v-model="formData.fullAddress" placeholder="请输入详细地址" clearable />
       </el-form-item>
       <el-form-item label="经纬度:" prop="point">
-        <el-input v-model="formData.point" placeholder="请输入经纬度 (格式:纬度,经度,可通过右侧地图小按钮获取)" clearable>
+        <el-input
+          v-model="formData.point"
+          placeholder="请输入经纬度 (格式:纬度,经度,可通过右侧地图小按钮获取)"
+          clearable
+        >
           <el-button slot="append" icon="el-icon-map-location" @click="dialogMapVisible = true" />
         </el-input>
       </el-form-item>
@@ -48,21 +53,28 @@
           @remove="handleBannerRemove"
         />
       </el-form-item>
+
       <el-form-item label="自定义属性:">
-        <el-radio-group v-model="formData.customize" size="mini">
+        <el-radio-group v-model="formData.customFlag" size="mini">
           <el-radio :label="0" border>否</el-radio>
           <el-radio :label="1" border>是</el-radio>
         </el-radio-group>
-        <div v-show="formData.customize" class="attributes">
-          <custom-items ref="customizeForm" @change="custromizeFormChange" />
-        </div>
       </el-form-item>
+
+      <template v-if="formData.customFlag === 1">
+        <el-form-item label="店铺备注:" prop="remarks">
+          <el-input v-model="formData.remarks" placeholder="店铺备注" clearable />
+        </el-form-item>
+      </template>
     </el-form>
+
+    <!-- 表单提交 返回 -->
     <div class="submit-btn">
       <el-button type="primary" @click="submit">保存</el-button>
       <el-button type="warning" @click="$_back()">返回</el-button>
     </div>
 
+    <!-- 地图坐标拾取 -->
     <el-dialog
       class="map-dialog"
       title="坐标拾取(请拖动标记点选取准确位置)"
@@ -82,7 +94,6 @@
 // import Location from '@/components/location'
 import AMapUI from '@/components/AMapUI'
 import UploadImage from '@/components/UploadImage'
-import CustomItems from '@/views/components/CustomItems'
 import { mapGetters } from 'vuex'
 import { saveBrandAuth, getAuthFormData } from '@/api/auth'
 import { getAddress } from '@/api/common'
@@ -92,8 +103,7 @@ export default {
   components: {
     // Location
     [AMapUI.name]: AMapUI,
-    UploadImage,
-    CustomItems
+    UploadImage
   },
   data() {
     var validatePoint = (rule, value, callback) => {
@@ -139,8 +149,8 @@ export default {
         mobile: '',
         logoImage: '',
         banner: '',
-        customize: 0,
-        customValue: ''
+        customFlag: 0,
+        remarks: ''
       },
       rules: {
         name: [{ required: true, message: '机构名称不能为空', trigger: ['blur', 'change'] }],
@@ -149,7 +159,8 @@ export default {
         point: [{ required: true, validator: validatePoint, trigger: ['blur', 'change'] }],
         mobile: [{ required: true, validator: validateMobile, trigger: ['blur', 'change'] }],
         logoImage: [{ required: true, message: '请上传机构logo', trigger: 'change' }],
-        banner: [{ required: true, message: '请至少上传一张banner图片', trigger: 'change' }]
+        banner: [{ required: true, message: '请至少上传一张banner图片', trigger: 'change' }],
+        remarks: [{ required: true, message: '店铺备注不能为空', trigger: 'blur' }]
       },
       // logo图片列表
       logoList: [],
@@ -168,7 +179,7 @@ export default {
         lazyLoad: async(node, resolve) => {
           const { level, value = 0 } = node
           const result = await getAddress({ parentId: value, type: level })
-          const nodes = result.data.map(item => ({ value: item.id, label: item.name, leaf: level >= 2 }))
+          const nodes = result.data.map((item) => ({ value: item.id, label: item.name, leaf: level >= 2 }))
           resolve(nodes)
         }
       }
@@ -211,7 +222,7 @@ export default {
     // 数据回显
     initFormData() {
       if (!this.authId) return
-      getAuthFormData({ authId: this.authId }).then(res => {
+      getAuthFormData({ authId: this.authId }).then((res) => {
         console.log(res)
         this.formData.name = res.data.authParty
 
@@ -221,8 +232,11 @@ export default {
         this.formData.logoImage = res.data.logo
         this.formData.banner = res.data.bannerList.length || ''
 
+        this.formData.customFlag = res.data.customFlag
+        this.formData.remarks = res.data.remarks
+
         this.logoList = [{ name: '', url: res.data.logo }]
-        this.bannerList = res.data.bannerList.map(item => ({ name: '', url: item }))
+        this.bannerList = res.data.bannerList.map((item) => ({ name: '', url: item }))
 
         this.formData.address = [res.data.provinceId, res.data.cityId, res.data.townId]
         // this.formData.address = '广东省/深圳市/福田区'
@@ -233,55 +247,55 @@ export default {
 
     // 表单提交保存
     submit() {
-      this.$refs.customizeForm.validate(valide => {
-        if (!valide && this.formData.customize) return
-
-        this.$refs.submitForm.validate(valide => {
-          if (!valide) return
+      this.$refs.submitForm.validate((valide) => {
+        if (!valide) return
 
-          console.log(this.formData)
-          const {
-            name: authParty,
-            address: [provinceId, cityId, townId],
-            mobile,
-            logoImage: logo,
-            point: lngAndLat
-          } = this.formData
+        console.log(this.formData)
+        const {
+          name: authParty,
+          address: [provinceId, cityId, townId],
+          mobile,
+          logoImage: logo,
+          point: lngAndLat,
+          customFlag,
+          remarks
+        } = this.formData
 
-          const authUserId = this.proxyInfo?.authUserId || this.authUserId
+        const authUserId = this.proxyInfo?.authUserId || this.authUserId
 
-          const data = {
-            authId: parseInt(this.authId),
-            authParty,
-            authUserId,
-            createBy: authUserId,
-            provinceId,
-            cityId,
-            townId,
-            address: this.formData.fullAddress,
-            mobile,
-            logo,
-            lngAndLat
-          }
+        const data = {
+          authId: parseInt(this.authId),
+          authParty,
+          authUserId,
+          createBy: authUserId,
+          provinceId,
+          cityId,
+          townId,
+          address: this.formData.fullAddress,
+          mobile,
+          logo,
+          lngAndLat,
+          remarks,
+          customFlag
+        }
 
-          data.bannerList = this.bannerList.map(item => (item.response ? item.response.data : item.url))
+        data.bannerList = this.bannerList.map((item) => (item.response ? item.response.data : item.url))
 
-          saveBrandAuth(data)
-            .then(res => {
-              const h = this.$createElement
-              this.$notify.success({
-                title: `修改授权机构`,
-                message: h('i', { style: 'color: #333' }, `已修改授权机构:"${this.formData.name}"`),
-                duration: 3000
-              })
-              this.$refs.submitForm.resetFields()
-              this.$store.dispatch('tagsView/delView', this.$route)
-              this.$router.push('/club/list')
-            })
-            .catch(err => {
-              this.$message.danger(err.msg)
+        saveBrandAuth(data)
+          .then((res) => {
+            const h = this.$createElement
+            this.$notify.success({
+              title: `修改授权机构`,
+              message: h('i', { style: 'color: #333' }, `已修改授权机构:"${this.formData.name}"`),
+              duration: 3000
             })
-        })
+            this.$refs.submitForm.resetFields()
+            this.$store.dispatch('tagsView/delView', this.$route)
+            this.$router.push('/club/list')
+          })
+          .catch((err) => {
+            this.$message.danger(err.msg)
+          })
       })
     },
     handleChange(e) {
@@ -349,7 +363,7 @@ export default {
   }
 }
 
-.attributes{
+.attributes {
   padding-top: 16px;
 }
 </style>

+ 129 - 21
src/views/normal/club/user/index.vue

@@ -4,7 +4,7 @@
     <div class="filter-container">
       <div class="filter-control">
         <span>姓名:</span>
-        <el-input v-model="listQuery.mobile" placeholder="姓名" @keyup.enter.native="getList" />
+        <el-input v-model="listQuery.name" placeholder="姓名" @keyup.enter.native="getList" />
       </div>
       <div class="filter-control">
         <span>手机号:</span>
@@ -28,7 +28,7 @@
       header-row-class-name="tableHeader"
     >
       <el-table-column label="序号" :index="indexMethod" type="index" width="80px" align="center" />
-      <el-table-column label="姓名" prop="invitationCode" align="center" />
+      <el-table-column label="姓名" prop="name" align="center" />
       <el-table-column label="手机号" width="140" align="center">
         <template slot-scope="{row}">
           <span v-if="row.mobile">{{ row.mobile }}</span>
@@ -61,6 +61,27 @@
     </el-table>
     <!-- 表格区域END -->
     <pagination v-show="total>0" :total="total" :page.sync="listQuery.pageNum" :limit.sync="listQuery.pageSize" @pagination="getList(listQuery)" />
+
+    <el-dialog
+      title="添加用户"
+      width="30%"
+      :visible.sync="dialogVisible"
+      @close="onDialogClose"
+    >
+      <el-form ref="form" label-width="80px" :model="formData" :rules="rules">
+        <el-form-item label="姓名:" prop="name">
+          <el-input v-model="formData.name" placeholder="请输入姓名" />
+        </el-form-item>
+        <el-form-item label="手机号:" prop="mobile">
+          <el-input v-model="formData.mobile" placeholder="请输入手机号" maxlength="11" show-word-limit />
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="onSave">确 定</el-button>
+      </span>
+    </el-dialog>
+
   </div>
 </template>
 
@@ -69,7 +90,16 @@ import PermissionButton from '@/views/components/PermissionButton'
 import Pagination from '@/components/Pagination' // secondary package based on el-pagination
 import { formatDate } from '@/utils'
 import { mapGetters } from 'vuex'
-import { getAuthUserList } from '@/api/auth'
+import { createClubUser, getAuthUserList, removeClubUser } from '@/api/auth'
+import { isMobile } from '@/utils/validate'
+
+const resetFormData = () => ({
+  clubUserId: '',
+  authId: '',
+  name: '',
+  mobile: ''
+})
+
 export default {
   components: { Pagination, PermissionButton },
   filters: {
@@ -81,50 +111,120 @@ export default {
     }
   },
   data() {
+    const validateMobile = (value, rule, callback) => {
+      if (isMobile(value)) {
+        callback()
+      } else {
+        callback(new Error('手机号格式不正确'))
+      }
+    }
+
     return {
       total: 0,
       authId: '', // 机构id
       listLoading: false,
       listQuery: {
         authId: '', // 机构id
+        name: '', // 用户名
         mobile: '', // 手机号
-        status: '', // 邀请码状态
         pageNum: 0, // 页码
         pageSize: 10 // 分页大小
       },
       list: [],
-      srcList: []
+      srcList: [],
+      dialogVisible: false,
+      formData: resetFormData(),
+      rules: {
+        name: [{ required: true, message: '请输入用户姓名', trigger: ['blur'] }],
+        mobile: [
+          { required: true, message: '请输入手机号', trigger: ['blur'] },
+          { validator: validateMobile, message: '手机号格式不正确', trigger: ['blur'] }
+        ]
+      }
     }
   },
   computed: {
-    ...mapGetters(['authUserId'])
+    ...mapGetters(['authUserId', 'authUserId'])
   },
   created() {
-    this.authId = this.$route.query.id
+    this.authId = parseInt(this.$route.query.id)
     this.getList()
   },
   methods: {
-    // 获取列表数据
+    // 更新列表
     getList() {
+      this.listQuery.pageNum = 1
+      this.fetchUserList()
+    },
+
+    // 获取列表数据
+    async fetchUserList() {
       this.listLoading = true
       this.listQuery.authId = this.authId
-      getAuthUserList(this.listQuery)
-        .then(res => {
-          if (res.code !== 0) return
-          this.list = res.data.list
-          this.total = res.data.total
-          console.log(res)
-        })
-        .finally(() => {
-          this.listLoading = false
-        })
+      try {
+        const res = await getAuthUserList(this.listQuery)
+        this.list = res.data.list
+        this.total = res.data.total
+      } catch (error) {
+        console.log(error)
+      } finally {
+        this.listLoading = false
+      }
     },
+
     // 创建用户
-    handleCreate() {},
+    handleCreate() {
+      this.dialogVisible = true
+    },
     // 修改用户
-    handleEdit() {},
+    handleEdit(row) {
+      this.formData.clubUserId = row.clubUserId
+      this.formData.authId = row.authId
+      this.formData.name = row.name
+      this.formData.mobile = row.mobile
+      this.dialogVisible = true
+    },
+
+    // 保存用户信息
+    async onSave() {
+      this.formData.authId = this.authId
+      try {
+        await createClubUser(this.formData)
+        this.$message.success('添加用户成功')
+        this.fetchUserList()
+        this.dialogVisible = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
     // 删除用户
-    handleRemove() {},
+    async handleRemove(row) {
+      let confirmType = ''
+      try {
+        confirmType = await this.$confirm('确认删除改用户?', '提示', {
+          confirmButtonText: '确认',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+      } catch (error) {
+        console.log(error)
+      }
+
+      if (!confirmType) return
+
+      try {
+        await removeClubUser({ clubUserId: row.clubUserId })
+        this.$message.success('删除用户成功')
+        this.fetchUserList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
+    onDialogClose() {
+      this.$refs.form.resetFields()
+      this.formData = resetFormData()
+    },
 
     indexMethod(index) {
       return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
@@ -134,6 +234,14 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+.app-container{
+  ::v-deep{
+    .el-dialog__body{
+      padding-bottom: 0;
+    }
+  }
+}
+
 .el-table .cell {
   overflow: visible;
 }

+ 8 - 6
src/views/normal/material/package/index.vue

@@ -118,13 +118,13 @@
       @close="beforeDialogClose"
     >
       <el-form ref="formRef" :model="dialogData" label-width="110px" :rules="dialogFormRules">
-        <el-form-item label="标题:" prop="fileTitle">
+        <el-form-item label="资料包名称:" prop="fileTitle">
           <el-input v-model="dialogData.fileTitle" maxlength="50" show-word-limit />
         </el-form-item>
-        <el-form-item label="上传文件:" prop="fileName" style="margin-bottom:0">
+        <el-form-item label="资料包路径:" prop="fileName" style="margin-bottom:0">
           <upload-file
             ref="fileUpload"
-            accept=".pdf"
+            accept=".zip"
             mode="document"
             :file-list="fileList"
             :auto-upload="false"
@@ -168,8 +168,9 @@ export default {
       submitLoading: false, // 按钮加载
       total: 0, // 列表条数
       dialogVisible: false, // 是否显示dialog
-      dialogTitle: '添加文件', // dialog标题
+      dialogTitle: '添加资料包:', // dialog标题
       listQuery: {
+        fileType: 2,
         authUserId: '', // 供应商用户id
         listType: 1, // 列表类型:1文件列表,2文件审核列表
         fileTitle: '', // 文件标题
@@ -181,6 +182,7 @@ export default {
       fileList: [],
       // dialog表单中的数据
       dialogData: {
+        fileType: 2,
         fileId: '',
         fileTitle: '',
         fileName: ''
@@ -304,9 +306,9 @@ export default {
 
     // 显示dialog对话框
     handleShowDialog(type, row) {
-      this.dialogTitle = '添加文件'
+      this.dialogTitle = '添加资料包'
       if (type === 'edit') {
-        this.dialogTitle = '修改文件'
+        this.dialogTitle = '修改资料包'
         this.setDialogData(row)
       }
       this.dialogVisible = true

+ 100 - 12
src/views/normal/personnel/operate/edit.vue

@@ -7,8 +7,27 @@
       <el-form-item label="从业资格证编号:" prop="certificateNo">
         <el-input v-model="formData.certificateNo" placeholder="请输入从业资格证编号" />
       </el-form-item>
-      <el-form-item label="所在机构:" prop="clubName">
+      <!-- <el-form-item label="所在机构:" prop="clubName">
         <el-input v-model="formData.clubName" placeholder="请输入机构名称" />
+      </el-form-item> -->
+      <el-form-item label="所在机构:" prop="clubName">
+        <el-select
+          v-model="selectClub"
+          style="width: 100%"
+          filterable
+          allow-create
+          default-first-option
+          placeholder="所在机构"
+          @change="onDoctorClubChange"
+        >
+          <el-option
+            v-for="item in clubList"
+            :key="item.authId"
+            :label="item.authParty"
+            :value="item.authId"
+          />
+        </el-select>
+        <el-input v-show="false" v-model="formData.clubName" />
       </el-form-item>
       <el-form-item label="操作医师照片:" prop="doctorImage">
         <el-input v-show="false" v-model="formData.doctorImage" />
@@ -32,18 +51,19 @@
         />
       </el-form-item>
 
-      <el-form-item label="操作医师标签">
+      <el-form-item label="操作医师标签" prop="tagList">
+        <el-input v-show="false" v-model="formData.tagList" />
         <div class="tag-control">
-          <el-input />
-          <el-button type="primary">添加</el-button>
+          <input v-model="tagName" class="el-input el-input__inner" placeholder="输入标签名后点击添加按钮">
+          <el-button type="primary" @click="addTag">添加</el-button>
         </div>
         <div class="tag-list">
-          <el-tag closable>医师标签</el-tag>
+          <el-tag v-for="(item,index) in addTagList" :key="index" closable @close="onTagClose(index)">{{ item }}</el-tag>
         </div>
       </el-form-item>
 
       <el-form-item label="自定义属性">
-        <doctor-custom-items ref="customItems" @change="customItemsChange" />
+        <doctor-custom-items v-if="!isRequest" ref="customItems" @change="customItemsChange" />
       </el-form-item>
 
       <el-form-item label="具备操作资格设备:" prop="equipment">
@@ -65,7 +85,7 @@ import { mapGetters } from 'vuex'
 import DeviceSection from '@/views/components/DeviceSection/index.vue'
 import DoctorCustomItems from '@/views/components/DoctorCustomItems/index.vue'
 import UploadImage from '@/components/UploadImage'
-import { doctorSave, doctorFormData } from '@/api/doctor'
+import { doctorSave, doctorFormData, fetchDoctorClubList } from '@/api/doctor'
 
 export default {
   components: { DeviceSection, UploadImage, DoctorCustomItems },
@@ -89,12 +109,15 @@ export default {
       point: {},
       disabled: false,
       formData: {
+        authId: '',
+        doctorType: 1,
         doctorName: '',
         certificateNo: '',
         clubName: '',
         banner: '',
         doctorImage: '',
-        equipment: ''
+        equipment: '',
+        tagList: ''
       },
       rules: {
         doctorName: [
@@ -105,14 +128,24 @@ export default {
         clubName: [{ required: true, message: '所在机构不能为空', trigger: ['blur', 'change'] }],
         doctorImage: [{ required: true, message: '请上传医师照片', trigger: 'change' }],
         banner: [{ required: true, message: '请上传至少一张轮播图', trigger: 'change' }],
-        equipment: [{ required: true, message: '具备操作资格设备不能为空', trigger: 'change' }]
+        equipment: [{ required: true, message: '具备操作资格设备不能为空', trigger: 'change' }],
+        tagList: [{ required: true, message: '医师标签不能为空', trigger: 'change' }]
       },
       // logo图片列表
       doctorImageList: [],
       // banner图片列表
       bannerList: [],
       // 资格仪器列表
-      deviceList: []
+      deviceList: [],
+      // 机构列表
+      clubList: [],
+      selectClub: '',
+      // 添加标签名
+      tagName: '',
+      // 医师标签列表
+      addTagList: [],
+      // 自定义参数列表
+      paramList: []
     }
   },
   computed: {
@@ -127,16 +160,48 @@ export default {
       }
     }
   },
+  watch: {
+    addTagList: {
+      handler: function(nVal) {
+        this.formData.tagList = this.addTagList.join(',')
+      },
+      deep: true
+    }
+  },
   created() {
     this.doctorId = parseInt(this.$route.query.id)
     this.editType = this.$route.query.type || 'edit'
+    this.fetchDoctorClubList()
     this.initFormData()
   },
   methods: {
 
+    // 添加标签
+    addTag() {
+      this.addTagList.push(this.tagName.trim())
+      this.tagName = ''
+    },
+
+    // 删除标签
+    onTagClose(index) {
+      this.addTagList.splice(index, 1)
+    },
+
+    // 选择医师机构
+    onDoctorClubChange(value) {
+      if (typeof value === 'number') {
+        this.formData.authId = value
+        this.formData.clubName = '非自定义'
+      } else {
+        this.formData.authId = -1
+        this.formData.clubName = value
+      }
+    },
+
     // 自定义字段变化
     customItemsChange(list) {
       console.log(list)
+      this.paramList = list
     },
 
     // 具备操作资格设备列表数据变化
@@ -162,14 +227,23 @@ export default {
       this.formData.certificateNo = data.certificateNo
       this.formData.clubName = data.clubName
       this.formData.doctorImage = data.doctorImage
+      this.formData.authId = data.authId
 
       this.formData.banner = data.bannerList.length
       this.formData.equipmentList = data.equipmentList.length
       this.doctorImageList.push({ url: data.doctorImage, name: 'doctor' })
       this.bannerList = data.bannerList.map(item => ({ url: item, name: '' }))
       this.deviceList = data.equipmentList
+      this.paramList = data.paramList
+      this.addTagList = data.tagList
+
+      this.selectClub = !data.authId ? data.clubName : data.authId
 
       this.isRequest = false
+
+      this.$nextTick(() => {
+        this.$refs.customItems.setParamsItem(this.paramList)
+      })
     },
 
     // 提交表单验证
@@ -193,7 +267,11 @@ export default {
         doctorName: this.formData.doctorName,
         certificateNo: this.formData.certificateNo,
         clubName: this.formData.clubName,
-        doctorImage: this.formData.doctorImage
+        doctorImage: this.formData.doctorImage,
+        tagList: this.addTagList,
+        authId: this.formData.authId,
+        doctorType: this.formData.doctorType,
+        paramList: this.paramList
       }
 
       console.log(this.formData)
@@ -203,10 +281,20 @@ export default {
       doctorSave(data).then(res => {
         this.$message.success('保存成功')
         this.$store.dispatch('tagsView/delView', this.$route)
-        this.$router.push('/doctor/list')
+        this.$router.push('/personnel/operate/list')
       })
     },
 
+    // 获取医师机构列表
+    async fetchDoctorClubList() {
+      try {
+        const res = await fetchDoctorClubList({ authUserId: this.authUserId })
+        this.clubList = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
     // 医师照片上传
     uploadDoctorImageSuccess({ response, file, fileList }) {
       this.doctorImageList = fileList

+ 5 - 2
src/views/normal/personnel/operate/index.vue

@@ -136,9 +136,12 @@ export default {
       tableKey: 0,
       total: 0,
       listQuery: {
-        listType: 1,
-        doctorName: '',
+        authUserId: '',
         auditStatus: '',
+        certificateNo: '',
+        doctorName: '',
+        doctorType: 1,
+        listType: 1,
         status: '',
         pageNum: 1,
         pageSize: 10

+ 124 - 19
src/views/normal/personnel/training/edit.vue

@@ -1,19 +1,38 @@
 <template>
   <div class="doctor-edit">
     <el-form ref="submitForm" class="doctor-edit-form" label-width="140px" :model="formData" :rules="rules">
-      <el-form-item label="医师姓名:" prop="doctorName">
-        <el-input v-model="formData.doctorName" type="text" placeholder="请输入医师姓名" :maxlength="30" />
+      <el-form-item label="操作医师姓名:" prop="doctorName">
+        <el-input v-model="formData.doctorName" type="text" placeholder="请输入操作医师姓名" :maxlength="30" />
       </el-form-item>
       <el-form-item label="从业资格证编号:" prop="certificateNo">
         <el-input v-model="formData.certificateNo" placeholder="请输入从业资格证编号" />
       </el-form-item>
-      <el-form-item label="所在机构:" prop="clubName">
+      <!-- <el-form-item label="所在机构:" prop="clubName">
         <el-input v-model="formData.clubName" placeholder="请输入机构名称" />
+      </el-form-item> -->
+      <el-form-item label="所在机构:" prop="clubName">
+        <el-select
+          v-model="selectClub"
+          style="width: 100%"
+          filterable
+          allow-create
+          default-first-option
+          placeholder="所在机构"
+          @change="onDoctorClubChange"
+        >
+          <el-option
+            v-for="item in clubList"
+            :key="item.authId"
+            :label="item.authParty"
+            :value="item.authId"
+          />
+        </el-select>
+        <el-input v-show="false" v-model="formData.clubName" />
       </el-form-item>
-      <el-form-item label="医师照片:" prop="doctorImage">
+      <el-form-item label="操作医师照片:" prop="doctorImage">
         <el-input v-show="false" v-model="formData.doctorImage" />
         <upload-image
-          tip="提示:上传医师个人照片,建议尺寸:200px * 200px"
+          tip="提示:上传操作医师个人照片,建议尺寸:200px * 200px"
           :image-list="doctorImageList"
           :before-upload="beforeDoctorImageUpload"
           @success="uploadDoctorImageSuccess"
@@ -32,18 +51,24 @@
         />
       </el-form-item>
 
-      <el-form-item label="操作医师标签">
+      <el-form-item label="操作医师标签" prop="tagList">
+        <el-input v-show="false" v-model="formData.tagList" />
         <div class="tag-control">
-          <el-input />
-          <el-button type="primary">添加</el-button>
+          <input v-model="tagName" class="el-input el-input__inner" placeholder="输入标签名后点击添加按钮">
+          <el-button type="primary" @click="addTag">添加</el-button>
         </div>
         <div class="tag-list">
-          <el-tag closable>医师标签</el-tag>
+          <el-tag v-for="(item,index) in addTagList" :key="index" closable @close="onTagClose(index)">{{ item }}</el-tag>
         </div>
       </el-form-item>
 
       <el-form-item label="自定义属性">
-        <doctor-custom-items ref="customItems" @change="customItemsChange" />
+        <doctor-custom-items v-if="!isRequest" ref="customItems" @change="customItemsChange" />
+      </el-form-item>
+
+      <el-form-item label="具备操作资格设备:" prop="equipment">
+        <el-input v-show="false" v-model="formData.equipment" />
+        <device-section v-if="!isRequest" ref="subForm" :list="deviceList" @change="deviceListDataChange" />
       </el-form-item>
 
     </el-form>
@@ -57,12 +82,13 @@
 <script>
 import { Promise } from 'jszip/lib/external'
 import { mapGetters } from 'vuex'
-import UploadImage from '@/components/UploadImage'
+import DeviceSection from '@/views/components/DeviceSection/index.vue'
 import DoctorCustomItems from '@/views/components/DoctorCustomItems/index.vue'
-import { doctorSave, doctorFormData } from '@/api/doctor'
+import UploadImage from '@/components/UploadImage'
+import { doctorSave, doctorFormData, fetchDoctorClubList } from '@/api/doctor'
 
 export default {
-  components: { DoctorCustomItems, UploadImage },
+  components: { DeviceSection, UploadImage, DoctorCustomItems },
   data() {
     var validateCertificateNo = (rule, value, callback) => {
       if (value === '') {
@@ -83,12 +109,15 @@ export default {
       point: {},
       disabled: false,
       formData: {
+        authId: '',
+        doctorType: 2,
         doctorName: '',
         certificateNo: '',
         clubName: '',
         banner: '',
         doctorImage: '',
-        equipment: ''
+        equipment: '',
+        tagList: ''
       },
       rules: {
         doctorName: [
@@ -99,14 +128,24 @@ export default {
         clubName: [{ required: true, message: '所在机构不能为空', trigger: ['blur', 'change'] }],
         doctorImage: [{ required: true, message: '请上传医师照片', trigger: 'change' }],
         banner: [{ required: true, message: '请上传至少一张轮播图', trigger: 'change' }],
-        equipment: [{ required: true, message: '具备操作资格设备不能为空', trigger: 'change' }]
+        equipment: [{ required: true, message: '具备操作资格设备不能为空', trigger: 'change' }],
+        tagList: [{ required: true, message: '医师标签不能为空', trigger: 'change' }]
       },
       // logo图片列表
       doctorImageList: [],
       // banner图片列表
       bannerList: [],
       // 资格仪器列表
-      deviceList: []
+      deviceList: [],
+      // 机构列表
+      clubList: [],
+      selectClub: '',
+      // 添加标签名
+      tagName: '',
+      // 医师标签列表
+      addTagList: [],
+      // 自定义参数列表
+      paramList: []
     }
   },
   computed: {
@@ -121,16 +160,54 @@ export default {
       }
     }
   },
+  watch: {
+    addTagList: {
+      handler: function(nVal) {
+        this.formData.tagList = this.addTagList.join(',')
+      },
+      deep: true
+    }
+  },
   created() {
     this.doctorId = parseInt(this.$route.query.id)
     this.editType = this.$route.query.type || 'edit'
+    this.fetchDoctorClubList()
     this.initFormData()
   },
   methods: {
 
+    // 添加标签
+    addTag() {
+      this.addTagList.push(this.tagName.trim())
+      this.tagName = ''
+    },
+
+    // 删除标签
+    onTagClose(index) {
+      this.addTagList.splice(index, 1)
+    },
+
+    // 选择医师机构
+    onDoctorClubChange(value) {
+      if (typeof value === 'number') {
+        this.formData.authId = value
+        this.formData.clubName = '非自定义'
+      } else {
+        this.formData.authId = -1
+        this.formData.clubName = value
+      }
+    },
+
     // 自定义字段变化
     customItemsChange(list) {
       console.log(list)
+      this.paramList = list
+    },
+
+    // 具备操作资格设备列表数据变化
+    deviceListDataChange(list) {
+      this.deviceList = list
+      this.formData.equipment = list.length || ''
     },
 
     // 表单数据回显
@@ -150,18 +227,32 @@ export default {
       this.formData.certificateNo = data.certificateNo
       this.formData.clubName = data.clubName
       this.formData.doctorImage = data.doctorImage
+      this.formData.authId = data.authId
 
       this.formData.banner = data.bannerList.length
       this.formData.equipmentList = data.equipmentList.length
       this.doctorImageList.push({ url: data.doctorImage, name: 'doctor' })
       this.bannerList = data.bannerList.map(item => ({ url: item, name: '' }))
+      this.deviceList = data.equipmentList
+      this.paramList = data.paramList
+      this.addTagList = data.tagList
+
+      this.selectClub = !data.authId ? data.clubName : data.authId
 
       this.isRequest = false
+
+      this.$nextTick(() => {
+        this.$refs.customItems.setParamsItem(this.paramList)
+      })
     },
 
     // 提交表单验证
     submit() {
-      Promise.all([this.$refs.customItems.valideAllForm(), this.$refs.submitForm.validate()]).then(res => {
+      Promise.all([
+        this.$refs.subForm.valideAllForm(),
+        this.$refs.submitForm.validate(),
+        this.$refs.customItems.valideAllForm()
+      ]).then(res => {
         this.save()
       })
     },
@@ -176,7 +267,11 @@ export default {
         doctorName: this.formData.doctorName,
         certificateNo: this.formData.certificateNo,
         clubName: this.formData.clubName,
-        doctorImage: this.formData.doctorImage
+        doctorImage: this.formData.doctorImage,
+        tagList: this.addTagList,
+        authId: this.formData.authId,
+        doctorType: this.formData.doctorType,
+        paramList: this.paramList
       }
 
       console.log(this.formData)
@@ -186,10 +281,20 @@ export default {
       doctorSave(data).then(res => {
         this.$message.success('保存成功')
         this.$store.dispatch('tagsView/delView', this.$route)
-        this.$router.push('/doctor/list')
+        this.$router.push('/personnel/training/list')
       })
     },
 
+    // 获取医师机构列表
+    async fetchDoctorClubList() {
+      try {
+        const res = await fetchDoctorClubList({ authUserId: this.authUserId })
+        this.clubList = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
     // 医师照片上传
     uploadDoctorImageSuccess({ response, file, fileList }) {
       this.doctorImageList = fileList

+ 8 - 5
src/views/normal/personnel/training/index.vue

@@ -2,8 +2,8 @@
   <div class="app-container">
     <div class="filter-container">
       <div class="filter-control">
-        <span>培训医师姓名:</span>
-        <el-input v-model="listQuery.doctorName" placeholder="培训医师姓名" @keyup.enter.native="handleFilter" />
+        <span>操作医师姓名:</span>
+        <el-input v-model="listQuery.doctorName" placeholder="操作医师姓名" @keyup.enter.native="handleFilter" />
       </div>
       <div class="filter-control">
         <span>审核状态:</span>
@@ -40,7 +40,7 @@
       header-row-class-name="tableHeader"
     >
       <el-table-column label="序号" :index="indexMethod" type="index" align="center" width="80" />
-      <el-table-column label="培训医师姓名" align="center" prop="doctorName" />
+      <el-table-column label="操作医师姓名" align="center" prop="doctorName" />
       <el-table-column label="从业资格证编号" align="center" prop="certificateNo" />
 
       <el-table-column label="审核状态" width="220px" align="center">
@@ -136,9 +136,12 @@ export default {
       tableKey: 0,
       total: 0,
       listQuery: {
-        listType: 1,
-        doctorName: '',
+        authUserId: '',
         auditStatus: '',
+        certificateNo: '',
+        doctorName: '',
+        doctorType: 2,
+        listType: 1,
         status: '',
         pageNum: 1,
         pageSize: 10