Browse Source

增加映射医疗机构药品功能

kumu 1 year ago
parent
commit
d2f52b5620

+ 1 - 0
package.json

@@ -58,6 +58,7 @@
     "quill": "1.3.7",
     "screenfull": "5.0.2",
     "sortablejs": "1.10.2",
+    "v-selectpage": "^2.1.4",
     "vue": "2.6.12",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",

+ 86 - 0
src/api/drugs/drugs.js

@@ -60,3 +60,89 @@ export function listAll(query) {
     params: query
   })
 }
+
+export function drugsMap(query) {
+  const {pageNum, pageSize, date, ...data} = query;
+  if (Array.isArray(date)) [data.startTime, data.endTime = data.startTime] = date;
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/pageHerbsMapping',
+    method: 'post',
+    data,
+    params: {pageNum, pageSize},
+  })
+}
+
+export function drugsMapDelete(id) {
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/deleteHerbsMapping',
+    method: 'post',
+    data: Array.isArray(id) ? id : [id],
+  })
+}
+
+export function drugsMapUpdate(data, query) {
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/addHerbsMapping',
+    method: 'post',
+    data: data.map(item => Object.assign({}, query, item))
+  })
+}
+
+export function drugsMapImport(query) {
+  const form = new FormData();
+  for (const [key, value] of Object.entries(query)) form.append(key, value);
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/importHerbsMapping',
+    method: 'post',
+    data: form,
+  })
+}
+
+export function drugsMapImportTemplate() {
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/downloadImportTemplate',
+    method: 'post',
+    responseType: 'blob',
+    fileType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8',
+  })
+}
+
+export function drugsMapExport(query) {
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/exportHerbsMapping',
+    method: 'post',
+    data: query,
+    responseType: 'blob',
+    fileType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8',
+  })
+}
+
+/**
+ * 搜索系统药品
+ * @param query
+ * @param {string} query.name
+ */
+export function drugsSearchForSystem(query) {
+  return request({
+    url: '/yfc-admin/drugs/drugs/listAll',
+    method: 'get',
+    params: query
+  })
+}
+
+/**
+ * 搜索医疗机构药品
+ * @param query
+ * @param {string} query.herbsName
+ * @param {string} query.communityId
+ * @param {string} query.mechanismId
+ */
+export function drugsSearchForMechanism(query) {
+  const {pageNum, pageSize, date, ...data} = query;
+  return request({
+    url: '/yfc-admin/medicalHerbsManage/getAllHerbs',
+    method: 'post',
+    data,
+    params: {pageNum, pageSize},
+  })
+}

+ 17 - 0
src/api/select-page.js

@@ -0,0 +1,17 @@
+import {drugsSearchForMechanism, drugsSearchForSystem} from "@/api/drugs/drugs";
+
+export default {
+  'drugsSearchForSystem': (query) => {
+    return drugsSearchForSystem({name: query.name || ''})
+  },
+  'drugsSearchForMechanism': (query) => {
+    return drugsSearchForMechanism({
+      herbsName: query.name || '',
+      communityId: query.communityId,
+      mechanismId: query.mechanismId,
+      isMapping: '',
+      pageNum: query.pageNumber,
+      pageSize: query.pageSize,
+    })
+  }
+}

+ 9 - 0
src/main.js

@@ -1,4 +1,6 @@
 import Vue from 'vue'
+import vSelectPage from 'v-selectpage'
+import vSelectPageDataLoad from '@/api/select-page'
 
 import Cookies from 'js-cookie'
 
@@ -71,6 +73,13 @@ Vue.use(directive)
 Vue.use(VueMeta)
 Vue.use(Print)
 
