Pārlūkot izejas kodu

餐饮计划增加导入,营养记录列表时间格式化

xiongxing 2 mēneši atpakaļ
vecāks
revīzija
b9f08dc20b

+ 2 - 1
src/views/elderly/nursing/records/nutrition-record/index.vue

@@ -62,7 +62,7 @@
       <el-table-column prop="bedInfo" header-align="center" align="center" label="床位号" min-width="200" show-overflow-tooltip/>
       <el-table-column prop="recordTime" header-align="center" align="center" label="记录时间" min-width="150" show-overflow-tooltip>
         <template #default="scope">
-          {{(scope.row.recordTime)}}
+          {{formatDate(scope.row.recordTime)}}
         </template>
       </el-table-column>
       <el-table-column prop="recordContent" header-align="center" align="center" label="营养情况描述" min-width="220" show-overflow-tooltip/>
@@ -122,6 +122,7 @@ import {
 import { useUserStore } from '@/store/modules/user'
 import {formatToDateTime, getCurrentMonthRange} from "@/utils/dateUtil";
 import {exportWithExpandedObjectArrays} from "@/utils/excel-export";
+import { formatDate } from '@/utils/formatTime'
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 const userStore = useUserStore()

+ 204 - 0
src/views/system/food/CateringPlan/importForm.vue

@@ -0,0 +1,204 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="props.config.title" width="500">
+    <div class="primary-wrap" v-if="props.config.downloadUrl">请先下载模版再导入数据!({{props.config.desc}})</div>
+    <div class="box-wrap">
+      <div class="left" @click="handleDownLoad" v-if="props.config.downloadUrl">
+        <Icon icon="fa:cloud-download" :size="46" />
+        <p>下载模版</p>
+      </div>
+      <div class="right">
+        <el-upload
+          ref="uploadRef"
+          v-model:file-list="fileList"
+          :action="importUrl"
+          :disabled="formLoading"
+          :headers="uploadHeaders"
+          class="upload-demo"
+          :on-progress="onProgressHandel"
+          :on-error="submitFormError"
+          :on-exceed="handleExceed"
+          :on-success="submitFormSuccess"
+          accept=".xlsx, .xls"
+        >
+
+        <Icon icon="fa:cloud-upload" :size="46" />
+        <p>立即导入</p>
+      </el-upload>
+      </div>
+    </div>
+    <template #footer>
+      <!-- <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> -->
+      <el-button :disabled="formLoading" :loading="formLoading" @click="dialogVisible = false">关 闭</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+import { getAccessToken, getTenantId } from '@/utils/auth'
+import download from '@/utils/download'
+import request from '@/config/axios'
+import {PropType} from "vue";
+defineOptions({ name: 'ImportFile' })
+
+interface configType {
+  title?: string
+  importUrl?: string
+  baseImportUrl?: string
+  exportUrl?: string
+  excelTempName: string
+  downloadUrl: string
+  desc: string
+  failExportUrl: string;
+  tenantId?: string
+}
+const props = defineProps({
+  config: {
+    type: Object as PropType<configType>,
+    default: () => {
+      return {
+        title: '导入',
+        importUrl: '',
+        baseImportUrl: '',
+        exportUrl: '',
+        excelTempName: '',
+        desc:'',
+        downloadUrl: '',
+        failExportUrl: '', // 上传失败的接口
+        tenantId: '',
+      }
+    }
+  }
+})
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const formLoading = ref(false) // 表单的加载中
+const uploadRef = ref()
+const importUrl = ref('')
+const uploadHeaders = ref({
+  Authorization: 'Bearer ' + getAccessToken(),
+  'tenant-id': getTenantId()
+}) // 上传 Header 头
+const fileList = ref([]) // 文件列表
+
+/** 打开弹窗 */
+const open = (restaurantId?: string | number) => {
+  dialogVisible.value = true
+  fileList.value = []
+  const baseUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL
+  const baseImportUrl = props.config.baseImportUrl || props.config.importUrl
+  if (restaurantId !== undefined && restaurantId !== null && restaurantId !== '') {
+    importUrl.value = `${baseUrl}${baseImportUrl}?restaurantId=${restaurantId}`
+  } else {
+    importUrl.value = `${baseUrl}${baseImportUrl}`
+  }
+  resetForm()
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 文件上传成功 */
+const emits = defineEmits(['success'])
+const submitFormSuccess = async (response: any) => {
+  if (response.code !== 0) {
+    message.error(response.msg)
+    formLoading.value = false
+    return
+  }
+  // 拼接提示语
+  const data = response.data
+  formLoading.value = false
+  dialogVisible.value = false
+  if(data.failCount > 0){
+    // 导出的二次确认
+    await message.exportConfirm(`上传成功${data.successCount}条,失败${data.failCount}条,是否导出错误信息?`)
+    if(!props.config.failExportUrl){
+      message.warning(`功能暂未开放,敬请期待~`)
+    }else{
+      // 下载
+      const res = await request.download({ url: props.config.failExportUrl, data: data.errorList, method: 'POST' })
+      download.excel(res, `${props.config.excelTempName}错误信息.xls`)
+    }
+  }else if(data.successCount > 0){
+    message.success(`上传成功${data.successCount}条`)
+  }
+
+  // 发送操作成功的事件
+  emits('success')
+}
+
+const onProgressHandel = () => {
+    formLoading.value = true
+}
+
+/** 上传错误提示 */
+const submitFormError = (): void => {
+  message.error('上传失败,请您重新上传!')
+  formLoading.value = false
+}
+
+/** 重置表单 */
+const resetForm = async (): Promise<void> => {
+  // 重置上传状态和文件
+  formLoading.value = false
+  await nextTick()
+  uploadRef.value?.clearFiles()
+}
+
+/** 文件数超出提示 */
+const handleExceed = (): void => {
+  message.error('最多只能上传一个文件!')
+}
+
+/** 下载模板操作 */
+const handleDownLoad = async () => {
+  const res = await  request.download({ url: props.config.downloadUrl })
+  download.excel(res, `${props.config.excelTempName}.xls`)
+}
+</script>
+<style lang="scss" scoped>
+.primary-wrap {
+  background-color: var(--el-color-primary-light-9);
+  color: var(--el-color-primary);
+  padding: 10px 5px;
+  border-radius: 4px;
+}
+.box-wrap {
+  display: flex;
+  justify-content: space-around;
+  .left,
+  .right {
+    margin-top: 20px;
+    width: 150px;
+    height: 150px;
+    border-radius: 8px;
+    text-align: center;
+    border: 1px solid var(--el-color-primary-light-7);
+    color: var(--el-color-primary);
+    cursor: pointer;
+  }
+  .right {
+    margin-left: 20px;
+    border: 1px solid var(--el-color-info-light-7);
+    color: var(--el-color-info);
+    .upload-demo{
+      height: 100%;
+    }
+  }
+  .el-icon {
+    margin-top: 30px;
+  }
+  p {
+    padding: 10px 0;
+  }
+}
+</style>
+<style lang="scss">
+.box-wrap {
+  .right{
+    .upload-demo{
+      .el-upload{
+        flex-direction: column !important;
+      }
+    }
+  }
+}
+</style>

+ 11 - 6
src/views/system/food/CateringPlan/index.vue

@@ -69,7 +69,7 @@
         <Icon icon="ep:delete" class="mr-5px" />
         复制计划
       </el-button>
-      <!-- <el-button type="success" @click="openImport"><Icon icon="ep:download" class="mr-5px" />导入</el-button> -->
+      <el-button v-hasPermi="['food:catering-plan:import']" type="success" @click="openImport"><Icon icon="ep:download" class="mr-5px" />导入</el-button>
     </div>
 
     <el-table
@@ -165,7 +165,7 @@
   <AddForm ref="addFoodRef" @success="getList" />
   <DetailsForm ref="foodDetailsForm" @success="getList" />
   <!-- 导入弹窗(复用 system/user 的 ImportFile 组件) -->
-  <Import ref="importRef" :config="importConfig" @success="getList" />
+  <ImportForm ref="importRef" :config="importConfig" @success="getList" />
 </template>
 
 <script setup lang="ts">
@@ -175,7 +175,7 @@ import AddForm from '@/views/system/food/CateringPlan/AddForm.vue'
 import DetailsForm from '@/views/system/food/CateringPlan/DetailsForm.vue'
 import { chargeCategoryDel } from '@/api/elderly/fee/chargeCategory'
 import {cateringPlanDelete, getCateringPlanPage, getListRestaurant} from "@/api/system/foods";
-import Import from '@/components/ImportFile/index.vue'
+import ImportForm from './importForm.vue'
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
@@ -376,17 +376,22 @@ const importRef = ref()
 const importConfig = reactive({
   title: '餐饮计划导入',
   // TODO: 替换成你的真实导入接口
-  importUrl: '/materialInfo/import',
+  importUrl: '/restaurant/cateringPlan/import',
+  baseImportUrl: '/restaurant/cateringPlan/import',
   excelTempName: '餐饮计划导入模板',
   // TODO: 替换成你的真实模板下载接口
-  downloadUrl: '/materialInfo/downloadExcel',
+  downloadUrl: '/restaurant/cateringPlan/import-template',
   desc: '餐饮计划',
   // TODO: 如果后端支持失败信息导出,填真实接口;不支持可留空
   failExportUrl: '',
 })
 
 const openImport = () => {
-  importRef.value?.open?.()
+  if (!queryParams.restaurantId) {
+    message.warning('请先选择餐厅后再导入')
+    return
+  }
+  importRef.value?.open?.(queryParams.restaurantId)
 }
 
 /** 初始化 **/