Bladeren bron

feature:笼位申请、申请带离增加品种品系优化,仪器预约历史记录增加

liuzhenlin 2 maanden geleden
bovenliggende
commit
f4c2553cae

+ 1 - 0
components.d.ts

@@ -41,6 +41,7 @@ declare module 'vue' {
     VanRow: typeof import('vant/es')['Row']
     VanSearch: typeof import('vant/es')['Search']
     VanStep: typeof import('vant/es')['Step']
+    VanStepper: typeof import('vant/es')['Stepper']
     VanSteps: typeof import('vant/es')['Steps']
     VanSwipe: typeof import('vant/es')['Swipe']
     VanSwipeItem: typeof import('vant/es')['SwipeItem']

+ 4 - 0
src/api/appoint/index.ts

@@ -31,5 +31,9 @@ export function useMyAppointApi() {
     toGetonList: (query?: object) => {
       return request.postRequest(instPath, 'MyAppointment', 'ToGetonList', query)
     },
+    // 预约记录
+    getAppointRecord: (query?: object) => {
+      return request.postRequest(instPath, 'MyAppointment', 'GetList', query)
+    }
   }
 }

+ 1 - 0
src/constants/pageConstants.ts

@@ -148,6 +148,7 @@ export interface TakeawayList {
 export interface CreateAnimalApplyLeavePayload {
   accessCardNumber: string // 门禁卡序列号
   categoryId: string | null // 动物种类
+  variety: string // 动物品系
   projectGroupId: number | null // 项目组ID
   projectGroupName: string // 项目组名称
   takeawayDate: string // 转出日期

File diff suppressed because it is too large
+ 373 - 517
src/view/animal/application/components/Application.vue


+ 8 - 2
src/view/animal/application/index.vue

@@ -152,11 +152,17 @@
                 </span>
               </p>
               <p class="inst-title">
-                <span>动物类</span>
+                <span>动物类</span>
                 <span class="title ml8">
                   {{ item.categoryName }}
                 </span>
               </p>
+              <p class="inst-title">
+                <span>品种品系</span>
+                <span class="title ml8">
+                  {{ item.variety }}
+                </span>
+              </p>
               <p class="inst-title">
                 <span>级别</span>
                 <span class="title ml8">
@@ -173,7 +179,7 @@
                     "
                     style="height: 25px"
                     type="primary"
-                    @click="handleRefundable(item)"
+                    @click.stop="handleRefundable(item)"
                   >
                     退还
                   </el-button>

+ 428 - 318
src/view/animal/applicationRemoval/components/addEdit.vue

@@ -1,300 +1,229 @@
 <template>
   <div class="application-dialog-container">
-    <el-dialog
-      :title="state.dialog.title"
+    <van-popup
+      v-model:show="state.dialog.isShowDialog"
+      position="bottom"
+      :style="{ height: '90vh' }"
+      round
+      :closeable="true"
       @close="onCancel"
-      :close-on-click-modal="false"
-      v-model="state.dialog.isShowDialog"
-      width="90%"
+      :close-on-click-overlay="false"
     >
-      <el-form
-        ref="expertDialogFormRef"
-        :model="state.form"
-        :rules="rules"
-        size="default"
-        label-width="140px"
-        label-position="top"
-      >
-        <h4 class="mb20 mt8">申请人信息</h4>
-        <el-row class="mb20">
-          <el-col :span="24">
-            <el-form-item
-              label="申请人姓名"
-              prop="userName"
-            >
-              <el-input
+      <div class="popup-wrapper">
+        <h3 class="popup-title">{{ state.dialog.title }}</h3>
+        <div class="popup-content">
+          <van-form
+            ref="expertDialogFormRef"
+            @submit="onSubmit"
+          >
+            <h4 class="mb20 mt8">申请人信息</h4>
+            <van-cell-group>
+              <van-field
                 v-model="state.form.userName"
-                disabled
+                label="申请人姓名"
+                placeholder="申请人姓名"
+                readonly
+                required
+                :rules="rules.userName"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="联系电话"
-              prop="phone"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.phone"
-                disabled
+                label="联系电话"
+                placeholder="联系电话"
+                readonly
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="课题组"
-              prop="projectGroupId"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.projectGroupName"
-                disabled
+                label="课题组"
                 placeholder="请选择"
-                class="w100"
-              ></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="科室"
-              prop="deptId"
-            >
-              <el-input
+                readonly
+                required
+                :rules="rules.projectGroupId"
+              />
+              <van-field
                 v-model="state.form.deptName"
-                disabled
+                label="科室"
+                placeholder="科室"
+                readonly
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <h4 class="mb20 mt20">转出情况</h4>
-        <el-row
-          class="mb20"
-        >
-          <el-col :span="24">
-            <el-form-item
-              label="品种品系"
-              prop="categoryId"
-            >
-              <el-select
-                v-model="state.form.categoryId"
+            </van-cell-group>
+
+            <h4 class="mb20 mt20">转出情况</h4>
+            <van-cell-group>
+              <van-field
+                v-model="state.form.categoryName"
+                label="动物品系"
                 placeholder="请选择"
-                :disabled="state.dialog.type === 'detail'"
-              >
-                <el-option
-                  v-for="item in animalTypeList"
-                  :key="item.id"
-                  :label="item.name"
-                  :value="item.id"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="转出日期"
-              prop="takeawayDate"
-            >
-              <el-date-picker
+                readonly
+                is-link
+                required
+                @click="showCategoryPicker = true"
+                :rules="rules.categoryId"
+              />
+              <van-field
+                v-model="state.form.variety"
+                label="品种品系"
+                placeholder="请输入品种品系"
+              />
+              <van-field
                 v-model="state.form.takeawayDate"
-                type="date"
+                label="转出日期"
                 placeholder="请选择时间"
-                clearable
-                value-format="YYYY-MM-DD"
-                style="width: 100%"
-                :disabled="state.dialog.type === 'detail'"
+                readonly
+                is-link
+                required
+                @click="showDatePicker = true"
+                :rules="rules.takeawayDate"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row
-          class="mb20"
-        >
-          <el-col :span="24">
-            <el-form-item
-              label="送往地点"
-              prop="takeawayAddress"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.takeawayAddress"
+                label="送往地点"
                 placeholder="请输入"
-                :disabled="state.dialog.type === 'detail'"
+                required
+                :rules="rules.takeawayAddress"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="带出原因"
-              prop="takeawayReason"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.takeawayReason"
+                label="带出原因"
                 placeholder="请输入"
-                :disabled="state.dialog.type === 'detail'"
+                required
+                :rules="rules.takeawayReason"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row
-          class="mb20"
-        >
-          <el-col :span="24">
-            <el-form-item
-              label="运输方式"
-              prop="takeawayTransport"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.takeawayTransport"
+                label="运输方式"
                 placeholder="请输入"
-                :disabled="state.dialog.type === 'detail'"
+                required
+                :rules="rules.takeawayTransport"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="门禁卡序列号"
-              prop="accessCardNumber"
-            >
-              <el-input
+              <van-field
                 v-model="state.form.accessCardNumber"
+                label="门禁卡序列号"
                 placeholder="请输入"
-                :disabled="state.dialog.type === 'detail'"
               />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row
-          class="mt10"
-        >
-          <el-col :span="24">
-            <el-form-item
-              label="雄性"
-              prop="takeawayMaleNumber"
-            >
-              <el-input-number
-                style="width: 100%"
-                placeholder="雄性数量"
+              <van-field
                 v-model="state.form.takeawayMaleNumber"
-                :min="0"
-                :disabled="state.dialog.type === 'detail'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="24">
-            <el-form-item
-              label="雌性"
-              prop="takewayFemaleNumber"
-            >
-              <el-input-number
-                style="width: 100%"
-                placeholder="雌性数量"
+                label="雄性"
+                placeholder="雄性数量"
+                type="digit"
+              >
+                <template #button>
+                  <van-stepper
+                    v-model="state.form.takeawayMaleNumber"
+                    :min="0"
+                    integer
+                  />
+                </template>
+              </van-field>
+              <van-field
                 v-model="state.form.takewayFemaleNumber"
-                :min="0"
-                :disabled="state.dialog.type === 'detail'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row
-          class="mt10"
-        >
-          <el-col
-            :span="24"
-            class="mt30 mb30"
-          >
-            <el-checkbox
-              v-model="safePromiseStatus"
-              :disabled="state.dialog.type === 'detail'"
-            >
-              本人已阅读并同意
-              <el-link
-                type="primary"
-                :underline="false"
-                @click="handleReadNotice"
+                label="雌性"
+                placeholder="雌性数量"
+                type="digit"
               >
-                《实验动物带离须知》
-              </el-link>
-              内容
-            </el-checkbox>
-          </el-col>
-        </el-row>
-      </el-form>
-
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button
-            type="info"
-            @click="onCancel"
-            size="default"
-          >
-            取 消
-          </el-button>
-          <el-button
+                <template #button>
+                  <van-stepper
+                    v-model="state.form.takewayFemaleNumber"
+                    :min="0"
+                    integer
+                  />
+                </template>
+              </van-field>
+            </van-cell-group>
+
+            <div class="mt30 mb30 checkbox-wrapper">
+              <van-checkbox v-model="safePromiseStatus">
+                本人已阅读并同意
+                <span
+                  class="link-text"
+                  @click.stop="handleReadNotice"
+                >
+                  《实验动物带离须知》
+                </span>
+                内容
+              </van-checkbox>
+            </div>
+          </van-form>
+        </div>
+        <div class="dialog-footer">
+          <van-button
             v-if="state.dialog.type !== 'detail'"
-            color="#2c78ff"
-            @click="onSubmit()"
-            size="default"
+            type="primary"
+            @click="onSubmit"
+            block
+            native-type="submit"
           >
             提交
-          </el-button>
-        </span>
-      </template>
-    </el-dialog>
-
-    <el-dialog
-      v-model="isShowNotice"
-      title="实验动物带离须知"
-      width="90%"
+          </van-button>
+        </div>
+      </div>
+    </van-popup>
+
+    <!-- 动物品系选择器 -->
+    <van-popup
+      v-model:show="showCategoryPicker"
+      position="bottom"
+    >
+      <van-picker
+        :columns="animalTypeList"
+        :columns-field-names="{ text: 'name', value: 'id' }"
+        @confirm="onCategoryConfirm"
+        @cancel="showCategoryPicker = false"
+      />
+    </van-popup>
+
+    <!-- 日期选择器 - 使用日历组件 -->
+    <van-popup
+      v-model:show="showDatePicker"
+      position="bottom"
+      :style="{ height: '80vh' }"
+      round
     >
-      <div class="text">
-        <p
-          class="mb20"
-          v-for="item in AnimalRemovalApplicationNotice.split('\n')"
-          :key="item"
-        >
-          {{ item }}
-        </p>
+      <van-calendar
+        v-model:show="showDatePicker"
+        @confirm="onDateConfirm"
+        :min-date="new Date()"
+      />
+    </van-popup>
+
+    <!-- 须知弹窗 -->
+    <van-popup
+      v-model:show="isShowNotice"
+      position="bottom"
+      round
+      :closeable="true"
+      :style="{ height: '70vh' }"
+    >
+      <div class="notice-content">
+        <h4 class="notice-title">实验动物带离须知</h4>
+        <div class="text">
+          <p
+            class="mb20"
+            v-for="(item, index) in AnimalRemovalApplicationNotice.split('\n').filter((item) => item.trim())"
+            :key="index"
+          >
+            {{ item }}
+          </p>
+        </div>
+        <div class="notice-footer">
+          <van-button
+            type="primary"
+            @click="isShowNotice = false"
+            block
+          >
+            确定
+          </van-button>
+        </div>
       </div>
-      <template #footer>
-        <el-button
-          type="primary"
-          @click="isShowNotice = false"
-        >
-          确定
-        </el-button>
-      </template>
-    </el-dialog>
+    </van-popup>
   </div>
 </template>
 
 <script setup lang="ts">
   import { reactive, ref, computed } from 'vue'
   import to from 'await-to-js'
-  import { ElMessage } from 'element-plus'
-  import type { FormRules, FormInstance } from 'element-plus'
+  import { showToast, showNotify } from 'vant'
+  import type { FormInstance } from 'vant/es'
 
   import { usePlatAnimalCageApplicationApi } from '/@/api/platform/animal'
   import {
@@ -306,6 +235,7 @@
   import { deepClone } from '/@/utils/other'
   import { useUserInfos } from '/@/hooks/useUserInfos'
   import { filterFields } from '/@/utils/func'
+  import { formatDate } from '/@/utils/formatTime'
 
   const emit = defineEmits(['refresh'])
 
@@ -316,20 +246,25 @@
   const animalTypeList = ref<{ id: string; name: string }[]>([])
   const safePromiseStatus = ref<boolean>(false)
   const isShowNotice = ref<boolean>(false)
+  const showCategoryPicker = ref<boolean>(false)
+  const showDatePicker = ref<boolean>(false)
+  const selectedDate = ref<Date | null>(null)
+
+  const rules = {
+    categoryId: [{ required: true, message: '动物品系不能为空' }],
+    projectGroupId: [{ required: true, message: '课题组不能为空' }],
+    takeawayDate: [{ required: true, message: '转出日期不能为空' }],
+    userName: [{ required: true, message: '申请人姓名不能为空' }],
+    takeawayAddress: [{ required: true, message: '送往地点不能为空' }],
+    takeawayReason: [{ required: true, message: '带出原因不能为空' }],
+    takeawayTransport: [{ required: true, message: '运输方式不能为空' }],
+  }
 
-  const rules = reactive<FormRules<CreateAnimalApplyLeavePayload>>({
-    categoryId: [{ required: true, message: '请选择动物种类', trigger: 'blur' }],
-    projectGroupId: [{ required: true, message: '请选择项目组', trigger: 'blur' }],
-    takeawayDate: [{ required: true, message: '请选择转出日期', trigger: 'blur' }],
-    userName: [{ required: true, message: '请输入申请人姓名', trigger: 'blur' }],
-    takeawayAddress: [{ required: true, message: '不能为空', trigger: 'change' }],
-    takeawayReason: [{ required: true, message: '不能为空', trigger: 'change' }],
-    takeawayTransport: [{ required: true, message: '不能为空', trigger: 'change' }],
-  })
-
-  const defaultFormFields: CreateAnimalApplyLeavePayload = {
+  const defaultFormFields: CreateAnimalApplyLeavePayload & { categoryName?: string } = {
     accessCardNumber: '',
     categoryId: null,
+    categoryName: '',
+    variety: '',
     projectGroupId: null,
     projectGroupName: '',
     takeawayDate: '',
@@ -345,7 +280,7 @@
   }
 
   const state = reactive<{
-    form: CreateAnimalApplyLeavePayload
+    form: CreateAnimalApplyLeavePayload & { categoryName?: string }
     safePromise: boolean
     safeRead: boolean
     dialog: { isShowDialog: boolean; type: string; title: string; submitTxt: string }
@@ -360,13 +295,7 @@
       submitTxt: '',
     },
   })
-
-  const animalNumber = computed(() => {
-    const maleNumber = state.form.takeawayMaleNumber || 0
-    const famaleNumber = state.form.takewayFemaleNumber || 0
-    return maleNumber + famaleNumber
-  })
-
+  
   const getDicts = async () => {
     const [_, res]: ToResponse = await to(platAnimalCageApplicationApi.getAnimalTypeList({}))
 
@@ -390,11 +319,26 @@
         ...state.form,
         ...sourceData,
       }
+      // 设置 categoryName 用于显示
+      if (sourceData.categoryId) {
+        const category = animalTypeList.value.find((item) => item.id === sourceData.categoryId)
+        if (category) {
+          state.form.categoryName = category.name
+        }
+      }
+      // 设置日期选择器的值
+      if (sourceData.takeawayDate) {
+        const dateParts = sourceData.takeawayDate.split('-')
+        selectedDate.value = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]))
+      }
     }
 
     if (type === 'add') {
       state.dialog.title = '新增实验动物带离单'
-      state.form.categoryId = animalTypeList.value[0].id
+      if (animalTypeList.value.length > 0) {
+        state.form.categoryId = animalTypeList.value[0].id
+        state.form.categoryName = animalTypeList.value[0].name
+      }
     }
     if (type === 'edit') {
       state.dialog.title = '编辑实验动物带离单'
@@ -408,8 +352,28 @@
   }
 
   const closeDialog = () => {
-    expertDialogFormRef.value.resetFields()
-    state.form = defaultFormFields
+    expertDialogFormRef.value?.resetValidation()
+    // 重置表单数据
+    state.form = {
+      accessCardNumber: '',
+      categoryId: null,
+      categoryName: '',
+      variety: '',
+      projectGroupId: null,
+      projectGroupName: '',
+      takeawayDate: '',
+      takeawayAddress: '',
+      takeawayReason: '',
+      takeawayTransport: '',
+      takewayFemaleNumber: 0,
+      takeawayMaleNumber: 0,
+      userName: '',
+      phone: '',
+      deptId: '',
+      deptName: '',
+    }
+    safePromiseStatus.value = false
+    selectedDate.value = null
     state.dialog.isShowDialog = false
   }
 
