Browse Source

新增药品计划申请与审核功能

hsh 6 months ago
parent
commit
99105b3a81

+ 47 - 0
src/api/yp-inventory/yp-plan-info.js

@@ -0,0 +1,47 @@
+import request from '../../utils/request'
+
+
+// 查询药品计划申请与审核信息
+export function selectYpPlanInfo(data) {
+    return request({
+        url: '/ypPlan/selectYpPlanInfo',
+        method: 'post',
+        data
+    })
+}
+
+// 查询药品计划申请与审核的药品明细
+export function selectYpPlanDetail(data) {
+    return request({
+        url: '/ypPlan/selectYpPlanDetail',
+        method: 'post',
+        data
+    })
+}
+
+// 根据fileID查询药品计划申请与审核的药品明细
+export function selectYpPlanDetailById(data) {
+    return request({
+        url: '/ypPlan/selectYpPlanDetailById',
+        method: 'post',
+        data
+    })
+}
+
+// 保存药品计划申请与审核的药品明细
+export function saveYpPlanFile(data) {
+    return request({
+        url: '/ypPlan/saveYpPlanFile',
+        method: 'post',
+        data
+    })
+}
+
+// 审核更新状态
+export function updateYpPlanAuditData(data) {
+    return request({
+        url: '/ypPlan/updateYpPlanAuditData',
+        method: 'post',
+        data
+    })
+}

+ 64 - 0
src/views/yp-inventory/YpPlanDetails.vue

@@ -0,0 +1,64 @@
+<template>
+  <div class="layout_display_flex_y">
+    <div class="layout_container">
+      <div class="layout_main layout_el-table">
+        <el-table :data="ypPlanDetailData.slice(pageSize * (currentPage - 1), pageSize * currentPage)" border stripe highlight-current-row>
+          <el-table-column type="index" label="序号" width="60" fixed/>
+          <el-table-column prop="remark" label="备注" width="120" fixed/>
+          <el-table-column prop="drugName" label="药品名称" width="220" show-overflow-tooltip fixed/>
+          <el-table-column prop="specification" label="规格" width="150" show-overflow-tooltip/>
+          <el-table-column prop="packRetprice" label="零售价" width="100"/>
+          <el-table-column prop="buyPrice" label="购入价" width="100"/>
+          <el-table-column prop="amount" label="库存量" width="100" />
+          <el-table-column prop="manuName" label="制药厂" width="150" show-overflow-tooltip/>
+          <el-table-column prop="amount3" label="3天用量" width="100" />
+          <el-table-column prop="amount7" label="7天用量" width="100" />
+          <el-table-column prop="amount14" label="14天用量" width="100" />
+          <el-table-column prop="amount30" label="30天用量" width="100" />
+          <el-table-column prop="amount60" label="60天用量" width="100" />
+          <el-table-column prop="days" label="可用天数" width="100" />
+          <el-table-column prop="buyAmount" label="采购计划" width="100" />
+          <el-table-column prop="unit" label="单位" width="100" />
+          <el-table-column prop="buyFee" label="购入金额" width="100" />
+          <el-table-column prop="impDate" label="导入时间" width="140" />
+        </el-table>
+      </div>
+      <div>
+        <el-pagination :current-page="currentPage" :page-size="pageSize" :page-sizes="[10, 15, 20, 25]"
+                       :total="ypPlanDetailData.length" layout="total, sizes, prev, pager, next, jumper"
+                       style="margin-top: 5px" @size-change="handleSizeChange"
+                       @current-change="handleCurrentChange">
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+<script setup name="YpPlanDetails">
+import { ref, onMounted, nextTick, watch } from 'vue'
+
+const props = defineProps({
+  ypPlanDetails: {
+    type: Object,
+    default: []
+  }
+})
+const ypPlanDetailData = ref([])
+const pageSize = ref(20)
+const currentPage = ref(1)
+const handleSizeChange = (val) => {
+  pageSize.value = val
+}
+const handleCurrentChange = (val) => {
+  currentPage.value = val
+}
+
+onMounted(() => {
+  nextTick(() => {
+    ypPlanDetailData.value = props.ypPlanDetails
+  })
+})
+
+watch(() => props.ypPlanDetails, () => {
+  ypPlanDetailData.value = props.ypPlanDetails
+})
+</script>

+ 402 - 0
src/views/yp-inventory/YpPlanInfo.vue

