Jelajahi Sumber

增加资产预约功能

guozhibo 1 tahun lalu
induk
melakukan
0ba1267e9b

+ 10 - 0
package.json

@@ -22,6 +22,13 @@
     "@babel/core": "^7.17.5",
     "@babel/eslint-parser": "^7.17.0",
     "@babel/preset-env": "^7.16.11",
+    "@fullcalendar/core": "^6.1.4",
+    "@fullcalendar/daygrid": "^6.1.4",
+    "@fullcalendar/interaction": "^6.1.4",
+    "@fullcalendar/multimonth": "^6.1.8",
+    "@fullcalendar/resource-timeline": "^6.1.4",
+    "@fullcalendar/timegrid": "^6.1.5",
+    "@fullcalendar/vue3": "^6.1.4",
     "@intlify/vue-i18n-loader": "^4.2.0",
     "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
     "@vue/babel-plugin-jsx": "^1.1.1",
@@ -53,5 +60,8 @@
   "repository": {
     "type": "http",
     "url": "https://a.leanwo.com:3000/prodog-client-2023/client-eam-v3.git"
+  },
+  "dependencies": {
+    "client-eam-v3": "file:"
   }
 }

+ 153 - 0
src/api/asset/AssetCalendarResource.js

@@ -0,0 +1,153 @@
+import Common from '../../common/Common.js';
+
+/**
+ * 工具类自动生成的API,请勿做任何修改,请勿做任何修改,请勿做任何修改(重要的事情说3遍)
+ * 工具作者: 杨志杰
+ * 设备预约 
+ */
+export default {
+
+  /**
+	 * 工具类自动生成的方法
+	 * 工具作者: 杨志杰
+	 * 删除人员预约数据 
+	 */
+  assetCalendarDelete: function(assetCalendarDeleteRequest){
+    var requestUrl = 'AssetCalendarResource/assetCalendarDelete';
+
+
+    return new Promise((resolve, reject) => {
+      $.ajax({
+        url: Common.getApiURL(requestUrl),
+        type: 'post',
+        contentType: 'application/json',
+				
+				
+        data: JSON.stringify(assetCalendarDeleteRequest),
+				
+        beforeSend: function(request) {
+          Common.addTokenToRequest(request);
+        },
+        success: function(data) {
+          resolve(data);
+        },
+        error: function(XMLHttpRequest, textStatus, errorThrown) {
+          reject(XMLHttpRequest);
+        },
+      });
+    });
+  },
+
+  /**
+	 * 工具类自动生成的方法
+	 * 工具作者: 杨志杰
+	 * 保存人员预约数据 
+	 */
+  assetCalendarInsert: function(assetCalendarInsertRequest){
+    var requestUrl = 'AssetCalendarResource/assetCalendarInsert';
+
+
+    return new Promise((resolve, reject) => {
+      $.ajax({
+        url: Common.getApiURL(requestUrl),
+        type: 'post',
+        contentType: 'application/json',
+				
+				
+        data: JSON.stringify(assetCalendarInsertRequest),
+				
+        beforeSend: function(request) {
+          Common.addTokenToRequest(request);
+        },
+        success: function(data) {
+          resolve(data);
+        },
+        error: function(XMLHttpRequest, textStatus, errorThrown) {
+          reject(XMLHttpRequest);
+        },
+      });
+    });
+  },
+
+  /**
+	 * 工具类自动生成的方法
+	 * 工具作者: 杨志杰
+	 * 修改人员预约数据 
+	 */
+  assetCalendarUpdate: function(assetCalendarUpdateRequest){
+    var requestUrl = 'AssetCalendarResource/assetCalendarUpdate';
+
+
+    return new Promise((resolve, reject) => {
+      $.ajax({
+        url: Common.getApiURL(requestUrl),
+        type: 'post',
+        contentType: 'application/json',
+				
+				
+        data: JSON.stringify(assetCalendarUpdateRequest),
+				
+        beforeSend: function(request) {
+          Common.addTokenToRequest(request);
+        },
+        success: function(data) {
+          resolve(data);
+        },
+        error: function(XMLHttpRequest, textStatus, errorThrown) {
+          reject(XMLHttpRequest);
+        },
+      });
+    });
+  },
+
+  /**
+	 * 工具类自动生成的方法
+	 * 工具作者: 杨志杰
+	 * 根据预约对象查询详细预约情况 
+	 */
+  queryAssetCalendarByParam: function(){
+    var requestUrl = 'AssetCalendarResource/queryAssetCalendarByParam';
+
+    return new Promise((resolve, reject) => {
+      $.ajax({
+        url: Common.getApiURL(requestUrl),
+        type: 'post',
+        contentType: 'application/json',
+				
+        beforeSend: function(request) {
+          Common.addTokenToRequest(request);
+        },
+        success: function(data) {
+          resolve(data);
+        },
+        error: function(XMLHttpRequest, textStatus, errorThrown) {
+          reject(XMLHttpRequest);
+        },
+      });
+    });
+  },
+	
+  queryAssetInstanceCalendarById:function(id){
+    var requestUrl = 'AssetCalendarResource/queryAssetCalendarByUserId';
+
+    return new Promise((resolve, reject) => {
+      $.ajax({
+        url: Common.getApiURL(requestUrl),
+        type: 'get',
+        contentType: 'application/json',
+        data:{
+          assetInstanceId:id,
+        },
+        beforeSend: function(request) {
+          Common.addTokenToRequest(request);
+        },
+        success: function(data) {
+          resolve(data);
+        },
+        error: function(XMLHttpRequest, textStatus, errorThrown) {
+          reject(XMLHttpRequest);
+        },
+      });
+    });
+  },
+};

+ 96 - 0
src/api/date.format.js