@@ -418,35 +382,80 @@
   }
 
   const onSubmit = async () => {
-    expertDialogFormRef.value.validate(async (valid: boolean) => {
-      if (!valid) return
-
-      if (!safePromiseStatus.value) {
-        ElMessage.error('请阅读并勾选安全承诺!')
-        return
+    try {
+      await expertDialogFormRef.value?.validate()
+    } catch (error: any) {
+      // 显示表单验证错误
+      let errorMessage = '请完善必填信息'
+      if (error) {
+        // Vant 表单验证错误可能是数组格式
+        if (Array.isArray(error) && error.length > 0) {
+          const firstError = error[0]
+          if (firstError && firstError.message) {
+            errorMessage = firstError.message
+          }
+        } else if (error.message) {
+          errorMessage = error.message
+        }
       }
+      showNotify({
+        type: 'warning',
+        message: errorMessage,
+      })
+      return
+    }
 
-      if (!state.form.takeawayMaleNumber && !state.form.takewayFemaleNumber) {
-        ElMessage.error('请添加雄性或雌性数量!')
-        return
-      }
+    if (!safePromiseStatus.value) {
+      showNotify({
+        type: 'warning',
+        message: '请阅读并勾选安全承诺!',
+      })
+      return
+    }
+
+    if (!state.form.takeawayMaleNumber && !state.form.takewayFemaleNumber) {
+      showNotify({
+        type: 'warning',
+        message: '请添加雄性或雌性数量!',
+      })
+      return
+    }
 
-      const post = platAnimalCageApplicationApi.createAnimalTakeawayApplications
-      const [err]: ToResponse = await to(
-        post(
-          filterFields({
-            ...deepClone(state.form),
-            deptId: userInfos.value.deptId,
-            projectGroupId: state.form.projectGroupId?.toString(),
-          }),
-        ),
-      )
-
-      if (err) return
-      ElMessage.success('操作成功')
-      closeDialog()
-      emit('refresh')
+    const post = platAnimalCageApplicationApi.createAnimalTakeawayApplications
+    const [err]: ToResponse = await to(
+      post(
+        filterFields({
+          ...deepClone(state.form),
+          deptId: userInfos.value.deptId,
+          projectGroupId: state.form.projectGroupId?.toString(),
+          takeawayMaleNumber: Number(state.form.takeawayMaleNumber) || 0,
+          takewayFemaleNumber: Number(state.form.takewayFemaleNumber) || 0,
+        }),
+      ),
+    )
+
+    if (err) return
+    showToast({
+      type: 'success',
+      message: '操作成功',
     })
+    closeDialog()
+    emit('refresh')
+  }
+
+  const onCategoryConfirm = ({ selectedOptions }: { selectedOptions: any[] }) => {
+    if (selectedOptions.length > 0) {
+      const selected = selectedOptions[0]
+      state.form.categoryId = selected.id
+      state.form.categoryName = selected.name
+    }
+    showCategoryPicker.value = false
+  }
+
+  const onDateConfirm = (date: Date) => {
+    selectedDate.value = date
+    state.form.takeawayDate = formatDate(date, 'YYYY-mm-dd')
+    showDatePicker.value = false
   }
 
   const handleReadNotice = () => {
@@ -459,25 +468,126 @@
 </script>
 <style lang="scss" scoped>
   .application-dialog-container {
-    .el-select {
-      width: 100%;
+    .popup-wrapper {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      overflow: hidden;
     }
-  }
-  h4 {
-    font-size: 18px;
-  }
-  ul {
-    padding-left: 20px;
-  }
-  .text {
-    p {
-      text-indent: 2em;
+
+    .popup-title {
+      font-size: 18px;
+      font-weight: 600;
+      text-align: center;
+      padding: 16px 0;
+      margin: 0;
+      border-bottom: 1px solid #ebedf0;
+      flex-shrink: 0;
+      background-color: #fff;
+      position: sticky;
+      top: 0;
+      z-index: 1;
+      padding-right: 40px; // 为关闭按钮留出空间
+    }
+
+    .popup-content {
+      flex: 1;
+      padding: 16px;
+      overflow-y: auto;
+      -webkit-overflow-scrolling: touch;
+    }
+
+    h4 {
+      font-size: 16px;
+      font-weight: 600;
+      margin: 16px 0 8px;
+      padding-left: 8px;
+      position: relative;
+
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 50%;
+        transform: translateY(-50%);
+        width: 3px;
+        height: 16px;
+        background-color: #1c9bfd;
+      }
+    }
+
+    .checkbox-wrapper {
+      padding: 16px;
+      background-color: #f7f8fa;
+      border-radius: 8px;
+      margin: 16px 0;
+
+      .link-text {
+        color: #1989fa;
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+
+    .dialog-footer {
+      padding: 16px;
+      padding-bottom: calc(16px + env(safe-area-inset-bottom));
+      flex-shrink: 0;
+      background-color: #fff;
+      border-top: 1px solid #ebedf0;
+      position: sticky;
+      bottom: 0;
+      z-index: 10;
+    }
+
+    .notice-content {
+      padding: 16px;
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+
+      .notice-title {
+        font-size: 18px;
+        font-weight: 600;
+        text-align: center;
+        padding: 16px 0;
+        margin: 0 0 16px;
+        border-bottom: 1px solid #ebedf0;
+      }
+
+      .text {
+        flex: 1;
+        overflow-y: auto;
+        padding: 0 8px;
+
+        p {
+          text-indent: 2em;
+          line-height: 1.6;
+          margin-bottom: 12px;
+        }
+      }
+
+      .notice-footer {
+        padding-top: 16px;
+        border-top: 1px solid #ebedf0;
+        margin-top: 16px;
+      }
     }
   }
-  .el-upload + .el-button {
-    vertical-align: top;
-  }
-  :deep(.el-checkbox) {
+
+  :deep(.van-checkbox) {
     white-space: pre-wrap;
+    line-height: 1.6;
+  }
+
+  :deep(.van-field__label) {
+    width: 120px;
+  }
+
+  // 确保关闭按钮显示在标题上方
+  :deep(.van-popup__close-icon) {
+    z-index: 100;
+    top: 16px;
+    right: 16px;
   }
 </style>

+ 237 - 303
src/view/animal/applicationRemoval/index.vue

@@ -1,70 +1,32 @@
 <template>
   <div class="entry-container">
-    <div
-      class="search-wrap"
-      ref="searchWrapRef"
-    >
-      <el-form
-        :model="state.queryParams"
-        ref="queryRef"
-      >
+    <div class="search-wrap" ref="searchWrapRef">
+      <el-form :model="state.queryParams" ref="queryRef">
         <el-form-item prop="applyDate">
-          <el-date-picker
-            v-model="state.queryParams.applyDate"
-            type="date"
-            style="width: 100%"
-            placeholder="申请时间"
-            clearable
-            @change="search"
-          />
+          <el-date-picker v-model="state.queryParams.applyDate" type="date" style="width: 100%" placeholder="申请时间"
+            clearable @change="search" />
         </el-form-item>
         <el-form-item prop="isMyself">
-          <el-select
-            v-model="state.queryParams.isMyself"
-            style="width: 100%"
-            placeholder="申请人"
-            clearable
-            @change="search"
-          >
-            <el-option
-              label="我申请的"
-              :value="1"
-            ></el-option>
-            <el-option
-              label="全部"
-              :value="0"
-            ></el-option>
+          <el-select v-model="state.queryParams.isMyself" style="width: 100%" placeholder="申请人" clearable
+            @change="search">
+            <el-option label="我申请的" :value="1"></el-option>
+            <el-option label="全部" :value="0"></el-option>
           </el-select>
         </el-form-item>
       </el-form>
       <div style="text-align: right">
-        <el-button
-          @click="handleExport"
-          color="#2c78ff"
-        >
+        <el-button @click="handleExport" color="#2c78ff">
           导出
         </el-button>
-        <el-button
-          color="#2c78ff"
-          @click="openCageApplicationModal()"
-        >
+        <el-button color="#2c78ff" @click="openCageApplicationModal()">
           申请带离
         </el-button>
       </div>
     </div>
 
     <div class="list-container">
-      <van-list
-        v-model:loading="state.loading"
-        :finished="state.finished"
-        finished-text="没有更多了"
-        @load="onLoad"
-      >
-        <van-cell
-          v-for="item in state.list"
-          :key="item"
-          @click="handleCheckDetail(item)"
-        >
+      <van-list v-model:loading="state.loading" :finished="state.finished" finished-text="没有更多了" @load="onLoad">
+        <van-cell v-for="item in state.list" :key="item" @click="handleCheckDetail(item)">
           <template #default>
             <div class="list">
               <header class="flex justify-between">
@@ -99,42 +61,33 @@
                 </span>
               </p>
               <p class="inst-title">
-                <span>动物种类</span>
+                <span>动物品系</span>
                 <span class="title ml8">
-                  {{ animalTypeList.find((type) => type.id === item.categoryId)?.name }}
+                  {{animalTypeList.find((type) => type.id === item.categoryId)?.name}}
+                </span>
+              </p>
+              <p class="inst-title">
+                <span>品种品系</span>
+                <span class="title ml8">
+                  {{ item.variety }}
                 </span>
               </p>
               <p class="inst-title">
                 <span>申请状态</span>
                 <span class="title ml8">
-                  <van-tag
-                    v-if="item.approveStatus == ApplyLeaveApproveStatus.SUBMIT"
-                    type="primary"
-                  >
+                  <van-tag v-if="item.approveStatus == ApplyLeaveApproveStatus.SUBMIT" type="primary">
                     提交
                   </van-tag>
-                  <van-tag
-                    v-else-if="item.approveStatus == ApplyLeaveApproveStatus.WAIT_APPROVE"
-                    type="primary"
-                  >
+                  <van-tag v-else-if="item.approveStatus == ApplyLeaveApproveStatus.WAIT_APPROVE" type="primary">
                     待审核
                   </van-tag>
-                  <van-tag
-                    v-else-if="item.approveStatus == ApplyLeaveApproveStatus.PASS"
-                    type="success"
-                  >
+                  <van-tag v-else-if="item.approveStatus == ApplyLeaveApproveStatus.PASS" type="success">
                     通过
                   </van-tag>
-                  <van-tag
-                    v-else-if="item.approveStatus == ApplyLeaveApproveStatus.REVOKE"
-                    type="success"
-                  >
+                  <van-tag v-else-if="item.approveStatus == ApplyLeaveApproveStatus.REVOKE" type="success">
                     撤回
                   </van-tag>
-                  <van-tag
-                    v-else-if="item.approveStatus == ApplyLeaveApproveStatus.REFUSE"
-                    type="danger"
-                  >
+                  <van-tag v-else-if="item.approveStatus == ApplyLeaveApproveStatus.REFUSE" type="danger">
                     审核不通过
                   </van-tag>
                 </span>
@@ -142,25 +95,16 @@
               <p class="inst-title">
                 <span>带离状态</span>
                 <span class="title ml8">
-                  <van-tag
-                    v-if="item.approveStatus == ApplyLeaveApproveStatus.PASS"
-                    type="success"
-                  >
+                  <van-tag v-if="item.approveStatus == ApplyLeaveApproveStatus.PASS" type="success">
                     已带离
                   </van-tag>
-                  <van-tag
-                    v-else-if="
-                      item.approveStatus == ApplyLeaveApproveStatus.WAIT_APPROVE ||
-                      item.approveStatus === ApplyLeaveApproveStatus.REFUSE
-                    "
-                    type="primary"
-                  >
+                  <van-tag v-else-if="
+                    item.approveStatus == ApplyLeaveApproveStatus.WAIT_APPROVE ||
+                    item.approveStatus === ApplyLeaveApproveStatus.REFUSE
+                  " type="primary">
                     待带离
                   </van-tag>
-                  <van-tag
-                    v-else-if="takeawayComplate(item)"
-                    type="success"
-                  >
+                  <van-tag v-else-if="takeawayComplate(item)" type="success">
                     已结束
                   </van-tag>
                 </span>
@@ -183,27 +127,16 @@
                   {{ item.returnFemaleNumber + item.returnMaleNumber }}
                 </span>
               </p>
-              <el-row
-                class="mt16"
-                :gutter="20"
-              >
+              <el-row class="mt16" :gutter="20">
                 <el-col :span="12">
-                  <el-button
-                    style="width: 100%"
-                    v-if="item.approveStatus === ApplyLeaveApproveStatus.PASS"
-                    type="primary"
-                    @click.stop="handleReturn(item)"
-                  >
+                  <el-button style="width: 100%" v-if="item.approveStatus === ApplyLeaveApproveStatus.PASS"
+                    type="primary" @click.stop="handleReturn(item)">
                     转回
                   </el-button>
                 </el-col>
                 <el-col :span="12">
-                  <el-button
-                    style="width: 100%"
-                    v-if="item.approveStatus === ApplyLeaveApproveStatus.PASS"
-                    type="primary"
-                    @click.stop="handleDie(item)"
-                  >
+                  <el-button style="width: 100%" v-if="item.approveStatus === ApplyLeaveApproveStatus.PASS"
+                    type="primary" @click.stop="handleDie(item)">
                     淘汰动物上报
                   </el-button>
                 </el-col>
@@ -214,239 +147,240 @@
       </van-list>
     </div>
   </div>
-  <AddEdit
-    ref="addEditRef"
-    @refresh="onLoad"
-  />
-  <TurnBackModal
-    ref="turnBackModalRef"
-    @refresh="onLoad"
-  />
-  <DieModal
-    ref="dieModalRef"
-    @refresh="onLoad"
-  />
+  <AddEdit ref="addEditRef" @refresh="onLoad(true)" />
+  <TurnBackModal ref="turnBackModalRef" @refresh="onLoad(true)" />
+  <DieModal ref="dieModalRef" @refresh="onLoad(true)" />
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive, onMounted } from 'vue'
-  import to from 'await-to-js'
-  import dayjs from 'dayjs'
-
-  import { usePlatAnimalCageApplicationApi } from '/@/api/platform/animal'
-  import { ApplyLeaveApproveStatus, TakeawayList } from '/@/constants/pageConstants'
-  import AddEdit from './components/addEdit.vue'
-  import TurnBackModal from './components/turnBack.vue'
-  import DieModal from './components/dieModal.vue'
-
-  const platAnimalCageApplicationApi = usePlatAnimalCageApplicationApi()
-
-  const addEditRef = ref<InstanceType<typeof AddEdit>>()
-  const turnBackModalRef = ref<InstanceType<typeof TurnBackModal>>()
-  const dieModalRef = ref<InstanceType<typeof DieModal>>()
-
-  const animalTypeList = ref([])
-  const dateTime = ref<any>([])
-
-  const state = reactive({
-    queryParams: {
-      pageNum: 1,
-      pageSize: 10,
-      isMyself: 0,
-      applyDate: '',
-      startDate: '',
-      endDate: '',
-    },
-    loading: true,
-    list: [] as any[],
-    finished: false,
+import { ref, reactive, onMounted } from 'vue'
+import to from 'await-to-js'
+import dayjs from 'dayjs'
+
+import { usePlatAnimalCageApplicationApi } from '/@/api/platform/animal'
+import { ApplyLeaveApproveStatus, TakeawayList } from '/@/constants/pageConstants'
+import AddEdit from './components/addEdit.vue'
+import TurnBackModal from './components/turnBack.vue'
+import DieModal from './components/dieModal.vue'
+
+const platAnimalCageApplicationApi = usePlatAnimalCageApplicationApi()
+
+const addEditRef = ref<InstanceType<typeof AddEdit>>()
+const turnBackModalRef = ref<InstanceType<typeof TurnBackModal>>()
+const dieModalRef = ref<InstanceType<typeof DieModal>>()
+
+const animalTypeList = ref([])
+const dateTime = ref<any>([])
+
+const state = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    isMyself: 0,
+    applyDate: '',
+    startDate: '',
+    endDate: '',
+  },
+  loading: true,
+  list: [] as any[],
+  finished: false,
+})
+
+const getDicts = () => {
+  Promise.all([platAnimalCageApplicationApi.getAnimalTypeList({})]).then(([animalType]) => {
+    animalTypeList.value = animalType.data
   })
+}
 
-  const getDicts = () => {
-    Promise.all([platAnimalCageApplicationApi.getAnimalTypeList({})]).then(([animalType]) => {
-      animalTypeList.value = animalType.data
-    })
+const setListPayload = (isExport?: boolean) => {
+  const payload = {
+    ...state.queryParams,
+    pageSize: isExport ? 99999 : state.queryParams.pageSize,
   }
 
-  const setListPayload = (isExport?: boolean) => {
-    const payload = {
-      ...state.queryParams,
-      pageSize: isExport ? 99999 : state.queryParams.pageSize,
-    }
+  if (dateTime.value && dateTime.value[0]) {
+    payload.startDate = dayjs(dateTime.value[0]).format('YYYY-MM-DD')
+  }
 
-    if (dateTime.value && dateTime.value[0]) {
-      payload.startDate = dayjs(dateTime.value[0]).format('YYYY-MM-DD')
-    }
+  if (dateTime.value && dateTime.value[1]) {
+    payload.endDate = dayjs(dateTime.value[1]).format('YYYY-MM-DD')
+  }
 
-    if (dateTime.value && dateTime.value[1]) {
-      payload.endDate = dayjs(dateTime.value[1]).format('YYYY-MM-DD')
+  Object.entries(payload).forEach(([key, value]) => {
+    if (value === '' || value === null) {
+      delete payload[key as keyof typeof payload]
     }
+  })
 
-    Object.entries(payload).forEach(([key, value]) => {
-      if (value === '' || value === null) {
-        delete payload[key as keyof typeof payload]
-      }
-    })
+  return payload
+}
 
-    return payload
-  }
+const onLoad = async (isSearch?: boolean) => {
+  const [err, res]: ToResponse = await to(
+    platAnimalCageApplicationApi.getAnimalTakeawayApplicationsList({
+      ...setListPayload(),
+      pageNum: isSearch ? 1 : state.queryParams.pageNum,
+    }),
+  )
+  if (err) return
 
-  const onLoad = async (isSearch?: boolean) => {
-    const [err, res]: ToResponse = await to(
-      platAnimalCageApplicationApi.getAnimalTakeawayApplicationsList({
-        ...setListPayload(),
-        pageNum: isSearch ? 1 : state.queryParams.pageNum,
-      }),
-    )
-    if (err) return
-
-    if (res && res.data && res.data.list) {
-      const list = res.data.list || []
-      state.loading = false
-
-      if (!isSearch) {
-        for (const item of list) {
-          state.list.push(item)
-        }
-        state.queryParams.pageNum++
-        if (list.length < state.queryParams.pageSize) {
-          state.finished = true
-        }
-      } else {
-        state.list = list
+  if (res && res.data && res.data.list || []) {
+    const list = res.data.list || []
+    state.loading = false
+
+    if (!isSearch) {
+      for (const item of list) {
+        state.list.push(item)
+      }
+      state.queryParams.pageNum++
+      if (list.length < state.queryParams.pageSize) {
+        state.finished = true
       }
+    } else {
+      state.list = list
     }
   }
+}
 
-  const search = () => {
-    onLoad(true)
-  }
+const search = () => {
+  onLoad(true)
+}
 
-  const handleExport = async () => {
-    const [err, res]: ToResponse = await to(
-      platAnimalCageApplicationApi.getAnimalTakeawayApplicationsListExport({
-        ...setListPayload(true),
-        pageSize: 99999,
-        base64Enable: 1,
-      }),
-    )
-
-    if (err) return
-
-    if (res && res.data) {
-      const { base64, name } = res.data
-      const link = document.createElement('a')
-      link.href = `data:application/octet-stream;base64,${base64}`
-      link.download = name
-      link.style.display = 'none'
-      document.body.appendChild(link)
-      link.click()
-      document.body.removeChild(link)
-    }
-  }
+const handleExport = async () => {
+  const [err, res]: ToResponse = await to(
+    platAnimalCageApplicationApi.getAnimalTakeawayApplicationsListExport({
+      ...setListPayload(true),
+      pageSize: 99999,
+      base64Enable: 1,
+    }),
+  )
+
+  if (err) return
 
-  const handleCheckDetail = (row: TakeawayList) => {
-    addEditRef.value?.openDialog('detail', row)
+  if (res && res.data) {
+    const { base64, name } = res.data
+    const link = document.createElement('a')
+    link.href = `data:application/octet-stream;base64,${base64}`
+    link.download = name
+    link.style.display = 'none'
+    document.body.appendChild(link)
+    link.click()
+    document.body.removeChild(link)
   }
+}
 
-  const formatToChineseDate = (dateStr: string) => {
-    const date = new Date(dateStr)
-    const year = date.getFullYear()
-    const month = String(date.getMonth() + 1).padStart(2, '0')
-    const day = String(date.getDate()).padStart(2, '0')
+const handleCheckDetail = (row: TakeawayList) => {
+  addEditRef.value?.openDialog('detail', row)
+}
 
-    return `${year}年${month}月${day}日`
-  }
+const formatToChineseDate = (dateStr: string) => {
+  const date = new Date(dateStr)
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
 
-  const takeawayComplate = (data: TakeawayList) => {
-    const {
-      dieFemaleNumber,
-      dieMaleNumber,
-      returnFemaleNumber,
-      returnMaleNumber,
-      takeawayMaleNumber,
-      takewayFemaleNumber,
-    } = data
-
-    const total = takeawayMaleNumber + takewayFemaleNumber
-    const returnTotal = returnFemaleNumber + returnMaleNumber
-    const dieTotal = dieFemaleNumber + dieMaleNumber
-
-    return returnTotal >= total || dieTotal >= total || returnTotal + dieTotal >= total
-  }
+  return `${year}年${month}月${day}日`
+}
 
-  const openCageApplicationModal = () => {
-    addEditRef.value.openDialog('add')
-  }
+const takeawayComplate = (data: TakeawayList) => {
+  const {
+    dieFemaleNumber,
+    dieMaleNumber,
+    returnFemaleNumber,
+    returnMaleNumber,
+    takeawayMaleNumber,
+    takewayFemaleNumber,
+  } = data
 
-  const handleReturn = (row: TakeawayList) => {
-    turnBackModalRef.value?.openDialog(row)
-  }
+  const total = takeawayMaleNumber + takewayFemaleNumber
+  const returnTotal = returnFemaleNumber + returnMaleNumber
+  const dieTotal = dieFemaleNumber + dieMaleNumber
 
-  const handleDie = (row: TakeawayList) => {
-    dieModalRef.value?.openDialog(row)
-  }
+  return returnTotal >= total || dieTotal >= total || returnTotal + dieTotal >= total
+}
 
-  onMounted(() => {
-    getDicts()
-    onLoad()
-  })
+const openCageApplicationModal = () => {
+  addEditRef.value.openDialog('add')
+}
+
+const handleReturn = (row: TakeawayList) => {
+  turnBackModalRef.value?.openDialog(row)
+}
+
+const handleDie = (row: TakeawayList) => {
+  dieModalRef.value?.openDialog(row)
+}
+
+onMounted(() => {
+  getDicts()
+  onLoad()
+})
 </script>
 
 <style lang="scss" scoped>
-  .entry-container {
-    position: relative;
-    display: flex;
-    flex-direction: column;
-    .search-wrap {
-      background: #fff;
-      margin-bottom: 10px;
-      padding: 15px;
-    }
-    .list-container {
-      overflow-y: auto;
-      padding: 10px;
-      border-radius: 4px;
-      flex: 1;
-    }
-    .van-list {
-      .van-cell {
-        background-color: #fff;
-        + .van-cell {
-          margin-top: 10px;
-        }
-        header,
-        footer {
-          color: #333;
-        }
-        .title {
-          flex: 1;
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          text-align: left;
-        }
-        .inst-title {
-          color: #333;
-          text-align: left;
-          flex: 1;
-          overflow: hidden;
-          white-space: nowrap;
-          text-overflow: ellipsis;
-          margin-top: 4px;
-        }
-        .time {
-          color: #f69a4d;
-        }
+.entry-container {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+
+  .search-wrap {
+    background: #fff;
+    margin-bottom: 10px;
+    padding: 15px;
+  }
+
+  .list-container {
+    overflow-y: auto;
+    padding: 10px;
+    border-radius: 4px;
+    flex: 1;
+  }
+
+  .van-list {
+    .van-cell {
+      background-color: #fff;
+
+      +.van-cell {
+        margin-top: 10px;
       }
-    }
-    .inst-title {
-      :first-child {
-        color: rgb(120, 120, 120);
+
+      header,
+      footer {
+        color: #333;
+      }
+
+      .title {
+        flex: 1;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        text-align: left;
+      }
+
+      .inst-title {
+        color: #333;
+        text-align: left;
+        flex: 1;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        margin-top: 4px;
+      }
+
+      .time {
+        color: #f69a4d;
       }
     }
   }
-  :deep(.van-tag) {
-    color: #fff !important;
+
+  .inst-title {
+    :first-child {
+      color: rgb(120, 120, 120);
+    }
   }
+}
+
+:deep(.van-tag) {
+  color: #fff !important;
+}
 </style>

+ 166 - 0
src/view/instr/appointList/appointRecord/index.vue

@@ -0,0 +1,166 @@
+<!--
+ * @Author: liuzhenlin 461480418@qq.ocm
+ * @Date: 2023-01-12 11:57:48
+ * @LastEditors: wanglj wanglijie@dashoo.cn
+ * @LastEditTime: 2025-03-26 17:59:17
+ * @Description: file content
+ * @FilePath: \labsop小程序\pages\schedule\myAppoint\index.vue
+-->
+<template>
+  <div class="panel-wrap">
+    <van-empty v-if="appointList.length == 0" mode="list" description="暂无预约记录"></van-empty>
+    <van-list v-else v-model:loading="listloading" class="data-list" :finished="finished" finished-text="没有更多了"
+      @load="onLoad">
+      <div class="inst-item mb40" v-for="(v, index) in appointList" :key="index">
+        <div class="flex flex-between mb20">
+          <div>
+            <div class="mr10">
+              <span class="fontSize14 primary-color bold">{{ v.instName }}</span>
+            </div>
+          </div>
+        </div>
+        <div class="flex mb20">
+          <div class="equ-tit">
+            <span class="fontSize14 bold">设备型号:</span>
+          </div>
+          <div>
+            <span class="fontSize14">{{ v.instNameEn }}</span>
+          </div>
+        </div>
+        <div class="flex mb20" v-if="v.projectName">
+          <div class="equ-tit">
+            <span class="fontSize14 bold">课题组:</span>
+          </div>
+          <div>
+            <span class="fontSize14">{{ v.projectName }}</span>
+          </div>
+        </div>
+        <div class="flex mb20" v-if="v.serviceName">
+          <div class="equ-tit">
+            <span class="fontSize14 bold">服务:</span>
+          </div>
+          <div>
+            <span class="fontSize14">{{ v.serviceName }}</span>
+          </div>
+        </div>
+        <div class="flex mb20">
+          <div class="equ-tit">
+            <span class="fontSize14 bold">所在位置:</span>
+          </div>
+          <div>
+            <span class="fontSize14">{{ v.placeAddress + '(' + (v.laboratoryName || '') + ')' }}</span>
+          </div>
+        </div>
+        <div class="flex">
+          <div class="equ-tit">
+            <span class="fontSize14 bold">开始时间:</span>
+          </div>
+          <div>
+            <span class="fontSize14">{{ v.startTime }}</span>
+          </div>
+        </div>
+        <div class="flex mt20" v-if="v.appointStatus == 10">
+          <van-button class="scan-txt" type="danger" size="small" @click.native.stop="handleCancelAppoint(v)">
+            取消预约
+          </van-button>
+        </div>
+      </div>
+    </van-list>
+  </div>
+</template>
+
+<script>
+import { useMyAppointApi } from '/@/api/appoint'
+const myAppointApi = useMyAppointApi()
+import instAppointApi from '/@/api/instr/instAppoint'
+import to from 'await-to-js'
+import { showConfirmDialog, showNotify } from 'vant'
+export default {
+  data() {
+    return {
+      appointList: [],
+      queryForm: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      curAppointInfo: 0,
+      total: 0,
+      listloading: false,
+      finished: false
+    }
+  },
+  created() { },
+  mounted() {
+    this.queryForm.pageNum = 1
+    this.getInstList()
+  },
+  methods: {
+    // 重新加载
+    onLoad() {
+      this.queryForm.pageNum++
+      this.getInstList()
+    },
+    // 查询列表
+    async getInstList() {
+      this.listloading = true
+      const [err, res] = await to(myAppointApi.getAppointRecord(this.queryForm))
+      this.listloading = false
+      if (err) return
+      if (res?.code === 200) {
+        this.appointList = this.queryForm.pageNum == 1 ? [...(res?.data?.list || [])] : [...this.appointList, ...(res?.data?.list || [])]
+        this.total = res?.data?.total
+        if (this.queryForm.pageNum * this.queryForm.pageSize >= res.data.total) {
+          this.finished = true
+        }
+      }
+    },
+    handleCancelAppoint(row) {
+      showConfirmDialog({
+        title: '提示',
+        message: '确认取消预约?'
+      })
+        .then((e) => {
+          this.cancelAppoint(row.id)
+        })
+        .catch(() => {
+          console.log('ssss')
+        })
+    },
+    async cancelAppoint(id) {
+      const params = { id }
+      const [err, res] = await to(instAppointApi.userCancelAppoint(params))
+      this.modalVisible = false
+      if (err) return
+      if (res?.code === 200) {
+        this.queryForm.pageNum = 1
+        this.appointList = []
+        this.getInstList()
+        showNotify({ type: 'success', message: '取消成功' })
+      }
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+* {
+  box-sizing: border-box;
+}
+
+.panel-wrap {
+  height: 100%;
+
+  .data-list {
+    .inst-item {
+      border-radius: 10px;
+      padding: 15px;
+      box-shadow: -2px 0px 9px rgba(0, 0, 0, 0.12);
+      margin-bottom: 20px;
+      background-color: #fff;
+
+      .equ-tit {
+        width: 74px;
+      }
+    }
+  }
+}
+</style>

+ 7 - 1
src/view/instr/appointList/index.vue

@@ -26,6 +26,11 @@
           <my-appoint v-if="active === 2" ref="myAppointRef" />
         </div>
       </van-tab>
+      <van-tab title="预约记录">
+        <div class="list-container">
+          <appoint-record v-if="active === 3" ref="recordRef" />
+        </div>
+      </van-tab>
     </van-tabs>
     <!-- </van-pull-refresh> -->
     <van-tabbar route :placeholder="true">
@@ -39,9 +44,10 @@
   import SoonGeton from './soonGeton/index.vue'
   import InProgress from './inProgress/index.vue'
   import MyAppoint from './myAppoint/index.vue'
+  import AppointRecord from './appointRecord/index.vue'
   export default {
     name: 'appointList',
-    components: { SoonGeton, InProgress, MyAppoint },
+    components: { SoonGeton, InProgress, MyAppoint, AppointRecord },
     data() {
       return {
         loading: false,

Some files were not shown because too many files changed in this diff