| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- <template>
- <div class="year-month-select">
- <div class="year-warp" :style="`width: ${this.showMonth ? 95 : 190}px`">
- <el-date-picker
- v-model="year"
- type="year"
- :clearable="false"
- placeholder="选择年"
- size="small"
- value-format="yyyy"
- :picker-options="datePickerOptions"
- style="width: 100% !important;"
- >
- </el-date-picker>
- </div>
- <div v-if="showMonth" class="month-wrap">
- <div class="month-list">
- <div
- :class="[{ active: month == item.value }, 'month-list-item']"
- v-for="item of monthList"
- :key="item.value"
- @click="handleMonthClick(item)"
- >
- {{ item.name }}
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { getVipYears } from "@/api/system/tenant";
- import { mapGetters } from "vuex";
- export default {
- name: "YearMonthSelect",
- props: {
- value: {
- type: String,
- default: "",
- },
- // 是否显示月份选择
- showMonth: {
- type: Boolean,
- default: true
- },
- // 是否显示全年
- showAllYear: {
- type: Boolean,
- default: true
- }
- },
- data() {
- return {
- monthList: [],
- year: "",
- month: "",
- };
- },
- watch: {
- value: {
- handler(newVal) {
- if (newVal) {
- let dateStr = newVal.replace(/-/g, '');
- this.year = dateStr.substr(0, 4);
- this.month = dateStr.substr(4, 2) || "00";
- }
- },
- immediate: true,
- },
- year(newVal) {
- this.$emit("input", this.formatYearMonth(newVal, this.month));
- this.$store.commit("SET_PAGEYEAR", newVal.substr(0, 4));
- },
- },
- computed: {
- ...mapGetters(['vipYearList', 'pageYear']),
- datePickerOptions() {
- return {
- disabledDate: time => {
- const year = new Date(time).getFullYear();
- return !this.vipYearList.includes(year);
- }
- }
- }
- },
- created() {
- this.initMonth();
- if (this.vipYearList.length) {
- this.setDefaultValue(this.vipYearList);
- return;
- }
- this.getVipYearsList((data) => {
- this.setDefaultValue(data);
- });
- },
- methods: {
- getVipYearsList(callback) {
- const loading = this.$loading({
- lock: true,
- text: '页面加载中...',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- getVipYears().then(({ data }) => {
- loading.close();
- let list = data.data.map(year => Number(year));
- this.$store.commit("SET_VIP_YEAR", list);
- callback && callback(list);
-
- }).catch(() => {
- loading.close();
- });
- },
- setDefaultValue(data) {
- let date = new Date();
- let currYear = date.getFullYear();
- let currMonth = date.getMonth() + 1;
- let currMonthStr = currMonth > 9 ? currMonth.toString() : `0${currMonth}`;
- const target = this.findNumberInArray(data, currYear);
- let targetYear;
- if (target.targetExists) {
- targetYear = target.targetValue;
- } else {
- targetYear = target.minGreaterThanTarget || target.maxLessThanTarget;
- }
- this.year = this.pageYear || targetYear.toString();
- this.month = currMonthStr;
- this.$emit("input", this.formatYearMonth(this.year, this.month));
- },
- initMonth() {
- let list = [];
- for (let i = 0; i < 12; i++) {
- let month = i + 1;
- list.push({
- name: month + "月",
- value: month > 9 ? month.toString() : "0" + month,
- });
- }
- if (this.showAllYear) {
- list.push({ name: "全年", value: "00" });
- }
- this.monthList = list;
- },
- formatYearMonth(year, month) {
- if (month == "00" || !this.showMonth) {
- return year;
- }
- return year + "" + month;
- },
- handleMonthClick(data) {
- if (!this.vipYearList.length) {
- this.$message.error("未开通权限!");
- return;
- }
- this.month = data.value;
- this.$emit("input", this.formatYearMonth(this.year, this.month));
- },
- /**
- * 在数组中查找目标数字,如果不存在则找最接近的值
- *
- * @param {Array} arr - 输入数组
- * @param {number} target - 目标数字
- * @returns {Object} 结果对象
- */
- findNumberInArray(arr, target) {
- // 检查目标是否在数组中
- if (arr.includes(target)) {
- return {
- targetExists: true,
- targetValue: target,
- message: `${target} 存在于数组中`
- };
- }
-
- // 过滤出小于和大于目标值的数字
- const lessThan = arr.filter(x => x < target);
- const greaterThan = arr.filter(x => x > target);
-
- // 找出小于目标的最大值
- const maxLess = lessThan.length > 0 ? Math.max(...lessThan) : null;
-
- // 找出大于目标的最小值
- const minGreater = greaterThan.length > 0 ? Math.min(...greaterThan) : null;
-
-
- return {
- targetExists: false,
- targetValue: target,
- maxLessThanTarget: maxLess,
- minGreaterThanTarget: minGreater,
- message: `${target} 不存在于数组中`
- };
- }
- },
- };
- </script>
- <style lang="scss">
- .year-month-select {
- display: flex;
- align-items: center;
- margin: 12px 0;
- }
- .month-list {
- display: flex;
- margin-left: 12px;
- &-item {
- width: 40px;
- height: 30px;
- line-height: 30px;
- text-align: center;
- background-color: #fff;
- color: #409eff;
- border-radius: 4px;
- margin-right: 8px;
- border: 1px solid #409eff;
- cursor: pointer;
- font-size: 12px;
- &.active {
- background-color: #409eff;
- color: #fff;
- }
- // &.primary {
- // background-color: #409EFF;
- // border: 1px solid #409EFF;
- // }
- // &.success {
- // background-color: #67c23a;
- // border-color: #67c23a;
- // }
- }
- }
- </style>
|