| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724 |
- <style>
- .com-time-select {
- width: 760px;
- margin-top: 12px;
- border: 1px solid #cccccc;
- }
- .item-box {
- display: flex;
- }
- .top-box {
- height: 50px;
- border-bottom: 1px solid #cccccc;
- }
- .bottom-box {
- height: 250px;
- }
- .left-box {
- width: 22%;
- background-color: #f5f6fa;
- border-right: 1px solid #cccccc;
- }
- .right-box {
- width: 78%;
- }
- .el-dropdown-link {
- cursor: pointer;
- color: #409EFF;
- }
- .el-icon-arrow-down {
- font-size: 12px;
- }
- .not-scroll {
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .scroll-box {
- overflow-y: scroll;
- }
- .date-item {
- padding: 10px 4px;
- text-align: center;
- border-bottom: 1px solid #cccccc;
- cursor: pointer;
- }
- .selected {
- background-color: #ffffff;
- font-weight: bold;
- }
- .date-item:last-child {
- border-bottom: none;
- }
- .top-right {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .bottom-right {
-
- }
- .time-select-box {
- }
- .time-select-item {
- display: flex;
- align-items: center;
- }
- .label-box {
- }
- .select-box {
- margin-right: 12px;
- }
- .time {
- display: inline-block;
- margin-bottom: 10px;
- margin-right: 10px;
- padding: 4px 10px;
- border: 1px solid #409EFF;
- border-radius: 6px;
- }
- .time-txt {
- display: inline-block;
- }
- .del-btn {
- display: inline-block;
- width: 18px;
- height: 18px;
- margin-left: 6px;
- border-radius: 50%;
- text-align: center;
- line-height: 18px;
- background-color: #666666;
- font-size: 18px;
- color: #ffffff;
- cursor: pointer;
- }
- .right-top-form {
- height: 50px;
- display: flex;
- align-items: center;
- }
- .form-item {
- width: 48%;
- }
- .btn {
- width: 9%;
- }
- .right-bottom-list {
- margin-top: 6px;
- }
- .all-select {
- }
- .all-box {
- height: 140px;
- overflow-y: scroll;
- }
- </style>
- <template id="com-time-select">
- <div class="com-time-select">
- <div class="item-box top-box">
- <div class="left-box not-scroll">
- <el-dropdown @command="handleCommand">
- <span class="el-dropdown-link">
- {{settingType.name}}<i class="el-icon-arrow-down el-icon--right"></i>
- </span>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item v-for="(item,index) in settingTypes" :key="index" :command="item.val">{{item.name}}</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </div>
- <div class="right-box top-right">
- <div>设置时间段</div>
- <div v-if="slotType == 1" style="color: #409EFF;cursor: pointer;" @click="onShowAdd">+ 添加时间段</div>
- </div>
- </div>
- <div class="item-box bottom-box">
- <div v-if="settingType.val == 1" class="left-box scroll-box">
- <div v-for="(item,index) in selectedDates" :key="index" class="date-item" :class="item.isSelect ? 'selected' : ''" @click="onDate(index)">{{item.date}}</div>
- </div>
- <div v-if="settingType.val == 2" class="left-box not-scroll">每天</div>
- <div v-if="slotType == 1 && timeList && timeList.length" class="right-box bottom-right scroll-box">
- <span v-for="(item,index) in timeList" :key="index" class="time">
- <span class="time-txt">{{item}}</span>
- <span class="del-btn" @click="delTimeItem(index)">×</span>
- </span>
- </div>
- <div v-if="slotType == 1 && timeList && !timeList.length" class="right-box">请选择时间段</div>
- <div v-if="slotType == 2" class="right-box">
- <div class="right-top-form">
- <div class="form-item">起止时间:
- <el-time-picker is-range v-model="timeRange" range-separator="-" :value-format="pickerFormatText" :format="pickerFormatText" :picker-options="{ selectableRange: '00:00:00 - 23:59:00', format: pickerFormatText }" start-placeholder="开始时间" end-placeholder="结束时间" placeholder="选择时间范围" size="small" style="width: 200px;" @change="onAutoRangeChange"></el-time-picker>
- </div>
- <div class="form-item" style="width: 41%;">时间跨度:
- <el-input placeholder="请输入时间跨度" v-model="timeSpan" style="width: 150px;">
- <template slot="append">分钟</template>
- </el-input>
- </div>
- <div class="btn">
- <el-button type="primary" @click="getAutoRange">确定</el-button>
- </div>
- </div>
- <div class="right-bottom-list">
- <div v-if="intervalList.length">
- <div class="all-select">
- <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
- </div>
- <div class="all-box">
- <el-checkbox-group v-model="checkedIntervalList" @change="handleCheckedIntervalChange">
- <el-checkbox v-for="item in intervalList" :label="item" :key="item">{{item}}</el-checkbox>
- </el-checkbox-group>
- </div>
- </div>
- <div v-else class="nodata"><el-alert title="暂无可用时间段" type="warning" :closable="false"></el-alert></div>
- </div>
- </div>
- </div>
- <el-dialog title="添加时间段" :visible.sync="dialogFormVisible" :modal="false" width="40%">
- <el-form>
- <div class="time-select-box">
- <div class="time-select-item">
- <div class="label-box">开始时间:</div>
- <div class="select-box">
- <el-time-picker v-model="startTime" placeholder="开始时间" :value-format="pickerFormatText" :format="pickerFormatText"
- :picker-options="{ selectableRange: '00:00:00 - 23:59:00', format: pickerFormatText }" @change="changeTime"></el-time-picker>
- </div>
- </div>
- <div class="time-select-item">
- <div class="label-box">结束时间:</div>
- <div class="select-box">
- <el-select v-model="isNextDay" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- </div>
- <div class="select-box">
- <el-time-picker v-model="endTime" placeholder="结束时间" :value-format="pickerFormatText" :format="pickerFormatText"
- :picker-options="{ selectableRange: `${minPickerTime} - 23:59:00`, format: pickerFormatText }"></el-time-picker>
- </div>
- </div>
- </div>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="dialogFormVisible = false">取 消</el-button>
- <el-button type="primary" @click="addTime">确 定</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- Vue.component('com-time-select', {
- template: '#com-time-select',
- props: {
- slotType: {
- type: Number,
- default: 1
- },
- dateList: {
- type: Array,
- default: () => {
- return []
- }
- },
- priceType: {
- type: Number,
- default: 0
- },
- preSelectedDates: {
- type: Array,
- default: () => {
- return []
- }
- },
- currentSetting: {
- type: Array,
- default: () => {
- return []
- }
- },
- selectListStr: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- settingTypes: [
- {
- val: 1,
- name: '逐天进行设置'
- },
- {
- val: 2,
- name: '每天设置相同时间段'
- }
- ],
- settingType: {
- val: 1,
- name: '逐天进行设置'
- },
- selectedDates: [],
- dialogFormVisible: false,
- startTime: '',
- endTime: '',
- minPickerTime: '00:00:00',
- pickerFormatText: 'HH:mm',
- options: [{
- value: 1,
- label: '今日'
- }, {
- value: 2,
- label: '次日'
- }],
- isNextDay: 1,
- timeList: [],
- currentTime: {},
- timeRange: ['',''],
- timeSpan: 30,
- intervalList: [],
- checkAll: false,
- isIndeterminate: true,
- checkedIntervalList: [],
- }
- },
- watch: {
- dateList: {
- handler(newvalue,oldvalue) {
- console.log('watch dateList', newvalue, oldvalue)
- this.$nextTick(() => {
- this.initData();
- });
- },
- immediate: true,
- deep: true
- },
- currentTime: {
- handler(newvalue,oldvalue) {
- this.timeList = this.currentTime.children;
- },
- immediate: true,
- deep: true
- },
- priceType: {
- handler(newvalue,oldvalue) {
- if(newvalue){
- this.$emit('select', this.selectedDates);
- }
- },
- immediate: true,
- deep: true
- },
- slotType: {
- handler(newvalue,oldvalue) {
- this.$emit('select', this.selectedDates);
- },
- immediate: true,
- deep: true
- },
- },
- methods: {
- initData() {
- let newArr = [...new Set(this.dateList)];
- console.log('com time select', this.dateList, this.priceType, this.currentSetting)
- if(this.currentSetting.length && (this.priceType == 1 || this.priceType == 0)){
- this.selectedDates = [];
- this.currentSetting.forEach(item => {
- this.selectedDates.push({
- date: item.date,
- isSelect: item.isSelect,
- children: item.times,
- intervalList: item.times,
- checkAll: true,
- isIndeterminate: true,
- checkedIntervalList: item.times
- });
- });
- let rarr2 = [];
- this.selectedDates.forEach(item => {
- if(newArr.indexOf(item.date) > -1){
- rarr2.push(item);
- }
- });
- this.selectedDates = JSON.parse(JSON.stringify(rarr2));
- let oldDates2 = [];
- this.selectedDates.forEach(item => {
- oldDates2.push(item.date);
- });
- for(let i = 0;i < newArr.length;i++){
- if(oldDates2.indexOf(newArr[i]) < 0){
- this.selectedDates.push({
- date: newArr[i],
- isSelect: false,
- children: [],
- intervalList: [],
- checkAll: false,
- isIndeterminate: true,
- checkedIntervalList: []
- });
- }
- }
- }else{
- if(this.selectListStr && this.selectListStr != '[]'){
- console.log('this.selectListStr', this.selectListStr)
- this.selectedDates = JSON.parse(this.selectListStr);
- let rarr1 = [];
- this.selectedDates.forEach(item => {
- if(newArr.indexOf(item.date) > -1){
- rarr1.push(item);
- }
- });
- this.selectedDates = JSON.parse(JSON.stringify(rarr1));
- let oldDates = [];
- this.selectedDates.forEach(item => {
- oldDates.push(item.date);
- });
- for(let i = 0;i < newArr.length;i++){
- if(oldDates.indexOf(newArr[i]) < 0){
- this.selectedDates.push({
- date: newArr[i],
- isSelect: false,
- children: [],
- intervalList: [],
- checkAll: false,
- isIndeterminate: true,
- checkedIntervalList: []
- });
- }
- }
- }else if(this.preSelectedDates.length){
- this.selectedDates = JSON.parse(JSON.stringify(this.preSelectedDates));
- let rarr1 = [];
- this.selectedDates.forEach(item => {
- if(newArr.indexOf(item.date) > -1){
- rarr1.push(item);
- }
- });
- this.selectedDates = JSON.parse(JSON.stringify(rarr1));
- let oldDates = [];
- this.selectedDates.forEach(item => {
- oldDates.push(item.date);
- });
- for(let i = 0;i < newArr.length;i++){
- if(oldDates.indexOf(newArr[i]) < 0){
- this.selectedDates.push({
- date: newArr[i],
- isSelect: false,
- children: [],
- intervalList: [],
- checkAll: false,
- isIndeterminate: true,
- checkedIntervalList: []
- });
- }
- }
- }else{
- let rarr = [];
- this.selectedDates.forEach(item => {
- if(newArr.indexOf(item.date) > -1){
- rarr.push(item);
- }
- });
- this.selectedDates = JSON.parse(JSON.stringify(rarr));
- let oldDates = [];
- this.selectedDates.forEach(item => {
- oldDates.push(item.date);
- });
- for(let i = 0;i < newArr.length;i++){
- if(oldDates.indexOf(newArr[i]) < 0){
- this.selectedDates.push({
- date: newArr[i],
- isSelect: false,
- children: [],
- intervalList: [],
- checkAll: false,
- isIndeterminate: true,
- checkedIntervalList: []
- });
- }
- }
- }
- }
- this.selectedDates.sort(function (a, b) {
- return new Date(a.date) - new Date(b.date);
- })
- this.selectedDates.forEach(item => {
- item.isSelect = false;
- });
- if(this.selectedDates.length){
- this.selectedDates.sort(function (a, b) {
- // a.date - b.date
- return new Date(a) - new Date(b);
- })
- this.selectedDates[0].isSelect = true;
- console.log('this.selectedDates[0]this.selectedDates[0]', this.selectedDates[0])
- this.currentTime = this.selectedDates[0];
- this.intervalList = this.selectedDates[0].intervalList;
- this.checkedIntervalList = this.selectedDates[0].checkedIntervalList;
- this.checkAll = this.selectedDates[0].checkAll;
- this.isIndeterminate = this.selectedDates[0].isIndeterminate;
- }
- this.$emit('select', this.selectedDates);
- },
- handleCommand(command) {
- if(this.settingType.val != command) {
- this.settingTypes.forEach(item => {
- if(item.val == command) {
- this.settingType.val = item.val;
- this.settingType.name = item.name;
- }
- });
- if(command == 1){
- this.selectedDates.forEach(item => {
- item.isSelect = false;
- });
- this.selectedDates[0].isSelect = true;
- this.currentTime = this.selectedDates[0];
- }
- if(command == 2){
- this.selectedDates.forEach(item => {
- item.children = [];
- item.intervalList = [];
- item.checkAll = false;
- item.isIndeterminate = true;
- item.checkedIntervalList = [];
- });
- this.intervalList = [];
- this.checkAll = false;
- this.isIndeterminate = true;
- this.checkedIntervalList = [];
- }
- this.$emit('select', this.selectedDates);
- }
- },
- onDate(index) {
- this.selectedDates.forEach(item => {
- item.isSelect = false;
- });
- this.selectedDates[index].isSelect = true;
- this.currentTime = this.selectedDates[index];
- this.intervalList = this.selectedDates[index].intervalList;
- this.checkedIntervalList = this.selectedDates[index].checkedIntervalList;
- this.checkAll = this.selectedDates[index].checkAll;
- this.isIndeterminate = this.selectedDates[index].isIndeterminate;
- },
- changeTime(event) {
- this.minPickerTime = `${event}:00`
- },
- delTimeItem(index) {
- this.timeList.splice(index,1);
- if(this.settingType.val == 2) {
- this.selectedDates.forEach(item => {
- item.children = this.timeList;
- });
- }
- if(this.settingType.val == 1) {
- this.selectedDates.forEach(item => {
- if(item.isSelect){
- item.children = this.timeList;
- }
- });
- }
- this.$emit('select', this.selectedDates);
- },
- onShowAdd() {
- if(this.selectedDates.length){
- this.dialogFormVisible = true;
- }else{
- this.$message.error('请先选择可预约日期');
- }
- },
- addTime() {
- let str = '';
- if (this.startTime === '') {
- this.$message.error("请选择开始时间")
- return
- }
- if (this.endTime === '') {
- this.$message.error("请选择结束时间")
- return
- }
- if(this.isNextDay == 2){
- str = this.startTime + '-次日' + this.endTime;
- }else{
- str = this.startTime + '-' + this.endTime;
- }
- if(str){
- if(this.settingType.val == 2) {
- this.selectedDates.forEach(item => {
- if (item.children.indexOf(str) === -1) item.children.push(str);
- });
- }
- if(this.settingType.val == 1) {
- this.selectedDates.forEach(item => {
- if(item.isSelect){
- if (item.children.indexOf(str) === -1) item.children.push(str);
- }
- });
- }
- this.$emit('select', this.selectedDates);
- }
- this.dialogFormVisible = false;
- },
- onAutoRangeChange() {},
- getAutoRange() {
- if(this.selectedDates.length){
- this.intervalList = [];
- let interval = parseInt(this.timeSpan);
- if(this.timeRange.length == 2 && this.timeRange[0] && this.timeRange[1] && interval){
- this.intervalList = this.createTimeArray(this.timeRange[0], this.timeRange[1], interval, 'h:m');
- this.checkedIntervalList = this.intervalList;
- this.checkAll = true;
- this.isIndeterminate = false;
- if(this.settingType.val == 2) {
- this.selectedDates.forEach(item => {
- item.intervalList = this.intervalList;
- item.checkedIntervalList = this.checkedIntervalList;
- item.checkAll = this.checkAll;
- item.isIndeterminate = this.isIndeterminate;
- });
- }
- if(this.settingType.val == 1) {
- this.selectedDates.forEach(item => {
- if(item.isSelect){
- item.intervalList = this.intervalList;
- item.checkedIntervalList = this.checkedIntervalList;
- item.checkAll = this.checkAll;
- item.isIndeterminate = this.isIndeterminate;
- }
- });
- }
- this.$emit('select', this.selectedDates);
- }else{
- this.$message.error('请先填写所需信息');
- }
- }else{
- this.$message.error('请先选择可预约日期');
- }
- },
- handleCheckAllChange(val) {
- this.checkedIntervalList = val ? this.intervalList : [];
- this.isIndeterminate = false;
- if(this.settingType.val == 2) {
- this.selectedDates.forEach(item => {
- item.checkedIntervalList = [];
- this.checkedIntervalList.forEach(it => {
- item.checkedIntervalList.push(it);
- });
- item.isIndeterminate = false;
- item.checkAll = this.checkAll;
- });
- }
- if(this.settingType.val == 1) {
- this.selectedDates.forEach(item => {
- if(item.isSelect){
- item.checkedIntervalList = [];
- this.checkedIntervalList.forEach(it => {
- item.checkedIntervalList.push(it);
- });
- item.isIndeterminate = false;
- item.checkAll = this.checkAll;
- }
- });
- }
- this.$emit('select', this.selectedDates);
- },
- handleCheckedIntervalChange(value) {
- let checkedCount = value.length;
- this.checkAll = checkedCount === this.intervalList.length;
- this.isIndeterminate = checkedCount > 0 && checkedCount < this.intervalList.length;
- if(this.settingType.val == 2) {
- this.selectedDates.forEach(item => {
- item.checkAll = this.checkAll;
- item.isIndeterminate = this.isIndeterminate;
- item.checkedIntervalList = [];
- this.checkedIntervalList.forEach(it => {
- item.checkedIntervalList.push(it);
- });
- });
- }
- if(this.settingType.val == 1) {
- this.selectedDates.forEach(item => {
- if(item.isSelect){
- item.checkAll = this.checkAll;
- item.isIndeterminate = this.isIndeterminate;
- item.checkedIntervalList = [];
- this.checkedIntervalList.forEach(it => {
- item.checkedIntervalList.push(it);
- });
- }
- });
- }
- this.$emit('select', this.selectedDates);
- },
- // 格式化时间-小于10补0
- formatDigit(n) {
- return n.toString().replace(/^(\d)$/, '0$1');
- },
- formatDate(timestamp, formats) {
- /*formats格式
- 1. Y-M-D
- 2. Y-M-D h:m:s
- 3. Y年M月D日
- 4. Y年M月D日 h时m分
- 5. Y年M月D日 h时m分s秒
- 示例:console.log(this.formatDate(new Date().getTime(), 'Y年M月D日 h:m:s')) ==> 2023年5月17日 11:00:00
- */
- formats = formats || 'Y-M-D';
- let myDate = undefined;
- if (timestamp) {
- if (typeof (timestamp) != 'string') {
- myDate = timestamp;
- } else {
- myDate = new Date(timestamp);
- }
- } else {
- myDate = new Date();
- }
- const year = myDate.getFullYear();
- const month = this.formatDigit(myDate.getMonth() + 1);
- const day = this.formatDigit(myDate.getDate());
- const hour = this.formatDigit(myDate.getHours());
- const minute = this.formatDigit(myDate.getMinutes());
- const second = this.formatDigit(myDate.getSeconds());
- return formats.replace(/Y|M|D|h|m|s/g, (matches) => {
- return {
- Y: year,
- M: month,
- D: day,
- h: hour,
- m: minute,
- s: second
- } [matches];
- });
- },
- //获取时间段范围
- createTimeArray(startTime, endTime, minutes, formats, date = new Date()) {
- //格式化标准时间
- const frontTime = this.formatDate(date, 'Y/M/D')
- //获得时间戳
- let startDate = new Date(frontTime + ' ' + this.formatDigit(startTime)).getTime();
- let endDate = new Date(frontTime + ' ' + this.formatDigit(endTime)).getTime();
- //所隔时间
- const space = minutes * 60 * 1000;
- let mod = endDate - startDate;
- let modNum = mod / space
- let dateArray = [];
- for (let i = 0; i + 1 <= modNum; i++) {
- const start = startDate + space * i
- const end = startDate + space * (i + 1)
- let final = this.formatDate(new Date(start), formats) + '-' + this.formatDate(new Date(end), formats)
- dateArray.push(final)
- }
- return dateArray
- },
- }
- })
- </script>
|