@@ -0,0 +1,96 @@
+/* eslint no-extend-native: 0 */
+
+(function () {
+  // Defining locale
+  Date.shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+  Date.longMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
+  Date.shortDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+  Date.longDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+  // Defining patterns
+  var replaceChars = {
+    // Day
+    d: function () { var d = this.getDate(); return (d < 10 ? '0' : '') + d; },
+    D: function () { return Date.shortDays[this.getDay()]; },
+    j: function () { return this.getDate(); },
+    l: function () { return Date.longDays[this.getDay()]; },
+    N: function () { var N = this.getDay(); return (N === 0 ? 7 : N); },
+    S: function () { var S = this.getDate(); return (S % 10 === 1 && S !== 11 ? 'st' : (S % 10 === 2 && S !== 12 ? 'nd' : (S % 10 === 3 && S !== 13 ? 'rd' : 'th'))); },
+    w: function () { return this.getDay(); },
+    z: function () { var d = new Date(this.getFullYear(), 0, 1); return Math.ceil((this - d) / 86400000); },
+    // Week
+    W: function () {
+      var target = new Date(this.valueOf());
+      var dayNr = (this.getDay() + 6) % 7;
+      target.setDate(target.getDate() - dayNr + 3);
+      var firstThursday = target.valueOf();
+      target.setMonth(0, 1);
+      if (target.getDay() !== 4) {
+        target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
+      }
+      var retVal = 1 + Math.ceil((firstThursday - target) / 604800000);
+
+      return (retVal < 10 ? '0' + retVal : retVal);
+    },
+    // Month
+    F: function () { return Date.longMonths[this.getMonth()]; },
+    m: function () { var m = this.getMonth(); return (m < 9 ? '0' : '') + (m + 1); },
+    M: function () { return Date.shortMonths[this.getMonth()]; },
+    n: function () { return this.getMonth() + 1; },
+    t: function () {
+      var year = this.getFullYear();
+      var nextMonth = this.getMonth() + 1;
+      if (nextMonth === 12) {
+        year = year++;
+        nextMonth = 0;
+      }
+      return new Date(year, nextMonth, 0).getDate();
+    },
+    // Year
+    L: function () { var L = this.getFullYear(); return (L % 400 === 0 || (L % 100 !== 0 && L % 4 === 0)); },
+    o: function () { var d = new Date(this.valueOf()); d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear(); },
+    Y: function () { return this.getFullYear(); },
+    y: function () { return ('' + this.getFullYear()).substr(2); },
+    // Time
+    a: function () { return this.getHours() < 12 ? 'am' : 'pm'; },
+    A: function () { return this.getHours() < 12 ? 'AM' : 'PM'; },
+    B: function () { return Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24); },
+    g: function () { return this.getHours() % 12 || 12; },
+    G: function () { return this.getHours(); },
+    h: function () { var h = this.getHours(); return ((h % 12 || 12) < 10 ? '0' : '') + (h % 12 || 12); },
+    H: function () { var H = this.getHours(); return (H < 10 ? '0' : '') + H; },
+    i: function () { var i = this.getMinutes(); return (i < 10 ? '0' : '') + i; },
+    s: function () { var s = this.getSeconds(); return (s < 10 ? '0' : '') + s; },
+    v: function () { var v = this.getMilliseconds(); return (v < 10 ? '00' : (v < 100 ? '0' : '')) + v; },
+    // Timezone
+    e: function () { return Intl.DateTimeFormat().resolvedOptions().timeZone; },
+    I: function () {
+      var DST = null;
+      for (var i = 0; i < 12; ++i) {
+        var d = new Date(this.getFullYear(), i, 1);
+        var offset = d.getTimezoneOffset();
+
+        if (DST === null) DST = offset;
+        else if (offset < DST) { DST = offset; break; } else if (offset > DST) break;
+      }
+      return (this.getTimezoneOffset() === DST) | 0;
+    },
+    O: function () { var O = this.getTimezoneOffset(); return (-O < 0 ? '-' : '+') + (Math.abs(O / 60) < 10 ? '0' : '') + 
+      Math.floor(Math.abs(O / 60)) + (Math.abs(O % 60) === 0 ? '00' : ((Math.abs(O % 60) < 10 ? '0' : '')) + (Math.abs(O % 60))); },
+    P: function () { var P = this.getTimezoneOffset(); return (-P < 0 ? '-' : '+') 
+      + (Math.abs(P / 60) < 10 ? '0' : '') + Math.floor(Math.abs(P / 60)) + ':' + (Math.abs(P % 60) === 0 ? '00' : ((Math.abs(P % 60) < 10 ? '0' : '')) + (Math.abs(P % 60))); },
+    T: function () { var tz = this.toLocaleTimeString(navigator.language, {timeZoneName: 'short'}).split(' '); return tz[tz.length - 1]; },
+    Z: function () { return -this.getTimezoneOffset() * 60; },
+    // Full Date/Time
+    c: function () { return this.format('Y-m-d\\TH:i:sP'); },
+    r: function () { return this.toString(); },
+    U: function () { return Math.floor(this.getTime() / 1000); },
+  };
+
+  // Simulates PHP's date function
+  Date.prototype.format = function (format) {
+    var date = this;
+    return format.replace(/(\\?)(.)/g, function (_, esc, chr) {
+      return (esc === '' && replaceChars[chr]) ? replaceChars[chr].call(date) : chr;
+    });
+  };
+}).call(this);

+ 15 - 0
src/api/event-utils.js

@@ -0,0 +1,15 @@
+
+let eventGuid = 0;
+// let todayStr = new Date().toISOString().replace(/T.*$/, '') // YYYY-MM-DD of today
+
+export const INITIAL_EVENTS = [
+  // {
+  //   id: createEventId(),
+  //   title: '点击日历格添加',
+  //   start: todayStr
+  // },
+];
+
+export function createEventId() {
+  return String(eventGuid++);
+}

+ 1110 - 0
src/customer/AssetInstanceFullCalendar.vue