@@ -0,0 +1,402 @@
+<template>
+  <div class="layout_container">
+    <header>
+      <el-input v-model="fileText" class="w-50 m-2" style="width: 220px" placeholder="请输入文件id或者名称" clearable>
+      </el-input>
+      <el-select v-model="ztFlag" placeholder="请选择审核进度" clearable style="width: 140px;margin-left: 3px">
+        <el-option v-for="item in ztOptions" :key="item.value" :label="item.label" :value="item.value">
+        </el-option>
+      </el-select>
+      <el-date-picker v-model="dateRange" type="daterange" :shortcuts="maxHalfYear" range-separator="至"
+                      start-placeholder="开始时间" end-placeholder="结束时间" style="width: 260px;margin-left: 3px">
+      </el-date-picker>
+      <el-button type="primary" icon="Search" @click="queryYpPlanInfoData" style="margin-left: 5px">查询
+      </el-button>
+<!--      <el-button type="primary" icon="Download" @click="exportData" style="margin-left: 5px">导出</el-button>-->
+    </header>
+    <div class="layout_main">
+      <el-tabs class="el-tabs__fill" v-model="editableTabsValue" type="border-card" @tab-click="handleClick">
+        <el-tab-pane key="ypPlanInfo" label="明细" name="ypPlanInfo">
+          <div class="layout_container">
+            <div class="layout_main layout_el-table">
+              <el-table :data="ypPlanInfoData.slice(pageSize * (currentPage - 1), pageSize * currentPage)" border
+                        stripe highlight-current-row @row-dblclick="queryYpPlanDetail">
+                <el-table-column type="index" label="序号" width="60" fixed/>
+                <el-table-column prop="fileId" label="id" width="120" fixed/>
+                <el-table-column prop="fileName" label="名称" width="220" show-overflow-tooltip fixed/>
+                <el-table-column prop="totalFee" label="总价" width="120"/>
+                <el-table-column prop="applyName" label="申请人" width="100"/>
+                <el-table-column prop="applyDate" label="申请时间" width="140"/>
+                <el-table-column prop="trialAudit" label="初审" width="100">
+                  <template #default="scope">
+                    <span v-if="scope.row.trialAudit === '1'">审核通过</span>
+                    <span v-else>未审核</span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="reviewAudit" label="复审" width="100">
+                  <template #default="scope">
+                    <span v-if="scope.row.reviewAudit === '1'">审核通过</span>
+                    <span v-else>未审核</span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="finalAudit" label="终审" width="100">
+                  <template #default="scope">
+                    <span v-if="scope.row.finalAudit === '1'">审核通过</span>
+                    <span v-else>未审核</span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="applyContent" label="药库负责人意见" width="200" show-overflow-tooltip/>
+                <el-table-column prop="trialName" label="初审人" width="100"/>
+                <el-table-column prop="trialContent" label="药剂科主任意见" width="200" show-overflow-tooltip/>
+                <el-table-column prop="reviewName" label="复审人" width="100"/>
+                <el-table-column prop="reviewContent" label="主管会计复审意见" width="200" show-overflow-tooltip/>
+                <el-table-column prop="finalName" label="终审人" width="100"/>
+                <el-table-column prop="finalContent" label="行政中心主任终审意见" width="200" show-overflow-tooltip/>
+                <el-table-column fixed="right" label="操作" min-width="180" width="180" header-align="center" align="center">
+                  <template #default="scope">
+                    <el-button type="primary" size="small" @click="trialAuditPlan(scope.row)">初审
+                    </el-button>
+                    <el-button type="primary" size="small" @click="reviewAuditPlan(scope.row)">复审
+                    </el-button>
+                    <el-button type="primary" size="small" @click="finalAuditPlan(scope.row)">终审
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+            <div>
+              <el-pagination :current-page="currentPage" :page-size="pageSize" :page-sizes="[15, 30, 45, 60]"
+                             :total="ypPlanInfoData.length" layout="total, sizes, prev, pager, next, jumper"
+                             style="margin-top: 5px" @size-change="handleSizeChange"
+                             @current-change="handleCurrentChange">
+              </el-pagination>
+            </div>
+          </div>
+          <el-dialog v-model="showYpPlanDetails" :close-on-click-modal="false" :before-close="handleClose"
+                     :close-on-press-escape="false" :title="ypPlanDetailsTitle" width="80%" destroy-on-close>
+            <YpPlanDetails :ypPlanDetails="ypPlanDetails" @closeTempPurchaseAudit="closeYpPlanDetails"/>
+          </el-dialog>
+          <el-dialog v-model="dialogFormVisible" title="审核" width="500" :close-on-click-modal="false" :close-on-press-escape="false" destroy-on-close>
+            <el-form :model="form">
+              <el-input v-model="form.fileId" v-if="false" />
+              <el-input v-model="form.type" v-if="false" />
+              <el-form-item label="审核意见" :label-width="formLabelWidth">
+                <el-input v-model="form.content" autocomplete="off" />
+              </el-form-item>
+            </el-form>
+            <template #footer>
+              <div class="dialog-footer">
+                <el-button @click="dialogFormVisible = false">取消</el-button>
+                <el-button type="primary" @click="updateYpPlanAudit">
+                  确认
+                </el-button>
+              </div>
+            </template>
+          </el-dialog>
+        </el-tab-pane>
+        <el-tab-pane key="ypPlan" label="导入" name="ypPlan">
+          <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px"
+                   class="demo-ruleForm" :size="formSize" status-icon>
+            <el-row>
+              <el-col :span="6">
+                <el-form-item label="ID" prop="fileId">
+                  <el-input v-model="ruleForm.fileId" maxlength="12" show-word-limit placeholder="年月+第几次:例如20250201"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="名称" prop="fileName">
+                  <el-input v-model="ruleForm.fileName" maxlength="60" show-word-limit placeholder="名称"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="药库意见" prop="applyContent">
+                  <el-input v-model="ruleForm.applyContent" maxlength="60" show-word-limit placeholder="药库意见"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="类别" prop="fileType">
+                  <el-select v-model="ruleForm.fileType" placeholder="请选择类别" clearable style="width: 100%">
+                    <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
+                      <span style="float: left">{{ item.label }}</span>
+                      <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px;">
+                          {{ item.value }}
+                      </span>
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6" style="margin-left: 60px">
+                <div style="margin-top: 10px">
+                  <el-upload
+                      class="upload-demo"
+                      ref="upload"
+                      accept=".xlsx,.xls"
+                      :action="apiUrl + '/ypPlan/saveYpPlanFile'"
+                      :headers="header"
+                      :file-list="fileList"
+                      :limit="1"
+                      :data="ruleForm"
+                      :on-exceed="fileSizeOutLimit"
+                      :on-success="uploadSuccess"
+                      :on-error="uploadError"
+                      :auto-upload="false"
+                  >
+                    <template #trigger>
+                      <el-button type="primary" icon="Picture">选取文件</el-button>
+                    </template>
+                    <el-button style="margin-left: 10px" type="success" icon="Upload" @click="submitUpload(ruleFormRef)">上传</el-button>
+                    <el-button type="info" @click="resetForm(ruleFormRef)">重置</el-button>
+                    <template #tip>
+                      <div class="el-upload__tip">
+                        只能上传 xls/xlsx 文件,且同时只能上传一个文件
+                      </div>
+                    </template>
+                  </el-upload>
+                </div>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
+</template>
+<script setup>
+import {useUserStore} from '@/pinia/user-store'
+import {nextTick, onMounted, ref} from "vue";
+import {formatDatetime, formatYear, getDateRangeFormatDate} from "@/utils/date.js";
+import {maxHalfYear} from "@/data/shortcuts.js";
+import {ElMessage} from "element-plus";
+import {selectYpPlanInfo, selectYpPlanDetailById, saveYpPlanFile, updateYpPlanAuditData} from "@/api/yp-inventory/yp-plan-info.js";
+import env from "@/utils/setting";
+import YpPlanDetails from "@/views/yp-inventory/YpPlanDetails.vue";
+
+const userInfo = useUserStore().userInfo
+const apiUrl = env.VITE_BASE_URL
+const upload = ref()
+const fileList = ref([])
+const header = {
+  token: useUserStore().getToken,
+};
+const fileSizeOutLimit = () => {
+  ElMessage.error("已经选取excel,如须更换请先移除已选取的excel!");
+};
+const uploadSuccess = () => {
+  ElMessage.success("上传成功!");
+};
+const uploadError = () => {
+  ElMessage.error("上传失败!");
+};
+const editableTabsValue = ref('ypPlanInfo')
+const userCode = userInfo.code
+const userName = userInfo.name
+const ypPlanInfoData = ref([])
+const fileText = ref('')
+const chargeCode = ref('')
+const ztFlag = ref('')
+const dateRange = ref([])
+const now = formatDatetime(new Date())
+const start = formatDatetime(maxHalfYear[2].value[0])
+const end = formatDatetime(maxHalfYear[2].value[1])
+const pageSize = ref(30)
+const currentPage = ref(1)
+const handleSizeChange = (val) => {
+  pageSize.value = val
+}
+const handleCurrentChange = (val) => {
+  currentPage.value = val
+}
+const handleClick = (tab, event) => {
+  editableTabsValue.value = tab.props.name
+  if (editableTabsValue.value === 'ypPlanInfo') {
+    queryYpPlanInfoData()
+  }
+}
+const ztOptions = [
+  {value: '1', label: '已初审'}, {value: '2', label: '未初审'}, {value: '3', label: '已复审'},
+  {value: '4', label: '未复审'}, {value: '5', label: '已终审'}, {value: '6', label: '未终审'}]
+const typeList = [{value: '1', label: '普通药品'}, {value: '2', label: '大输液'},{value: '3', label: '麻精药品'},{value: '4', label: '其他药品'}]
+const queryData = ref({
+  fileId: '',
+  fileType: '',
+  startTime: '',
+  endTime: '',
+})
+onMounted(() => {
+  nextTick(() => {
+    queryData.startTime = start;
+    queryData.endTime = end + " 23:59:59";
+    dateRange.value = [start, end];
+    queryYpPlanInfoData()
+  })
+})
+const formSize = ref('default')
+const ruleFormRef = ref()
+const ruleForm = ref({
+  fileId: '', // 文件id
+  fileName: '', // 文件名称
+  fileType: '', // 文件类型
+  applyDate: now, // 申请日期
+  applyId: '', // 申请人id
+  applyName: '', // 申请人
+  applyContent: '', // 申请人意见
+})
+const rules = ref({
+  fileType: [
+    {required: true, message: '请选择文件类型', trigger: 'change'},
+  ],
+  fileId: [
+    {required: true, message: '请填写文件ID', trigger: 'blur'},
+  ],
+  fileName: [
+    {required: true, message: '请填写文件名称', trigger: 'blur'},
+  ],
+  fileList: [
+    {required: true, message: '请选择文件', trigger: 'blur'},
+  ],
+})
+
+const submitUpload = async (formEl) => {
+  if (!formEl) return
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      nextTick(() => {
+        upload.value.submit();
+      });
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+}
+
+const submitForm = async (formEl) => {
+  if (!formEl) return
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      saveYpPlanFile(ruleForm.value).then((res) => {
+        if (res.cg) {
+          ElMessage({
+            type: "success",
+            message: res.cg,
+            duration: 2500,
+            showClose: true,
+          });
+
+          formEl.resetFields()
+          editableTabsValue.value = 'ypPlanInfo'
+          queryYpPlanInfoData()
+        }
+      });
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+}
+
+const resetForm = (formEl) => {
+  if (!formEl) return
+  formEl.resetFields()
+}
+
+const queryYpPlanInfoData = () => {
+  if (dateRange.value) {
+    let dateS = getDateRangeFormatDate(dateRange.value)
+    queryData.value.startTime = dateS.startTime
+    queryData.value.endTime = dateS.endTime
+  }
+  queryData.value.fileId = fileText.value
+  queryData.value.ztFlag = ztFlag.value
+  selectYpPlanInfo(queryData.value)
+      .then((res) => {
+        ypPlanInfoData.value = res
+      })
+      .catch(() => {
+        ypPlanInfoData.value = []
+      })
+}
+
+const ypPlanDetails = ref([]);
+const ypPlanDetailsTitle = ref('药品计划申请与审核明细')
+const showYpPlanDetails = ref(false);
+const queryYpPlanDetail = (row) => {
+  let data = {
+    fileId: row.fileId,
+  }
+  selectYpPlanDetailById(data)
+    .then((res) => {
+      ypPlanDetails.value = res;
+      showYpPlanDetails.value = true;
+    })
+    .catch(() => {
+      ypPlanDetails.value = [];
+    });
+}
+const closeYpPlanDetails = (flag) => {
+  if (flag) {
+    showYpPlanDetails.value = false
+  }
+  queryYpPlanInfoData()
+}
+const handleClose = (done) => {
+  queryYpPlanInfoData()
+  done()
+}
+
+
+const dialogFormVisible = ref(false)
+const formLabelWidth = '140px'
+const form = ref({
+  fileId: '', // 审核计划id
+  content: '', // 审核意见
+  trialAudit: '',
+  reviewAudit: '',
+  finalAudit: '',
+  type: 0, // 审核类型(1:初审,2:复审,3:终审)
+})
+// 审核
+const trialAuditPlan = (row) => {
+  dialogFormVisible.value = true
+  form.value.fileId = row.fileId
+  form.value.type = 1
+  form.value.trialAudit = '1'
+}
+const reviewAuditPlan = (row) => {
+  dialogFormVisible.value = true
+  form.value.fileId = row.fileId
+  form.value.type = 2
+  form.value.reviewAudit = '1'
+}
+const finalAuditPlan = (row) => {
+  dialogFormVisible.value = true
+  form.value.fileId = row.fileId
+  form.value.type = 3
+  form.value.finalAudit = '1'
+}
+const updateYpPlanAudit = () => {
+  dialogFormVisible.value = false
+  updateYpPlanAuditData(form.value)
+    .then((res) => {
+      if (res.cg) {
+        ElMessage({
+          type: "success",
+          message: res.cg,
+          duration: 2500,
+          showClose: true,
+        });
+        queryYpPlanInfoData()
+      }
+    })
+    .catch(() => {
+      ElMessage({
+        type: "error",
+        message: '药品计划审核失败!',
+        duration: 2500,
+        showClose: true,
+      });
+      queryYpPlanInfoData()
+    })
+}
+
+</script>