+Vue.use(vSelectPage, {
+  // 服务器端数据加载器
+  dataLoad: function(vue, data, params) {
+    return vSelectPageDataLoad[data](params);
+  }
+})
+
 // import printer from '@/utils/printer.js'
 // Vue.mixin(printer)
 /**

+ 9 - 0
src/utils/request.js

@@ -53,6 +53,15 @@ service.interceptors.request.use(config => {
 
 // 响应拦截器
 service.interceptors.response.use(res => {
+    if (res.config.fileType && res.data instanceof Blob) {
+      const value = res.headers['Content-Disposition'] || res.headers['content-disposition'] || '';
+      return {
+        name: (value.match(/fileName=["']([^"']+)["']/) || [])[1],
+        blob: new Blob([res.data], { type: res.config.fileType }),
+      }
+    } else if (res.config.forced) {
+      return res;
+    }
     // 未设置状态码则默认成功状态
     const code = res.data.code || 200;
     // 获取错误信息

+ 207 - 0
src/views/drugs/map/edit.vue

@@ -0,0 +1,207 @@
+<script>
+import {drugsMapUpdate} from "@/api/drugs/drugs";
+
+
+export default {
+  components: {
+    // 'v-selectpage': SelectPage
+  },
+  props: {
+    communityId: {type: [String, Number], required: true},
+    mechanismId: {type: [String, Number], required: true},
+  },
+  data() {
+    return {
+      dataset: [],
+      searchTableForSystemColumns: [
+        {title: "名称", data: "drugsName"},
+        {title: "编码", data: "drugsId"},
+        {title: "规格", data: "drugsSpecsName"},
+        {title: "产地", data: "placeName"},
+        {title: "零售价", data: "retail"},
+      ],
+      searchTableForMechanismColumns: [
+        {title: "名称", data: "herbsName"},
+        {title: "编码", data: "herbsCode"},
+        {title: "规格", data: "specsName"},
+        {title: "产地", data: "placeName"},
+      ],
+
+      editSystem: -1,
+      editMechanism: -1,
+    }
+  },
+  computed: {
+    tableHeight() {
+      return Math.min(Math.floor(window.innerHeight * 0.6), 598 + 2);
+    },
+    selected() {
+      return this.dataset.filter(item => item && item.drugsId && item.herbsId);
+    },
+  },
+  mounted() {
+    const dataset = Array.from({length: 1 - this.dataset.length});
+    for (const _ of dataset) this.append();
+  },
+  methods: {
+    append(model) {
+      this.dataset.push(model || {});
+    },
+    handleDelete(row, index) {
+      this.dataset.splice(index, 1);
+    },
+    tableSpanMethod({row, column, rowIndex, columnIndex}) {
+      if (column.type === 'index' || column.label === '操作') return [1, 1];
+
+      if (columnIndex === 1) return row.drugsName ? [1, 1] : [1, 2];
+      if (columnIndex === 2) return row.drugsName ? [1, 1] : [0, 0];
+      if (columnIndex === 3) return row.herbsName ? [1, 1] : [1, 4];
+      return row.herbsName ? [1, 1] : [0, 0];
+    },
+    async handle() {
+      if (!this.selected.length) return this.msgInfo('请至少填写一条数据');
+
+      const index = this.dataset.findIndex(item => (item.drugsId && !item.herbsId) || (item.herbsId && !item.drugsId));
+      if (index !== -1) return this.msgInfo(`第 ${index + 1} 行数据请补充完整`);
+
+      try {
+        const {msg = '创建成功'} = await drugsMapUpdate(this.selected, {
+          communityId: this.communityId,
+          mechanismId: this.mechanismId,
+        })
+        this.msgSuccess(msg);
+        this.$emit('close', true);
+      } catch (error) {}
+    },
+    cancel() {
+      this.$emit('close', false);
+    },
+
+
+    searchTableFormat(res) {
+      try {
+        if (res.rows) return {totalRow: res.total, list: res.rows};
+        else return {totalRow: res.data.length, list: res.data};
+      } catch (error) { return {totalRow: 0, list: []} }
+    },
+    selectSystem([value], row, index) {
+      if (value) {
+        row.drugsId = value.drugsId;
+        row.drugsName = value.drugsName;
+        row.drugsPriceId = value.priceId;
+        row.drugsSpecsId = value.specsId;
+        row.drugsSpecsName = value.drugsSpecsName;
+        row.drugsPlaceId = value.placeId;
+        row.drugsPlaceName = value.placeName;
+      } else {
+        delete row.drugsId;
+        delete row.drugsName;
+        delete row.drugsPriceId;
+        delete row.drugsSpecsId;
+        delete row.drugsSpecsName;
+        delete row.drugsPlaceId;
+        delete row.drugsPlaceName;
+        this.dataset.splice(index, 1, row);
+      }
+      if (row.drugsId && row.herbsId) this.append();
+      this.editSystem = -1;
+    },
+    selectMechanism([value], row, index) {
+      if (value) {
+        row.herbsId = value.id;
+        row.herbsCode = value.herbsCode;
+        row.herbsName = value.herbsName;
+        row.herbsSpecsCode = value.specsCode;
+        row.herbsSpecsName = value.specsName;
+        row.herbsPlaceCode = value.placeCode;
+        row.herbsPlaceName = value.placeName;
+      } else {
+        delete row.herbsId;
+        delete row.herbsCode;
+        delete row.herbsName;
+        delete row.herbsSpecsCode;
+        delete row.herbsSpecsName;
+        delete row.herbsPlaceCode;
+        delete row.herbsPlaceName;
+        this.dataset.splice(index, 1, row);
+      }
+      if (row.drugsId && row.herbsId) this.append();
+      this.editMechanism = -1;
+    },
+  },
+}
+</script>
+
+<template>
+  <div class="wrapper">
+    <el-table :data="dataset" style="width: 100%;" :height="tableHeight" stripe :span-method="tableSpanMethod">
+      <el-table-column type="index" width="55" align="center" label="序号" fixed/>
+      <el-table-column label="系统药品" align="center">
+        <el-table-column prop="drugsName" label="名称" align="center">
+          <template slot-scope="scope">
+            <template v-if="scope.$index === editSystem || !scope.row.drugsId">
+              <v-selectpage :tb-columns="searchTableForSystemColumns"
+                            key-field="drugsId" v-model="scope.row.drugsId"
+                            placeholder="请输入系统药品名称" title="系统药品"
+                            data="drugsSearchForSystem" :params="{}" :pagination="false"
+                            :result-format="searchTableFormat"
+                            @values="selectSystem($event, scope.row, scope.$index)"
+              ></v-selectpage>
+            </template>
+            <a v-else>
+              {{ scope.row.drugsName }}
+              <i class="icon el-icon-circle-close" @click="selectSystem([], scope.row, scope.$index)"></i>
+            </a>
+          </template>
+        </el-table-column>
+        <el-table-column prop="drugsId" label="编码" align="center"></el-table-column>
+      </el-table-column>
+      <el-table-column label="医疗机构药品" align="center">
+        <el-table-column prop="herbsName" label="名称" align="center">
+          <template slot-scope="scope">
+            <template v-if="scope.$index === editMechanism || !scope.row.herbsId">
+              <v-selectpage :tb-columns="searchTableForMechanismColumns"
+                            key-field="id" v-model="scope.row.herbsId"
+                            placeholder="请输入医疗机构药品名称" title="医疗机构药品"
+                            data="drugsSearchForMechanism" :params="$props" :pagination="true"
+                            :result-format="searchTableFormat"
+                            @values="selectMechanism($event, scope.row, scope.$index)"
+              ></v-selectpage>
+            </template>
+            <a v-else>
+              {{ scope.row.herbsName }}
+              <i class="icon el-icon-circle-close" @click="selectMechanism([], scope.row, scope.$index)"></i>
+            </a>
+          </template>
+        </el-table-column>
+        <el-table-column prop="herbsCode" label="编码" align="center"></el-table-column>
+        <el-table-column prop="herbsSpecsName" label="规格" align="center"></el-table-column>
+        <el-table-column prop="herbsSpecsCode" label="规格编码" align="center"></el-table-column>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="80" fixed="right">
+        <template slot-scope="scope">
+          <el-button style="width: 40px;" type="danger" size="mini"
+                     :disabled="Object.keys(scope.row).length === 0"
+                     @click="handleDelete(scope.row, scope.$index)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="el-dialog__footer">
+      <el-button type="primary" @click="handle" :disabled="selected.length === 0">保 存</el-button>
+      <el-button @click="cancel">取 消</el-button>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.icon {
+  margin-top: 6px;
+  float: right;
+
+  &:hover {
+    color: #00afff;
+  }
+}
+</style>

+ 324 - 0
src/views/drugs/map/index.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <div class="query-box">
+        <div class="query-box__left">
+          <el-form-item label="" prop="communityId">
+            <el-select style="width:160px" v-model="queryParams.communityId"
+                       placeholder="请选择医共体" size="small" :clearable="false"
+                       @change="getMechanismList()"
+            >
+              <el-option v-for="item in cascade[0]" :key="item.id" :value="item.id" :label="item.name"
+                         :disabled="item.disabled"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="mechanismId">
+            <el-select style="width:160px" v-model="queryParams.mechanismId"
+                       placeholder="请选择医疗机构" size="small" :clearable="false"
+                       @change="getDeptList()"
+            >
+              <el-option v-for="item in cascade[1]" :key="item.id" :value="item.id" :label="item.name"
+                         :disabled="item.disabled"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="mechanismId">
+            <el-select style="width:160px" v-model="queryParams.deptId"
+                       placeholder="请选择科室" size="small" clearable
+            >
+              <el-option v-for="item in cascade[2]" :key="item.id" :value="item.id" :label="item.name"
+                         :disabled="item.disabled"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="herbsCode">
+            <el-input style="width:160px" v-model="queryParams.herbsCode" placeholder="医疗机构药品编码" size="small"
+                      clearable
+                      @keyup.enter.native="handleQuery"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="" prop="herbsName">
+            <el-input style="width:160px" v-model="queryParams.herbsName" placeholder="医疗机构药品名称" size="small"
+                      clearable
+                      @keyup.enter.native="handleQuery"
+            ></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+            <el-button type="primary" plain icon="el-icon-plus" size="mini"
+                       v-hasPermi="['drugs:map:create']" @click="handleEdit()"
+            >新增
+            </el-button>
+            <el-button type="default" plain icon="el-icon-upload2" size="mini"
+                       :loading="importing"
+                       v-hasPermi="['drugs:map:import']" @click="startUpload = true;"
+            >导入
+            </el-button>
+            <el-button type="default" plain icon="el-icon-download" size="mini"
+                       :loading="exporting"
+                       v-hasPermi="['drugs:map:export']" @click="handleExport()"
+            >导出
+            </el-button>
+          </el-form-item>
+        </div>
+      </div>
+    </el-form>
+
+    <el-table v-loading="loading" :data="list" size="mini" border>
+      <el-table-column type="index" width="55" align="center" label="序号"/>
+      <el-table-column prop="drugsName" label="系统药品名称" align="center"/>
+      <el-table-column prop="drugsId" label="系统药品编码" align="center"></el-table-column>
+      <el-table-column prop="herbsName" label="医疗机构药品名称" align="center"></el-table-column>
+      <el-table-column prop="herbsCode" label="医疗机构药品编码" align="center"></el-table-column>
+      <el-table-column prop="herbsSpecsName" label="医疗机构药品规格" align="center"></el-table-column>
+      <el-table-column prop="herbsSpecsCode" label="医疗机构药品规格编码" align="center"></el-table-column>
+      <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
+      <el-table-column prop="updateTime" label="修改时间" align="center"></el-table-column>
+
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="80" fixed="right">
+        <template slot-scope="scope">
+          <el-button style="width: 40px;" type="danger" size="mini"
+                     v-hasPermi="['drugs:map:remove']"
+                     @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改入库单对话框 -->
+    <el-dialog :fullscreen="false" :title="title" :visible.sync="open" width="80%" append-to-body size="mini"
+               destroy-on-close>
+      <edit :community-id="model.communityId" :mechanism-id="model.mechanismId" :dept-id="model.deptId"
+            @close="open = false;$event && getList()"
+      />
+    </el-dialog>
+
+    <el-dialog :fullscreen="false" title="药品映射" :visible.sync="startUpload" width="400px" append-to-body
+               size="mini">
+      <upload
+        :uploading="uploading" @upload="handleImport($event)"
+        :downloading="downloading" @download="handleDownload()"
+      />
+    </el-dialog>
+
+
+  </div>
+</template>
+
+<script>
+import selectTable from '@/components/selectTable/selectTable.vue'
+import Edit from "./edit.vue";
+import Upload from "./upload.vue";
+import {listCommunity} from "@/api/system/community";
+import {listMechanismId} from "@/api/medical/mechanism";
+import {getByMechanismId} from "@/api/medical/dept";
+import {drugsMap, drugsMapDelete, drugsMapExport, drugsMapImport, drugsMapImportTemplate} from "@/api/drugs/drugs";
+
+export default {
+  name: "DrugsMap",
+  computed: {},
+  components: {
+    Edit,
+    Upload,
+    selectTable
+  },
+  data() {
+    return {
+      cascade: [[], [], []],
+      list: [],
+      model: {},
+      // 遮罩层
+      loading: false,
+      exporting: false,
+      importing: false,
+      uploading: false,
+      downloading: false,
+      startUpload: false,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 是否显示弹出层
+      open: false,
+      // 弹出层标题
+      title: "药品映射",
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        pharmacyId: window.localStorage.getItem("pharmacyId"),
+
+        herbsCode: '',
+        herbsName: '',
+
+        communityId: '',
+        mechanismId: '',
+        deptId: '',
+      },
+      backupsParams: {},
+    };
+  },
+  created() {
+    this.resetQuery();
+  },
+  methods: {
+    /** 查询医共体列表 */
+    async getCommunityList() {
+      try {
+        const {rows} = await listCommunity();
+        this.$set(this.cascade, 0, rows.map(item => (item.disabled = item.state === '0', item)))
+      } catch (error) {
+        this.$set(this.cascade, 0, []);
+      }
+      const list = this.cascade[0];
+      const select = this.queryParams.communityId;
+      if (list.length && !(select && list.find(item => item.id === select))) this.queryParams.communityId = list[0].id;
+    },
+    /** 查询医疗机构列表 */
+    async getMechanismList() {
+      try {
+        if (!this.queryParams.communityId) throw '';
+        const {data: rows} = await listMechanismId(this.queryParams.communityId);
+        this.$set(this.cascade, 1, rows.map(item => (item.disabled = item.state === '0', item)))
+      } catch (error) {
+        this.$set(this.cascade, 1, []);
+      }
+      const list = this.cascade[1];
+      const select = this.queryParams.mechanismId;
+      if (list.length && !(select && list.find(item => item.id === select))) this.queryParams.mechanismId = list[0].id;
+
+      this.$set(this.cascade, 2, [])
+      this.queryParams.deptId = '';
+    },
+    /** 查询科室列表 */
+    async getDeptList() {
+      try {
+        if (!this.queryParams.mechanismId) throw '';
+        const {data: rows} = await getByMechanismId(this.queryParams.mechanismId);
+        this.$set(this.cascade, 2, rows.map(item => (item.disabled = item.state === '0', item)))
+      } catch (error) {
+        this.$set(this.cascade, 2, []);
+      }
+      const select = this.queryParams.deptId;
+      if (select && !this.cascade[2].find(item => item.id === select)) this.queryParams.deptId = '';
+    },
+
+    async getList() {
+      this.queryParams.communityId = this.backupsParams.communityId;
+      this.queryParams.mechanismId = this.backupsParams.mechanismId;
+      this.queryParams.deptId = this.backupsParams.deptId;
+      this.loading = true;
+      try {
+        const {rows, total} = await drugsMap(this.queryParams);
+        this.list = rows;
+        this.total = total;
+      } catch (error) {}
+      this.loading = false;
+    },
+
+    /** 搜索按钮操作 */
+    handleQuery() {
+      const {communityId, mechanismId, deptId} = this.queryParams;
+      this.backupsParams = {communityId, mechanismId, deptId}
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    async resetQuery() {
+      this.resetForm("queryForm");
+      /*this.queryParams.date = [
+        dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),
+        dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss'),
+      ]*/
+
+      this.queryParams.communityId = this.backupsParams.communityId;
+      await this.getCommunityList();
+      if (!this.queryParams.communityId) return;
+      this.queryParams.mechanismId = this.backupsParams.mechanismId;
+      await this.getMechanismList();
+      if (!this.queryParams.mechanismId) return;
+      this.handleQuery();
+      await this.getDeptList()
+    },
+    handleEdit() {
+      this.model = {...this.backupsParams};
+      this.editable = true;
+      this.open = true;
+    },
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm("是否删除该药品映射?", "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        })
+        .then(() => drugsMapDelete(ids))
+        .then(() => {
+          this.open = false;
+          this.getList();
+          this.msgSuccess("删除成功");
+        })
+        .catch(() => {});
+    },
+    async handleExport() {
+      this.exporting = true;
+      try {
+        const {blob, name = ''} = await drugsMapExport(this.backupsParams);
+        await this.download(blob, name);
+        this.msgSuccess(`${name} 下载成功`);
+      } catch (error) {}
+      this.exporting = false;
+    },
+    async handleDownload() {
+      this.downloading = true;
+      try {
+        const {blob, name = ''} = await drugsMapImportTemplate(this.backupsParams);
+        await this.download(blob, name);
+        this.msgSuccess(`${name} 下载成功`);
+      } catch (e) { }
+      this.downloading = false;
+    },
+    async handleImport(file) {
+      this.uploading = true;
+      try {
+        const {msg} = await drugsMapImport(Object.assign({file}, this.backupsParams));
+        this.msgSuccess(msg);
+        this.startUpload = false;
+        this.getList().then();
+      } catch (e) {}
+      this.uploading = false;
+    },
+    download(blob, filename = '') {
+      const link = document.createElement('a');
+      document.body.appendChild(link);
+
+      const url = URL.createObjectURL(blob);
+      link.href = url;
+      link.download = filename;
+      link.click();
+
+      return new Promise(resolve => {
+        setTimeout(() => {
+          document.body.removeChild(link);
+          URL.revokeObjectURL(url);
+          resolve();
+        }, 20)
+      })
+    }
+  },
+};
+</script>
+<style scoped>
+.el-input--small .el-input__inner {
+  height: 36px;
+  line-height: 36px;
+}
+</style>