@@ -0,0 +1,1110 @@
+<template>
+  <Navbar title="资产预约" :is-go-back="false" />
+  <div class="demo-app">
+    <div>
+      <a-modal
+        ref="calendarUpdateModal"
+        v-model:open="assetCalendarUpdate.visible"
+        :mask-closable="false"
+        title="修改预约内容"
+        @ok="handleOk"
+      >
+        <template #footer>
+          <a-button key="delete" type="danger" @click="handleDelete">
+            删除
+          </a-button>
+          <a-button key="back" @click="handleCancel">取消</a-button>
+          <a-button
+            key="submit"
+            type="primary"
+            :loading="loading"
+            @click="handleOk"
+          >
+            提交
+          </a-button>
+        </template>
+        <p>
+          <span style="color: red">预约资产:</span>
+          <SearchWidget
+            info-window-no="280147"
+            :field="assetField"
+            :field-value="assetFieldValue"
+            :display-name="assetField.listDisplayFieldName"
+            @value-changed="assetValueChanged"
+          />
+        </p>
+        <p>
+          <span style="color: red">预约申请人:</span>
+          <SearchWidget
+            info-window-no="050408"
+            :field="userField"
+            :field-value="userFieldValue"
+            :display-name="userField.listDisplayFieldName"
+            :readonly="true"
+            @value-changed="userValueChanged"
+          />
+        </p>
+        <p>
+          <span style="color: red">开始时间:</span>
+          <DateTime
+            v-model="assetCalendarUpdate.startDate"
+            :readonly="false"
+            style="width: 100%"
+          />
+        </p>
+        <p>
+          <span style="color: red">结束时间:</span>
+          <DateTime
+            v-model="assetCalendarUpdate.endDate"
+            :readonly="false"
+            style="width: 100%"
+          />
+        </p>        
+        <p>
+          <span style="color: red">用途:</span>
+          <a-input
+            v-model:value="assetCalendarUpdate.content"
+            placeholder="内容"
+          />
+        </p>
+        <p>
+          <span style="color: red">地点:</span>
+          <a-input
+            v-model:value="assetCalendarUpdate.location"
+            placeholder="地点"
+          />
+        </p>
+        <p>
+          <span style="color: red">备注:</span>
+          <a-input
+            v-model:value="assetCalendarUpdate.description"
+            placeholder="备注"
+          />
+        </p>
+      </a-modal>
+      <a-modal
+        ref="calendarDeleteModal"
+        v-model:open="visible"
+        :mask-closable="false"
+        title="再次确认"
+        ok-text="确认"
+        cancel-text="取消"
+        @ok="assetCalendarDeleteMethod"
+      >
+        <p>确认是否删除?</p>
+      </a-modal>
+
+      <a-modal
+        v-model:open="assetCalendarInsert.visible"
+        :title="assetCalendarInsert.title"
+        :mask-closable="false"
+        ok-text="确认"
+        cancel-text="取消"
+        @ok="assetCalendarInsertMethod"
+      >
+        <p>
+          <span style="color: red">预约资产:</span>
+          <SearchWidget
+            info-window-no="280147"
+            :field="assetField"
+            :field-value="assetFieldValue"
+            :display-name="assetField.listDisplayFieldName"
+            @value-changed="assetValueChanged"
+          />
+        </p>
+        <p>
+          <span style="color: red">开始时间:</span>
+          <DateTime
+            v-model="assetCalendarInsert.startDate"
+            :readonly="false"
+            style="width: 100%"
+          />
+        </p>
+        <p>
+          <span style="color: red">结束时间:</span>
+          <DateTime
+            v-model="assetCalendarInsert.endDate"
+            :readonly="false"
+            style="width: 100%"
+          />
+        </p>
+        <p>
+          <span style="color: red">内容:</span>
+          <a-input
+            v-model:value="assetCalendarInsert.content"
+            placeholder="内容"
+          />
+        </p>
+        <p>
+          <span style="color: red">地点:</span>
+          <a-input
+            v-model:value="assetCalendarInsert.location"
+            placeholder="地点"
+          />
+        </p>
+        <p>
+          <span style="color: red">备注:</span>
+          <a-textarea
+            v-model:value="assetCalendarInsert.description"
+            placeholder="备注"
+          />
+        </p>
+      </a-modal>
+    </div>
+    <div class="userGroup">
+      <h4>资产名单</h4>
+      <div v-for="item in equipmentLists" :key="item.assetInstanceId">
+        <a-checkbox
+          v-model:checked="item.checked"
+          @change="checkedChange(item)"
+        >
+          {{ item.assetInstanceName }}
+        </a-checkbox>
+      </div>
+    </div>
+    <div class="demo-app-main">
+      <FullCalendar
+        ref="fullCalendar"
+        class="demo-app-calendar"
+        :options="calendarOptions"
+      />
+    </div>
+    <Loading v-if="isLoading" />
+  </div>
+</template>
+
+<script>
+import FullCalendar from '@fullcalendar/vue3';
+import dayGridPlugin from '@fullcalendar/daygrid';
+import timeGridPlugin from '@fullcalendar/timegrid';
+import interactionPlugin from '@fullcalendar/interaction';
+import multiMonthPlugin from '@fullcalendar/multimonth';
+import { INITIAL_EVENTS } from '../api/event-utils';
+import { Notify, Common, SqlApi } from 'pc-component-v3';
+import AssetCalendarResource from '../api/asset/AssetCalendarResource.js';
+import '../api/date.format.js';
+import { message } from 'ant-design-vue';
+
+export default {
+  components: {
+    FullCalendar,
+    Common,
+    SqlApi,
+    AssetCalendarResource,
+  },
+  data() {
+    return {
+      calendarOptions: {
+        plugins: [
+          dayGridPlugin,
+          interactionPlugin,
+          timeGridPlugin,
+          multiMonthPlugin,
+        ],
+        customButtons: {
+          create: {
+            text: '新建',
+            click: this.assetCalendarInsertData,
+          },
+          refulsh: {
+            text: '刷新',
+            click: this.refulshData,
+          },
+        },
+        headerToolbar: {
+          left: 'prev,next today create refulsh',
+          center: 'title',
+          right: 'multiMonthYear,dayGridMonth,timeGridWeek,timeGridDay',
+        },
+        buttonText: {
+          today: '今天',
+          create: '新建',
+          refulsh: '刷新',
+          multiMonthYear: '年',
+          month: '月',
+          week: '周',
+          day: '日',
+        },
+        multiMonthMinWidth: 300,
+        locale: 'zh-cn', //选择语言
+        allDayText: '全天',
+        allDaySlot: false,
+        firstDay: 1,
+        weekends: true, // 周末
+        initialView: 'dayGridMonth',
+        initialEvents: INITIAL_EVENTS, // alternatively, use the `events` setting to fetch from a feed
+        editable: true, //可拖拽
+        eventDurationEditable: true,
+        eventDrop: this.assetInstanceCalendarEventDrop,
+        eventResize: this.assetInstanceCalendarEventDrop, //调整大小时停止并且事件的持续时间发生变化时触发。
+        selectable: true,
+        selectMirror: true,
+        dayMaxEvents: true,
+        height: 'auto',
+        select: this.assetCalendarInsertData, //选中日历格事件
+        eventClick: this.handleEventClick, //选中备忘录事件
+        eventsSet: this.handleEvents,
+        assetCalendarLists: this.assetCalendarLists,
+        slotEventOverlap: true, // 相同时间段的多个日程视觉上是否允许重叠,默认true允许
+      },
+      equipmentLists: [],
+      assetCalendarLists: [],
+      assetCalendarLineLists: [],
+      assetCalendarInsert: {
+        // 新增预约资产
+        title: '新建预约资产',
+        visible: false,
+        startDate: undefined,
+        endDate: undefined,
+        content: '',
+        location: '',
+        description: '',
+      },
+      assetCalendarUpdate: {
+        // 修改预约资产
+        visible: false,
+        startDate: undefined,
+        endDate: undefined,
+        content: '',
+        location: '',
+        description: '',
+      },
+      assetField: {
+        name: '',
+        listDisplayFieldName: 'assetInstance.name',
+      },
+      assetFieldValue: {
+        id: null,
+        displayValue: [''],
+        fieldType: 'String',
+      },
+      userField: {
+        name: '',
+        listDisplayFieldName: 'name',
+      },
+      userFieldValue: {
+        id: null,
+        displayValue: [''],
+        fieldType: 'String',
+      },
+      projectItemField: {
+        name: '',
+        listDisplayFieldName: 'i.name',
+      },
+      projectItemFieldValue: {
+        id: null,
+        displayValue: [''],
+        fieldType: 'String',
+      },
+      selectItemId: undefined, // 选中的预约对象
+      visible: false,
+      loading: false,
+      weekDay: [
+        '星期日',
+        '星期一',
+        '星期二',
+        '星期三',
+        '星期四',
+        '星期五',
+        '星期六',
+      ],
+      clickInfo: null,
+      userName: JSON.parse(localStorage.getItem('#LoginInfo')).userName,
+      isLoading: false,
+      assetName: null,
+    };
+  },
+
+  mounted: function () {
+    var _self = this;
+    // _self.queryAssetCalendarByParam();
+    _self.queryAssetInstance();
+  },
+
+  methods: {
+    // 日历拖拽更新
+    assetInstanceCalendarEventDrop: function (eventDropInfo) {
+      //拖动停止并且事件已移至不同的日期/时间时触发。
+      var _self = this;
+      const startTime = _self.getYearMonthDate(eventDropInfo.oldEvent.start);
+      const endTime = _self.getYearMonthDate(eventDropInfo.oldEvent.end);
+      const currentTime = _self.getYearMonthDate(new Date());
+      const timeQuantum = [startTime, endTime];
+      if (
+        _self.compareTime(endTime, currentTime) > 0 &&
+        _self.userName !== 'admin'
+      ) {
+        message.warning('已完成的预约无法修改,请联系管理员');
+        _self.refulshData();
+      } else if (
+        _self.isBetweenTime(currentTime, timeQuantum) &&
+        _self.userName !== 'admin'
+      ) {
+        message.warning('进行中的预约无法修改,请联系管理员');
+        _self.refulshData();
+      } else {
+        _self.assetCalendarLineLists.forEach(item => {
+          if (item.id == eventDropInfo.event.id) {
+            _self.assetCalendarUpdate = {
+              title: '修改资产预约数据',
+              visible: false,
+              id: item.id,
+              inventorySitpId: item.inventorySitpId,
+              inventorySitpName: item.inventorySitpName,
+              startDate: _self.getYearMonthDate(eventDropInfo.event.start),
+              endDate: _self.getYearMonthDate(eventDropInfo.event.end),
+              userId: item.userId,
+              userName: item.userName,
+              content: item.content,
+              location: item.location,
+              description: item.description,
+              assetInstanceName: item.assetInstanceName,
+              assetInstanceId: item.assetInstanceId,
+            };
+          }
+        });
+        _self.assetCalendarUpdateMethod();
+        // _self.queryAssetCalendarByParam();
+      }
+    },
+
+    //  预约资产名单
+    queryAssetInstance: function () {
+      var _self = this;
+      _self.equipmentLists = [];
+      _self.isLoading = true;
+      SqlApi.execute('20230414_135409').then(successData => {
+        if (successData.errorCode === 0) {
+          successData.dataList.forEach(item => {
+            item.checked = false;
+            if (item.assetInstanceId === _self.selectItemId) {
+              item.checked = true;
+            }
+            let lists = {
+              assetInstanceId: item.assetInstanceId,
+              assetInstanceName: item.assetInstanceName,
+              assetInstanceNo: item.assetInstanceNo,
+              checked: item.checked,
+            };
+            _self.equipmentLists.push(lists);            
+          });
+          errorData => {
+            Common.processException(errorData);
+            _self.isLoading = false;
+          };
+        }
+        _self.isLoading = false;
+      });
+    },
+
+    // 预约资产事件合集
+    assetCalendarById: function (assetInstanceId) {
+      this.isLoading = true;
+      AssetCalendarResource.queryAssetInstanceCalendarById(
+        assetInstanceId,
+      ).then(
+        successData => {
+          if (successData.datas != null && successData.datas.length > 0) {
+            successData.datas.forEach(item => {
+              this.addCalendarEvent(item);
+            });
+          }
+          this.isLoading = false;
+        },
+        errorData => {
+          Common.processException(errorData);
+          this.isLoading = false;
+        },
+      );
+    },
+
+    // 向日历中添加事件
+    addCalendarEvent(data) {
+      data.title = data.content;
+      data.start = data.startDate;
+      data.end = data.endDate;
+      data.editable = true;
+      data.color = '#2EB09A';
+      this.calendarOptions.events.push(data);
+      this.assetCalendarLineLists.push(data);
+    },
+
+    // 预约对象切换事件
+    checkedChange: function (item) {
+      var _self = this;
+      if (item.checked === true) {
+        _self.selectItemId = item.assetInstanceId;
+        _self.equipmentLists.forEach(function (val) {
+          if (item.assetInstanceId != val.assetInstanceId) {
+            val.checked = false;
+          } else {
+            val.checked = true;
+            _self.assetName = item.assetInstanceName;
+          }
+        });
+        _self.calendarOptions.events = [];
+        _self.assetCalendarLineLists = [];
+        _self.assetCalendarById(item.assetInstanceId);
+      } else {
+        // 取消所有的选择
+        _self.selectItemId = undefined;
+        _self.equipmentLists.forEach(function (val) {
+          val.checked = false;
+        });
+      }
+    },
+
+    //点击备忘录事件
+    handleEventClick: function (clickInfo) {
+      var _self = this;
+      _self.clickInfo = clickInfo;
+      _self.assetCalendarLineLists.forEach(function (item) {
+        if (item.id == clickInfo.event.id) {
+          _self.assetCalendarUpdate = {
+            title: '修改资产预约数据',
+            visible: true,
+            id: item.id,
+            inventorySitpId: item.inventorySitpId,
+            inventorySitpName: item.inventorySitpName,
+            startDate: item.startDate,
+            endDate: item.endDate,
+            assetInstanceId: item.assetInstanceId,
+            assetInstanceName: item.assetInstanceName,
+            userId: item.userId,
+            userName: item.userName,
+            content: item.content,
+            location: item.location,
+            description: item.description,
+          };
+          _self.assetFieldValue = {
+            displayValue: [item.assetInstanceName],
+            fieldType: 'Key',
+            id: item.assetInstanceId,
+          };
+          _self.userFieldValue = {
+            displayValue: [item.userName],
+            fieldType: 'Key',
+            id: item.userId,
+          };
+          _self.projectItemFieldValue = {
+            displayValue: [item.inventorySitpName],
+            fieldType: 'Key',
+            id: item.inventorySitpId,
+          };
+        }
+      });
+    },
+
+    // 新建预约数据
+    assetCalendarInsertData: function (selectInfo) {
+      var _self = this;
+      var flag = true;
+      _self.equipmentLists.some(item => {
+        if (item.checked === true) {
+          // console.log(item);
+          flag = false;
+          if (_self.assetCalendarLineLists.length === 0) {
+            if (selectInfo instanceof PointerEvent) {
+              (_self.assetCalendarInsert = {
+                title: '新建资产预约数据',
+                id: '',
+                visible: true,
+                content: '',
+                location: '',
+                description: '',
+                inventorySitpId: '',
+                inventorySitpName: '',
+                startDate: '',
+                endDate: '',
+                assetInstanceId: item.assetInstanceId,
+                assetInstanceName: item.assetInstanceName,
+              }),
+              (_self.assetFieldValue = {
+                id: item.assetInstanceId,
+                fieldType: 'String',
+                displayValue: [_self.assetName],
+              });
+              _self.userFieldValue = {
+                displayValue: [''],
+                fieldType: 'Key',
+                id: null,
+              };
+              _self.userField = {
+                name: '',
+                listDisplayFieldName: 'name',
+              };
+              _self.projectItemFieldValue = {
+                id: null,
+                displayValue: [''],
+                fieldType: 'String',
+              };
+              _self.projectItemField = {
+                name: '',
+                listDisplayFieldName: 'i.name',
+              };
+            } else {
+              _self.assetCalendarInsert = {
+                title: '新建资产预约数据',
+                id: '',
+                visible: true,
+                content: '',
+                location: '',
+                description: '',
+                inventorySitpId: '',
+                inventorySitpName: '',
+                startDate: _self.getYearMonthDate(selectInfo.start),
+                endDate: _self.getYearMonthDate(selectInfo.end),
+                userId: item.assetInstanceId,
+                assetInstanceId: item.assetInstanceId,
+                assetInstanceName: item.assetInstanceName,
+              };
+              _self.userFieldValue = {
+                displayValue: [''],
+                fieldType: 'Key',
+                id: null,
+              };
+              _self.userField = {
+                name: '',
+                listDisplayFieldName: 'name',
+              };
+              _self.projectItemFieldValue = {
+                id: null,
+                displayValue: [''],
+                fieldType: 'String',
+              };
+              _self.assetFieldValue = {
+                id: item.assetInstanceId,
+                displayValue: [_self.assetName],
+                fieldType: 'String',
+              };
+              _self.projectItemField = {
+                name: '',
+                listDisplayFieldName: 'i.name',
+              };
+            }
+          }
+          _self.assetCalendarLineLists.forEach(function (item) {
+            if (selectInfo instanceof PointerEvent) {
+              (_self.assetCalendarInsert = {
+                title: '新建资产预约数据',
+                id: item.id,
+                visible: true,
+                content: '',
+                location: '',
+                description: '',
+                inventorySitpId: '',
+                inventorySitpName: '',
+                startDate: '',
+                endDate: '',
+                userId: item.userId,
+                assetInstanceId: item.assetInstanceId,
+                assetInstanceName: item.assetInstanceName,
+              }),
+              (_self.userFieldValue = {
+                displayValue: [''],
+                fieldType: 'Key',
+                id: null,
+              });
+              _self.userField = {
+                name: '',
+                listDisplayFieldName: 'name',
+              };
+              _self.projectItemFieldValue = {
+                id: null,
+                displayValue: [''],
+                fieldType: 'String',
+              };
+              _self.assetFieldValue = {
+                id: item.assetInstanceId,
+                displayValue: [_self.assetName],
+                fieldType: 'String',
+              };
+              _self.projectItemField = {
+                name: '',
+                listDisplayFieldName: 'i.name',
+              };
+            } else {
+              _self.assetCalendarInsert = {
+                title: '新建资产预约数据',
+                id: item.id,
+                visible: true,
+                content: '',
+                location: '',
+                description: '',
+                inventorySitpId: '',
+                inventorySitpName: '',
+                startDate: _self.getYearMonthDate(selectInfo.start),
+                endDate: _self.getYearMonthDate(selectInfo.end),
+                userId: item.targetUserId,
+                assetInstanceId: item.assetInstanceId,
+                assetInstanceName: item.assetInstanceName,
+              };
+              _self.userFieldValue = {
+                displayValue: [''],
+                fieldType: 'Key',
+                id: null,
+              };
+              _self.userField = {
+                name: '',
+                listDisplayFieldName: 'name',
+              };
+              _self.projectItemFieldValue = {
+                id: null,
+                displayValue: [''],
+                fieldType: 'String',
+              };
+              _self.assetFieldValue = {
+                id: item.assetInstanceId,
+                displayValue: [_self.assetName],
+                fieldType: 'String',
+              };
+              _self.projectItemField = {
+                name: '',
+                listDisplayFieldName: 'i.name',
+              };
+            }
+          });
+        }
+      });
+      if (flag) {
+        message.error('请选择预约资产');
+      }
+    },
+
+    /**
+     * 保存预约数据
+     */
+    assetCalendarInsertMethod: function () {
+      var _self = this;
+      if (
+        _self.assetCalendarInsert.content == null ||
+        _self.assetCalendarInsert.content.length == 0
+      ) {
+        Notify.error('失败', '预约内容不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarInsert.assetInstanceId == null ||
+        _self.assetCalendarInsert.assetInstanceId.length == 0
+      ) {
+        Notify.error('失败', '预约资产不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarInsert.startDate == null ||
+        _self.assetCalendarInsert.startDate.length == 0
+      ) {
+        Notify.error('失败', '预约开始时间不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarInsert.endDate == null ||
+        _self.assetCalendarInsert.endDate.length == 0
+      ) {
+        Notify.error('失败', '预约结束时间不能为空', true);
+        return;
+      }
+
+      var boolean = _self.judgeDate(
+        _self.assetCalendarInsert.startDate,
+        _self.assetCalendarInsert.endDate,
+      );
+      if (boolean) {
+        return;
+      }
+
+      AssetCalendarResource.assetCalendarInsert(_self.assetCalendarInsert).then(
+        successData => {
+          // console.log(_self.assetCalendarInsert,'xxx')
+          Notify.success('成功', '保存成功', true);
+          _self.refulshData();
+        },
+        errorData => {
+          Common.processException(errorData);
+          _self.refulshData();
+        },
+      );
+    },
+
+    // 删除预约数据
+    assetCalendarDeleteMethod: function () {
+      var _self = this;
+      this.visible = false;
+      AssetCalendarResource.assetCalendarDelete(_self.assetCalendarUpdate).then(
+        successData => {
+          Notify.success('成功', '删除成功', true);
+          _self.refulshData();
+        },
+        errorData => {
+          Common.processException(errorData);
+          _self.refulshData();
+        },
+      );
+    },
+
+    // 修改预约数据
+    assetCalendarUpdateMethod: function () {
+      var _self = this;
+      if (
+        _self.assetCalendarUpdate.content == null ||
+        _self.assetCalendarUpdate.content.length == 0
+      ) {
+        Notify.error('失败', '预约内容不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarUpdate.assetInstanceId == null ||
+        _self.assetCalendarUpdate.assetInstanceId.length == 0
+      ) {
+        Notify.error('失败', '预约资产不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarUpdate.startDate == null ||
+        _self.assetCalendarUpdate.startDate.length == 0
+      ) {
+        Notify.error('失败', '预约开始时间不能为空', true);
+        return;
+      }
+      if (
+        _self.assetCalendarUpdate.endDate == null ||
+        _self.assetCalendarUpdate.endDate.length == 0
+      ) {
+        Notify.error('失败', '预约结束时间不能为空', true);
+        return;
+      }
+
+      var boolean = _self.judgeDate(
+        _self.assetCalendarUpdate.startDate,
+        _self.assetCalendarUpdate.endDate,
+      );
+      if (boolean) {
+        return;
+      }
+
+      AssetCalendarResource.assetCalendarUpdate(_self.assetCalendarUpdate).then(
+        successData => {
+          Notify.success('成功', '保存成功', true);
+          _self.restoreData();
+
+          _self.assetCalendarUpdate.visible = false;
+          _self.loading = false;
+          _self.refulshData();
+        },
+        errorData => {
+          Common.processException(errorData);
+          _self.refulshData();
+        },
+      );
+    },
+
+    // 刷新
+    refulshData: function () {
+      var _self = this;
+      _self.assetCalendarLists = [];
+      _self.calendarOptions.events = [];
+      (_self.assetCalendarUpdate = {
+        // 修改预约数据对象
+        title: '修改预约资产数据',
+        visible: false,
+        content: '',
+        location: '',
+        description: '',
+      }),
+      (_self.assetCalendarInsert = {
+        // 新增预约数据对象
+        visible: false,
+        content: '',
+        location: '',
+        description: '',
+      });
+      // (_self.assetCalendarLineLists = []), // 单个月预约对象集合
+      // _self.queryAssetCalendarByParam();
+      if (_self.selectItemId !== undefined) {
+        _self.assetCalendarById(_self.selectItemId);
+      } else {
+        message.info('请选择资产');
+      }
+    },
+
+    //  数据更新后,还原界面数据
+    restoreData: function () {
+      var _self = this;
+      _self.assetCalendarUpdate = {
+        title: '修改预约资产',
+        visible: false,
+        content: '',
+        location: '',
+        description: '',
+      };
+    },
+
+    handleOk() {
+      var _self = this;
+      _self.loading = true;
+      const startTime = _self.getYearMonthDate(_self.clickInfo.event.start);
+      const endTime = _self.getYearMonthDate(_self.clickInfo.event.end);
+      const currentTime = _self.getYearMonthDate(new Date());
+      const timeQuantum = [startTime, endTime];
+      if (
+        _self.compareTime(endTime, currentTime) > 0 &&
+        _self.userName !== 'admin'
+      ) {
+        message.warning('完成的预约无法修改,请联系管理员');
+      } else if (
+        _self.isBetweenTime(currentTime, timeQuantum) &&
+        _self.userName !== 'admin'
+      ) {
+        message.warning('进行中的预约无法修改,请联系管理员');
+      } else {
+        _self.assetCalendarUpdateMethod();
+      }
+      _self.loading = false;
+    },
+
+    handleCancel() {
+      this.assetCalendarUpdate.visible = false;
+    },
+
+    handleDelete() {
+      var _self = this;
+      _self.visible = true;
+    },
+
+    /**
+     * 改变资产事件
+     * @param {*} newResponsibilityFieldValue
+     */
+    assetValueChanged: function (newResponsibilityFieldValue) {
+      var _self = this;
+      _self.assetFieldValue = newResponsibilityFieldValue;
+      _self.assetCalendarUpdate.assetInstanceId =
+        newResponsibilityFieldValue.id;
+      _self.assetCalendarInsert.assetInstanceId =
+        newResponsibilityFieldValue.id;
+    },
+
+    /**
+     *
+     * @param {*} newResponsibilityFieldValue
+     */
+    userValueChanged: function (newResponsibilityFieldValue) {
+      var _self = this;
+      _self.userFieldValue = newResponsibilityFieldValue;
+      _self.assetCalendarUpdate.userId = newResponsibilityFieldValue.id;
+      _self.assetCalendarInsert.userId = newResponsibilityFieldValue.id;
+    },
+
+    //把时间格转换为yyyy-mm-dd
+    formatDate: function (date) {
+      if (date != '' && date != null) {
+        var dateStr = date + '';
+        return dateStr.substr(0, 10);
+      } else {
+        return '';
+      }
+    },
+    // 比较时间
+    compareTime: function (beginTime, endTime) {
+      var beginTimes = beginTime.replace(/-/g, '/');
+      var endTimes = endTime.replace(/-/g, '/');
+      var a = (Date.parse(endTimes) - Date.parse(beginTimes)) / 3600 / 1000;
+      return a;
+    },
+    // 是否在时间区间
+    isBetweenTime: function (currentDate, timeQuantum) {
+      let isBetween = true;
+      let currentTime = new Date(currentDate);
+      let startTime = new Date(timeQuantum[0]);
+      let endTime = new Date(timeQuantum[1]);
+      let t1 = currentTime.getTime() - startTime.getTime();
+      let t2 = currentTime.getTime() - endTime.getTime();
+      if (t1 < 0 || t2 > 0) {
+        isBetween = false;
+      }
+      return isBetween;
+    },
+    getYearMonthDate: function (date) {
+      var y = date.getFullYear();
+      var m = date.getMonth() + 1;
+      m = m < 10 ? '0' + m : m;
+      var d = date.getDate();
+      d = d < 10 ? '0' + d : d;
+      var h = date.getHours();
+      h = h < 10 ? '0' + h : h;
+      var s = date.getMinutes();
+      s = s < 10 ? '0' + s : s;
+      return y + '-' + m + '-' + d + ' ' + h + ':' + s + ':' + '00';
+    },
+
+    addDate: function (time, n) {
+      //加n天
+      //指定日期time 2020-01-07
+      var timestamp = Date.parse(new Date(time));
+
+      timestamp = timestamp / 1000;
+      timestamp += Number(n) * 86400; //加一天
+      var newTime = new Date(timestamp * 1000).format('Y-m-d H:i:s');
+
+      return newTime;
+    },
+
+    judgeWeek: function (startDate, endDate, weekList) {
+      const start = new Date(startDate.replace(/-/gi, '/'));
+      const end = new Date(endDate.replace(/-/gi, '/'));
+      // 用毫秒值计算
+      if (end.getTime() - start.getTime() < 6 * 24 * 60 * 60 * 1000) {
+        const count = (end - start) / (24 * 60 * 60 * 1000) + 1;
+        const arr = [];
+        for (let i = 0; i < count; i++) {
+          // 获取从开始时间-结束时间中存在周几
+          arr.push(
+            new Date(start.getTime() + i * 24 * 60 * 60 * 1000).getDay(),
+          );
+        }
+        // 开始时间, 结束时间中间存在周几拼成的字符串
+        // 例如 2022-10-15-2022-10-16 是周六/周日 拼成 60
+        const str = arr.join('');
+        // 循环传入的数组,都存在str中说明全部满足
+        for (let k = 0; k < weekList.length; k++) {
+          if (str.indexOf(weekList[k]) === -1) {
+            return false;
+          } else {
+            return true;
+          }
+        }
+      }
+      // 开始时间-结束时间大于7天全部都有直接返回
+      return true;
+    },
+
+    judgeDate: function (startDate, endDate) {
+      var _self = this;
+      var startDateStr = _self.formatDate(startDate);
+      // var startDayIndex = new Date(startDateStr).getDay();
+      // //根据日期下标获取周几 例如 根据2023-02-14 的下标为2 星期二
+      // if (
+      //   _self.weekDay[startDayIndex] === "星期六" ||
+      //   _self.weekDay[startDayIndex] === "星期日"
+      // ) {
+      //   Notify.error("失败", "预约开始时间不能选定周六或周日", true);
+      //   _self.refulshData();
+      //   return true;
+      // }
+
+      const comparDate = dateValue => {
+        return (
+          new Date().getTime() >
+          new Date(dateValue).getTime() + 3600 * 1000 * 24
+        );
+      };
+      if (comparDate(startDateStr) && _self.userName !== 'admin') {
+        Notify.error('失败', '预约开始时间需大于当前日期', true);
+        _self.refulshData();
+        return true;
+      }
+
+      // var endDateStr = _self.formatDate(endDate);
+      // var endDayIndex = new Date(endDateStr).getDay();
+      // //根据日期下标获取周几 例如 根据2023-02-14 的下标为2 星期二
+      // if (
+      //   _self.weekDay[endDayIndex] === "星期六" ||
+      //   _self.weekDay[endDayIndex] === "星期日"
+      // ) {
+      //   Notify.error("失败", "预约结束时间不能选定周六或周日", true);
+      //   _self.refulshData();
+      //   return true;
+      // }
+
+      if (new Date(endDate).getTime() - new Date(startDate).getTime() <= 0) {
+        Notify.error('失败', '预约结束时间不能小于或等于预约开始时间', true);
+        _self.refulshData();
+        return true;
+      }
+
+      var dateStr = _self.addDate(startDate, 30);
+      if (endDate > dateStr) {
+        // var boolean = _self.judgeWeek(
+        //   startDateStr,
+        //   _self.formatDate(endDate),
+        //   [0, 6]
+        // );
+        // if (boolean) {
+        //   dateStr = _self.addDate(startDate, 5);
+        //   if (endDate > dateStr) {
+        //     Notify.error(
+        //       "失败",
+        //       "可预约最长时间为:" + dateStr + ",请修改预约结束时间。",
+        //       true
+        //     );
+        //     return true;
+        //   }
+        // } else {
+        Notify.error(
+          '失败',
+          '可预约最长时间为:' +
+            dateStr +
+            ' (30天)' +
+            ',请修改预约结束时间。',
+          true,
+        );
+        _self.refulshData();
+        return true;
+        // }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="css">
+.userGroup {
+  width: 160px;
+  height: 500px;
+  margin-top: 24px;
+  float: left;
+  overflow: auto;
+}
+.demo-app {
+  display: flex;
+  min-height: 100%;
+  font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+  font-size: 14px;
+}
+
+.demo-app-sidebar {
+  width: 100px;
+  height: 816px;
+  line-height: 1.5;
+  background: black;
+  border-right: 1px solid #ffffff;
+  text-align: center;
+}
+
+.demo-app-sidebar-section {
+  padding: 2em;
+}
+.demo-app-main {
+  flex-grow: 1;
+  padding: 1em;
+}
+
+.fc {
+  /* the calendar root */
+  max-width: 1100px;
+  margin: 0 auto;
+  --fc-today-bg-color: #ffffff;
+}
+.fc .fc-col-header-cell-cushion {
+  color: black;
+}
+.fc .fc-daygrid-day-number {
+  color: black;
+}
+.fc-event-main {
+  overflow: hidden;
+}
+.fc-daygrid-event-harness {
+  overflow: hidden;
+}
+</style>

+ 2 - 0
src/index.js

@@ -44,6 +44,7 @@ import InventoryAssetInstanceSearch from './customer/InventoryAssetInstanceSearc
 import RunDataArchive from './components/customer/RunDataArchive.vue';
 import AssetRfidRecord from './components/rfidRecord/AssetRfidRecord.vue';
 import BatchUploadImages from './components/sonicAlbumUpload/index.vue';
+import AssetInstanceFullCalendar from './customer/AssetInstanceFullCalendar.vue';
 
 export {
   langZhCn,
@@ -89,4 +90,5 @@ export {
   AssetRfidRecord,
   BatchUploadImages,
   AssetLabelPrinting,
+  AssetInstanceFullCalendar,
 };

+ 2 - 0
src/router/index.js

@@ -37,6 +37,7 @@ const AssetLabelPrinting = () => import(/* webpackChunkName: "component-35" */ '
 const RunDataArchive = () => import(/* webpackChunkName: "component-35" */ '../components/customer/RunDataArchive.vue');
 const AssetRfidRecord = () => import('../components/rfidRecord/AssetRfidRecord.vue');
 const BatchUploadImages = () => import('../components/sonicAlbumUpload/index.vue');
+const AssetInstanceFullCalendar = () => import('../customer/AssetInstanceFullCalendar.vue');
 
 const routes = [
 
@@ -307,6 +308,7 @@ const routes = [
   {
     path: '/eam/batchUploadImages', component: BatchUploadImages,
   },
+  { path: '/eam/AssetInstanceFullCalendar', component: AssetInstanceFullCalendar },
 ];
 
 

+ 11 - 11
webpack.dev.js

@@ -60,65 +60,65 @@ module.exports = WebpackMerge.merge(baseConfig, {
 
     proxy: {
       '/api': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/static': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/content': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/dashboard': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/mock': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/authApi': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/Dictionary': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/Files': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: false,
         changeOrigin: true,
         secure: true,
       },
       '/WebSocket': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: true,
         changeOrigin: true,
       },
       '/TrainVideo': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: true,
         changeOrigin: true,
       },
       '/gateway-api': {
-        target: 'http://wuzhixin.vip:10022/',
+        target: 'http://192.168.1.8:10023/',
         ws: true,
         changeOrigin: true,
         secure: true,