소스 검색

散客/团队预定添加功能

gqx 2 년 전
부모
커밋
9e2f8ba7cf

+ 41 - 4
src/views/room/fangtailive.vue

@@ -55,6 +55,12 @@
               type="danger"
               >批量制卡</a-button
             >
+            <a-button
+              style="margin-bottom: 10px"
+              @click="toPage"
+              type="danger"
+              >查询散客详单</a-button
+            >
           </div>
           <div class="week-top">
             <div class="w-choose-status">
@@ -385,6 +391,14 @@
       ref="ModalScheduleRoom"
       @ok="modalFormOk"
     ></schedule-room-modal>
+    <schedule-team-room-modal
+      ref="ModalScheduleTeamRoom"
+      @ok="modalFormOk"
+    ></schedule-team-room-modal>
+    <edit-schedule-room-modal
+      ref="ModalEditScheduleRoom"
+      @ok="modalFormOk"
+    ></edit-schedule-room-modal>
   </a-card>
 </template>
 
@@ -397,6 +411,8 @@ import UpkeepRoomModal from "./modules/upkeep/UpkeepRoomModal.vue";
 import BillRoomInfoModal from "./modules/checkIn/BillRoomInfoModal.vue";
 import BillRoomFormModal from "./modules/checkIn/BillRoomFormModal.vue";
 import ScheduleRoomModal from "./modules/schedule/ScheduleRoomModal.vue";
