invoice.vue 6.55 KB
<template>
  <layout-body>
    <layout-filter class="filter-wrap">
      <filter-item :label="filters.orderCode.label">
        <i-input v-model.trim="filters.orderCode.model" :placeholder="filters.orderCode.holder" />
      </filter-item>
      <filter-item :label="filters.createTime.label">
        <Date-picker
          v-model="filters.createTime.model"
          placement="bottom-end"
          type="datetimerange"
          format="yyyy-MM-dd HH:mm"
          placeholder="选择日期时间"
          class="date-picker"
        />
      </filter-item>
      <filter-item label=" " class="action-wrap">
        <Button type="primary" @click="search">
          查询
        </Button>
        <Button @click="reset">
          清空条件
        </Button>
        <Button type="warning" class="table-btn" @click="exportList">
          导出
        </Button>
      </filter-item>
    </layout-filter>
    <layout-tab>
      <Tabs :value="activate" :animated="false" @on-click="switchTab">
        <Tab-pane :label="noOpenTabLabel" name="UNOPEN"></Tab-pane>
        <Tab-pane :label="returnNoOptTabLabel" name="REJECT_UNHANDLED"></Tab-pane>
        <Tab-pane :label="openTabLabel" name="OPNED"></Tab-pane>
        <Tab-pane label="全部" name="all"></Tab-pane>
      </Tabs>
    </layout-tab>
    <layout-list>
      <Table border :columns="tableCols" :data="tableData" />
      <Page :total="pageData.total" :current="pageData.pageNo" :page-size="20" show-total @on-change="pageChange" />
    </layout-list>
    <invoice-update v-if="modalVisible" ref="modal" @updated="invoiceUpdated" />
  </layout-body>
</template>

<script>
import list from './store/list';
import filter from './store/filter';
import { InvoiceStatusName2Id } from './store/constant';
import InvoiceService from 'services/finance/invoice-service';
import InvoiceUpdate from './components/invoice-update';

import _ from 'lodash';
import moment from 'moment';

// 格式化时间范围为接口需要的YYYY-MM-DD HH:mm:ss
function timeFormat(time) {
  if (time === 0) {
    return 0;
  }

  return moment(time).format('YYYY-MM-DD HH:mm:ss');
}

export default {
  components: {
    InvoiceUpdate,
  },
  data() {
    return {
      ...list.call(this),
      ...filter,
      activate: 'all', // 当前tabname, all|UNOPEN|REJECT_UNHANDLED|OPNED
      noOpenInvoiceSum: 0, // 未开票
      openInvoiceSum: 0, // 已开票
      returnNoOptionSum: 0, // 退货待处理

      modalVisible: false,
    };
  },
  computed: {
    startTime() {
      const createTime = this.filters.createTime.model;

      if (_.isEmpty(createTime) || createTime[0] == null) {
        return 0;
      } else {
        return timeFormat(createTime[0]);
      }
    },
    endTime() {
      const createTime = this.filters.createTime.model;

      if (_.isEmpty(createTime) || createTime[1] == null) {
        return 0;
      } else {
        return timeFormat(createTime[1]);
      }
    },
    noOpenTabLabel() {
      return `待开票${this.noOpenInvoiceSum === 0 ? '' : '(' + this.noOpenInvoiceSum + ')'}`;
    },
    returnNoOptTabLabel() {
      return `退货待处理${this.returnNoOptionSum === 0 ? '' : '(' + this.returnNoOptionSum + ')'}`;
    },
    openTabLabel() {
      return `已开票${this.openInvoiceSum === 0 ? '' : '(' + this.openInvoiceSum + ')'}`;
    },
  },
  watch: {
    $route() {
      this.setActiveTab();
    },
  },
  created() {
    this.invoiceService = new InvoiceService();
    this.setActiveTab();
    // this.search();
  },
  methods: {
    switchTab(name) {
      this.$router.replace({
        name: `finance.invoice`,
        query: {
          tab: name,
        },
      });
    },
    setActiveTab() {
      const { tab } = this.$route.query;
      this.activate = tab || 'all';
      this.search();
    },
    filterValues(usePage = true) {
      const params = {
        orderCode: this.filters.orderCode.model,
        shopId: this.$user.currentShop.shopsId,
        startDate: this.startTime,
        endDate: this.endTime,
      };

      if (usePage) {
        params.pageSize = this.pageData.pageSize;
        params.pageNo = Math.max(this.pageData.pageNo - 1, 0);
      }

      if (this.activate !== 'all') {
        params.status = InvoiceStatusName2Id[this.activate];
      }

      return _.pickBy(params, val => val);
    },
    search() {
      this.invoiceService.queryList(this.filterValues()).then(({ data }) => {
        this.tableData = _.get(data, 'pageData.records', []);
        this.pageData.total = _.get(data, 'pageData.totalCount', 0);
        this.pageData.pageNo = _.get(data, 'pageData.pageNo', 0) + 1;

        this.noOpenInvoiceSum = _.get(data, 'noOpenInvoiceSum', 0);
        this.returnNoOptionSum = _.get(data, 'returnNoOptionSum', 0);
        this.openInvoiceSum = _.get(data, 'openInvoiceSum', 0);
      });
    },
    reset() {
      this.filters.orderCode.model = null;
      this.filters.createTime.model = null;
      this.pageData.pageNo = 1;
      this.pageData.total = 0;

      this.search();
    },
    pageChange(val) {
      this.pageData.pageNo = val;
      this.search();
    },
    onClickInfo(params) {
      this.modalVisible = true;
      this.$nextTick(() => {
        this.$refs.modal.show(params.row);
      });
    },
    exportList() {
      const params = { ...this.filterValues(false) };
      let msg;
      if (!params.endDate || !params.startDate) {
        // timeRange is required
        msg = `请选择需要导出的时间范围`;
      } else {
        const range = new Date(params.endDate) - new Date(params.startDate);

        // 这里使用32,与需求(30天)不一样,主要是时间选择默认是1个月,且当天时间为全天,当为31天时,用户在选择导出时会提示,检验不好
        if (range > 32 * 24 * 3600 * 1000) {
          // 30days
          // timeRange is limited in 30 days
          msg = `最多允许导出连续30天的发票列表, 请把时间范围调整不多于30天`;
        }
      }

      if (msg) {
        this.$Message.warning({
          content: msg,
          duration: 3, // default 1.5
        });
        return;
      }

      const href = this.invoiceService.getExportUrl(params);

      window.open(href, '_blank');
    },
    invoiceUpdated() {
      // 刷新
      this.search();
    },
  },
};
</script>

<style lang="scss" scoped>
.text-red {
  color: #ed3f14;
}
.layout-filter /deep/ {
  .ivu-col-span-6:nth-child(2) {
    width: 400px;
  }
  .ivu-col-span-6:nth-child(3) {
    width: 40% !important;
  }
}

.action-wrap {
  /deep/ {
    .ivu-col-span-8 {
      font-size: 0;
      width: 20px;
    }
    button {
      margin: 0 5px;
    }
  }
}
</style>