+ 52 - 0
src/views/drugs/map/upload.vue

@@ -0,0 +1,52 @@
+<script>
+
+export default {
+  props: {
+    uploading: {type: Boolean, default: false},
+    downloading: {type: Boolean, default: false},
+  },
+  data() {
+    return {}
+  },
+  watch: {
+    uploading(value, oldValue) {
+      if (!value && oldValue) { this.$refs.upload.value = ''; }
+    },
+  },
+  methods: {
+    upload(event) {
+      let files = [];
+      if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) files = event.dataTransfer.files;
+      else {
+        files = event.target.files;
+      }
+      if (files.length > 0) this.$emit('upload', files[0]);
+    }
+  }
+}
+</script>
+
+<template>
+  <div>
+    <div tabindex="0" class="el-upload el-upload--text"
+         @click="$refs.upload.click()"
+         @dragover.prevent.stop @dragleave.prevent.stop @drop.prevent.stop="upload"
+    >
+      <div class="el-upload-dragger">
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em data-v-456458ea="">点击上传</em></div>
+      </div>
+      <input ref="upload" type="file" name="file" accept=".xlsx, .xls" class="el-upload__input" @change="upload"/>
+    </div>
+    <div class="el-upload__tip text-center">
+      <span>仅允许导入xls、xlsx格式文件。</span>
+      <el-button type="link" size="mini" :loading="downloading" @click.stop="$emit('download')">
+        下载模板
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>