+import ScheduleTeamRoomModal from "./modules/scheduleTeam/ScheduleRoomModal.vue";
+import EditScheduleRoomModal from "./modules/schedule/EditScheduleRoomModal.vue";
 import { TreeSelect } from "ant-design-vue";
 const SHOW_PARENT = TreeSelect.SHOW_PARENT;
 const treeData = [
@@ -607,6 +623,8 @@ export default {
     BillRoomInfoModal,
     BillRoomFormModal,
     ScheduleRoomModal,
+    ScheduleTeamRoomModal,
+    EditScheduleRoomModal,
   },
   data() {
     return {
@@ -689,9 +707,24 @@ export default {
     // this.$refs.ModalScheduleRoom.addList([]);
     //   this.$refs.ModalScheduleRoom.title = "预定登记";
     //   this.$refs.ModalScheduleRoom.disableSubmit = false;
+    // this.$refs.ModalScheduleTeamRoom.addList([]);
+    //   this.$refs.ModalScheduleTeamRoom.title = "团队预定登记";
+    //   this.$refs.ModalScheduleTeamRoom.disableSubmit = false;
+    // this.$refs.ModalEditScheduleRoom.addList([]);
+    // this.$refs.ModalEditScheduleRoom.title = "详单";
+    // this.$refs.ModalEditScheduleRoom.disableSubmit = false;
+    
   },
   methods: {
-    scheduleClick() {
+    toPage(){
+      this.$router.push({path:'/room/scheduledetail',query: {id:'YD20230329144252390'}})
+    },
+    addScheduleTeam() {
+      this.$refs.ModalScheduleTeamRoom.addList([]);
+      this.$refs.ModalScheduleTeamRoom.title = "团队预定登记";
+      this.$refs.ModalScheduleTeamRoom.disableSubmit = false;
+    },
+    scheduleClick(e) {
       var selectRoom = [];
       this.planList2.forEach((t) => {
         t.child.forEach((c) => {
@@ -706,9 +739,13 @@ export default {
         this.$message.warning("请先选择房间");
         return;
       }
-      this.$refs.ModalScheduleRoom.addList(selectRoom);
-      this.$refs.ModalScheduleRoom.title = "预定登记";
-      this.$refs.ModalScheduleRoom.disableSubmit = false;
+      if (e.key == "1") {
+        this.$refs.ModalScheduleRoom.addList(selectRoom);
+        this.$refs.ModalScheduleRoom.title = "预定登记";
+        this.$refs.ModalScheduleRoom.disableSubmit = false;
+      } else {
+        this.addScheduleTeam();
+      }
     },
     handleMenuClick(e) {
       console.log("click", e);

+ 856 - 0
src/views/room/modules/schedule/EditScheduleRoomForm.vue

@@ -0,0 +1,856 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <div style="display: flex; gap: 15px">
+            <div style="width: 39%">
+              <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">
+                订价信息
+              </h4>
+              <a-divider />
+              <a-col :span="24">
+                <a-form-model-item
+                  label="入住类型"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.bookingType"
+                >
+                  <a-select
+                    placeholder="入住类型"
+                    v-model="model.orderInfo.bookingType"
+                    @change="bookingTypeChange"
+                  >
+                    <a-select-option :value="1"> 全天 </a-select-option>
+                    <a-select-option :value="2"> 钟点 </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+
+              <a-col :span="24">
+                <a-form-model-item
+                  label="预抵时间"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.arrivalTime2"
+                >
+                  <j-date
+                    placeholder="预抵时间"
+                    v-model="model.orderInfo.arrivalTime2"
+                    style="width: 180px"
+                    :allowClear="false"
+                    :disabled-date="disabledDate"
+                    @change="arrivalTimeChange"
+                  />
+                  <a-time-picker
+                    style="width: 80px; margin-left: 2px"
+                    v-model="model.orderInfo.arrivalTimeSpan"
+                    :default-value="moment('12:00', 'HH:mm')"
+                    format="HH:mm"
+                    :allowClear="false"
+                  />
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="预离时间"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.dueOutTime2"
+                >
+                  <j-date
+                    placeholder="预离时间"
+                    v-model="model.orderInfo.dueOutTime2"
+                    style="width: 180px"
+                    :allowClear="false"
+                    :disabled-date="disabledDate"
+                    @change="arrivalTimeChange"
+                  />
+                  <a-time-picker
+                    style="width: 80px; margin-left: 2px"
+                    v-model="model.orderInfo.dueOutTimeSpan"
+                    format="HH:mm"
+                    :allowClear="false"
+                  />
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="客人来源"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.customerSource"
+                >
+                  <a-select
+                    placeholder="客人来源"
+                    v-model="model.orderInfo.customerSource"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in customerSourceList"
+                      :key="item.id"
+                    >
+                      {{ item.itemText }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24" v-if="model.orderInfo.bookingType == 2">
+                <a-form-model-item
+                  label="时长"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.hourRoomId"
+                >
+                  <a-select
+                    placeholder="时长"
+                    v-model="model.orderInfo.hourRoomId"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in hourRoomRuleList"
+                      :key="item.id"
+                    >
+                      {{ item.hourRoomName }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24" v-else>
+                <a-form-model-item
+                  label="天数"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.dayCount"
+                >
+                  <a-input-number
+                    v-model="model.orderInfo.dayCount"
+                    placeholder="天数"
+                    :min="1"
+                    @change="dayCountChange"
+                  ></a-input-number>
+                </a-form-model-item>
+              </a-col>
+
+              <a-col :span="24">
+                <a-form-model-item
+                  label="早餐"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.breakfastNum"
+                >
+                  <a-input-number
+                    v-model="model.orderInfo.breakfastNum"
+                    placeholder="早餐"
+                    :min="0"
+                  ></a-input-number>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="预定方式"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.bookingDicWay"
+                >
+                  <a-select
+                    placeholder="预定方式"
+                    v-model="model.orderInfo.bookingDicWay"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in bookingdicWayList"
+                      :key="item.id"
+                    >
+                      {{ item.itemText }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="客人类型"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.customerType"
+                >
+                  <a-select
+                    placeholder="客人类型"
+                    v-model="model.orderInfo.customerType"
+                  >
+                    <a-select-option :value="1"> 散客 </a-select-option>
+                    <a-select-option :value="2"> 会员 </a-select-option>
+                    <a-select-option :value="3"> 协议单位 </a-select-option>
+                    <a-select-option :value="4"> 中介 </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24" v-if="model.orderInfo.bookingType === 1">
+                <a-form-model-item
+                  label="房价方案"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.roomPriceSlnId"
+                >
+                  <a-select
+                    placeholder="房价方案"
+                    v-model="model.orderInfo.roomPriceSlnId"
+                  >
+                    <a-select-option value="会员价"> 会员价 </a-select-option>
+                    <a-select-option value="平日价"> 平日价 </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">
+                其他信息
+              </h4>
+              <a-divider />
+              <a-col :span="24">
+                <a-form-model-item
+                  label="联系人"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="contactName"
+                >
+                  <a-auto-complete
+                    v-model="model.contactName"
+                    placeholder="联系人"
+                    @search="handleSearch"
+                    @select="(e) => handleSelectMember(e)"
+                  >
+                    <template slot="dataSource">
+                      <a-select-option v-for="item in result" :key="item">{{
+                        item
+                      }}</a-select-option>
+                    </template>
+                  </a-auto-complete>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="电话"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="phone"
+                >
+                  <a-input v-model="model.phone" placeholder="电话"></a-input>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="担保方式"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.warrantType"
+                >
+                  <a-select
+                    placeholder="担保方式"
+                    v-model="model.orderInfo.warrantType"
+                  >
+                    <a-select-option :value="1"> 无担保 </a-select-option>
+                    <a-select-option :value="2"> 有担保 </a-select-option>
+                    <a-select-option :value="3"> OTA担保 </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="销售员"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.warranter"
+                >
+                  <a-select
+                    placeholder="销售员"
+                    v-model="model.orderInfo.warranter"
+                  >
+                    <a-select-option
+                      value="a"
+                      v-for="item in warranterList"
+                      :key="item.id"
+                    >
+                      {{ item.name }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="外部单号"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.outerOrdersNo"
+                >
+                  <a-input
+                    v-model="model.orderInfo.outerOrdersNo"
+                    placeholder="外部单号"
+                  ></a-input>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item
+                  label="备注"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.remark"
+                >
+                  <a-textarea
+                    v-model="model.orderInfo.remark"
+                    rows="4"
+                    placeholder="备注"
+                  />
+                </a-form-model-item>
+              </a-col>
+            </div>
+            <div style="width: 61%">
+              <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">
+                选择房间
+              </h4>
+              <a-divider />
+              <p>
+                <span>占房天数:{{ model.orderInfo.dayCount }}晚</span>
+                <span style="padding-left: 10px">总价:{{ amount }}</span>
+              </p>
+              <a-table
+                :columns="columns"
+                :data-source="canUserRooms"
+                :pagination="false"
+                :rowKey="rowKey"
+              >
+                <div
+                  slot="expandedRowRender"
+                  slot-scope="record, index, indent, expanded"
+                  style="margin: 0"
+                >
+                  <p>
+                    已排房:
+                    <template
+                      v-for="(building, bIndex) in record.buildingRooms"
+                    >
+                      <a-tag
+                        color="blue"
+                        closable
+                        :visible="visible"
+                        @close.stop="tagClose2(rindex, bIndex, index)"
+                        v-for="(item, rindex) in building.floorRooms"
+                        :key="rindex"
+                        v-if="item.check && item.check == 1"
+                        >{{ item.name }}</a-tag
+                      >
+                      <!-- <a-tag
+                        color="blue"
+                        closable
+                        :visible="visible"
+                        @close.stop="tagClose2(rindex, index)"
+                        v-for="(item, rindex) in record.rooms"
+                        :key="rindex"
+                        >{{ item.name }}</a-tag
+                      > -->
+                    </template>
+                  </p>
+                  <p>
+                    未排房:{{
+                      record.layout.presetNum - (record.rooms || []).length
+                    }}间
+                  </p>
+                </div>
+                <template slot="favPrice" slot-scope="text, record, index">
+                  <!-- <editable-cell
+                    :text="record.layout.favPrice"
+                    @change="onCellChange('favPrice', index, $event)"
+                  /> -->
+                  {{ record.layout.favPrice }}
+                </template>
+                <template slot="presetNum" slot-scope="text, record, index">
+                  <div>
+                    <a-input-number
+                      v-model="record.layout.presetNum"
+                      :min="(record.rooms || []).length"
+                      :max="record.layout.oldTags"
+                      @change="presetNumChange($event, record)"
+                    />
+                  </div>
+                </template>
+                <span slot="action" slot-scope="text, record, index">
+                  <a
+                    :disabled="record.layout.presetNum <= 0"
+                    @click="pulsRoom(index)"
+                    >排房</a
+                  >
+                </span>
+              </a-table>
+            </div>
+          </div>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+    <select-room-form-modal
+      ref="modalSelectRoomForm"
+      @ok="modalFormOk"
+    ></select-room-form-modal>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction, postAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+import moment from "moment";
+import EditableCell from "@views/room/modules/checkIn/EditableCell.vue";
+import SelectRoomFormModal from "./SelectRoomFormModal.vue";
+const date = new Date();
+const endDate = new Date(date.setDate(date.getDate() + 1));
+const columns = [
+  // {
+  //     title: "",
+  //     dataIndex: "key",
+  //     width: 20,
+  //   },
+  {
+    title: "房型",
+    dataIndex: "name",
+    width: 150,
+    customRender: function (text, record) {
+      return record.layout.name;
+    },
+  },
+  {
+    title: "门市价",
+    dataIndex: "marketPrice",
+    width: 100,
+    customRender: function (text, record) {
+      return record.layout.marketPrice;
+    },
+  },
+  {
+    title: "优惠价",
+    dataIndex: "favPrice",
+    width: 120,
+    scopedSlots: { customRender: "favPrice" },
+  },
+  {
+    title: "可订数/可超数",
+    dataIndex: "canUseCount",
+    width: 170,
+    customRender: function (text, record) {
+      return record.layout.canUseCount + "/0";
+    },
+  },
+  {
+    title: "预定间数",
+    dataIndex: "presetNum",
+    width: 100,
+    scopedSlots: { customRender: "presetNum" },
+  },
+  {
+    title: "操作",
+    dataIndex: "action",
+    align: "center",
+    fixed: "right",
+    width: 70,
+    scopedSlots: { customRender: "action" },
+  },
+];
+const data = [];
+for (let i = 0; i < 2; i++) {
+  data.push({
+    id: i,
+    key1: `双人床` + i,
+    key2: 298,
+    key3: 298,
+    key4: 8,
+    key5: 0,
+    key6: 0,
+  });
+}
+export default {
+  name: "ScheduleRoomForm",
+  components: { EditableCell, SelectRoomFormModal },
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+    id: {
+      type: Boolean,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      visible: true,
+      columns,
+      model: {
+        // data: data,
+        orderInfo: {
+          bookingOrdersType: 1,
+          arrivalTime2: moment(new Date()).format("YYYY-MM-DD"),
+          dueOutTime2: moment(endDate).format("YYYY-MM-DD"),
+          arrivalTimeSpan: moment("18:00", "HH:mm"),
+          dueOutTimeSpan: moment("12:00", "HH:mm"),
+          bookingType: 1,
+          dayCount: 1,
+          warrantType: 1,
+          hourRoomId: "",
+          breakfastNum: 0,
+        },
+        roomIds: [],
+        layoutDayPrices: [],
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        "orderInfo.bookingType": [
+          { required: true, message: "请选择入住类型!" },
+        ],
+        "orderInfo.arrivalTime2": [
+          { required: true, message: "请选择预抵时间!" },
+        ],
+        "orderInfo.dueOutTime2": [
+          { required: true, message: "请选择预离时间!" },
+        ],
+        "orderInfo.customerSource": [
+          { required: true, message: "请选择客人来源!" },
+        ],
+        "orderInfo.bookingDicWay": [
+          { required: true, message: "请选择预定方式!" },
+        ],
+        "orderInfo.customerType": [
+          { required: true, message: "请选择客人类型!" },
+        ],
+        contactName: [{ required: true, message: "请输入联系人!" }],
+        phone: [{ required: true, message: "请输入电话!" }],
+      },
+      url: {
+        add: "/business/busRoomBookingOrders/add",
+        edit: "/business/busMeetingRoom/edit",
+        getBookingOrderInfo:
+          "/business/busRoomBookingOrders/getBookingOrderInfo",
+      },
+      result: [],
+      selectIndex: 0,
+      customerSourceList: [],
+      bookingdicWayList: [],
+      warranterList: [],
+      hourRoomRuleList: [],
+      canUserRooms: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+    amount() {
+      var sum = 0;
+      this.canUserRooms.forEach((t) => {
+        sum += t.layout.favPrice * t.layout.presetNum;
+      });
+      return sum.toFixed(2);
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+
+    getAction("/business/busDictItem/list", {
+      hotelId: _info.id,
+      dictId: "1639538915239743490",
+    }).then((res) => {
+      if (res.success) {
+        this.customerSourceList = res.result.records;
+      }
+    });
+    getAction("/business/busDictItem/list", {
+      hotelId: _info.id,
+      dictId: "1639544187093995521",
+    }).then((res) => {
+      if (res.success) {
+        this.bookingdicWayList = res.result.records;
+      }
+    });
+    getAction("/business/busSalesPerson/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.warranterList = res.result.records;
+      }
+    });
+
+    getAction("/rooms/cesHourRoomRule/list", {
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.hourRoomRuleList = res.result.records;
+      }
+    });
+
+    postAction("/rooms/cesAllDayPriceRule/fetch", { hotelId: _info.id }).then(
+      (res) => {
+        if (res.success) {
+          if (
+            res.result &&
+            res.result.cesAllDayPriceRule &&
+            res.result.cesAllDayPriceRule.leaveTime
+          ) {
+            this.model.orderInfo.dueOutTimeSpan = moment(
+              res.result.cesAllDayPriceRule.leaveTime,
+              "HH:mm"
+            );
+          }
+        }
+
+        this.loadRooms();
+      }
+    );
+
+    getAction(this.url.getBookingOrderInfo, {
+      bookingNo: this.id,
+    }).then((res) => {
+      if (res.success) {
+        this.hourRoomRuleList = res.result.records;
+      }
+    });
+  },
+  methods: {
+    presetNumChange(e, record) {
+      console.log(e);
+      record.layout.canUseCount = record.layout.oldTags - e;
+    },
+    onCellChange(key, dataIndex, value) {
+      const dataSource = [...this.canUserRooms];
+      const target = dataSource[dataIndex];
+      console.log("target", target);
+      if (target && target.layout) {
+        target.layout[key] = value;
+        this.canUserRooms = dataSource;
+      }
+      console.log("this.canUserRooms", this.canUserRooms);
+    },
+    rowKey(record) {
+      return record.layout.id;
+    },
+    loadRooms() {
+      getAction("/rooms/cesRooms/can-user-rooms", {
+        startOf:
+          this.model.orderInfo.arrivalTime2 +
+          " " +
+          moment(this.model.orderInfo.arrivalTimeSpan).format("HH:mm"),
+        endOf:
+          this.model.orderInfo.dueOutTime2 +
+          " " +
+          moment(this.model.orderInfo.dueOutTimeSpan).format("HH:mm"),
+        bookingType: this.model.orderInfo.bookingType,
+        hourRoomRuleId: this.model.orderInfo.hourRoomId,
+      }).then((res) => {
+        if (res.success) {
+          res.result.forEach((t) => {
+            t.layout = Object.assign({}, t.layout, {
+              presetNum: 0,
+              oldTags: t.layout.canUseCount,
+            });
+            t.buildingRooms.forEach((b) => {
+              b.floorRooms.forEach((f) => {
+                this.$set(f, "check", 0);
+              });
+            });
+          });
+          this.canUserRooms = res.result;
+        }
+      });
+    },
+    bookingTypeChange(e) {
+      if (this.model.orderInfo.bookingType == 1) {
+        this.model.orderInfo.hourRoomId = "";
+      } else {
+        var hourRoomRule = this.hourRoomRuleList[0];
+        if (hourRoomRule) {
+          this.model.orderInfo.hourRoomId = hourRoomRule.id;
+        }
+      }
+      this.loadRooms();
+    },
+    dayCountChange(e) {
+      this.model.orderInfo.dueOutTime2 = moment(
+        this.model.orderInfo.arrivalTime2
+      )
+        .add(e, "days")
+        .format("YYYY-MM-DD");
+      this.loadRooms();
+    },
+    disabledDate(current) {
+      return current && current < moment().add(-1, "days").endOf("day");
+    },
+    arrivalTimeChange(e) {
+      this.model.orderInfo.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.orderInfo.arrivalTime2).getTime() -
+            new Date(this.model.orderInfo.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    arrivalTimeSpanChange(m, time) {
+      console.log(time);
+      console.log(moment(m).format("HH:mm"));
+    },
+    tagClose2(rindex, bindex, index) {
+      // console.log(rindex, index);
+      // console.log(this.canUserRooms[index]);
+      this.canUserRooms[index].rooms.splice(rindex, 1);
+
+      this.$set(
+        this.canUserRooms[index].buildingRooms[bindex].floorRooms[rindex],
+        "check",
+        0
+      );
+      console.log(this.canUserRooms);
+    },
+    modalFormOk(e) {
+      // this.modelDefault = Object.assign({}, this.modelDefault, {
+      //   rooms: e,
+      // });
+      // this.edit(this.modelDefault);
+      this.$set(this.canUserRooms[this.selectIndex], "rooms", e);
+      console.log(this.canUserRooms[this.selectIndex]);
+    },
+    pulsRoom(index) {
+      this.selectIndex = index;
+      this.$refs.modalSelectRoomForm.add(this.canUserRooms[this.selectIndex]);
+      this.$refs.modalSelectRoomForm.title = "排房";
+      this.$refs.modalSelectRoomForm.disableSubmit = false;
+    },
+    handleSearch(value) {
+      let result;
+      if (!value) {
+        result = [];
+      } else {
+        result = ["a", "b", "c"].map(
+          (domain) => `${value}${domain}(15888888888)`
+        );
+      }
+      this.result = result;
+    },
+    handleSelectMember(e) {
+      this.model.mobile = "158888888888";
+    },
+    moment,
+    onChange(date, dateString) {
+      console.log(date, dateString);
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    addList(roomLiveList) {
+      this.modelDefault = Object.assign({}, this.modelDefault, {
+        rooms: roomLiveList,
+      });
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      that.model.roomIds = [];
+      that.canUserRooms.forEach((t) => {
+        var lastlayoutId = t.layout.id;
+        t.buildingRooms.forEach((b) => {
+          b.floorRooms.forEach((f) => {
+            if (f.check && f.check === 1) {
+              that.model.roomIds.push({ layoutId: t.layout.id, roomId: f.id });
+            }
+          });
+        });
+        const roomIds = that.model.roomIds.filter(
+          (it) => it.layoutId === lastlayoutId
+        );
+        var len = roomIds.length;
+        for (var i = len; i < t.layout.presetNum; i++) {
+          that.model.roomIds.push({ layoutId: t.layout.id, roomId: null });
+        }
+        for (var b = 0; b < that.model.orderInfo.dayCount; b++) {
+          var dayTime = moment(this.model.orderInfo.arrivalTime2)
+            .add(b, "days")
+            .format("YYYY-MM-DD");
+          that.model.layoutDayPrices.push({
+            bookingType: 1,
+            dayTime: dayTime,
+            price: t.layout.favPrice,
+            roomLayoutId: t.layout.id,
+          });
+        }
+      });
+      console.log("this.model", this.model);
+      if (that.model.roomIds.length <= 0) {
+        that.$message.warning("请先添加房间");
+        return;
+      }
+      // 触发表单验证
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          this.model.orderInfo.arrivalTime =
+            this.model.orderInfo.arrivalTime2 +
+            " " +
+            moment(this.model.orderInfo.arrivalTimeSpan).format("HH:mm");
+          this.model.orderInfo.dueOutTime =
+            this.model.orderInfo.dueOutTime2 +
+            " " +
+            moment(this.model.orderInfo.dueOutTimeSpan).format("HH:mm");
+          that.confirmLoading = true;
+          let httpurl = "";
+          let method = "";
+          if (!this.model.id) {
+            httpurl += this.url.add;
+            method = "post";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+/deep/.ant-divider-horizontal {
+  margin: 12px 0 !important;
+}
+/deep/ .ant-form-item {
+  margin-bottom: 5px !important;
+}
+</style>

+ 88 - 0
src/views/room/modules/schedule/EditScheduleRoomModal.vue

@@ -0,0 +1,88 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <schedule-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></schedule-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import ScheduleRoomForm from './EditScheduleRoomForm'
+  export default {
+    name: 'ScheduleRoomModal',
+    components: {
+      ScheduleRoomForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1300,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      addList(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.addList(record);
+      });
+    },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+<style scoped>
+/deep/.ant-modal-body {
+  padding: 12px;
+  max-height: calc(80vh - 150px);
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+    /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #e3e3e6;
+    border-radius: 6px;
+  }
+
+  &::-webkit-scrollbar-track {
+    background: transparent;
+    border-radius: 5px;
+  }
+}
+</style>

+ 439 - 88
src/views/room/modules/schedule/ScheduleRoomForm.vue

@@ -19,11 +19,15 @@
                   label="入住类型"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.bookingType"
                 >
-                  <a-select placeholder="入住类型">
-                    <a-select-option value="全天"> 全天 </a-select-option>
-                    <a-select-option value="钟点"> 钟点 </a-select-option>
+                  <a-select
+                    placeholder="入住类型"
+                    v-model="model.orderInfo.bookingType"
+                    @change="bookingTypeChange"
+                  >
+                    <a-select-option :value="1"> 全天 </a-select-option>
+                    <a-select-option :value="2"> 钟点 </a-select-option>
                   </a-select>
                 </a-form-model-item>
               </a-col>
@@ -33,17 +37,22 @@
                   label="预抵时间"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.arrivalTime2"
                 >
                   <j-date
                     placeholder="预抵时间"
-                    v-model="model.endTime"
+                    v-model="model.orderInfo.arrivalTime2"
                     style="width: 180px"
+                    :allowClear="false"
+                    :disabled-date="disabledDate"
+                    @change="arrivalTimeChange"
                   />
                   <a-time-picker
                     style="width: 80px; margin-left: 2px"
-                    :default-value="moment('18:00', 'HH:mm')"
+                    v-model="model.orderInfo.arrivalTimeSpan"
+                    :default-value="moment('12:00', 'HH:mm')"
                     format="HH:mm"
+                    :allowClear="false"
                   />
                 </a-form-model-item>
               </a-col>
@@ -52,17 +61,21 @@
                   label="预离时间"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.dueOutTime2"
                 >
                   <j-date
                     placeholder="预离时间"
-                    v-model="model.endTime"
+                    v-model="model.orderInfo.dueOutTime2"
                     style="width: 180px"
+                    :allowClear="false"
+                    :disabled-date="disabledDate"
+                    @change="arrivalTimeChange"
                   />
                   <a-time-picker
                     style="width: 80px; margin-left: 2px"
-                    :default-value="moment('12:00', 'HH:mm')"
+                    v-model="model.orderInfo.dueOutTimeSpan"
                     format="HH:mm"
+                    :allowClear="false"
                   />
                 </a-form-model-item>
               </a-col>
@@ -71,25 +84,70 @@
                   label="客人来源"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.customerSource"
                 >
-                  <a-select placeholder="订单来源">
-                    <a-select-option value="散客"> 散客 </a-select-option>
-                    <a-select-option value="美团"> 美团 </a-select-option>
+                  <a-select
+                    placeholder="客人来源"
+                    v-model="model.orderInfo.customerSource"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in customerSourceList"
+                      :key="item.id"
+                    >
+                      {{ item.itemText }}
+                    </a-select-option>
                   </a-select>
                 </a-form-model-item>
               </a-col>
-              <a-col :span="24">
+              <a-col :span="24" v-if="model.orderInfo.bookingType == 2">
+                <a-form-model-item
+                  label="时长"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.hourRoomId"
+                >
+                  <a-select
+                    placeholder="时长"
+                    v-model="model.orderInfo.hourRoomId"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in hourRoomRuleList"
+                      :key="item.id"
+                    >
+                      {{ item.hourRoomName }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24" v-else>
                 <a-form-model-item
                   label="天数"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.dayCount"
                 >
                   <a-input-number
-                    v-model="model.userName"
+                    v-model="model.orderInfo.dayCount"
                     placeholder="天数"
                     :min="1"
+                    @change="dayCountChange"
+                  ></a-input-number>
+                </a-form-model-item>
+              </a-col>
+
+              <a-col :span="24">
+                <a-form-model-item
+                  label="早餐"
+                  :labelCol="labelCol"
+                  :wrapperCol="wrapperCol"
+                  prop="orderInfo.breakfastNum"
+                >
+                  <a-input-number
+                    v-model="model.orderInfo.breakfastNum"
+                    placeholder="早餐"
+                    :min="0"
                   ></a-input-number>
                 </a-form-model-item>
               </a-col>
@@ -98,14 +156,18 @@
                   label="预定方式"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.bookingDicWay"
                 >
-                  <a-select placeholder="预定方式">
-                    <a-select-option value="美团酒店">
-                      美团酒店
-                    </a-select-option>
-                    <a-select-option value="携程酒店">
-                      携程酒店
+                  <a-select
+                    placeholder="预定方式"
+                    v-model="model.orderInfo.bookingDicWay"
+                  >
+                    <a-select-option
+                      :value="item.id"
+                      v-for="(item, index) in bookingdicWayList"
+                      :key="item.id"
+                    >
+                      {{ item.itemText }}
                     </a-select-option>
                   </a-select>
                 </a-form-model-item>
@@ -115,22 +177,30 @@
                   label="客人类型"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.customerType"
                 >
-                  <a-select placeholder="客人类型">
-                    <a-select-option value="散客"> 散客 </a-select-option>
-                    <a-select-option value="会员"> 会员 </a-select-option>
+                  <a-select
+                    placeholder="客人类型"
+                    v-model="model.orderInfo.customerType"
+                  >
+                    <a-select-option :value="1"> 散客 </a-select-option>
+                    <a-select-option :value="2"> 会员 </a-select-option>
+                    <a-select-option :value="3"> 协议单位 </a-select-option>
+                    <a-select-option :value="4"> 中介 </a-select-option>
                   </a-select>
                 </a-form-model-item>
               </a-col>
-              <a-col :span="24">
+              <a-col :span="24" v-if="model.orderInfo.bookingType === 1">
                 <a-form-model-item
                   label="房价方案"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.roomPriceSlnId"
                 >
-                  <a-select placeholder="房价方案">
+                  <a-select
+                    placeholder="房价方案"
+                    v-model="model.orderInfo.roomPriceSlnId"
+                  >
                     <a-select-option value="会员价"> 会员价 </a-select-option>
                     <a-select-option value="平日价"> 平日价 </a-select-option>
                   </a-select>
@@ -145,10 +215,10 @@
                   label="联系人"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="contactName"
                 >
                   <a-auto-complete
-                    v-model="model.key1"
+                    v-model="model.contactName"
                     placeholder="联系人"
                     @search="handleSearch"
                     @select="(e) => handleSelectMember(e)"
@@ -166,9 +236,9 @@
                   label="电话"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="phone"
                 >
-                  <a-input v-model="model.mobile" placeholder="电话"></a-input>
+                  <a-input v-model="model.phone" placeholder="电话"></a-input>
                 </a-form-model-item>
               </a-col>
               <a-col :span="24">
@@ -176,11 +246,15 @@
                   label="担保方式"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.warrantType"
                 >
-                  <a-select placeholder="担保方式">
-                    <a-select-option value="无担保"> 无担保 </a-select-option>
-                    <a-select-option value="有担保"> 有担保 </a-select-option>
+                  <a-select
+                    placeholder="担保方式"
+                    v-model="model.orderInfo.warrantType"
+                  >
+                    <a-select-option :value="1"> 无担保 </a-select-option>
+                    <a-select-option :value="2"> 有担保 </a-select-option>
+                    <a-select-option :value="3"> OTA担保 </a-select-option>
                   </a-select>
                 </a-form-model-item>
               </a-col>
@@ -189,11 +263,19 @@
                   label="销售员"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.warranter"
                 >
-                  <a-select placeholder="销售员">
-                    <a-select-option value="a"> a </a-select-option>
-                    <a-select-option value="b"> b </a-select-option>
+                  <a-select
+                    placeholder="销售员"
+                    v-model="model.orderInfo.warranter"
+                  >
+                    <a-select-option
+                      value="a"
+                      v-for="item in warranterList"
+                      :key="item.id"
+                    >
+                      {{ item.name }}
+                    </a-select-option>
                   </a-select>
                 </a-form-model-item>
               </a-col>
@@ -202,10 +284,10 @@
                   label="外部单号"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="sex"
+                  prop="orderInfo.outerOrdersNo"
                 >
                   <a-input
-                    v-model="model.mobile"
+                    v-model="model.orderInfo.outerOrdersNo"
                     placeholder="外部单号"
                   ></a-input>
                 </a-form-model-item>
@@ -215,10 +297,10 @@
                   label="备注"
                   :labelCol="labelCol"
                   :wrapperCol="wrapperCol"
-                  prop="remark"
+                  prop="orderInfo.remark"
                 >
                   <a-textarea
-                    v-model="model.remark"
+                    v-model="model.orderInfo.remark"
                     rows="4"
                     placeholder="备注"
                   />
@@ -231,46 +313,75 @@
               </h4>
               <a-divider />
               <p>
-                <span>占房天数:1晚</span>
-                <span style="padding-left: 10px">总价:599.00</span>
+                <span>占房天数:{{ model.orderInfo.dayCount }}晚</span>
+                <span style="padding-left: 10px">总价:{{ amount }}</span>
               </p>
               <a-table
                 :columns="columns"
-                :data-source="model.data"
+                :data-source="canUserRooms"
                 :pagination="false"
-                rowKey="id"
+                :rowKey="rowKey"
               >
                 <div
                   slot="expandedRowRender"
-                  slot-scope="text, record, index"
+                  slot-scope="record, index, indent, expanded"
                   style="margin: 0"
                 >
                   <p>
-                    已排房:<a-tag
-                      color="blue"
-                      closable
-                      :visible="visible"
-                      @close.stop="tagClose2(rindex, index)"
-                      v-for="(item, rindex) in text.rooms"
-                      :key="rindex"
-                      >{{ item.roomNo }}</a-tag
+                    已排房:
+                    <template
+                      v-for="(building, bIndex) in record.buildingRooms"
                     >
+                      <a-tag
+                        color="blue"
+                        closable
+                        :visible="visible"
+                        @close.stop="tagClose2(rindex, bIndex, index)"
+                        v-for="(item, rindex) in building.floorRooms"
+                        :key="rindex"
+                        v-if="item.check && item.check == 1"
+                        >{{ item.name }}</a-tag
+                      >
+                      <!-- <a-tag
+                        color="blue"
+                        closable
+                        :visible="visible"
+                        @close.stop="tagClose2(rindex, index)"
+                        v-for="(item, rindex) in record.rooms"
+                        :key="rindex"
+                        >{{ item.name }}</a-tag
+                      > -->
+                    </template>
+                  </p>
+                  <p>
+                    未排房:{{
+                      record.layout.presetNum - (record.rooms || []).length
+                    }}间
                   </p>
-                  <p>未排房:0间</p>
                 </div>
-                <template slot="key3" slot-scope="text, record, index">
-                  <editable-cell
-                    :text="text"
-                    @change="onCellChange('key3', index, $event)"
-                  />
+                <template slot="favPrice" slot-scope="text, record, index">
+                  <!-- <editable-cell
+                    :text="record.layout.favPrice"
+                    @change="onCellChange('favPrice', index, $event)"
+                  /> -->
+                  {{ record.layout.favPrice }}
                 </template>
-                <template slot="key6" slot-scope="text, record, index">
+                <template slot="presetNum" slot-scope="text, record, index">
                   <div>
-                    <a-input-number v-model="model.data[index].key6" :min="0" />
+                    <a-input-number
+                      v-model="record.layout.presetNum"
+                      :min="(record.rooms || []).length"
+                      :max="record.layout.oldTags"
+                      @change="presetNumChange($event, record)"
+                    />
                   </div>
                 </template>
                 <span slot="action" slot-scope="text, record, index">
-                  <a @click="pulsRoom(index)">排房</a>
+                  <a
+                    :disabled="record.layout.presetNum <= 0"
+                    @click="pulsRoom(index)"
+                    >排房</a
+                  >
                 </span>
               </a-table>
             </div>
@@ -286,11 +397,13 @@
 </template>
 
 <script>
-import { httpAction, getAction } from "@/api/manage";
+import { httpAction, getAction, postAction } from "@/api/manage";
 import { validateDuplicateValue } from "@/utils/util";
 import moment from "moment";
 import EditableCell from "@views/room/modules/checkIn/EditableCell.vue";
 import SelectRoomFormModal from "./SelectRoomFormModal.vue";
+const date = new Date();
+const endDate = new Date(date.setDate(date.getDate() + 1));
 const columns = [
   // {
   //     title: "",
@@ -299,33 +412,39 @@ const columns = [
   //   },
   {
     title: "房型",
-    dataIndex: "key1",
+    dataIndex: "name",
     width: 150,
+    customRender: function (text, record) {
+      return record.layout.name;
+    },
   },
   {
     title: "门市价",
-    dataIndex: "key2",
+    dataIndex: "marketPrice",
     width: 100,
+    customRender: function (text, record) {
+      return record.layout.marketPrice;
+    },
   },
   {
     title: "优惠价",
-    dataIndex: "key3",
+    dataIndex: "favPrice",
     width: 120,
-    scopedSlots: { customRender: "key3" },
+    scopedSlots: { customRender: "favPrice" },
   },
   {
     title: "可订数/可超数",
-    dataIndex: "key4",
+    dataIndex: "canUseCount",
     width: 170,
     customRender: function (text, record) {
-      return text + "/" + record.key5;
+      return record.layout.canUseCount + "/0";
     },
   },
   {
     title: "预定间数",
-    dataIndex: "key6",
+    dataIndex: "presetNum",
     width: 100,
-    scopedSlots: { customRender: "key6" },
+    scopedSlots: { customRender: "presetNum" },
   },
   {
     title: "操作",
@@ -363,7 +482,23 @@ export default {
     return {
       visible: true,
       columns,
-      model: { data: data },
+      model: {
+        // data: data,
+        orderInfo: {
+          bookingOrdersType: 1,
+          arrivalTime2: moment(new Date()).format("YYYY-MM-DD"),
+          dueOutTime2: moment(endDate).format("YYYY-MM-DD"),
+          arrivalTimeSpan: moment("18:00", "HH:mm"),
+          dueOutTimeSpan: moment("12:00", "HH:mm"),
+          bookingType: 1,
+          dayCount: 1,
+          warrantType: 1,
+          hourRoomId: "",
+          breakfastNum: 0,
+        },
+        roomIds: [],
+        layoutDayPrices: [],
+      },
       labelCol: {
         xs: { span: 24 },
         sm: { span: 5 },
@@ -374,22 +509,52 @@ export default {
       },
       confirmLoading: false,
       validatorRules: {
-        dateRange: [{ required: true, message: "请选择维修时间!" }],
-        remark: [{ required: true, message: "请输入维修原因!" }],
+        "orderInfo.bookingType": [
+          { required: true, message: "请选择入住类型!" },
+        ],
+        "orderInfo.arrivalTime2": [
+          { required: true, message: "请选择预抵时间!" },
+        ],
+        "orderInfo.dueOutTime2": [
+          { required: true, message: "请选择预离时间!" },
+        ],
+        "orderInfo.customerSource": [
+          { required: true, message: "请选择客人来源!" },
+        ],
+        "orderInfo.bookingDicWay": [
+          { required: true, message: "请选择预定方式!" },
+        ],
+        "orderInfo.customerType": [
+          { required: true, message: "请选择客人类型!" },
+        ],
+        contactName: [{ required: true, message: "请输入联系人!" }],
+        phone: [{ required: true, message: "请输入电话!" }],
       },
       url: {
-        add: "/business/busMeetingRoom/add",
+        add: "/business/busRoomBookingOrders/add",
         edit: "/business/busMeetingRoom/edit",
         queryById: "/business/busMeetingRoom/queryById",
       },
       result: [],
       selectIndex: 0,
+      customerSourceList: [],
+      bookingdicWayList: [],
+      warranterList: [],
+      hourRoomRuleList: [],
+      canUserRooms: [],
     };
   },
   computed: {
     formDisabled() {
       return this.disabled;
     },
+    amount() {
+      var sum = 0;
+      this.canUserRooms.forEach((t) => {
+        sum += t.layout.favPrice * t.layout.presetNum;
+      });
+      return sum.toFixed(2);
+    },
   },
   created() {
     var _info = JSON.parse(localStorage.getItem("storeInfo"));
@@ -398,21 +563,167 @@ export default {
     }
     //备份model原始值
     this.modelDefault = JSON.parse(JSON.stringify(this.model));
+
+    getAction("/business/busDictItem/list", {
+      hotelId: _info.id,
+      dictId: "1639538915239743490",
+    }).then((res) => {
+      if (res.success) {
+        this.customerSourceList = res.result.records;
+      }
+    });
+    getAction("/business/busDictItem/list", {
+      hotelId: _info.id,
+      dictId: "1639544187093995521",
+    }).then((res) => {
+      if (res.success) {
+        this.bookingdicWayList = res.result.records;
+      }
+    });
+    getAction("/business/busSalesPerson/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.warranterList = res.result.records;
+      }
+    });
+
+    getAction("/rooms/cesHourRoomRule/list", {
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.hourRoomRuleList = res.result.records;
+      }
+    });
+
+    postAction("/rooms/cesAllDayPriceRule/fetch", { hotelId: _info.id }).then(
+      (res) => {
+        if (res.success) {
+          if (
+            res.result &&
+            res.result.cesAllDayPriceRule &&
+            res.result.cesAllDayPriceRule.leaveTime
+          ) {
+            this.model.orderInfo.dueOutTimeSpan = moment(
+              res.result.cesAllDayPriceRule.leaveTime,
+              "HH:mm"
+            );
+          }
+        }
+
+        this.loadRooms();
+      }
+    );
   },
   methods: {
-    tagClose2(rindex, index) {
-      this.model.data[index].rooms.splice(rindex, 1);
+    presetNumChange(e, record) {
+      console.log(e);
+      record.layout.canUseCount = record.layout.oldTags - e;
+    },
+    onCellChange(key, dataIndex, value) {
+      const dataSource = [...this.canUserRooms];
+      const target = dataSource[dataIndex];
+      console.log("target", target);
+      if (target && target.layout) {
+        target.layout[key] = value;
+        this.canUserRooms = dataSource;
+      }
+      console.log("this.canUserRooms", this.canUserRooms);
+    },
+    rowKey(record) {
+      return record.layout.id;
+    },
+    loadRooms() {
+      getAction("/rooms/cesRooms/can-user-rooms", {
+        startOf:
+          this.model.orderInfo.arrivalTime2 +
+          " " +
+          moment(this.model.orderInfo.arrivalTimeSpan).format("HH:mm"),
+        endOf:
+          this.model.orderInfo.dueOutTime2 +
+          " " +
+          moment(this.model.orderInfo.dueOutTimeSpan).format("HH:mm"),
+        bookingType: this.model.orderInfo.bookingType,
+        hourRoomRuleId: this.model.orderInfo.hourRoomId,
+      }).then((res) => {
+        if (res.success) {
+          res.result.forEach((t) => {
+            t.layout = Object.assign({}, t.layout, {
+              presetNum: 0,
+              oldTags: t.layout.canUseCount,
+            });
+            t.buildingRooms.forEach((b) => {
+              b.floorRooms.forEach((f) => {
+                this.$set(f, "check", 0);
+              });
+            });
+          });
+          this.canUserRooms = res.result;
+        }
+      });
+    },
+    bookingTypeChange(e) {
+      if (this.model.orderInfo.bookingType == 1) {
+        this.model.orderInfo.hourRoomId = "";
+      } else {
+        var hourRoomRule = this.hourRoomRuleList[0];
+        if (hourRoomRule) {
+          this.model.orderInfo.hourRoomId = hourRoomRule.id;
+        }
+      }
+      this.loadRooms();
+    },
+    dayCountChange(e) {
+      this.model.orderInfo.dueOutTime2 = moment(
+        this.model.orderInfo.arrivalTime2
+      )
+        .add(e, "days")
+        .format("YYYY-MM-DD");
+      this.loadRooms();
+    },
+    disabledDate(current) {
+      return current && current < moment().add(-1, "days").endOf("day");
+    },
+    arrivalTimeChange(e) {
+      this.model.orderInfo.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.orderInfo.arrivalTime2).getTime() -
+            new Date(this.model.orderInfo.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    arrivalTimeSpanChange(m, time) {
+      console.log(time);
+      console.log(moment(m).format("HH:mm"));
+    },
+    tagClose2(rindex, bindex, index) {
+      // console.log(rindex, index);
+      // console.log(this.canUserRooms[index]);
+      this.canUserRooms[index].rooms.splice(rindex, 1);
+
+      this.$set(
+        this.canUserRooms[index].buildingRooms[bindex].floorRooms[rindex],
+        "check",
+        0
+      );
+      console.log(this.canUserRooms);
     },
     modalFormOk(e) {
       // this.modelDefault = Object.assign({}, this.modelDefault, {
       //   rooms: e,
       // });
       // this.edit(this.modelDefault);
-      this.$set(this.model.data[this.selectIndex], "rooms", e);
+      this.$set(this.canUserRooms[this.selectIndex], "rooms", e);
+      console.log(this.canUserRooms[this.selectIndex]);
     },
     pulsRoom(index) {
       this.selectIndex = index;
-      this.$refs.modalSelectRoomForm.add();
+      this.$refs.modalSelectRoomForm.add(this.canUserRooms[this.selectIndex]);
       this.$refs.modalSelectRoomForm.title = "排房";
       this.$refs.modalSelectRoomForm.disableSubmit = false;
     },
@@ -449,11 +760,51 @@ export default {
     },
     submitForm() {
       const that = this;
-      that.$message.warning("未实现");
-      return;
+      that.model.roomIds = [];
+      that.canUserRooms.forEach((t) => {
+        var lastlayoutId = t.layout.id;
+        t.buildingRooms.forEach((b) => {
+          b.floorRooms.forEach((f) => {
+            if (f.check && f.check === 1) {
+              that.model.roomIds.push({ layoutId: t.layout.id, roomId: f.id });
+            }
+          });
+        });
+        const roomIds = that.model.roomIds.filter(
+          (it) => it.layoutId === lastlayoutId
+        );
+        var len = roomIds.length;
+        for (var i = len; i < t.layout.presetNum; i++) {
+          that.model.roomIds.push({ layoutId: t.layout.id, roomId: null });
+        }
+        for (var b = 0; b < that.model.orderInfo.dayCount; b++) {
+          var dayTime = moment(this.model.orderInfo.arrivalTime2)
+            .add(b, "days")
+            .format("YYYY-MM-DD");
+          that.model.layoutDayPrices.push({
+            bookingType: 1,
+            dayTime: dayTime,
+            price: t.layout.favPrice,
+            roomLayoutId: t.layout.id,
+          });
+        }
+      });
+      console.log("this.model", this.model);
+      if (that.model.roomIds.length <= 0) {
+        that.$message.warning("请先添加房间");
+        return;
+      }
       // 触发表单验证
       this.$refs.form.validate((valid) => {
         if (valid) {
+          this.model.orderInfo.arrivalTime =
+            this.model.orderInfo.arrivalTime2 +
+            " " +
+            moment(this.model.orderInfo.arrivalTimeSpan).format("HH:mm");
+          this.model.orderInfo.dueOutTime =
+            this.model.orderInfo.dueOutTime2 +
+            " " +
+            moment(this.model.orderInfo.dueOutTimeSpan).format("HH:mm");
           that.confirmLoading = true;
           let httpurl = "";
           let method = "";

+ 35 - 22
src/views/room/modules/schedule/SelectRoomForm.vue

@@ -13,15 +13,11 @@
               label="房型"
               :labelCol="labelCol"
               :wrapperCol="wrapperCol"
-              prop="roomType"
             >
-              <a-checkbox-group
-                v-model="model.roomType"
-                :options="roomTypeOptions"
-              />
+              <a-checkbox default-checked disabled>{{ layoutName }}</a-checkbox>
             </a-form-model-item>
           </a-col>
-          <a-col :span="24">
+          <!-- <a-col :span="24">
             <a-form-model-item
               label="房态"
               :labelCol="labelCol"
@@ -33,14 +29,14 @@
                 :options="roomStatusOptions"
               />
             </a-form-model-item>
-          </a-col>
+          </a-col> -->
           <a-col :span="24">
             <a-form-model-item
-            label="已排房"
+              label="已排房"
               :labelCol="labelCol"
               :wrapperCol="wrapperCol"
             >
-            {{model.rooms.length||0}}/1
+              {{ model.rooms.length || 0 }}/{{ presetNum }}
             </a-form-model-item>
           </a-col>
           <a-col :span="24">
@@ -57,10 +53,10 @@
                 color="blue"
                 closable
                 :visible="visible"
-                @close.stop="tagClose2(index, item.roomNo)"
+                @close.stop="tagClose2(index, item.name)"
                 v-for="(item, index) in model.rooms"
                 :key="index"
-                >{{ item.roomNo }}</a-tag
+                >{{ item.name }}</a-tag
               >
             </a-form-model-item>
           </a-col>
@@ -74,14 +70,14 @@
               }"
             >
               <a-tabs
-                :default-active-key="0"
+                default-active-key="room0"
                 tab-position="left"
                 :style="{ height: '300px' }"
               >
                 <a-tab-pane
                   v-for="(room, index) in roomList"
-                  :key="index"
-                  :tab="room.key"
+                  :key="'room' + index"
+                  :tab="room.floorName"
                 >
                   <div
                     id="components-grid-demo-playground"
@@ -90,8 +86,8 @@
                     <a-row :gutter="[8, 8]">
                       <a-col
                         :span="3"
-                        v-for="(r, rIndex) in room.child"
-                        :key="rIndex"
+                        v-for="(r, rIndex) in room.floorRooms"
+                        :key="'floorRooms' + rIndex"
                       >
                         <div
                           :class="[
@@ -100,7 +96,7 @@
                           ]"
                           @click="checkRoomClick(r)"
                         >
-                          {{ r.roomNo }}
+                          {{ r.name }}
                         </div></a-col
                       >
                     </a-row>
@@ -154,9 +150,9 @@ export default {
         { key: "1层", child: rooms },
         { key: "2层", child: rooms2 },
       ],
-      roomTypeOptions: ["休闲家庭房", "特价房"],
+      roomTypeOptions: [],
       roomStatusOptions: ["空净", "空脏"],
-      model: { rooms: [] },
+      model: { roomType: "", rooms: [] },
       labelCol: {
         xs: { span: 24 },
         sm: { span: 2 },
@@ -175,6 +171,8 @@ export default {
         edit: "/business/busMeetingRoom/edit",
         queryById: "/business/busMeetingRoom/queryById",
       },
+      layoutName: "",
+      presetNum: 0,
     };
   },
   computed: {
@@ -197,6 +195,10 @@ export default {
         var index = this.model.rooms.findIndex((t) => t.key1 == row.key1);
         this.model.rooms.splice(index, 1);
       } else {
+        if (this.model.rooms.length >= this.presetNum) {
+          this.$message.warning("超过排房数量");
+          return;
+        }
         row.check = 1;
         this.model.rooms.push(row);
       }
@@ -204,8 +206,8 @@ export default {
     tagClose2(index, key1) {
       this.model.rooms.splice(index, 1);
       this.roomList.some((t) => {
-        var r = t.child.some((c) => {
-          if (c.roomNo === key1) {
+        var r = t.floorRooms.some((c) => {
+          if (c.name === key1) {
             c.check = 0;
             return true;
           }
@@ -219,11 +221,22 @@ export default {
     onChange(date, dateString) {
       console.log(date, dateString);
     },
-    add() {
+    add(row) {
+      console.log("buildingRooms", row.buildingRooms);
+      this.layoutName = row.layout.name;
+      this.presetNum = row.layout.presetNum;
+      this.roomList = row.buildingRooms;
       this.edit(this.modelDefault);
     },
     edit(record) {
       this.model = Object.assign({}, record);
+      this.roomList.forEach((t) => {
+        t.floorRooms.forEach((f) => {
+          if (f.check && f.check == 1) {
+            this.model.rooms.push(f);
+          }
+        });
+      });
       this.visible = true;
     },
     submitForm() {

+ 2 - 2
src/views/room/modules/schedule/SelectRoomFormModal.vue

@@ -33,10 +33,10 @@ export default {
     };
   },
   methods: {
-    add() {
+    add(row) {
       this.visible = true;
       this.$nextTick(() => {
-        this.$refs.realForm.add();
+        this.$refs.realForm.add(row);
       });
     },
     edit(record) {

+ 521 - 0
src/views/room/modules/scheduleTeam/BatchSelectRoomTypeForm.vue

@@ -0,0 +1,521 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预抵时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="arrivalTime2"
+            >
+              <j-date
+                placeholder="预抵时间"
+                v-model="model.arrivalTime2"
+                style="width: 180px"
+                :allowClear="false"
+                :disabled-date="disabledDate"
+                @change="arrivalTimeChange"
+              />
+              <a-time-picker
+                style="width: 80px; margin-left: 2px"
+                v-model="model.arrivalTimeSpan"
+                format="HH:mm"
+                :allowClear="false"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预离时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="dueOutTime2"
+            >
+              <j-date
+                placeholder="预离时间"
+                v-model="model.dueOutTime2"
+                style="width: 180px"
+                :allowClear="false"
+                :disabled-date="disabledDate"
+                @change="arrivalTimeChange2"
+              />
+              <a-time-picker
+                style="width: 80px; margin-left: 2px"
+                v-model="model.dueOutTimeSpan"
+                format="HH:mm"
+                :allowClear="false"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="天数"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="dayCount"
+            >
+              <a-input-number
+                v-model="model.dayCount"
+                placeholder="天数"
+                :min="1"
+                @change="dayCountChange"
+              ></a-input-number>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">
+              选择房间
+            </h4>
+            <a-divider />
+            <p>
+              <span>占房天数:{{ model.dayCount }}晚</span>
+              <span style="padding-left: 10px">总价:{{ amount }}</span>
+            </p>
+            <a-table
+              :columns="columns"
+              :data-source="canUserRooms"
+              :pagination="false"
+              :rowKey="rowKey"
+            >
+              <div
+                slot="expandedRowRender"
+                slot-scope="record, index, indent, expanded"
+                style="margin: 0"
+              >
+                <p>
+                  已排房:
+                  <template v-for="(building, bIndex) in record.buildingRooms">
+                    <a-tag
+                      color="blue"
+                      closable
+                      :visible="visible"
+                      @close.stop="tagClose2(rindex, bIndex, index)"
+                      v-for="(item, rindex) in building.floorRooms"
+                      :key="rindex"
+                      v-if="item.check && item.check == 1"
+                      >{{ item.name }}</a-tag
+                    >
+                  </template>
+                </p>
+                <p>
+                  未排房:{{
+                    record.layout.presetNum - (record.rooms || []).length
+                  }}间
+                </p>
+              </div>
+              <template slot="favPrice" slot-scope="text, record, index">
+                <!-- <editable-cell
+                    :text="record.layout.favPrice"
+                    @change="onCellChange('favPrice', index, $event)"
+                  /> -->
+                {{ record.layout.favPrice }}
+              </template>
+              <template slot="presetNum" slot-scope="text, record, index">
+                <div>
+                  <a-input-number
+                    v-model="record.layout.presetNum"
+                    :min="(record.rooms || []).length"
+                    :max="record.layout.oldTags"
+                    @change="presetNumChange($event, record)"
+                  />
+                </div>
+              </template>
+              <span slot="action" slot-scope="text, record, index">
+                <a
+                  :disabled="record.layout.presetNum <= 0"
+                  @click="pulsRoom(index)"
+                  >排房</a
+                >
+              </span>
+            </a-table>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+    <select-room-form-modal
+      ref="modalSelectRoomForm"
+      @ok="modalFormOk"
+    ></select-room-form-modal>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+import SelectRoomFormModal from "./SelectRoomFormModal.vue";
+import moment from "moment";
+export default {
+  name: "SelectRoomForm",
+  components: { SelectRoomFormModal },
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+    orderInfo: {
+      type: Object,
+      default: {},
+    },
+    batchRoomsTypeList: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      visible: true,
+      columns: [
+        // {
+        //     title: "",
+        //     dataIndex: "key",
+        //     width: 20,
+        //   },
+        {
+          title: "房型",
+          dataIndex: "name",
+          width: 150,
+          customRender: function (text, record) {
+            return record.layout.name;
+          },
+        },
+        {
+          title: "门市价",
+          dataIndex: "marketPrice",
+          width: 100,
+          customRender: function (text, record) {
+            return record.layout.marketPrice;
+          },
+        },
+        {
+          title: "优惠价",
+          dataIndex: "favPrice",
+          width: 120,
+          scopedSlots: { customRender: "favPrice" },
+        },
+        {
+          title: "可订数/可超数",
+          dataIndex: "canUseCount",
+          width: 170,
+          customRender: function (text, record) {
+            return record.layout.canUseCount + "/0";
+          },
+        },
+        {
+          title: "预定间数",
+          dataIndex: "presetNum",
+          width: 100,
+          scopedSlots: { customRender: "presetNum" },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 70,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      model: {
+        arrivalTime2: moment(new Date()).format("YYYY-MM-DD"),
+        dueOutTime2: this.orderInfo.dueOutTime2,
+        arrivalTimeSpan: moment("18:00", "HH:mm"),
+        dueOutTimeSpan: this.orderInfo.dueOutTimeSpan,
+        dayCount: 1,
+        bookingType: this.orderInfo.bookingType,
+        hourRoomId: this.orderInfo.hourRoomId,
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 2 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        dateRange: [{ required: true, message: "请选择维修时间!" }],
+        remark: [{ required: true, message: "请输入维修原因!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoom/add",
+        edit: "/business/busMeetingRoom/edit",
+        queryById: "/business/busMeetingRoom/queryById",
+      },
+      layoutName: "",
+      presetNum: 0,
+      canUserRooms: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+    amount() {
+      var sum = 0;
+      this.canUserRooms.forEach((t) => {
+        sum += t.layout.favPrice * t.layout.presetNum * this.model.dayCount;
+      });
+      return sum.toFixed(2);
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    this.loadRooms();
+  },
+  methods: {
+    tagClose2(rindex, bindex, index) {
+      this.canUserRooms[index].rooms.splice(rindex, 1);
+
+      this.$set(
+        this.canUserRooms[index].buildingRooms[bindex].floorRooms[rindex],
+        "check",
+        0
+      );
+      console.log(this.canUserRooms);
+    },
+    modalFormOk(e) {
+      this.$set(this.canUserRooms[this.selectIndex], "rooms", e);
+      console.log(this.canUserRooms[this.selectIndex]);
+    },
+    pulsRoom(index) {
+      this.selectIndex = index;
+      this.$refs.modalSelectRoomForm.add(this.canUserRooms[this.selectIndex]);
+      this.$refs.modalSelectRoomForm.title = "排房";
+      this.$refs.modalSelectRoomForm.disableSubmit = false;
+    },
+    presetNumChange(e, record) {
+      console.log(e);
+      record.layout.canUseCount = record.layout.oldTags - e;
+    },
+    rowKey(record) {
+      return record.layout.id;
+    },
+    dayCountChange(e) {
+      this.model.dueOutTime2 = moment(this.model.arrivalTime2)
+        .add(e, "days")
+        .format("YYYY-MM-DD");
+      this.loadRooms();
+    },
+    disabledDate(current) {
+      return current && current < moment().add(-1, "days").endOf("day");
+    },
+    arrivalTimeChange(e) {
+      this.model.dueOutTime2 = moment(this.model.arrivalTime2)
+        .add(this.model.dayCount, "days")
+        .format("YYYY-MM-DD");
+      this.model.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.arrivalTime2).getTime() -
+            new Date(this.model.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    arrivalTimeChange2(e) {
+      this.model.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.arrivalTime2).getTime() -
+            new Date(this.model.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    isDateIntersection(start1, end1, start2, end2) {
+      var startdate1 = new Date(start1.replace("-", "/").replace("-", "/"));
+      var enddate1 = new Date(end1.replace("-", "/").replace("-", "/"));
+
+      var startdate2 = new Date(start2.replace("-", "/").replace("-", "/"));
+      var enddate2 = new Date(end2.replace("-", "/").replace("-", "/"));
+
+      if (startdate1 >= startdate2 && startdate1 <= enddate2) {
+        return true;
+      }
+
+      if (enddate1 >= startdate2 && enddate1 <= enddate2) {
+        return true;
+      }
+
+      if (startdate1 <= startdate2 && enddate1 >= enddate2) {
+        return true;
+      }
+      return false;
+    },
+    loadRooms() {
+      var startOf =
+        this.model.arrivalTime2 +
+        " " +
+        moment(this.model.arrivalTimeSpan).format("HH:mm");
+      var endOf =
+        this.model.dueOutTime2 +
+        " " +
+        moment(this.model.dueOutTimeSpan).format("HH:mm");
+
+      getAction("/rooms/cesRooms/can-user-rooms", {
+        startOf: startOf,
+        endOf: endOf,
+        bookingType: this.model.bookingType,
+        hourRoomRuleId: this.model.hourRoomId,
+      }).then((res) => {
+        if (res.success) {
+          if (this.batchRoomsTypeList.length > 0) {
+            this.batchRoomsTypeList.forEach((bt) => {
+              var dateArr = bt.key.split(",");
+              var startOf2 = dateArr[0];
+              var endOf2 = dateArr[1];
+              //判断日期段是否有交集,有交集的情况下可订数量动态计算,动态排除已选排房
+              var isDateSection = this.isDateIntersection(
+                startOf,
+                endOf,
+                startOf2,
+                endOf2
+              );
+              console.log("isDateSection", isDateSection);
+              if (isDateSection) {
+                res.result.forEach((t) => {
+                  var find = bt.data.find(
+                    (ibt) => ibt.layout.id === t.layout.id
+                  );
+
+                  t.layout = Object.assign({}, t.layout, {
+                    presetNum: 0,
+                    canUseCount:
+                      t.layout.canUseCount - (find ? find.layout.presetNum : 0),
+                    oldTags:
+                      t.layout.canUseCount - (find ? find.layout.presetNum : 0),
+                  });
+                  t.buildingRooms.forEach((b) => {
+                    if (find && find.buildingRooms) {
+                      find.buildingRooms.forEach((fbr) => {
+                        fbr.floorRooms.forEach((fbrfloorRoom) => {
+                          if (fbrfloorRoom.check && fbrfloorRoom.check == 1) {
+                            var findIndex = b.floorRooms.findIndex(
+                              (floorRoom) => floorRoom.id === fbrfloorRoom.id
+                            );
+                            if (findIndex >= 0) {
+                              b.floorRooms.splice(findIndex, 1);
+                            }
+                          }
+                        });
+                      });
+                    }
+                    b.floorRooms.forEach((f) => {
+                      this.$set(f, "check", 0);
+                    });
+                  });
+                });
+              } else {
+                res.result.forEach((t) => {
+                  t.layout = Object.assign({}, t.layout, {
+                    presetNum: 0,
+                    oldTags: t.layout.canUseCount,
+                  });
+                  t.buildingRooms.forEach((b) => {
+                    b.floorRooms.forEach((f) => {
+                      this.$set(f, "check", 0);
+                    });
+                  });
+                });
+              }
+            });
+            this.canUserRooms = res.result;
+          } else {
+            res.result.forEach((t) => {
+              t.layout = Object.assign({}, t.layout, {
+                presetNum: 0,
+                oldTags: t.layout.canUseCount,
+              });
+              t.buildingRooms.forEach((b) => {
+                b.floorRooms.forEach((f) => {
+                  this.$set(f, "check", 0);
+                });
+              });
+            });
+            this.canUserRooms = res.result;
+          }
+        }
+      });
+    },
+    moment,
+    add(row) {
+      // console.log("buildingRooms", row.buildingRooms);
+      // this.layoutName = row.layout.name;
+      // this.presetNum = row.layout.presetNum;
+      // this.roomList = row.buildingRooms;
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      var data = that.canUserRooms.filter((it) => it.layout.presetNum > 0);
+      if (data.length <= 0) {
+        that.$message.warning("请先添加房间");
+        return;
+      }
+      that.$emit("ok", {
+        key:
+          this.model.arrivalTime2 +
+          " " +
+          moment(this.model.arrivalTimeSpan).format("HH:mm") +
+          "," +
+          this.model.dueOutTime2 +
+          " " +
+          moment(this.model.dueOutTimeSpan).format("HH:mm"),
+        arrivalTime2: this.model.arrivalTime2,
+        dueOutTime2: this.model.dueOutTime2,
+        arrivalTimeSpan: this.model.arrivalTimeSpan,
+        dueOutTimeSpan: this.model.dueOutTimeSpan,
+        dayCount: this.model.dayCount,
+        amount: this.amount,
+        data: data,
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+#components-grid-demo-playground [class~="ant-col"] {
+  background: transparent;
+  border: 0;
+}
+#components-grid-demo-playground [class~="ant-col"] > div {
+  /* background: #00a0e9; */
+  height: 28px;
+  line-height: 28px;
+  font-size: 13px;
+  text-align: center;
+  cursor: pointer;
+  border-radius: 5px;
+}
+#components-grid-demo-playground .check {
+  border: 1px solid #00a0e9;
+}
+#components-grid-demo-playground .kz {
+  background: rgba(166, 166, 166, 1);
+}
+#components-grid-demo-playground pre {
+  background: #f9f9f9;
+  border-radius: 6px;
+  font-size: 13px;
+  padding: 8px 16px;
+}
+</style>

+ 77 - 0
src/views/room/modules/scheduleTeam/BatchSelectRoomTypeFormModal.vue

@@ -0,0 +1,77 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <batch-select-room-type-form
+      ref="realForm"
+      @ok="submitCallback"
+      :disabled="disableSubmit"
+      :orderInfo="orderInfo"
+      :batchRoomsTypeList="batchRoomsTypeList"
+    ></batch-select-room-type-form>
+  </j-modal>
+</template>
+
+<script>
+import BatchSelectRoomTypeForm from "./BatchSelectRoomTypeForm";
+export default {
+  name: "BatchSelectRoomTypeFormModal",
+  components: {
+    BatchSelectRoomTypeForm,
+  },
+  props: {
+    orderInfo: {
+      type: Object,
+      default: {},
+    },
+    batchRoomsTypeList: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 900,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add(row) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.add(row);
+      });
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.realForm.submitForm();
+    },
+    submitCallback(e) {
+      console.log("e", e);
+      this.$emit("ok", e);
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 527 - 0
src/views/room/modules/scheduleTeam/EditBatchSelectRoomTypeForm.vue

@@ -0,0 +1,527 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预抵时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="arrivalTime2"
+            >
+              <j-date
+                placeholder="预抵时间"
+                v-model="model.arrivalTime2"
+                style="width: 180px"
+                :allowClear="false"
+                :disabled-date="disabledDate"
+                @change="arrivalTimeChange"
+              />
+              <a-time-picker
+                style="width: 80px; margin-left: 2px"
+                v-model="model.arrivalTimeSpan"
+                format="HH:mm"
+                :allowClear="false"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预离时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="dueOutTime2"
+            >
+              <j-date
+                placeholder="预离时间"
+                v-model="model.dueOutTime2"
+                style="width: 180px"
+                :allowClear="false"
+                :disabled-date="disabledDate"
+                @change="arrivalTimeChange2"
+              />
+              <a-time-picker
+                style="width: 80px; margin-left: 2px"
+                v-model="model.dueOutTimeSpan"
+                format="HH:mm"
+                :allowClear="false"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="天数"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="dayCount"
+            >
+              <a-input-number
+                v-model="model.dayCount"
+                placeholder="天数"
+                :min="1"
+                @change="dayCountChange"
+              ></a-input-number>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">
+              选择房间
+            </h4>
+            <a-divider />
+            <p>
+              <span>占房天数:{{ model.dayCount }}晚</span>
+              <span style="padding-left: 10px">总价:{{ amount }}</span>
+            </p>
+            <a-table
+              :columns="columns"
+              :data-source="canUserRooms"
+              :pagination="false"
+              :rowKey="rowKey"
+            >
+              <div
+                slot="expandedRowRender"
+                slot-scope="record, index, indent, expanded"
+                style="margin: 0"
+              >
+                <p>
+                  已排房:
+                  <template v-for="(building, bIndex) in record.buildingRooms">
+                    <a-tag
+                      color="blue"
+                      closable
+                      :visible="visible"
+                      @close.stop="tagClose2(rindex, bIndex, index)"
+                      v-for="(item, rindex) in building.floorRooms"
+                      :key="rindex"
+                      v-if="item.check && item.check == 1"
+                      >{{ item.name }}</a-tag
+                    >
+                  </template>
+                </p>
+                <p>
+                  未排房:{{
+                    record.layout.presetNum - (record.rooms || []).length
+                  }}间
+                </p>
+              </div>
+              <template slot="favPrice" slot-scope="text, record, index">
+                <!-- <editable-cell
+                    :text="record.layout.favPrice"
+                    @change="onCellChange('favPrice', index, $event)"
+                  /> -->
+                {{ record.layout.favPrice }}
+              </template>
+              <template slot="presetNum" slot-scope="text, record, index">
+                <div>
+                  <a-input-number
+                    v-model="record.layout.presetNum"
+                    :min="(record.rooms || []).length"
+                    :max="record.layout.oldTags"
+                    @change="presetNumChange($event, record)"
+                  />
+                </div>
+              </template>
+              <span slot="action" slot-scope="text, record, index">
+                <a
+                  :disabled="record.layout.presetNum <= 0"
+                  @click="pulsRoom(index)"
+                  >排房</a
+                >
+              </span>
+            </a-table>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+    <select-room-form-modal
+      ref="modalSelectRoomForm"
+      @ok="modalFormOk"
+    ></select-room-form-modal>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+import SelectRoomFormModal from "./SelectRoomFormModal.vue";
+import moment from "moment";
+export default {
+  name: "SelectRoomForm",
+  components: { SelectRoomFormModal },
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+    orderInfo: {
+      type: Object,
+      default: {},
+    },
+    batchRoomsTypeList: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      visible: true,
+      columns: [
+        // {
+        //     title: "",
+        //     dataIndex: "key",
+        //     width: 20,
+        //   },
+        {
+          title: "房型",
+          dataIndex: "name",
+          width: 150,
+          customRender: function (text, record) {
+            return record.layout.name;
+          },
+        },
+        {
+          title: "门市价",
+          dataIndex: "marketPrice",
+          width: 100,
+          customRender: function (text, record) {
+            return record.layout.marketPrice;
+          },
+        },
+        {
+          title: "优惠价",
+          dataIndex: "favPrice",
+          width: 120,
+          scopedSlots: { customRender: "favPrice" },
+        },
+        {
+          title: "可订数/可超数",
+          dataIndex: "canUseCount",
+          width: 170,
+          customRender: function (text, record) {
+            return record.layout.canUseCount + "/0";
+          },
+        },
+        {
+          title: "预定间数",
+          dataIndex: "presetNum",
+          width: 100,
+          scopedSlots: { customRender: "presetNum" },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 70,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      model: {
+        arrivalTime2: this.orderInfo.arrivalTime2,
+        dueOutTime2: this.orderInfo.dueOutTime2,
+        arrivalTimeSpan: this.orderInfo.arrivalTimeSpan,
+        dueOutTimeSpan: this.orderInfo.dueOutTimeSpan,
+        dayCount: this.orderInfo.dayCount,
+        bookingType: this.orderInfo.bookingType,
+        hourRoomId: this.orderInfo.hourRoomId,
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 2 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        dateRange: [{ required: true, message: "请选择维修时间!" }],
+        remark: [{ required: true, message: "请输入维修原因!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoom/add",
+        edit: "/business/busMeetingRoom/edit",
+        queryById: "/business/busMeetingRoom/queryById",
+      },
+      layoutName: "",
+      presetNum: 0,
+      canUserRooms: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+    amount() {
+      var sum = 0;
+      this.canUserRooms.forEach((t) => {
+        sum += t.layout.favPrice * t.layout.presetNum * this.model.dayCount;
+      });
+      return sum.toFixed(2);
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    this.loadRooms();
+  },
+  methods: {
+    tagClose2(rindex, bindex, index) {
+      this.canUserRooms[index].rooms.splice(rindex, 1);
+
+      this.$set(
+        this.canUserRooms[index].buildingRooms[bindex].floorRooms[rindex],
+        "check",
+        0
+      );
+      console.log(this.canUserRooms);
+    },
+    modalFormOk(e) {
+      this.$set(this.canUserRooms[this.selectIndex], "rooms", e);
+      console.log(this.canUserRooms[this.selectIndex]);
+    },
+    pulsRoom(index) {
+      this.selectIndex = index;
+      this.$refs.modalSelectRoomForm.add(this.canUserRooms[this.selectIndex]);
+      this.$refs.modalSelectRoomForm.title = "排房";
+      this.$refs.modalSelectRoomForm.disableSubmit = false;
+    },
+    rowKey(record) {
+      return record.layout.id;
+    },
+    dayCountChange(e) {
+      this.model.dueOutTime2 = moment(this.model.arrivalTime2)
+        .add(e, "days")
+        .format("YYYY-MM-DD");
+      this.loadRooms();
+    },
+    disabledDate(current) {
+      return current && current < moment().add(-1, "days").endOf("day");
+    },
+    arrivalTimeChange(e) {
+      this.model.dueOutTime2 = moment(this.model.arrivalTime2)
+        .add(this.model.dayCount, "days")
+        .format("YYYY-MM-DD");
+      this.model.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.arrivalTime2).getTime() -
+            new Date(this.model.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    arrivalTimeChange2(e) {
+      this.model.dayCount = Math.abs(
+        parseInt(
+          (new Date(this.model.arrivalTime2).getTime() -
+            new Date(this.model.dueOutTime2).getTime()) /
+            (1000 * 60 * 60 * 24)
+        )
+      );
+      this.loadRooms();
+    },
+    isDateIntersection(start1, end1, start2, end2) {
+      var startdate1 = new Date(start1.replace("-", "/").replace("-", "/"));
+      var enddate1 = new Date(end1.replace("-", "/").replace("-", "/"));
+
+      var startdate2 = new Date(start2.replace("-", "/").replace("-", "/"));
+      var enddate2 = new Date(end2.replace("-", "/").replace("-", "/"));
+
+      if (startdate1 >= startdate2 && startdate1 <= enddate2) {
+        return true;
+      }
+
+      if (enddate1 >= startdate2 && enddate1 <= enddate2) {
+        return true;
+      }
+
+      if (startdate1 <= startdate2 && enddate1 >= enddate2) {
+        return true;
+      }
+      return false;
+    },
+    presetNumChange(e, record) {
+      console.log(e);
+      record.layout.canUseCount = record.layout.oldTags - e;
+    },
+    loadRooms() {
+      var startOf =
+        this.model.arrivalTime2 +
+        " " +
+        moment(this.model.arrivalTimeSpan).format("HH:mm");
+      var endOf =
+        this.model.dueOutTime2 +
+        " " +
+        moment(this.model.dueOutTimeSpan).format("HH:mm");
+
+      getAction("/rooms/cesRooms/can-user-rooms", {
+        startOf: startOf,
+        endOf: endOf,
+        bookingType: this.model.bookingType,
+        hourRoomRuleId: this.model.hourRoomId,
+      }).then((res) => {
+        if (res.success) {
+          if (this.batchRoomsTypeList.length > 0) {
+            this.batchRoomsTypeList.forEach((bt) => {
+              var dateArr = bt.key.split(",");
+              var startOf2 = dateArr[0];
+              var endOf2 = dateArr[1];
+              //判断日期段是否有交集,有交集的情况下可订数量动态计算,动态排除已选排房
+              var isDateSection = this.isDateIntersection(
+                startOf,
+                endOf,
+                startOf2,
+                endOf2
+              );
+              console.log("isDateSection", isDateSection);
+              if (isDateSection) {
+                res.result.forEach((t) => {
+                  this.$set(t, "rooms", []);
+                  var find = bt.data.find(
+                    (ibt) => ibt.layout.id === t.layout.id
+                  );
+
+                  t.layout = Object.assign({}, t.layout, {
+                    presetNum: find ? find.layout.presetNum : 0,
+                    canUseCount:
+                      t.layout.canUseCount - (find ? find.layout.presetNum : 0),
+                    // oldTags:
+                    //   t.layout.canUseCount - (find ? find.layout.presetNum : 0),
+                    oldTags: t.layout.canUseCount,
+                  });
+                  t.buildingRooms.forEach((b) => {
+                    if (find && find.buildingRooms) {
+                      find.buildingRooms.forEach((fbr) => {
+                        fbr.floorRooms.forEach((fbrfloorRoom) => {
+                          if (fbrfloorRoom.check && fbrfloorRoom.check == 1) {
+                            var findIndex = b.floorRooms.findIndex(
+                              (floorRoom) => floorRoom.id === fbrfloorRoom.id
+                            );
+                            if (findIndex >= 0) {
+                              // b.floorRooms.splice(findIndex, 1);
+                              this.$set(b.floorRooms[findIndex], "check", 1);
+                              t.rooms.push(b)
+                            }
+                          }
+                        });
+                      });
+                    }
+                    b.floorRooms.forEach((f) => {
+                      if (!f.check) {
+                        this.$set(f, "check", 0);
+                      }
+                    });
+                  });
+                });
+              } else {
+                res.result.forEach((t) => {
+                  t.layout = Object.assign({}, t.layout, {
+                    presetNum: 0,
+                    oldTags: t.layout.canUseCount,
+                  });
+                  t.buildingRooms.forEach((b) => {
+                    b.floorRooms.forEach((f) => {
+                      this.$set(f, "check", 0);
+                    });
+                  });
+                });
+              }
+            });
+            this.canUserRooms = res.result;
+          } else {
+            res.result.forEach((t) => {
+              t.layout = Object.assign({}, t.layout, {
+                presetNum: 0,
+                oldTags: t.layout.canUseCount,
+              });
+              t.buildingRooms.forEach((b) => {
+                b.floorRooms.forEach((f) => {
+                  this.$set(f, "check", 0);
+                });
+              });
+            });
+            this.canUserRooms = res.result;
+          }
+        }
+      });
+    },
+    moment,
+    add(row) {
+      // console.log("buildingRooms", row);
+      // this.layoutName = row.layout.name;
+      // this.presetNum = row.layout.presetNum;
+      // this.roomList = row.buildingRooms;
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      var data = that.canUserRooms.filter((it) => it.layout.presetNum > 0);
+      if (data.length <= 0) {
+        that.$message.warning("请先添加房间");
+        return;
+      }
+      that.$emit("ok", {
+        key:
+          this.model.arrivalTime2 +
+          " " +
+          moment(this.model.arrivalTimeSpan).format("HH:mm") +
+          "," +
+          this.model.dueOutTime2 +
+          " " +
+          moment(this.model.dueOutTimeSpan).format("HH:mm"),
+        arrivalTime2: this.model.arrivalTime2,
+        dueOutTime2: this.model.dueOutTime2,
+        arrivalTimeSpan: this.model.arrivalTimeSpan,
+        dueOutTimeSpan: this.model.dueOutTimeSpan,
+        dayCount: this.model.dayCount,
+        amount: this.amount,
+        data: data,
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+#components-grid-demo-playground [class~="ant-col"] {
+  background: transparent;
+  border: 0;
+}
+#components-grid-demo-playground [class~="ant-col"] > div {
+  /* background: #00a0e9; */
+  height: 28px;
+  line-height: 28px;
+  font-size: 13px;
+  text-align: center;
+  cursor: pointer;
+  border-radius: 5px;
+}
+#components-grid-demo-playground .check {
+  border: 1px solid #00a0e9;
+}
+#components-grid-demo-playground .kz {
+  background: rgba(166, 166, 166, 1);
+}
+#components-grid-demo-playground pre {
+  background: #f9f9f9;
+  border-radius: 6px;
+  font-size: 13px;
+  padding: 8px 16px;
+}
+</style>

+ 77 - 0
src/views/room/modules/scheduleTeam/EditBatchSelectRoomTypeFormModal.vue

@@ -0,0 +1,77 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <batch-select-room-type-form
+      ref="realForm"
+      @ok="submitCallback"
+      :disabled="disableSubmit"
+      :orderInfo="orderInfo"
+      :batchRoomsTypeList="batchRoomsTypeList"
+    ></batch-select-room-type-form>
+  </j-modal>
+</template>
+
+<script>
+import BatchSelectRoomTypeForm from "./EditBatchSelectRoomTypeForm";
+export default {
+  name: "BatchSelectRoomTypeFormModal",
+  components: {
+    BatchSelectRoomTypeForm,
+  },
+  props: {
+    orderInfo: {
+      type: Object,
+      default: {},
+    },
+    batchRoomsTypeList: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 900,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add(row) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.add(row);
+      });
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.realForm.submitForm();
+    },
+    submitCallback(e) {
+      console.log("e", e);
+      this.$emit("ok", e);
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1036 - 0
src/views/room/modules/scheduleTeam/EditScheduleRoomForm.vue


+ 88 - 0
src/views/room/modules/scheduleTeam/EditScheduleRoomModal.vue

@@ -0,0 +1,88 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <schedule-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></schedule-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import ScheduleRoomForm from './EditScheduleRoomForm'
+  export default {
+    name: 'ScheduleRoomModal',
+    components: {
+      ScheduleRoomForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1300,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      addList(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.addList(record);
+      });
+    },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+<style scoped>
+/deep/.ant-modal-body {
+  padding: 12px;
+  max-height: calc(80vh - 150px);
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+    /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #e3e3e6;
+    border-radius: 6px;
+  }
+
+  &::-webkit-scrollbar-track {
+    background: transparent;
+    border-radius: 5px;
+  }
+}
+</style>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1036 - 0
src/views/room/modules/scheduleTeam/ScheduleRoomForm.vue


+ 88 - 0
src/views/room/modules/scheduleTeam/ScheduleRoomModal.vue

@@ -0,0 +1,88 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <schedule-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></schedule-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import ScheduleRoomForm from './ScheduleRoomForm'
+  export default {
+    name: 'ScheduleRoomModal',
+    components: {
+      ScheduleRoomForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1300,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      addList(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.addList(record);
+      });
+    },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+<style scoped>
+/deep/.ant-modal-body {
+  padding: 12px;
+  max-height: calc(80vh - 150px);
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+    /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #e3e3e6;
+    border-radius: 6px;
+  }
+
+  &::-webkit-scrollbar-track {
+    background: transparent;
+    border-radius: 5px;
+  }
+}
+</style>

+ 279 - 0
src/views/room/modules/scheduleTeam/SelectRoomForm.vue

@@ -0,0 +1,279 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="房型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-checkbox default-checked disabled>{{ layoutName }}</a-checkbox>
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="24">
+            <a-form-model-item
+              label="房态"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="roomStatus"
+            >
+              <a-checkbox-group
+                v-model="model.roomStatus"
+                :options="roomStatusOptions"
+              />
+            </a-form-model-item>
+          </a-col> -->
+          <a-col :span="24">
+            <a-form-model-item
+              label="已排房"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              {{ model.rooms.length || 0 }}/{{ presetNum }}间
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="已选"
+              :labelCol="labelCol"
+              :wrapperCol="{
+                xs: { span: 24 },
+                sm: { span: 20 },
+              }"
+              prop="roomStatus"
+            >
+              <a-tag
+                color="blue"
+                closable
+                :visible="visible"
+                @close.stop="tagClose2(index, item.name)"
+                v-for="(item, index) in model.rooms"
+                :key="index"
+                >{{ item.name }}</a-tag
+              >
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="房间"
+              :labelCol="labelCol"
+              :wrapperCol="{
+                xs: { span: 24 },
+                sm: { span: 20 },
+              }"
+            >
+              <a-tabs
+                default-active-key="room0"
+                tab-position="left"
+                :style="{ height: '300px' }"
+              >
+                <a-tab-pane
+                  v-for="(room, index) in roomList"
+                  :key="'room' + index"
+                  :tab="room.floorName"
+                >
+                  <div
+                    id="components-grid-demo-playground"
+                    style="height: 300px; overflow: hidden auto"
+                  >
+                    <a-row :gutter="[8, 8]">
+                      <a-col
+                        :span="3"
+                        v-for="(r, rIndex) in room.floorRooms"
+                        :key="'floorRooms' + rIndex"
+                      >
+                        <div
+                          :class="[
+                            r.check == 1 ? 'check' : '',
+                            r.kz == 1 ? 'kz' : '',
+                          ]"
+                          @click="checkRoomClick(r)"
+                        >
+                          {{ r.name }}
+                        </div></a-col
+                      >
+                    </a-row>
+                  </div>
+                </a-tab-pane>
+              </a-tabs>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+export default {
+  name: "SelectRoomForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    const rooms = [];
+    for (let i = 0; i < 100; i++) {
+      rooms.push({
+        id: "100" + i,
+        roomNo: 1000 + i,
+        check: 0,
+        kz: i == 1 ? 1 : 0,
+      });
+    }
+    const rooms2 = [];
+    for (let i = 0; i < 50; i++) {
+      rooms2.push({
+        id: "200" + i,
+        roomNo: 2000 + i,
+        check: 0,
+        kz: i == 5 ? 1 : 0,
+      });
+    }
+    return {
+      visible: true,
+      roomList: [
+        { key: "1层", child: rooms },
+        { key: "2层", child: rooms2 },
+      ],
+      roomTypeOptions: [],
+      roomStatusOptions: ["空净", "空脏"],
+      model: { roomType: "", rooms: [] },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 2 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        dateRange: [{ required: true, message: "请选择维修时间!" }],
+        remark: [{ required: true, message: "请输入维修原因!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoom/add",
+        edit: "/business/busMeetingRoom/edit",
+        queryById: "/business/busMeetingRoom/queryById",
+      },
+      layoutName: "",
+      presetNum: 0,
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    checkRoomClick(row) {
+      if (row.check === 1) {
+        row.check = 0;
+        var index = this.model.rooms.findIndex((t) => t.key1 == row.key1);
+        this.model.rooms.splice(index, 1);
+      } else {
+        if (this.model.rooms.length >= this.presetNum) {
+          this.$message.warning("超过排房数量");
+          return;
+        }
+        row.check = 1;
+        this.model.rooms.push(row);
+      }
+    },
+    tagClose2(index, key1) {
+      this.model.rooms.splice(index, 1);
+      this.roomList.some((t) => {
+        var r = t.floorRooms.some((c) => {
+          if (c.name === key1) {
+            c.check = 0;
+            return true;
+          }
+          return false;
+        });
+        if (r === true) {
+          return true;
+        }
+      });
+    },
+    onChange(date, dateString) {
+      console.log(date, dateString);
+    },
+    add(row) {
+      console.log("buildingRooms", row.buildingRooms);
+      this.layoutName = row.layout.name;
+      this.presetNum = row.layout.presetNum;
+      this.roomList = row.buildingRooms;
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.roomList.forEach((t) => {
+        t.floorRooms.forEach((f) => {
+          if (f.check && f.check == 1) {
+            this.model.rooms.push(f);
+          }
+        });
+      });
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      if (that.model.rooms.length === 0) {
+        that.$message.warning("请先选择房间");
+        return;
+      }
+      that.$emit("ok", that.model.rooms);
+    },
+  },
+};
+</script>
+<style scoped>
+#components-grid-demo-playground [class~="ant-col"] {
+  background: transparent;
+  border: 0;
+}
+#components-grid-demo-playground [class~="ant-col"] > div {
+  /* background: #00a0e9; */
+  height: 28px;
+  line-height: 28px;
+  font-size: 13px;
+  text-align: center;
+  cursor: pointer;
+  border-radius: 5px;
+}
+#components-grid-demo-playground .check {
+  border: 1px solid #00a0e9;
+}
+#components-grid-demo-playground .kz {
+  background: rgba(166, 166, 166, 1);
+}
+#components-grid-demo-playground pre {
+  background: #f9f9f9;
+  border-radius: 6px;
+  font-size: 13px;
+  padding: 8px 16px;
+}
+</style>

+ 65 - 0
src/views/room/modules/scheduleTeam/SelectRoomFormModal.vue

@@ -0,0 +1,65 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <select-room-form
+      ref="realForm"
+      @ok="submitCallback"
+      :disabled="disableSubmit"
+    ></select-room-form>
+  </j-modal>
+</template>
+
+<script>
+import SelectRoomForm from "./SelectRoomForm";
+export default {
+  name: "SelectRoomFormModal",
+  components: {
+    SelectRoomForm,
+  },
+  data() {
+    return {
+      title: "",
+      width: 800,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add(row) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.add(row);
+      });
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.realForm.submitForm();
+    },
+    submitCallback(e) {
+      console.log("e", e);
+      this.$emit("ok", e);
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 162 - 0
src/views/room/scheduledetail.vue

@@ -0,0 +1,162 @@
+<template>
+  <a-card style="width: 100%; height: 100%">
+    <div style="display: flex; gap: 10px">
+      <div style="width: 18%; background: #f4f5f8">
+        <div style="font-size: 16px; font-weight: 600; padding: 15px 15px 0">
+          共计关联2个房间
+        </div>
+        <a-divider></a-divider>
+        <a-collapse v-model="activeKey" :bordered="false">
+          <a-collapse-panel
+            key="1"
+            header="接待(1间)"
+            style="
+              background: #f7f7f7;
+              border-radius: 4px;
+              margin-bottom: 24px;
+              border: 0;
+              overflow: hidden;
+            "
+          >
+            <div slot="extra" style="color: #1890ff">合计:-82.00</div>
+            <div class="cell_check_group">
+              <a-checkbox-group @change="onChange">
+                <a-row>
+                  <a-col :span="12">
+                    <a-checkbox value="1"> 正常入住 </a-checkbox>
+                  </a-col>
+                  <a-col :span="12">
+                    <a-checkbox value="2"> 未结退房 </a-checkbox>
+                  </a-col>
+                  <a-col :span="12">
+                    <a-checkbox value="3"> 已结退房</a-checkbox>
+                  </a-col>
+                  <a-col :span="12">
+                    <a-checkbox value="4"> 联房退房 </a-checkbox>
+                  </a-col>
+                </a-row>
+              </a-checkbox-group>
+            </div>
+          </a-collapse-panel>
+          <a-collapse-panel
+            key="2"
+            header="Q100(1人)"
+            style="
+              background: #f7f7f7;
+              border-radius: 4px;
+              margin-bottom: 24px;
+              border: 0;
+              overflow: hidden;
+            "
+          >
+            <div class="select">
+              <a-tag color="#87d068"> 正常入住 </a-tag>
+              <span
+                class="booking_circle_span orange_color"
+                style="margin-left: 4px"
+                >主</span
+              >
+              <span style="font-weight: 700">何先生</span>
+              <div style="font-weight: 700; float: right">¥ -82.00</div>
+            </div>
+          </a-collapse-panel>
+          <a-collapse-panel
+            key="3"
+            header="预定(2间)"
+            style="
+              background: #f7f7f7;
+              border-radius: 4px;
+              margin-bottom: 24px;
+              border: 0;
+              overflow: hidden;
+            "
+          >
+          <div class="select">
+              <a-tag color="#2db7f5"> 预定中 </a-tag>
+              <span>何先生</span>
+              <div style="float: right">1888888888</div>
+            </div>
+          </a-collapse-panel>
+        </a-collapse>
+      </div>
+      <div style="width: 82%">
+        <a-tabs default-active-key="1">
+          <a-tab-pane key="1">
+            <span slot="tab"> 详单 </span>
+            <edit-schedule-room-form :id="id"></edit-schedule-room-form>
+          </a-tab-pane>
+          <a-tab-pane key="2">
+            <span slot="tab"> 账单 </span>
+          </a-tab-pane>
+          <a-tab-pane key="3">
+            <span slot="tab"> 日志 </span>
+          </a-tab-pane>
+        </a-tabs>
+      </div>
+    </div>
+  </a-card>
+</template>
+
+<script>
+import EditScheduleRoomForm from "./modules/schedule/EditScheduleRoomForm.vue";
+
+export default {
+  components: {
+    EditScheduleRoomForm,
+  },
+  props: {
+    id: {
+      type: Boolean,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      activeKey: ["1", "2", "3"],
+    };
+  },
+  created() {
+    this.id = this.$route.query.id;
+    console.log("created");
+  },
+  methods: {
+    onChange(checkedValues) {
+      console.log("checked = ", checkedValues);
+    },
+  },
+};
+</script>
+
+<style scoped>
+.cell_check_group {
+  padding: 10px;
+  background-color: #d9e5ec;
+  border-radius: 4px;
+  margin: 0px 0 6px 0px;
+}
+.orange_color {
+  border-color: #ff9e35 !important;
+  color: #ff9e35 !important;
+  vertical-align: initial;
+}
+.booking_circle_span {
+  width: 18px;
+  height: 18px;
+  border-radius: 50%;
+  color: #f24e4c;
+  border: 1px solid #f24e4c;
+  font-size: 12px;
+  text-align: center;
+  line-height: 16px;
+  display: inline-block;
+}
+.select {
+  color: #000 !important;
+  border: 1px solid #f24e4c !important;
+  background: transparent;
+  border-radius: 4px;
+  padding: 0 10px;
+  line-height: 32px;
+  cursor: pointer;
+}
+</style>