From 3fb908f2d537a8a047388963202185e5844317cb Mon Sep 17 00:00:00 2001
From: yangkang <yangkang@xalxzn.com>
Date: 星期二, 12 九月 2023 09:26:35 +0800
Subject: [PATCH] 预测性维护

---
 src/views/eam/modules/predictiveWorkPlan/PredictiveWorkPlanModal.vue      |  448 ++++
 src/views/eam/common/MaintenanceStandardWorkInstruction.vue               |  379 +++
 src/views/eam/common/PlanSparePartSelect.vue                              |  234 ++
 src/views/eam/common/MaintenanceStandardSafetyRequirementModal.vue        |  259 ++
 src/views/eam/PredictiveWorkOrderList.vue                                 |  532 +++++
 src/views/eam/common/MaintenanceStandardPlanningMaterialModal.vue         |  262 ++
 src/views/eam/common/RepairOrderDetailModal.vue                           |  289 ++
 src/views/eam/modules/predictiveWorkPlan/WarnSelect.vue                   |  220 ++
 src/views/eam/common/JSelectMaintenanceStandardSafetyRequirementModal.vue |  261 ++
 src/views/eam/common/MaintenanceStandardSafetyRequirement.vue             |  215 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveParameterModal.vue     |  281 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveParameters.vue         |  194 +
 src/views/eam/common/MaintenanceStandardWorkInstructionModal.vue          |  344 +++
 src/views/eam/PredictiveWorkPlanList.vue                                  |  471 ++++
 src/views/eam/common/RepairOrderDetailList.vue                            |  228 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveSparePartsModal.vue    |  302 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveSpareParts.vue         |  204 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveWarn.vue               |  194 +
 src/views/eam/modules/predictiveWorkPlan/ParameterSelect.vue              |  225 ++
 src/views/eam/modules/predictiveWorkPlan/PredictiveWarnModal.vue          |  277 ++
 src/views/eam/common/MaintenanceStandardPlanningMaterial.vue              |  232 ++
 21 files changed, 6,051 insertions(+), 0 deletions(-)

diff --git a/src/views/eam/PredictiveWorkOrderList.vue b/src/views/eam/PredictiveWorkOrderList.vue
new file mode 100644
index 0000000..251e261
--- /dev/null
+++ b/src/views/eam/PredictiveWorkOrderList.vue
@@ -0,0 +1,532 @@
+<template>
+  <a-card
+    :bordered="false"
+    title="涓撲笟淇濆吇宸ュ崟"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+          <a-col
+            :md="6"
+            :sm="8"
+          >
+            <a-form-item label="淇濆吇宸ュ崟缂栫爜">
+              <a-input
+                placeholder="璇疯緭鍏ヤ繚鍏诲伐鍗曠紪鐮�"
+                v-model="queryParam.num"
+              ></a-input>
+            </a-form-item>
+          </a-col>
+          <!-- <a-col
+            :md="6"
+            :sm="8"
+          >
+            <a-form-item label="鐐规鏂规硶鍚嶇О">
+              <j-input
+                placeholder="璇疯緭鍏ョ偣妫�鏂规硶鍚嶇О"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col> -->
+          <a-col
+            :md="6"
+            :sm="8"
+          >
+            <span
+              style="float: left;overflow: hidden;"
+              class="table-page-search-submitButtons"
+            >
+              <a-button
+                type="primary"
+                @click="searchQuery"
+                icon="search"
+              >鏌ヨ</a-button>
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+              >閲嶇疆</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 鏌ヨ鍖哄煙-END -->
+
+    <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
+    <div class="table-operator">
+      <a-button
+        @click="handleAdd"
+        type="primary"
+        icon="plus"
+      >鏂板</a-button>
+      <a-button
+        v-if="selectedRowKeys.length > 0"
+        type="primary"
+        @click="batchAssign"
+        style="margin-left: 8px"
+      >宸ュ崟娲惧伐</a-button>
+    </div>
+
+    <!-- table鍖哄煙-begin -->
+    <div>
+      <div
+        class="ant-alert ant-alert-info"
+        style="margin-bottom: 16px;"
+      >
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 宸查�夋嫨 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>椤�
+        <a
+          style="margin-left: 24px"
+          @click="onClearSelected"
+        >娓呯┖</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: 'calc(1900px + 50%)', y: 900 }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <!-- :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" -->
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾涓嬪彂宸ュ崟鍚�?"
+            @confirm="() => handleOrderIssue(record)"
+          >
+            <a v-if="record.status == '1'">涓嬪彂</a>
+          </a-popconfirm>
+          <a-divider
+            v-if="record.status == '1'"
+            type="vertical"
+          />
+          <a-popconfirm
+            title="纭畾鎾ゅ洖宸ュ崟鍚�?"
+            @confirm="() => handleOrderReset(record)"
+          >
+            <a v-if="record.status == '2'">鎾ゅ洖</a>
+          </a-popconfirm>
+          <a-divider
+            v-if="record.status == '2'"
+            type="vertical"
+          />
+          <a-popconfirm
+            title="纭畾鎭㈠宸ュ崟鍚�?"
+            @confirm="() => handleOrderRecover(record)"
+          >
+            <a v-if="record.status == '7'">鎭㈠</a>
+          </a-popconfirm>
+          <a-divider
+            v-if="record.status == '7'"
+            type="vertical"
+          />
+          <a-popconfirm
+            title="纭畾浣滃簾宸ュ崟鍚�?"
+            @confirm="() => handleOrderCancel(record)"
+          >
+            <a v-if="record.status == '2'">浣滃簾</a>
+          </a-popconfirm>
+          <a-divider
+            v-if="record.status == '2'"
+            type="vertical"
+          />
+          <a-popconfirm
+            title="纭畾棰嗗彇宸ュ崟鍚�?"
+            @confirm="() => handleOrderGet(record)"
+          >
+            <a v-if="record.status == '2' && record.assignMode == '1'">棰嗗彇</a>
+          </a-popconfirm>
+          <a
+            v-if="record.status == '2' && record.assignMode == '2'  "
+            @click="handleAssignOrder(record)"
+          >娲惧伐</a>
+          <a
+            v-if="record.status == '2'&& record.assignMode == '3'  && record.inspectionUserName != null  "
+            @click="handleAssignOrder(record)"
+          >鏀规淳</a>
+          <a
+            v-if="record.status == '3'"
+            @click="handleAssignOrder(record)"
+          >鏀规淳</a>
+          <a-divider
+            v-if="record.status == '2'"
+            type="vertical"
+          />
+          <a-divider
+            v-if="record.status === '3'"
+            type="vertical"
+          />
+          <a
+            v-if="record.status === '3' || record.status === '4'  "
+            @click="handleOrderExe(record)"
+          >鎵ц</a>
+          <a-divider
+            v-if="record.status === '3' || record.status === '4' "
+            type="vertical"
+          />
+          <a
+            v-if="record.status === '1'"
+            @click="handleEdit(record)"
+          >缂栬緫</a>
+          <a-divider
+            v-if="record.status === '1'"
+            type="vertical"
+          />
+          <a-dropdown>
+            <a class="ant-dropdown-link">鏇村 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">璇︽儏</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="纭畾鍒犻櫎鍚�?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a v-if="record.status === '1'">鍒犻櫎</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+        <span
+          slot="num"
+          slot-scope="text, record"
+        >
+          <a
+            v-if="record.status === '3' || record.status === '4' ||record.status === '5'  ||record.status === '7' "
+            class="lot"
+            @click="handleOrderExe(record)"
+          >{{record.num}}</a>
+          <span v-else>{{record.num}}</span>
+        </span>
+
+      </a-table>
+    </div>
+
+    <maintenance-order-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></maintenance-order-modal>
+    <inspection-order-assign-modal
+      ref="InspectionOrderAssignModal"
+      @ok="modalFormOk"
+    ></inspection-order-assign-modal>
+    <specialy-maintenance-order-exe-drawer
+      ref="SpecialyMaintenanceOrderExeDrawer"
+      @ok="modalFormOk"
+    ></specialy-maintenance-order-exe-drawer>
+    <specialty-maintenance-order-assign-modal
+      ref="SpecialtyMaintenanceOrderAssignModal"
+      @ok="modalFormOk"
+    >
+    </specialty-maintenance-order-assign-modal>
+  </a-card>
+</template>
+
+<script>
+
+import '@/assets/less/TableExpand.less'
+import { mixinDevice } from '@/utils/mixin'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import MaintenanceOrderModal from './modules/specialtyMaintenanceOrder/MaintenanceOrderModal'
+import InspectionOrderAssignModal from './modules/specialtyMaintenanceOrder/InspectionOrderAssignModal'
+import SpecialyMaintenanceOrderExeDrawer from './modules/specialtyMaintenanceOrder/SpecialyMaintenanceOrderExeDrawer'
+import { getAction, postAction, requestPut } from '@/api/manage'
+import SpecialtyMaintenanceOrderAssignModal from './modules/specialtyMaintenanceOrder/SpecialtyMaintenanceOrderAssignModal.vue'
+import SpecialtyInspectionOrderAssignModal from './modules/specialtyInspectionOrder/SpecialtyInspectionOrderAssignModal.vue'
+
+export default {
+  name: 'PredictiveWorkOrderList',
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    MaintenanceOrderModal,
+    InspectionOrderAssignModal,
+    SpecialyMaintenanceOrderExeDrawer,
+    SpecialtyMaintenanceOrderAssignModal,
+    SpecialtyInspectionOrderAssignModal
+  },
+  data() {
+    return {
+      description: '棰勬祴鎬х淮鎶ゅ伐鍗�',
+      // 琛ㄥご
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          width: 60,
+          align: "center",
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1;
+          }
+        },
+        {
+          title: '鐘舵��',
+          align: "center",
+          dataIndex: 'statusName'
+        },
+        {
+          title: '鍗曟嵁鍙�',
+          align: "center",
+          dataIndex: 'num',
+          scopedSlots: { customRender: 'num' }
+        },
+        {
+          title: '鐩戞帶绫诲瀷',
+          align: "center",
+          dataIndex: 'maintenanceMode'
+        },
+        {
+          title: '璁惧缂栫爜',
+          align: "center",
+          dataIndex: 'departName',
+        },
+        {
+          title: '璁惧鍚嶇О',
+          align: "center",
+          dataIndex: 'maintenanceTypeName',
+        },
+        {
+          title: '鍨嬪彿',
+          align: "center",
+          dataIndex: 'maintenanceCycleName',
+        },
+        {
+          title: '鏍囧噯缂栫爜',
+          align: 'center',
+          dataIndex: 'assignModeName',
+        },
+        {
+          title: '鐗堟湰',
+          align: "center",
+          dataIndex: 'specialtyMaintenancePlanNum',
+        },
+        {
+          title: '浣跨敤閮ㄩ棬',
+          align: "center",
+          dataIndex: 'teamName',
+        },
+        {
+          title: '娲惧伐鏂瑰紡',
+          align: "center",
+          dataIndex: 'sumOfWorkingHourQuota',
+        },
+        {
+          title: '璐d换鐝粍',
+          align: "center",
+          dataIndex: 'planStartTime',
+          width: 170
+
+        },
+        {
+          title: '璐d换浜�',
+          align: "center",
+          dataIndex: 'planEndTime',
+          width: 170
+        },
+        {
+          title: '宸ユ椂瀹氶锛堝皬鏃讹級',
+          align: "center",
+          dataIndex: 'planEndTime',
+          width: 170
+        },
+        {
+          title: '瀹為檯宸ユ椂',
+          align: "center",
+          dataIndex: 'planEndTime',
+          width: 170
+        },
+        {
+          title: '瀹為檯寮�濮嬫椂闂�',
+          align: "center",
+          dataIndex: 'actualStartTime',
+          width: 170
+        },
+        {
+          title: '瀹為檯缁撴潫鏃堕棿',
+          align: "center",
+          dataIndex: 'actualEndTime',
+          width: 170
+        },
+        {
+          title: '鍒涘缓浜�',
+          align: "center",
+          dataIndex: 'createBy'
+        },
+        {
+          title: '鍒涘缓鏃ユ湡',
+          align: "center",
+          dataIndex: 'createTime',
+          width: 170
+        },
+        {
+          title: '鎿嶄綔',
+          dataIndex: 'action',
+          align: "center",
+          fixed: "right",
+          width: 300,
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      url: {
+        list: "/eam/predictiveworkorder/pageOrderList",
+        delete: "/eam/specialtyMaintenanceOrder/delete",
+        deleteBatch: "/eam/specialtyMaintenanceOrder/deleteBatch",
+        exportXlsUrl: "/eam/specialtyMaintenanceOrder/exportXls",
+        importExcelUrl: "eam/specialtyMaintenanceOrder/importExcel",
+        edit: "/eam/specialtyMaintenanceOrder/editStatus",
+        orderGet: "/eam/specialtyMaintenanceOrder/orderGet",
+      },
+    }
+  },
+
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+    },
+    rowSelection() {
+      return {
+        type: 'checkbox',
+        onChange: (selectedRowKeys, selectedRows) => {
+          this.selectedRowKeys = selectedRowKeys;
+          this.onSelectChange(selectedRows);
+        },
+        getCheckboxProps: record => ({
+          props: {
+            disabled: record.distable
+          },
+        }),
+        selectedRowKeys: this.selectedRowKeys,
+      };
+    },
+  },
+
+  methods: {
+
+    batchAssign() {
+      this.$refs.InspectionOrderAssignModal.visible = true
+      this.$refs.InspectionOrderAssignModal.title = '宸ュ崟娲惧伐'
+      this.$refs.InspectionOrderAssignModal.selectionRows
+      this.$refs.InspectionOrderAssignModal.handleShow()
+      this.$bus.$emit('selectionRows', this.selectionRows);
+    },
+    onSelectChange(selectionRows) {
+      this.selectionRows = selectionRows;
+    },
+
+    handleOrderExe(record) {
+      this.$refs.SpecialyMaintenanceOrderExeDrawer.visible = true
+      this.$refs.SpecialyMaintenanceOrderExeDrawer.title = '涓撲笟淇濆吇宸ュ崟鎵ц'
+      this.$refs.SpecialyMaintenanceOrderExeDrawer.handleShow(record)
+      if (record.status === '3') {
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.buttonDistable = true//淇濆瓨銆佹殏瀛樸�佹姤宸�
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.revocationDistable = true//鎾ら攢鎸夐挳
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.SWbuttonDistable = false//寮�宸ユ寜閽�
+      } else if (record.status === '4') {
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.buttonDistable = false
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.revocationDistable = true
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.SWbuttonDistable = true
+      } else if (record.status === '5') {
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.buttonDistable = true
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.revocationDistable = false
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.SWbuttonDistable = true
+      } else if (record.status === '7') {
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.buttonDistable = true
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.revocationDistable = true
+        this.$refs.SpecialyMaintenanceOrderExeDrawer.SWbuttonDistable = true
+      }
+    },
+
+    handleOrderIssue(record) {
+      const that = this;
+      requestPut(that.url.edit, { id: record.id, status: '2' }).then((res) => {
+        if (res.success) {
+          that.$message.success("宸ュ崟涓嬪彂鎴愬姛锛�")
+          that.loadData()
+        } else {
+          that.$message.warning("宸ュ崟涓嬪彂澶辫触锛�")
+        }
+      })
+    },
+    //鎾ゅ洖
+    handleOrderReset(record) {
+      const that = this;
+      requestPut(that.url.edit, { id: record.id, status: '1' }).then((res) => {
+        if (res.success) {
+          that.$message.success("宸ュ崟鎾ゅ洖鎴愬姛锛�")
+          that.loadData()
+        } else {
+          that.$message.warning("宸ュ崟鎾ゅ洖澶辫触锛�")
+        }
+      })
+    },
+    handleOrderGet(record) {
+      const that = this;
+      requestPut(that.url.orderGet, { id: record.id, status: '1' }).then((res) => {
+        if (res.success) {
+          that.$message.success("宸ュ崟棰嗗彇鎴愬姛锛�")
+          that.loadData()
+        } else {
+          that.$message.warning("宸ュ崟棰嗗彇澶辫触锛�")
+        }
+      })
+    },
+    //浣滃簾
+    handleOrderCancel(record) {
+      const that = this;
+      requestPut(that.url.edit, { id: record.id, status: '7' }).then((res) => {
+        if (res.success) {
+          that.$message.success("宸ュ崟浣滃簾鎴愬姛锛�")
+          that.loadData()
+        } else {
+          that.$message.warning("宸ュ崟浣滃簾澶辫触锛�")
+        }
+      })
+    },
+
+    //鎭㈠
+    handleOrderRecover(record) {
+      const that = this;
+      requestPut(that.url.edit, { id: record.id, status: '2' }).then((res) => {
+        if (res.success) {
+          that.$message.success("宸ュ崟鎭㈠鎴愬姛锛�")
+          that.loadData()
+        } else {
+          that.$message.warning("宸ュ崟鎭㈠澶辫触锛�")
+        }
+      })
+    },
+    handleAssignOrder: function (record) {
+      this.$refs.SpecialtyMaintenanceOrderAssignModal.edit(record)
+      this.$refs.SpecialtyMaintenanceOrderAssignModal.title = '宸ュ崟鏀规淳'
+      this.$refs.SpecialtyMaintenanceOrderAssignModal.disableSubmit = false
+    },
+    // modalFormOk() {
+    //   alert(0)
+    //   // 鏂板/淇敼 鎴愬姛鏃讹紝閲嶈浇鍒楄〃
+    //   this.loadData();
+    //   //娓呯┖鍒楄〃閫変腑
+    //   this.onClearSelected()
+    // },
+  }
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>
\ No newline at end of file
diff --git a/src/views/eam/PredictiveWorkPlanList.vue b/src/views/eam/PredictiveWorkPlanList.vue
new file mode 100644
index 0000000..57ea9ff
--- /dev/null
+++ b/src/views/eam/PredictiveWorkPlanList.vue
@@ -0,0 +1,471 @@
+<template>
+  <a-card
+    title="棰勬祴鎬х淮鎶ゆ柟妗�"
+    :bordered='false'
+  >
+    <div class='table-page-search-wrapper'>
+      <a-form
+        layout='inline'
+        @keyup.enter.native='searchQuery'
+      >
+        <a-row :gutter='24'>
+          <a-col
+            :xl='6'
+            :lg='7'
+            :md='8'
+            :sm='24'
+          >
+            <a-form-item label='鏂规缂栫爜'>
+              <a-input
+                placeholder='璇疯緭鍏ユ柟妗堢紪鐮�'
+                v-model='queryParam.planNum'
+              ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col
+            :xl='6'
+            :lg='7'
+            :md='8'
+            :sm='24'
+          >
+            <a-form-item label='璁惧鍚嶇О'>
+              <a-input
+                placeholder='璇疯緭鍏ヨ澶囧悕绉�'
+                v-model='queryParam.deviceName'
+              ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col
+            :md="10"
+            :sm="8"
+          >
+            <a-form-item label="鐗堟湰鐘舵��">
+              <a-radio-group
+                v-model="queryParam.versionStatus"
+                @change="onChange"
+                default-value="2"
+              >
+                <a-radio-button value="1">
+                  鏈敓鏁�
+                </a-radio-button>
+                <a-radio-button value="2">
+                  宸茬敓鏁�
+                </a-radio-button>
+                <a-radio-button value="3">
+                  宸插け鏁�
+                </a-radio-button>
+              </a-radio-group>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+
+    <div class="table-operator">
+      <a-button
+        @click='handleAdd'
+        type='primary'
+        icon='plus'
+      >鏂板
+      </a-button>
+      <a-button
+        type='primary'
+        @click='searchQuery'
+        icon='search'
+      >鏌ヨ
+      </a-button>
+      <a-button
+        type='primary'
+        @click='searchReset'
+        icon='reload'
+        style='margin-left: 8px'
+      >閲嶇疆
+      </a-button>
+    </div>
+
+    <!-- table鍖哄煙-begin -->
+    <div>
+      <div
+        class='ant-alert ant-alert-info'
+        style='margin-bottom: 16px;'
+      >
+        <i class='anticon anticon-info-circle ant-alert-icon'></i> 宸查�夋嫨 <a style='font-weight: 600'>{{
+        selectedRowKeys.length }}</a>椤�
+        <a
+          style='margin-left: 24px'
+          @click='onClearSelected'
+        >娓呯┖</a>
+      </div>
+
+      <a-table
+        ref='table'
+        size='middle'
+        bordered
+        rowKey='id'
+        :scroll="{ x: 'calc(1400px + 50%)', y: 900 }"
+        :columns='columns'
+        :dataSource='dataSource'
+        :pagination='ipagination'
+        :loading='loading'
+        :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio' }"
+        :customRow='clickThenSelect'
+        @change='handleTableChange'
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a
+            v-if="record.status == '2'"
+            @click="handleRevise(record)"
+          >鍗囩増</a>
+          <a
+            v-if="record.status == '1'"
+            @click="handleTakeEffect(record)"
+          >鐢熸晥</a>
+          <a-divider type="vertical"/>
+          <a
+            v-if="record.status == '1'"
+            @click="handleEdit(record)"
+          >缂栬緫</a>
+          <a-divider type="vertical"/>
+          <a-popconfirm
+            v-if="record.status == '1'"
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+
+      </a-table>
+      <a-tabs
+        type="card"
+        defaultActiveKey="1"
+      >
+        <a-tab-pane
+          tab='瑙﹀彂鏉′欢'
+          key="1" forceRender
+        >
+          <div
+            class="table-operator"
+            style="margin:-16px"
+          >
+            <predictive-spare-parts :planId='planId' :isEdit="isEdit" :isAdd="isAdd" :isDel="isDel"/>
+            <!--            v-if="selectionRows[0].monitorType == 'smkz'"-->
+            <predictive-parameters :planId='planId' :equipmentId='equipmentId' :isEdit="isEdit" :isAdd="isAdd"
+                                   :isDel="isDel"/>
+            <!--            v-if="selectionRows[0].monitorType == 'cskz'" -->
+            <predictive-warn :planId='planId' :equipmentId='equipmentId' :isEdit="isEdit" :isAdd="isAdd"
+                             :isDel="isDel"/>
+            <!--            v-if="selectionRows[0].monitorType == 'bjkz'"-->
+          </div>
+        </a-tab-pane>
+
+        <a-tab-pane
+          tab='缁存姢鍐呭'
+          key="2" forceRender
+        >
+          <div
+            class="table-operator"
+            style="margin:-16px"
+          >
+            <repair-order-detail-list :mainId='planId' :isEdit="isEdit" :isAdd="isAdd" :isDel="isDel"/>
+          </div>
+        </a-tab-pane>
+        <a-tab-pane
+          tab='璁″垝鐢ㄦ枡'
+          key="3" forceRender
+        >
+          <div
+            class="table-operator"
+            style="margin:-16px"
+          >
+            <maintenance-standard-planning-material :maintenanceStandardId='planId' :isEdit="isEdit" :isAdd="isAdd"
+                                                    :isDel="isDel"/>
+          </div>
+        </a-tab-pane>
+        <a-tab-pane
+          tab='鍗遍櫓闃叉帶'
+          key="4" forceRender
+        >
+          <div
+            class="table-operator"
+            style="margin:-16px"
+          >
+            <maintenance-standard-safety-requirement :maintenanceStandardId='planId' :isEdit="isEdit" :isAdd="isAdd"
+                                                     :isDel="isDel"/>
+          </div>
+        </a-tab-pane>
+
+        <a-tab-pane
+          tab='浣滀笟鎸囧涔�'
+          key="5" forceRender
+        >
+          <div
+            class="table-operator"
+            style="margin:-16px"
+          >
+            <maintenance-standard-work-instruction :maintenanceStandardId='planId' :isEdit="isEdit" :isAdd="isAdd"
+                                                   :isDel="isDel"/>
+          </div>
+        </a-tab-pane>
+
+      </a-tabs>
+    </div>
+
+    <predictive-work-plan-modal
+      ref='modalForm'
+      @ok='modalFormOk'
+    ></predictive-work-plan-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+
+  import { requestPut } from '@/api/manage'
+
+  import DailyMaintenanceStandardDetail from './modules/dailyMaintenanceStandard/DailyMaintenanceStandardDetail'
+  //璁″垝鐢ㄦ枡
+  import MaintenanceStandardPlanningMaterial from '@/views/eam/common/MaintenanceStandardPlanningMaterial'
+  //鍗遍櫓闃叉帶
+  import MaintenanceStandardSafetyRequirement from '@/views/eam/common/MaintenanceStandardSafetyRequirement'
+  //鏂板缂栬緫
+  import PredictiveWorkPlanModal from './modules/predictiveWorkPlan/PredictiveWorkPlanModal'
+  //鍙傛暟
+  import PredictiveParameters from './modules/predictiveWorkPlan/PredictiveParameters'
+  //鎶ヨ
+  import PredictiveWarn from './modules/predictiveWorkPlan/PredictiveWarn'
+  //澶囦欢
+  import PredictiveSpareParts from './modules/predictiveWorkPlan/PredictiveSpareParts'
+  //浣滀笟鎸囧涔�
+  import MaintenanceStandardWorkInstruction from '@/views/eam/common/MaintenanceStandardWorkInstruction'
+  //缁存姢鍐呭
+  import RepairOrderDetailList from '@/views/eam/common/RepairOrderDetailList'
+  import '@/assets/less/TableExpand.less'
+
+  export default {
+    name: 'PredictiveWorkPlanList',
+    mixins: [JeecgListMixin],
+    components: {
+      DailyMaintenanceStandardDetail,
+      PredictiveWorkPlanModal,
+      MaintenanceStandardPlanningMaterial,
+      MaintenanceStandardSafetyRequirement,
+      MaintenanceStandardWorkInstruction,
+      PredictiveSpareParts,
+      PredictiveParameters,
+      PredictiveWarn,
+      RepairOrderDetailList
+    },
+    data() {
+      return {
+        equipmentId: '',
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 60,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鐗堟湰鐘舵��',
+            align: 'center',
+            dataIndex: 'statusName'
+          },
+          // {
+          //   title: '瀹℃壒鐘舵��',
+          //   align: 'center',
+          //   dataIndex: 'versionStatusName'
+          // },
+          {
+            title: '鐗堟湰',
+            align: 'center',
+            dataIndex: 'planVersion'
+          },
+
+          {
+            title: '鏂规缂栫爜',
+            align: 'center',
+            dataIndex: 'num'
+          },
+          {
+            title: '鏂规鍚嶇О',
+            align: 'center',
+            dataIndex: 'name'
+          },
+          {
+            title: '鐩戞帶绫诲瀷',
+            align: 'center',
+            dataIndex: 'monitorTypeName'
+          },
+          {
+            title: '璁惧缂栫爜',
+            align: 'center',
+            dataIndex: 'deviceNum'
+          },
+          {
+            title: '璁惧鍚嶇О',
+            align: 'center',
+            dataIndex: 'deviceName'
+          },
+          {
+            title: '璁惧鍨嬪彿',
+            align: 'center',
+            dataIndex: 'deviceModel'
+          },
+          {
+            title: '缁翠繚鏂瑰紡',
+            align: 'center',
+            dataIndex: 'maintenanceMethodName'
+          },
+          {
+            title: '娲惧伐鏂瑰紡',
+            align: 'center',
+            dataIndex: 'assignModeName'
+          },
+          {
+            title: '璐d换鐝粍',
+            align: 'center',
+            dataIndex: 'teamName'
+          },
+          {
+            title: '鍒涘缓浜�',
+            align: 'center',
+            dataIndex: 'createBy'
+          },
+          {
+            title: '鍒涘缓鏃ユ湡',
+            align: 'center',
+            dataIndex: 'createTime'
+          },
+          // {
+          //   title: '鏇存柊浜�',
+          //   align: 'center',
+          //   dataIndex: 'updateBy',
+          // },
+          // {
+          //   title: '鏇存柊鏃ユ湡',
+          //   align: 'center',
+          //   dataIndex: 'updateTime',
+          // },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align: 'center',
+            fixed: 'right',
+            scopedSlots: { customRender: 'action' },
+            width: 200
+          }
+        ],
+        monitorType: '',
+        planId: '',
+        isEdit: false,
+        isAdd: false,
+        isDel: false,
+        url: {
+          list: '/eam/predictiveworkplan/pagePredictiveWorkPlan',
+          delete: '/eam/maintenanceStandard/delete',
+          deleteBatch: '/eam/maintenanceStandard/deleteBatch',
+          versionTakeEffect: '/eam/maintenanceStandard/versionTakeEffect'
+        }
+      }
+    },
+    methods: {
+      clickThenSelect(record) {
+        return {
+          on: {
+            click: () => {
+              this.onSelectChange(record.id.split(','), [record])
+            }
+          }
+        }
+      },
+      onClearSelected() {
+        this.selectedRowKeys = []
+        this.selectionRows = []
+        this.planId = ''
+        this.equipmentId = ''
+        this.isAdd = false
+      },
+      onSelectChange(selectedRowKeys, selectionRows) {
+        this.selectedRowKeys = selectedRowKeys
+        this.selectionRows = selectionRows
+        this.planId = this.selectedRowKeys[0]
+        this.equipmentId = selectionRows[0].equipment_id
+        this.isAdd = true
+      },
+
+      onChange(e) {
+        this.queryParam.status = e.target.value
+        this.loadData()
+      },
+
+      handleEdit: function(record) {
+        this.$refs.modalForm.edit(record)
+        this.$refs.modalForm.title = '缂栬緫'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.isRevise = false
+      },
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '鏂板'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.isRevise = false
+      },
+
+      //鍗囩増
+      handleRevise: function(record) {
+        this.$refs.modalForm.edit(record)
+        this.$refs.modalForm.title = '淇濆吇鏍囧噯鐗堟湰鍗囩骇'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.isRevise = true
+      },
+
+      //鐢熸晥
+      handleTakeEffect(record) {
+        const that = this
+        that.confirmLoading = true
+        this.$confirm({
+          title: '鏃ュ父淇濆吇鏍囧噯鐗堟湰鐢熸晥锛�',
+          content: '鎻愮ず锛氱増鏈敓鏁堝悗涓婁竴鐗堟湰灏嗚嚜鍔ㄥけ鏁堬紝璇疯皑鎱庢搷浣滐紒',
+          okText: '纭',
+          cancelText: '鍙栨秷',
+          onOk() {
+            requestPut(that.url.versionTakeEffect, {
+              id: record.id,
+              num: record.num,
+              versionStatus: '2'
+            }).then((res) => {
+              if (res.success) {
+                that.$message.success('鐗堟湰鐢熸晥鎴愬姛锛�')
+                that.loadData(1)
+              } else {
+                that.$message.warning('鐗堟湰鐢熸晥澶辫触锛�')
+              }
+            }).finally(() => {
+              that.confirmLoading = false
+            })
+          }
+        })
+      },
+
+      searchReset() {
+        this.loadData(1)
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+
+  .table-operator .ant-btn {
+    margin: 10px 8px 8px 10px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/eam/common/JSelectMaintenanceStandardSafetyRequirementModal.vue b/src/views/eam/common/JSelectMaintenanceStandardSafetyRequirementModal.vue
new file mode 100644
index 0000000..ffd40fb
--- /dev/null
+++ b/src/views/eam/common/JSelectMaintenanceStandardSafetyRequirementModal.vue
@@ -0,0 +1,261 @@
+<template>
+  <!--鏀寔鍏ㄥ睆缂╂斁-->
+  <a-modal
+    :visible='visible'
+    :title='title'
+    switchFullscreen
+    @ok='handleSubmit'
+    @cancel='close'
+    style='top:50px'
+    cancelText='鍏抽棴'
+    :width='1050'
+  >
+    <a-card :bordered='false'>
+      <div class='table-page-search-wrapper'>
+        <a-form
+          layout='inline'
+          @keyup.enter.native='searchQuery'
+        >
+          <a-row :gutter='24'>
+            <a-col
+              :md='8'
+              :sm='6'
+            >
+              <a-form-item label='鍗遍櫓婧愮紪鐮�'>
+                <a-input
+                  placeholder='璇疯緭鍏ュ嵄闄╂簮缂栫爜'
+                  v-model='queryParam.num'
+                />
+              </a-form-item>
+            </a-col>
+            <a-col :md='3'>
+              <span
+                style='float: left;overflow: hidden;'
+                class='table-page-search-submitButtons'
+              >
+                <a-button
+                  type='primary'
+                  @click='searchQuery'
+                  icon='search'
+                >鏌ヨ</a-button>
+                <a-button
+                  @click='searchReset'
+                  icon='reload'
+                  style='margin-left: 10px'
+                >閲嶇疆</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <a-table
+        ref='table'
+        :scroll='scrollTrigger'
+        size='middle'
+        rowKey='id'
+        bordered
+        :columns='columns'
+        :dataSource='dataSource'
+        :pagination='ipagination'
+        :rowSelection='rowSelection'
+        :loading='loading'
+        @change='handleTableChange'
+      >
+
+      </a-table>
+    </a-card>
+  </a-modal>
+</template>
+
+<script>
+import { filterObj } from '@/utils/util'
+import { getAction } from '@/api/manage'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+
+export default {
+  name: 'JSelectMaintenanceStandardSafetyRequirementModal',
+  mixins: [JeecgListMixin],
+  components: {},
+  props: {},
+  data() {
+    return {
+      queryParam: {},
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          width: 50,
+          align: 'center',
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1
+          }
+        },
+        {
+          title: '鍗遍櫓婧愮紪鐮�',
+          align: 'center',
+          dataIndex: 'num'
+        },
+
+        {
+          title: '鍗遍櫓婧�',
+          align: 'center',
+          dataIndex: 'name'
+        },
+        {
+          title: '鍗遍櫓鎻忚堪',
+          align: 'center',
+          dataIndex: 'description'
+        },
+        {
+          title: '闃叉帶鎺柦',
+          align: 'center',
+          dataIndex: 'measure'
+        },
+      ],
+      selectedRowKeys: [],
+      oldSelectRows: [],
+      scrollTrigger: {},
+      dataSource: [],
+      selectionRows: [],
+      title: '鏍规嵁鏌ヨ缁撴灉閫夋嫨鍗遍櫓闃叉帶',
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['5', '10', '30', '50', '100'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 鍏�' + total + '鏉�'
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0
+      },
+      isorter: {
+        column: 'num',
+        order: 'desc'
+      },
+      visible: false,
+      loading: false,
+      url: {
+        list: '/eam/riskPrevention/list'
+      }
+    }
+  },
+  computed: {
+    rowSelection() {
+      return {
+        type: 'checkbox',
+        onChange: (selectedRowKeys, selectedRows) => {
+          this.selectedRowKeys = selectedRowKeys
+          this.onSelectChange(selectedRows)
+        },
+        getCheckboxProps: record => ({
+          props: {
+            disabled: record.distable
+          }
+        }),
+        selectedRowKeys: this.selectedRowKeys
+      }
+    }
+  },
+
+  methods: {
+
+    async loadData(arg) {
+      if (arg === 1) {
+        this.ipagination.current = 1
+      }
+      let that = this
+      this.loading = true
+      let params = this.getQueryParams()//鏌ヨ鏉′欢
+      await getAction(this.url.list, params).then((res) => {
+        if (res.success) {
+          for (let i = 0; i < res.result.records.length; i++) {
+            if (that.oldSelectRows.indexOf(res.result.records[i].id) > -1) {
+              res.result.records[i].distable = true
+            } else {
+              res.result.records[i].distable = false
+            }
+          }
+          this.dataSource = res.result.records
+          this.ipagination.total = res.result.total
+        }
+        if (res.code === 510) {
+          this.$message.warning(res.message)
+        }
+        this.loading = false
+      })
+    },
+
+    showModals(oldSelectRows) {
+      this.oldSelectRows = oldSelectRows
+      this.visible = true
+      this.loadData(1)
+    },
+    getQueryParams() {
+      let param = Object.assign({}, this.queryParam, this.isorter)
+      param.field = this.getQueryField()
+      param.pageNo = this.ipagination.current
+      param.pageSize = this.ipagination.pageSize
+      return filterObj(param)
+    },
+    //鏌ヨ鏉′欢澶勭悊
+    getQueryField() {
+      let str = 'id,'
+      for (let a = 0; a < this.columns.length; a++) {
+        str += ',' + this.columns[a].dataIndex
+      }
+      return str
+    },
+    searchReset(num) {
+      let that = this
+      this.queryParam = []
+      if (num !== 0) {
+        that.loadData(1)
+      }
+      that.selectborrowIds = []
+    },
+    close() {
+      this.searchReset(0)
+      this.selectedRowKeys = []
+      this.visible = false
+    },
+    handleTableChange(pagination, filters, sorter) {
+      //TODO 绛涢��
+
+      if (Object.keys(sorter).length > 0) {
+        this.isorter.column = sorter.field
+        this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc'
+      }
+      this.ipagination = pagination
+      this.loadData()
+    },
+    handleSubmit() {
+      this.$bus.$emit('selection2Rows', this.selectionRows)
+      this.searchReset(0)
+      this.close()
+    },
+    onSelectChange(selectionRows) {
+      this.selectionRows = selectionRows
+    },
+    searchQuery() {
+      this.loadData(1)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.ant-table-tbody .ant-table-row td {
+  padding-top: 10px;
+  padding-bottom: 10px;
+}
+
+#components-layout-demo-custom-trigger .trigger {
+  font-size: 18px;
+  line-height: 64px;
+  padding: 0 24px;
+  cursor: pointer;
+  transition: color 0.3s;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/eam/common/MaintenanceStandardPlanningMaterial.vue b/src/views/eam/common/MaintenanceStandardPlanningMaterial.vue
new file mode 100644
index 0000000..a6cc244
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardPlanningMaterial.vue
@@ -0,0 +1,232 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="maintenanceStandardId !='' && isAdd "
+    >鏂板
+    </a-button>
+    <div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+    <maintenance-standard-planning-material-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+      :mainId="maintenanceStandardId"
+    ></maintenance-standard-planning-material-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { getAction, deleteAction } from '@/api/manage'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import MaintenanceStandardPlanningMaterialModal from './MaintenanceStandardPlanningMaterialModal'
+
+  export default {
+    name: 'MaintenanceStandardPlanningMaterial',
+    components: {
+      Tooltip,
+      MaintenanceStandardPlanningMaterialModal
+    },
+    mixins: [JeecgListMixin],
+    props: {
+      maintenanceStandardId: {
+        type: String,
+        required: false
+      },
+      isEdit: {
+        type: Boolean,
+        default: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mounted() {
+
+    },
+    watch: {
+      maintenanceStandardId: function(val) {
+        this.clearList()
+        if (this.maintenanceStandardId) {
+          this.queryParam.maintenanceStandardId = val
+          this.queryParam.delFlag = 0
+          this.loadData(1)
+        }
+      }
+    },
+    data() {
+      return {
+        disableMixinCreated:true,
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 60,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '澶囦欢缂栧彿',
+            dataIndex: 'num',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢鍚嶇О',
+            dataIndex: 'name',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢瑙勬牸',
+            dataIndex: 'specification',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢鍨嬪彿',
+            dataIndex: 'model',
+            align: 'center'
+          },
+          {
+            title: '鍒堕�犲晢',
+            dataIndex: 'constructorName',
+            align: 'center'
+          },
+          {
+            title: '鏁伴噺',
+            dataIndex: 'quantity',
+            align: 'center'
+          },
+          {
+            title: '鍗曚綅',
+            dataIndex: 'unitName',
+            align: 'center'
+          },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align: 'center',
+            fixed: 'right',
+            width: 250,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: '/eam/maintenanceStandardPlanningMaterial/getMaintenanceStandardPlanningMaterialList',
+          delete: '/eam/maintenanceStandardPlanningMaterial/delete'
+        }
+      }
+    },
+
+    methods: {
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '璁″垝鐢ㄦ枡'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.maintenanceStandardId = this.maintenanceStandardId
+      },
+
+      handleDelete: function(id) {
+        if (!this.url.delete) {
+          this.$message.error('璇疯缃畊rl.delete灞炴��!')
+          return
+        }
+        var that = this
+        deleteAction(that.url.delete, { id: id }).then((res) => {
+          if (res.success) {
+            //閲嶆柊璁$畻鍒嗛〉闂
+            that.reCalculatePage(1)
+            that.$message.success(res.message)
+            that.loadData()
+            that.alterFlag = new Date()
+          } else {
+            that.$message.warning(res.message)
+          }
+        })
+      },
+      clearList() {
+        this.dataSource = []
+        this.selectedRowKeys = []
+        this.ipagination.current = 1
+      },
+      loadData(arg) {
+        if (!this.url.list) {
+          this.$message.error('璇疯缃畊rl.list灞炴��!')
+          return
+        }
+        //鍔犺浇鏁版嵁 鑻ヤ紶鍏ュ弬鏁�1鍒欏姞杞界涓�椤电殑鍐呭
+        if (arg === 1) {
+          this.ipagination.current = 1
+        }
+        var params = this.getQueryParams()//鏌ヨ鏉′欢
+        this.loading = true
+        // this.originTargetKeys = [];
+        getAction(this.url.list, params).then((res) => {
+          if (res.success) {
+            this.dataSource = res.result.records || res.result
+
+            if (res.result.total) {
+              this.ipagination.total = res.result.total
+            } else {
+              this.ipagination.total = 0
+            }
+            //update-end---author:zhangyafei    Date:20201118  for锛氶�傞厤涓嶅垎椤电殑鏁版嵁鍒楄〃------------
+          } else {
+            this.$message.warning(res.message)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/common/MaintenanceStandardPlanningMaterialModal.vue b/src/views/eam/common/MaintenanceStandardPlanningMaterialModal.vue
new file mode 100644
index 0000000..3528b30
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardPlanningMaterialModal.vue
@@ -0,0 +1,262 @@
+
+<template>
+  <a-modal
+    :title="title"
+    :width="900"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row style="width: 100%">
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="澶囦欢缂栧彿"
+            >
+              <a-input-search
+                placeholder="璇烽�夋嫨澶囦欢"
+                enter-button
+                @search="onSearchSparePart()"
+                v-decorator="['sparePartNum',validatorRules.sparePartNum]"
+                :read-only="true"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2" >
+            <a-form-item label="澶囦欢鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['sparePartName', validatorRules.sparePartName]" placeholder="璇疯緭鍏ヨ澶囧悕绉�" ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2" >
+            <a-form-item label="澶囦欢鍨嬪彿" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true"  v-decorator="['sparePartModel', validatorRules.sparePartModel]" placeholder="璇疯緭鍏ヨ澶囧瀷鍙�" ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2" >
+            <a-form-item label="澶囦欢瑙勬牸" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true"  v-decorator="['sparePartSpecification', validatorRules.sparePartSpecification]" placeholder="璇疯緭鍏ヨ澶囪鏍�" ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2" >
+            <a-form-item label="鍒堕�犲晢" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true"  v-decorator="['constructorName', validatorRules.constructorName]" placeholder="璇疯緭鍏ュ埗閫犲晢" ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2" >
+            <a-form-item label="鍗曚綅" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true"  v-decorator="['mainUnitName', validatorRules.mainUnitName]" placeholder="璇疯緭鍏ュ崟浣�" ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:3}" 
+              :wrapperCol="{span:21}"
+              label="鏁伴噺"
+            >
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ユ暟閲�"
+                v-decorator="['quantity', validatorRules.quantity]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-spin>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel"
+      >
+        鍏抽棴
+      </a-button>
+      <a-button
+        :disabled="disableSubmit || confirmLoading"
+        :loading="confirmLoading"
+        @click="handleOk"
+        type="primary"
+      >纭畾</a-button>
+    </template>
+
+    <plan-spare-part-select
+      ref="planSparePartSelect"
+      @sendSparePartRecord='sendSparePartRecord'
+    ></plan-spare-part-select>
+
+  </a-modal>
+</template>
+
+<script>
+import pick from 'lodash.pick'
+import { postAction, requestPut } from '@/api/manage'
+import { duplicateCheck } from '@/api/api'
+import PlanSparePartSelect from './PlanSparePartSelect.vue'
+
+
+export default {
+  name: 'MaintenanceStandardPlanningMaterialModal',
+  components: {
+    PlanSparePartSelect
+  },
+  props:{
+    mainId:{
+        type:String,
+        required:false,
+        default:''
+      }
+  },
+  data() {
+    return {
+      title: "鎿嶄綔",
+      visible: false,
+      codeDisable: true,
+      disableSubmit: false,
+      maintenanceStandardId: '',
+      sparePartId: '',
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 6 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 18 },
+      },
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+      validatorRules: {
+        sparePartName: {
+          rules: [
+            { required: true, message: '璇烽�夋嫨澶囦欢!' },
+          ]
+        },
+        quantity: {
+          rules: [
+            { required: true, message: '璇疯緭鍏ユ暟閲�!' },
+          ]
+        }
+      },
+      url: {
+        add: "/eam/maintenanceStandardPlanningMaterial/add",
+        edit: "/eam/maintenanceStandardPlanningMaterial/edit"
+      },
+      //鏂板銆佺紪杈戙�佸垹闄ゃ�佹壒閲忓垹闄ゆ搷浣滄敼鍙樻暟鎹悗鍒锋柊鍏宠仈鐨勭粍浠剁殑鐩戝惉灞炴��
+      alterFlag: "",
+    }
+  },
+  created() {
+  },
+  methods: {
+
+    add() {
+      this.edit({});
+    },
+
+    edit(record) {
+      this.form.resetFields();
+      this.model = Object.assign({}, record);
+      this.visible = true;
+      this.disableSubmit = false;
+      this.$nextTick(() => {
+        this.form.setFieldsValue(pick(this.model,
+          'sparePartNum',
+          'sparePartName',
+          'sparePartModel',
+          'sparePartSpecification',
+          'mainUnitName',
+          'constructorName',
+          'quantity'));
+      });
+      if (record.id) {
+        this.codeDisable = true;
+      } else {
+        this.codeDisable = false;
+      }
+    },
+
+    close() {
+      this.$emit('close');
+      this.visible = false;
+    },
+
+    //淇濆瓨骞舵柊澧炴寜閽Е鍙�
+
+
+    handleOk() {
+      const that = this;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          that.confirmLoading = true;
+          let formData = Object.assign(this.model, values);
+          formData.maintenanceStandardId = this.mainId;
+          formData.sparePartId = this.sparePartId
+          let obj;
+          if (!this.model.id) {
+            obj = postAction(this.url.add, formData);
+          } else {
+            obj = requestPut(this.url.edit, formData, { id: this.model.id });
+          }
+          obj.then((res) => {
+            if (res.success) {
+              that.$message.success(res.message);
+              that.$emit('ok');
+              that.alterFlag = new Date();
+            } else {
+              that.$message.warning(res.message);
+            }
+          }).finally(() => {
+            that.confirmLoading = false;
+            that.close();
+          })
+        }
+      })
+    },
+
+    onSearchSparePart() {
+      this.$refs.planSparePartSelect.list();
+      this.$refs.planSparePartSelect.title = "閫夋嫨澶囦欢";
+    },
+    sendSparePartRecord(data) {
+      let record = data.record;
+      this.sparePartId = record.id;
+      this.form.setFieldsValue({ sparePartId : record.id,sparePartNum: record.num,sparePartName: record.name,sparePartModel: record.model,
+        sparePartSpecification: record.specification,mainUnitId:record.mainUnitId,mainUnitName: record.mainUnitId_dictText,constructorName:record.constructorId_dictText });
+    },
+
+    handleCancel() {
+      this.close()
+    },
+
+  },
+}
+</script>
+
+<style scoped>
+.ant-btn {
+  padding: 0 10px;
+  margin-left: 3px;
+}
+
+.ant-form-item-control {
+  line-height: 0px;
+}
+
+/** 涓昏〃鍗曡闂磋窛 */
+.ant-form .ant-form-item {
+  margin-bottom: 10px;
+}
+
+/** Tab椤甸潰琛岄棿璺� */
+.ant-tabs-content .ant-form-item {
+  margin-bottom: 0px;
+}
+</style>
diff --git a/src/views/eam/common/MaintenanceStandardSafetyRequirement.vue b/src/views/eam/common/MaintenanceStandardSafetyRequirement.vue
new file mode 100644
index 0000000..fac3031
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardSafetyRequirement.vue
@@ -0,0 +1,215 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="maintenanceStandardId !='' && isAdd "
+    >鏂板
+    </a-button>
+    <div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+    <maintenance-standard-safety-requirement-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></maintenance-standard-safety-requirement-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { getAction, deleteAction } from '@/api/manage'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import MaintenanceStandardSafetyRequirementModal from './MaintenanceStandardSafetyRequirementModal'
+
+  export default {
+    name: 'MaintenanceStandardPlanningMaterial',
+    components: {
+      Tooltip,
+      MaintenanceStandardSafetyRequirementModal
+    },
+    mixins: [JeecgListMixin],
+    props: {
+      maintenanceStandardId: {
+        type: String,
+        required: false
+      },
+      isEdit: {
+        type: Boolean,
+        default: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mounted() {
+    },
+    watch: {
+      maintenanceStandardId: function(val) {
+        this.clearList()
+        if (this.maintenanceStandardId) {
+          this.queryParam.maintenanceStandardId = val
+          this.queryParam.delFlag = 0
+          this.loadData(1)
+        }
+      }
+    },
+    data() {
+      return {
+        disableMixinCreated:true,
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 100,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鍗遍櫓婧愮紪鐮�',
+            align: 'center',
+            dataIndex: 'num'
+          },
+
+          {
+            title: '鍗遍櫓婧�',
+            align: 'center',
+            dataIndex: 'name'
+          },
+          {
+            title: '鍗遍櫓鎻忚堪',
+            align: 'center',
+            dataIndex: 'description'
+          },
+          {
+            title: '闃叉帶鎺柦',
+            align: 'center',
+            dataIndex: 'measure'
+          },
+          {
+            title: '鎿嶄綔',
+            align: 'center',
+            dataIndex: 'action',
+            scopedSlots: {
+              customRender: 'action'
+            }
+          }
+        ],
+        url: {
+          list: '/eam/maintenanceStandardSafetyRequirement/getMaintenanceStandardSafetyRequirementList',
+          delete: '/eam/maintenanceStandardSafetyRequirement/delete'
+        }
+      }
+    },
+
+    methods: {
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '鍗遍櫓闃叉帶'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.maintenanceStandardId = this.maintenanceStandardId
+      },
+
+      handleDelete: function(id) {
+        if (!this.url.delete) {
+          this.$message.error('璇疯缃畊rl.delete灞炴��!')
+          return
+        }
+        var that = this
+        deleteAction(that.url.delete, { id: id }).then((res) => {
+          if (res.success) {
+            //閲嶆柊璁$畻鍒嗛〉闂
+            that.reCalculatePage(1)
+            that.$message.success(res.message)
+            that.loadData()
+            that.alterFlag = new Date()
+          } else {
+            that.$message.warning(res.message)
+          }
+        })
+      },
+      clearList() {
+        this.dataSource = []
+        this.selectedRowKeys = []
+        this.ipagination.current = 1
+      },
+      loadData(arg) {
+        if (!this.url.list) {
+          this.$message.error('璇疯缃畊rl.list灞炴��!')
+          return
+        }
+        //鍔犺浇鏁版嵁 鑻ヤ紶鍏ュ弬鏁�1鍒欏姞杞界涓�椤电殑鍐呭
+        if (arg === 1) {
+          this.ipagination.current = 1
+        }
+        var params = this.getQueryParams()//鏌ヨ鏉′欢
+        this.loading = true
+        getAction(this.url.list, params).then((res) => {
+          if (res.success) {
+            this.dataSource = res.result.records || res.result
+
+            if (res.result.total) {
+              this.ipagination.total = res.result.total
+            } else {
+              this.ipagination.total = 0
+            }
+            //update-end---author:zhangyafei    Date:20201118  for锛氶�傞厤涓嶅垎椤电殑鏁版嵁鍒楄〃------------
+          } else {
+            this.$message.warning(res.message)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/common/MaintenanceStandardSafetyRequirementModal.vue b/src/views/eam/common/MaintenanceStandardSafetyRequirementModal.vue
new file mode 100644
index 0000000..ae16ff1
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardSafetyRequirementModal.vue
@@ -0,0 +1,259 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1050"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+
+      </a-form>
+    </a-spin>
+
+    <a-button
+      type="primary"
+      :style="{ marginRight: '8px',marginBottom:'8px' }"
+      :loading="confirmLoading"
+      @click="selectSafetyRequirement()"
+    >鍗遍櫓闃叉帶</a-button>
+    <a-table
+      ref="table"
+      bordered
+      size="middle"
+      rowKey='id'
+      :columns="columns"
+      :dataSource="dataSource"
+    >
+
+      <span
+        slot="action"
+        slot-scope="text, record, index"
+      >
+        <a-popconfirm
+          title="纭畾鍒犻櫎鍚�?"
+          @confirm="() => handleDelete(text,record, index)"
+        >
+          <a>鍒犻櫎</a>
+        </a-popconfirm>
+      </span>
+    </a-table>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel"
+      >
+        鍏抽棴
+      </a-button>
+      <a-button
+        :disabled="disableSubmit || confirmLoading"
+        :loading="confirmLoading"
+        @click="handleOk"
+        type="primary"
+      >纭畾</a-button>
+    </template>
+    <j-select-maintenance-standard-safety-requirement-modal ref="maintenanceStandardSafetyRequirementModalForm"></j-select-maintenance-standard-safety-requirement-modal>
+  </a-modal>
+</template>
+
+<script>
+import pick from 'lodash.pick'
+import { postAction, requestPut } from '@/api/manage'
+import { duplicateCheck } from '@/api/api'
+import JSelectMaintenanceStandardSafetyRequirementModal from './JSelectMaintenanceStandardSafetyRequirementModal'
+
+export default {
+  name: 'MaintenanceStandardSafetyRequirementModal',
+  components: {
+    JSelectMaintenanceStandardSafetyRequirementModal
+  },
+  data() {
+    return {
+      title: "鎿嶄綔",
+      visible: false,
+      codeDisable: true,
+      disableSubmit: false,
+      maintenanceStandardId: '',
+      dataSource: [],
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 6 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 18 },
+      },
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          align: 'center',
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1
+          },
+          width: 50,
+        },
+        {
+          title: '鍗遍櫓婧愮紪鐮�',
+          align: 'center',
+          dataIndex: 'num'
+        },
+
+        {
+          title: '鍗遍櫓婧�',
+          align: 'center',
+          dataIndex: 'name'
+        },
+        {
+          title: '鍗遍櫓鎻忚堪',
+          align: 'center',
+          dataIndex: 'description'
+        },
+        {
+          title: '闃叉帶鎺柦',
+          align: 'center',
+          dataIndex: 'measure'
+        },
+        {
+          title: '鎿嶄綔',
+          align: 'center',
+          dataIndex: 'action',
+          scopedSlots: {
+            customRender: 'action'
+          },
+        }
+      ],
+      url: {
+        add: "/eam/maintenanceStandardSafetyRequirement/add",
+        edit: "/eam/maintenanceStandardSafetyRequirement/edit"
+      },
+      //鏂板銆佺紪杈戙�佸垹闄ゃ�佹壒閲忓垹闄ゆ搷浣滄敼鍙樻暟鎹悗鍒锋柊鍏宠仈鐨勭粍浠剁殑鐩戝惉灞炴��
+      alterFlag: "",
+    }
+  },
+  created() {
+  },
+
+  mounted() {
+    this.$bus.$on('selection2Rows', (data) => {
+      for (let i = 0; i < data.length; i++) {
+        this.dataSource.push({
+          id: data[i].id,
+          num: data[i].num,
+          name: data[i].name,
+          description: data[i].description,
+          measure: data[i].measure,
+        })
+      }
+    })
+  },
+  methods: {
+
+    add() {
+      this.dataSource = [];
+      this.edit({});
+    },
+
+    edit(record) {
+      this.form.resetFields();
+      this.model = Object.assign({}, record);
+      this.visible = true;
+      this.disableSubmit = false;
+      if (record.id) {
+        this.codeDisable = true;
+      } else {
+        this.codeDisable = false;
+      }
+    },
+
+    close() {
+      this.$emit('close');
+      this.visible = false;
+    },
+
+    //淇濆瓨骞舵柊澧炴寜閽Е鍙�
+
+
+    handleOk() {
+      const that = this;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          that.confirmLoading = true;
+          let formData = Object.assign(this.model, values);
+          formData.maintenanceStandardId = this.maintenanceStandardId;
+          formData.riskPreventionList = this.dataSource;
+          let obj;
+          if (!this.model.id) {
+            obj = postAction(this.url.add, formData);
+          } else {
+            obj = requestPut(this.url.edit, formData, { id: this.model.id });
+          }
+          obj.then((res) => {
+            if (res.success) {
+              that.$message.success(res.message);
+              that.$emit('ok');
+              that.alterFlag = new Date();
+            } else {
+              that.$message.warning(res.message);
+            }
+          }).finally(() => {
+            that.confirmLoading = false;
+            that.close();
+          })
+        }
+      })
+    },
+
+    handleCancel() {
+      this.close()
+    },
+
+    handleDelete(text, record, index) {
+      this.dataSource.splice(index, 1);
+    },
+
+    selectSafetyRequirement: function () {
+      let ids = [];
+      for (let i = 0; i < this.dataSource.length; i++) {
+        ids.push(this.dataSource[i].id);
+      }
+      this.$refs.maintenanceStandardSafetyRequirementModalForm.showModals(ids);
+      this.$refs.maintenanceStandardSafetyRequirementModalForm.title = '閫夋嫨鍗遍櫓闃叉帶';
+      this.$refs.maintenanceStandardSafetyRequirementModalForm.disableSubmit = false;
+    },
+
+  },
+}
+</script>
+
+<style scoped>
+.ant-btn {
+  padding: 0 10px;
+  margin-left: 3px;
+}
+
+.ant-form-item-control {
+  line-height: 0px;
+}
+
+/** 涓昏〃鍗曡闂磋窛 */
+.ant-form .ant-form-item {
+  margin-bottom: 10px;
+}
+
+/** Tab椤甸潰琛岄棿璺� */
+.ant-tabs-content .ant-form-item {
+  margin-bottom: 0px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/eam/common/MaintenanceStandardWorkInstruction.vue b/src/views/eam/common/MaintenanceStandardWorkInstruction.vue
new file mode 100644
index 0000000..4cd78ec
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardWorkInstruction.vue
@@ -0,0 +1,379 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="maintenanceStandardId !='' && isAdd "
+    >鏂板</a-button>
+    <div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="size"
+          slot-scope="text"
+          class="error"
+        >
+          {{sizeConvert(text)}}
+        </span>
+        <!-- <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span> -->
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+
+          <Tooltip
+            placement="top"
+            title="棰勮鍥剧墖"
+          >
+            <img
+              v-if="record.upload.path && (record.upload.format.toLowerCase()=='jpg'||record.upload.format.toLowerCase()=='bmp'||record.upload.format.toLowerCase()=='png'||record.upload.format.toLowerCase()=='jpeg'||record.upload.format.toLowerCase()=='gif')"
+              width="30"
+              height="14"
+              border="1"
+              draggable="false"
+              preview="1"
+              :preview-text="''"
+              :src="record.upload.src"
+            />
+          </Tooltip>
+
+          <a
+            v-if="record.upload.path && record.upload.format.toLowerCase()=='pdf'"
+            href="javascript:;"
+            @click="view(record)"
+          >
+            棰勮
+          </a>
+
+          <a-divider
+            v-if="record.upload.path && (record.upload.format.toLowerCase()=='jpg'||record.upload.format.toLowerCase()=='bmp'||record.upload.format.toLowerCase()=='png'||record.upload.format.toLowerCase()=='jpeg'||record.upload.format.toLowerCase()=='gif'||record.upload.format.toLowerCase()=='pdf')"
+            type="vertical"
+          />
+
+          <a
+            href="javascript:;"
+            @click="handleDownload(record)"
+          >涓嬭浇</a>
+
+          <a-divider type="vertical" />
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+
+        </span>
+      </a-table>
+    </div>
+    <pdf-view ref="pdfview"></pdf-view>
+    <maintenance-standard-work-instruction-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></maintenance-standard-work-instruction-modal>
+  </a-card>
+</template>
+
+<script>
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import { getAction, deleteAction, downFile } from '@/api/manage'
+import Tooltip from 'ant-design-vue/es/tooltip'
+import MaintenanceStandardWorkInstructionModal from './MaintenanceStandardWorkInstructionModal'
+
+import JInput from '@/components/jeecg/JInput'
+import JEllipsis from "@/components/jeecg/JEllipsis";
+
+import { preview } from 'vue-photo-preview'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import Vue from 'vue'
+import PdfView from '@views/common/PdfView'
+import { getFileAccessHttpUrl } from '@/api/manage';
+import store from '@/store/'
+
+export default {
+  name: "MaintenanceStandardWorkInstruction",
+  components: {
+    Tooltip,
+    MaintenanceStandardWorkInstructionModal,
+    JInput,
+    JEllipsis,
+    PdfView,
+    preview,
+  },
+  mixins: [JeecgListMixin],
+  props: {
+    maintenanceStandardId: {
+      type: String,
+      required: false
+    },
+    isEdit: {
+      type: Boolean,
+      default: false
+    },
+    isAdd: {
+      type: Boolean,
+      default: false
+    },
+    isDel: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted() {
+  },
+  watch: {
+    maintenanceStandardId: function(val) {
+      this.clearList()
+      if (this.maintenanceStandardId) {
+        this.queryParam.maintenanceStandardId = val
+        this.queryParam.delFlag = 0
+        this.loadData(1)
+      }
+    }
+  },
+  data() {
+    return {
+      disableMixinCreated:true,
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          width: 100,
+          align: "center",
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1;
+          }
+        },
+        {
+          title: '鏂囨。缂栫爜',
+          align: 'center',
+          dataIndex: 'num'
+        },
+
+        {
+          title: '鏂囨。鍚嶇О',
+          align: 'center',
+          dataIndex: 'name'
+        },
+        {
+          title: '鏂囨。绫诲瀷',
+          align: 'center',
+          dataIndex: 'typeName'
+        },
+        {
+          title: '鏂囨。澶у皬',
+          align: 'center',
+          dataIndex: 'size',
+          scopedSlots: { customRender: 'size' },
+        },
+        {
+          title: '鎿嶄綔',
+          align: 'center',
+          dataIndex: 'action',
+          scopedSlots: {
+            customRender: 'action'
+          },
+        }
+      ],
+      url: {
+        list: "/eam/maintenanceStandardWorkInstruction/getMaintenanceStandardWorkInstructionList",
+        delete: "/eam/maintenanceStandardWorkInstruction/delete",
+        urlDownload: window._CONFIG['staticDomainURL'],
+        download: '/sys/upload/downloadFile',
+      },
+    }
+  },
+
+  methods: {
+    handleAdd: function () {
+      this.$refs.modalForm.add();
+      this.$refs.modalForm.title = "浣滀笟鎸囧涔�";
+      this.$refs.modalForm.disableSubmit = false;
+      this.$refs.modalForm.maintenanceStandardId = this.maintenanceStandardId
+    },
+
+    handleDelete: function (id) {
+      if (!this.url.delete) {
+        this.$message.error("璇疯缃畊rl.delete灞炴��!")
+        return
+      }
+      var that = this;
+      deleteAction(that.url.delete, { id: id }).then((res) => {
+        if (res.success) {
+          //閲嶆柊璁$畻鍒嗛〉闂
+          that.reCalculatePage(1)
+          that.$message.success(res.message);
+          that.loadData();
+          that.alterFlag = new Date();
+        } else {
+          that.$message.warning(res.message);
+        }
+      });
+    },
+    clearList() {
+      this.dataSource = []
+      this.selectedRowKeys = []
+      this.ipagination.current = 1
+    },
+    loadData(arg) {
+      if (!this.url.list) {
+        this.$message.error("璇疯缃畊rl.list灞炴��!")
+        return
+      }
+      //鍔犺浇鏁版嵁 鑻ヤ紶鍏ュ弬鏁�1鍒欏姞杞界涓�椤电殑鍐呭
+      if (arg === 1) {
+        this.ipagination.current = 1;
+      }
+      var params = this.getQueryParams();//鏌ヨ鏉′欢
+      this.loading = true;
+      getAction(this.url.list, params).then((res) => {
+        if (res.success) {
+          for (let i = 0; i < res.result.records.length; i++) {
+            let r = res.result.records[i].upload;
+            r.src = this.getSrc(res.result.records[i].upload);
+          }
+          this.dataSource = res.result.records || res.result;
+          if (res.result.total) {
+            this.ipagination.total = res.result.total;
+          } else {
+            this.ipagination.total = 0;
+          }
+          //update-end---author:zhangyafei    Date:20201118  for锛氶�傞厤涓嶅垎椤电殑鏁版嵁鍒楄〃------------
+        } else {
+          this.$message.warning(res.message)
+        }
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+
+    handleDownload(record) {
+      downFile(this.url.download, { id: record.upload.id }).then((res) => {
+        if (!res) {
+          this.$message.warning('鏂囦欢涓嬭浇澶辫触')
+          return
+        } else {
+          let fileName = record.name;
+          if (typeof window.navigator.msSaveBlob !== 'undefined') {
+            window.navigator.msSaveBlob(new Blob([res]), fileName);
+          } else {
+            let url = window.URL.createObjectURL(new Blob([res]));
+            let link = document.createElement('a');
+            link.style.display = 'none';
+            link.href = url;
+            link.setAttribute('download', fileName);
+            document.body.appendChild(link);
+            link.click()
+            document.body.removeChild(link) //涓嬭浇瀹屾垚绉婚櫎鍏冪礌
+            window.URL.revokeObjectURL(url) //閲婃斁鎺塨lob瀵硅薄
+          }
+        }
+      })
+    },
+
+    //鎷艰src
+    getSrc(record) {
+
+      if (!record.path) {
+        return '';
+      }
+      //鏈湴锛歭ocal\Minio锛歮inio\闃块噷浜戯細alioss
+      if (record.uploadType == 'local') {
+
+        let ssoLoginFlag = Vue.ls.get("ssoLoginFlag");
+        let deployMode = Vue.ls.get("deployMode");
+
+        if (ssoLoginFlag && deployMode == "container") {
+          var baseProject = Vue.ls.get("baseProject");
+          console.log("baseProject==>" + baseProject)
+
+          var hostname = window.location.protocol + "//" + window.location.host;
+          var url = hostname + '/' + baseProject + '/sys/common/static';
+          return getFileAccessHttpUrl(record.path + record.encodeName, url, window._CONFIG['hyperTextTransfer'])
+        } else {
+          //鏍规嵁鍙戝竷鐘舵�佷慨鏀筯ttps 鎴� http
+          return getFileAccessHttpUrl(record.path + record.encodeName, this.url.urlDownload, window._CONFIG['hyperTextTransfer'])
+        }
+
+      } else if (record.uploadType == 'alioss') {
+
+        const OSS = require('ali-oss')
+        const client = new OSS({
+          // region浠ユ澀宸炰负渚嬶紙oss-cn-hangzhou锛夛紝鍏朵粬region鎸夊疄闄呮儏鍐靛~鍐欍��
+          region: window._CONFIG['region'],
+          // 闃块噷浜戜富璐﹀彿AccessKey鎷ユ湁鎵�鏈堿PI鐨勮闂潈闄愶紝椋庨櫓寰堥珮銆傚己鐑堝缓璁偍鍒涘缓骞朵娇鐢≧AM璐﹀彿杩涜API璁块棶鎴栨棩甯歌繍缁达紝璇风櫥褰昍AM鎺у埗鍙板垱寤篟AM璐﹀彿銆�
+          accessKeyId: window._CONFIG['accessKeyId'],
+          accessKeySecret: window._CONFIG['accessKeySecret'],
+          bucket: window._CONFIG['bucket'],
+        })
+        // object-key琛ㄧず浠嶰SS涓嬭浇鏂囦欢鏃堕渶瑕佹寚瀹氬寘鍚枃浠跺悗缂�鍦ㄥ唴鐨勫畬鏁磋矾寰勶紝渚嬪abc/efg/123.jpg銆�
+        return client.signatureUrl(record.path)
+      }
+    },
+
+
+    sizeConvert(limit) {
+      var size = "";
+      if (limit < 0.1 * 1024) {
+        size = parseFloat(limit).toFixed(2) + "B";//灏忎簬0.1KB锛屽垯杞寲鎴怋
+      } else if (limit < 0.1 * 1024 * 1024) {
+        size = (parseFloat(limit) / 1024).toFixed(2) + "KB";//灏忎簬0.1MB锛屽垯杞寲鎴怟B
+      } else if (limit < 0.1 * 1024 * 1024 * 1024) {
+        size = (parseFloat(limit) / (1024 * 1024)).toFixed(2) + "MB";//灏忎簬0.1GB锛屽垯杞寲鎴怣B
+      } else {
+        size = (parseFloat(limit) / (1024 * 1024 * 1024)).toFixed(2) + "GB";//鍏朵粬杞寲鎴怗B
+      }
+      var sizeStr = size + "";//杞垚瀛楃涓�
+      var index = sizeStr.indexOf(".");//鑾峰彇灏忔暟鐐瑰鐨勭储寮�
+      var dou = sizeStr.substr(index + 1, 2);//鑾峰彇灏忔暟鐐瑰悗涓や綅鐨勫��
+      if (dou == "00") {//鍒ゆ柇鍚庝袱浣嶆槸鍚︿负00锛屽鏋滄槸鍒欏垹闄�00
+        return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2);
+      }
+      return size;
+    },
+
+    view(record) {
+      this.$refs.pdfview.showPdf(record.upload.src);
+    },
+  }
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/common/MaintenanceStandardWorkInstructionModal.vue b/src/views/eam/common/MaintenanceStandardWorkInstructionModal.vue
new file mode 100644
index 0000000..3263783
--- /dev/null
+++ b/src/views/eam/common/MaintenanceStandardWorkInstructionModal.vue
@@ -0,0 +1,344 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="850"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row :gutter="24">
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:4}"
+              :wrapperCol="{span:18}"
+              label="鏂囨。缂栫爜"
+            >
+              <a-input
+                :disabled="disableSubmit"
+                placeholder="璇疯緭鍏ユ枃妗g紪鐮�"
+                v-decorator="['num', validatorRules.num ]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:3}"
+              :wrapperCol="{span:21}"
+              label="鏂囦欢绫诲瀷"
+            >
+              <a-radio-group
+                v-for="(item,index) in fileTypes"
+                :key="index"
+                button-style="solid"
+                v-decorator="['fileType', validatorRules.fileType ]"
+                :disabled="disableSubmit"
+              >
+
+                <a-radio-button :value="item.value">
+                  {{item.text}}
+                </a-radio-button>
+              </a-radio-group>
+
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:4}"
+              :wrapperCol="{span:18}"
+              label="鏂囦欢涓婁紶"
+            >
+              <a-upload-dragger
+                name="file"
+                :customRequest="customRequest"
+                @change="handleChange"
+                :file-list="fileList"
+                :multiple="false"
+              >
+                <p class="ant-upload-drag-icon">
+                  <a-icon type="inbox" />
+                </p>
+                <p class="ant-upload-text">
+                  鐐瑰嚮涓婁紶鎴栨嫋鎷芥枃浠惰嚦璇ュ尯鍩熻繘琛屼笂浼�
+                </p>
+                <p class="ant-upload-hint">
+                  浠呮敮鎸佸崟鏂囦欢涓婁紶
+                </p>
+              </a-upload-dragger>
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:4}"
+              :wrapperCol="{span:18}"
+              label="鏂囦欢鍚嶇О"
+            >
+              <a-input
+                :disabled="true "
+                placeholder="璇疯緭鍏ユ枃浠跺悕绉�"
+                v-decorator="['name', validatorRules.name ]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+
+        <a-row :gutter="24">
+          <a-col :span="24">
+            <a-form-item
+              :labelCol="{span:4}"
+              :wrapperCol="{span:18}"
+              label="鏂囦欢鎻忚堪"
+            >
+              <a-textarea
+                :disabled="disableSubmit"
+                placeholder="璇疯緭鍏ユ枃浠舵弿杩�"
+                allow-clear
+                v-decorator="['description', validatorRules.description]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+ 
+<script>
+import { getAction, postAction, postFileAction } from '@/api/manage'
+import Vue from 'vue'
+import JInput from '@/components/jeecg/JInput'
+import Tooltip from 'ant-design-vue/es/tooltip'
+import JEllipsis from "@/components/jeecg/JEllipsis";
+import { ajaxGetDictItems } from '@/api/api'
+import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
+
+export default {
+  name: "UploadModel",
+  components: {
+    JInput,
+    Tooltip,
+    JEllipsis,
+  },
+  data() {
+    return {
+      title: "鎿嶄綔",
+      visible: false,
+      disableSubmit: false,
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+      headers: {},
+      validatorRules: {
+        num: {
+          rules: [
+            { required: true, message: '璇疯緭鍏ョ紪鐮侊紒' },
+            { min: 0, max: 150, message: '鏈�闀� 30 涓瓧绗�', trigger: 'blur' },
+          ]
+        },
+        fileType: {
+          rules: [
+            { required: true, message: '璇疯緭鍏ラ�夋嫨绫诲瀷锛�' },
+          ]
+        },
+        name: {
+          rules: [
+            { required: true, message: '璇疯緭鍏ュ悕绉帮紒' },
+          ]
+        },
+      },
+      url: {
+        add: "/eam/maintenanceStandardWorkInstruction/add",
+        edit: "/eam/maintenanceStandardWorkInstruction/edit",
+        listByBusIdAndBusType: "/system/sysUploadRela/listByBusIdAndBusType",
+      },
+      //鐢ㄤ簬灞曠ず鏂囦欢
+      fileList: [],
+      fileObject: {},
+      fileTypes: [],
+      //鐢ㄤ簬鍒ゆ柇闄勪欢鐨勭姸鎬�  add锛氭柊澧為〉闈㈢殑闄勪欢  edit锛氱紪杈戦〉闈㈢殑闄勪欢涓鸿淇敼i   editUpdate锛氱紪杈戦〉闈㈢殑闄勪欢琚慨鏀�
+      isFileChange: false,
+      uploadId: '',
+      maintenanceStandardId: '',
+    }
+  },
+
+  methods: {
+    customRequest(val) {
+      if (this.fileList.length == 0) {
+        this.fileObject = val;
+      }
+    },
+
+    handleChange(info) {
+      //榛樿缁欓檮浠剁姸鎬侊紝浠呮帶鍒舵牱寮�
+      let file = info.file;
+      //鏂囦欢鏇存敼锛屾爣璁版洿鏂�
+      if (this.model.id) {
+        this.isFileChange = true;
+      }
+      //鍒犻櫎
+      if (file.status == "removed") {
+        this.fileList = [];
+        this.fileObject.file = {};
+        this.form.setFieldsValue({ name: '' });
+        return false;
+      }
+      //鍗曟枃浠舵帶鍒�
+      if (this.fileList.length > 0) {
+        this.$message.warning("褰撳墠浠呭厑璁镐笂浼犱竴涓枃浠讹紒");
+        return false;
+      }
+      file.status = 'done';
+      //椤甸潰灞曠ず涓婁紶鏂囦欢
+      this.fileList.push(file);
+      this.form.setFieldsValue({ name: file.name });
+    },
+
+    add() {
+      this.edit({})
+    },
+
+    edit(record) {
+      let that = this;
+      that.visible = true;
+      that.isFileChange = false;
+      that.model = Object.assign({}, record);
+      that.fileList = [];
+      that.form.resetFields();
+      that.uploadId = ''
+      if (record.isNoPhotoFlag) {
+        //鑾峰彇褰撳墠鏂囦欢瀵瑰簲闄勪欢
+        getAction(that.url.listByBusIdAndBusType, { busId: record.id, busType: 'maintenance_standard_work_instruction' }).then((res) => {
+          if (res.success) {
+            for (let i = 0; i < res.result.length; i++) {
+              that.fileList.push({
+                uid: res.result[i].upload.id,
+                name: res.result[i].upload.name,
+                status: "done",
+              })
+              that.$nextTick(() => {
+                that.form.setFieldsValue({ name: res.result[i].upload.name });
+              });
+            }
+          }
+        })
+      }
+    },
+
+    close() {
+      this.$emit('close');
+      this.visible = false;
+    },
+
+    handleOk() {
+      const that = this;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      that.form.validateFields((err, values) => {
+        if (JSON.stringify(that.fileObject.file) == '{}' && that.uploadId == '' && that.fileList.length == 0) {
+          that.$message.warning("璇蜂笂浼犳枃浠�");
+          return false
+        }
+        if (!err) {
+          that.confirmLoading = true;
+          let httpurl = ''
+          let method = ''
+          if (!that.model.id) {
+            httpurl += that.url.add;
+            method = 'post';
+          } else {
+            httpurl += that.url.edit;
+            method = 'put';
+          }
+          let formData = Object.assign(that.model, values);
+
+          formData.type = "maintenance_standard_work_instruction";
+          formData.uploadId = that.uploadId;
+          // formData.fileType = "7";//鏂囦欢绫诲瀷  7锛氬浘鐗�
+          formData.maintenanceStandardId = this.maintenanceStandardId;
+          var saveDate = new FormData();
+
+          formData.isFileChange = that.isFileChange;
+
+          saveDate.append("file", that.fileObject.file);
+          saveDate.append('data', JSON.stringify(formData));
+
+          postFileAction(httpurl, saveDate, this.headers).then((res) => {
+            if (res.success) {
+              that.$message.success(res.message);
+              that.$emit('ok');
+            } else {
+              that.$message.warning(res.message);
+            }
+          }).finally(() => {
+            that.confirmLoading = false;
+            that.close();
+          })
+        }
+      }).catch((e) => { })
+    },
+
+    handleCancel() {
+      this.close();
+    },
+    initFileTypes() {
+      ajaxGetDictItems("common_upload_type", null).then((res) => {
+        if (res.success) {
+          this.fileTypes = res.result;
+        }
+      })
+    },
+
+  },
+
+  created() {
+    this.initFileTypes();
+    const token = Vue.ls.get(ACCESS_TOKEN);
+    const tenantid = Vue.ls.get(TENANT_ID)
+    this.headers = {
+      'Content-Type': 'multipart/form-data',
+      "X-Access-Token": token,
+      'X-Access-Tenant': tenantid
+    };
+  },
+}
+</script>
+<style scoped>
+.ant-btn {
+  padding: 0 10px;
+  margin-left: 3px;
+}
+
+.ant-form-item-control {
+  line-height: 0px;
+}
+
+/** 涓昏〃鍗曡闂磋窛 */
+.ant-form .ant-form-item {
+  margin-bottom: 10px;
+}
+
+/** Tab椤甸潰琛岄棿璺� */
+.ant-tabs-content .ant-form-item {
+  margin-bottom: 0px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/eam/common/PlanSparePartSelect.vue b/src/views/eam/common/PlanSparePartSelect.vue
new file mode 100644
index 0000000..f77176d
--- /dev/null
+++ b/src/views/eam/common/PlanSparePartSelect.vue
@@ -0,0 +1,234 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1000"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <!-- 鏌ヨ鍖哄煙 -->
+        <div class="table-page-search-wrapper">
+          <a-form
+            layout="inline"
+            @keyup.enter.native="searchQuery"
+          >
+            <a-row :gutter="24">
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="澶囦欢缂栫爜">
+                  <j-input
+                    placeholder="璇疯緭鍏ュ浠剁紪鐮�"
+                    v-model="queryParam.num"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="澶囦欢鍚嶇О">
+                  <j-input
+                    placeholder="璇疯緭鍏ュ浠跺悕绉�"
+                    v-model="queryParam.name"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-button
+                  type="primary"
+                  @click="searchQuery"
+                  icon="search"
+                >鏌ヨ</a-button>
+                <a-button
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left:8px;"
+                >閲嶇疆</a-button>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :span="24">
+
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <div style="margin-top:8px;">
+          <a-table
+            ref="table"
+            bordered
+            size="middle"
+            rowKey="id"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="ipagination"
+            :loading="loading"
+            :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: 'radio'}"
+            @change="handleTableChange"
+            :customRow="clickThenCheck"
+          >
+          </a-table>
+        </div>
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import JInput from '@/components/jeecg/JInput'
+export default {
+  name: "PlanSparePartSelectTable",
+  mixins: [JeecgListMixin],
+  components: {
+    JInput
+  },
+  data() {
+    return {
+      title: "鎿嶄綔",
+      visible: false,
+      model: {},
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          width: 50,
+          align: 'center',
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1
+          }
+        },
+        {
+          title: '澶囦欢缂栧彿',
+          align: 'center',
+          dataIndex: 'num',
+          sorter: true,
+        },
+        {
+          title: '澶囦欢鍚嶇О',
+          align: 'center',
+          dataIndex: 'name',
+          sorter: true,
+        },
+        {
+          title: '澶囦欢瑙勬牸',
+          align: 'center',
+          dataIndex: 'specification',
+          sorter: true,
+        },
+        {
+          title: '澶囦欢鍨嬪彿',
+          align: 'center',
+          dataIndex: 'model',
+          sorter: true,
+        },
+        {
+          title: '鍒堕�犲晢',
+          align: 'center',
+          dataIndex: 'constructorId_dictText',
+          sorter: true,
+        },
+        {
+          title: '鍗曚綅',
+          align: 'center',
+          dataIndex: 'mainUnitId_dictText',
+          sorter: true,
+        },
+
+      ],
+      url: {
+        list: "/spare/sparePart/list",
+      },
+      index: '',
+    }
+  },
+  methods: {
+
+    searchQuery() {
+      this.loadData(1);
+    },
+
+    list(index) {
+      this.visible = true;
+      this.index = index;
+      this.loadData(1);
+    },
+
+    clickThenCheck(record) {
+      return {
+        on: {
+          click: (e) => {
+            this.selectedRowRecord = record;
+            this.onSelectChange(record.id.split(","), [record]);
+          }
+        }
+      };
+    },
+
+    onSelectChange(selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys;
+      this.selectedRowRecord = selectedRows[0];
+    },
+
+    close() {
+      this.queryParam = {};
+      this.$emit('close');
+      this.visible = false;
+      this.selectedRowKeys = [];
+    },
+
+    handleOk() {
+      const that = this;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      if (that.selectedRowKeys.length > 0) {
+        if (that.selectedRowRecord.id != null && that.selectedRowRecord.id != "") {
+          that.$emit('sendSparePartRecord', { index: this.index, record: that.selectedRowRecord });
+          that.close();
+        } else {
+          that.$message.error("璇烽�夋嫨澶囦欢锛�")
+        }
+      } else {
+        that.$message.error("璇烽�夋嫨澶囦欢锛�")
+      }
+    },
+
+    handleCancel() {
+      this.close();
+    },
+
+  }
+}
+</script>
+<style>
+@import '~@assets/less/common.less';
+.frozenRowClass {
+  color: #c9c9c9;
+}
+
+.fontweight {
+  font-weight: bold;
+}
+
+.fontweightfrozen {
+  font-weight: bold;
+  color: #c9c9c9;
+}
+.success {
+  color: green;
+}
+.error {
+  color: red;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/eam/common/RepairOrderDetailList.vue b/src/views/eam/common/RepairOrderDetailList.vue
new file mode 100644
index 0000000..cad8690
--- /dev/null
+++ b/src/views/eam/common/RepairOrderDetailList.vue
@@ -0,0 +1,228 @@
+<template>
+  <a-card :bordered="false" :class="'cust-erp-sub-tab'">
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 鏌ヨ鍖哄煙-END -->
+
+    <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
+    <div class="table-operator" v-if="mainId">
+      <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="mainId !='' && isAdd "
+      >鏂板</a-button>
+    </div>
+
+    <!-- table鍖哄煙-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange">
+        <!-- :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" -->
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犲浘鐗�</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犳枃浠�</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            涓嬭浇
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record" >
+          <a @click="handleEdit(record)" v-if="addStatus" >缂栬緫</a>
+          <a-divider type="vertical"  v-if="addStatus" />
+          <a-popconfirm title="纭畾鍒犻櫎鍚�?" @confirm="() => handleDelete(record.id)" >
+            <a v-if="addStatus">鍒犻櫎</a>
+          </a-popconfirm>
+          <a style="font-size: 12px;font-style: italic;" v-if="!addStatus">璇ョ姸鎬佷笉鍙搷浣�</a>
+        </span>
+
+      </a-table>
+    </div>
+
+    <repairOrderDetail-modal ref="modalForm" @ok="modalFormOk" :mainId="mainId"></repairOrderDetail-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import RepairOrderDetailModal from './RepairOrderDetailModal'
+  export default {
+    name: "RepairOrderDetailList",
+    mixins:[JeecgListMixin],
+    components: { RepairOrderDetailModal },
+    props:{
+      mainId:{
+        type:String,
+        default:'',
+        required:false
+      },
+      maintenanceStandardId: {
+        type: String,
+        required: false
+      },
+      isEdit: {
+        type: Boolean,
+        default: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+
+    },
+    watch:{
+      mainId:{
+        immediate: true,
+        handler(val) {
+          if(!this.mainId){
+            this.clearList()
+          }else{
+            this.queryParam['repairOrderId'] = val
+            this.loadData(1);
+          }
+        }
+      }
+    },
+    data () {
+      return {
+        disableMixinCreated:true,
+        repairOrderSelectionRows:[],
+        // 琛ㄥご
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'閮ㄤ綅',
+            align:"center",
+            dataIndex: 'location'
+          },
+          {
+            title:'绀烘剰鍥�',
+            align:"center",
+            scopedSlots: {customRender: 'imgSlot'},
+            dataIndex: 'sketchMap'
+          },
+          // {
+          //   title:'缁翠慨椤圭洰',
+          //   align:"center",
+          //   dataIndex: 'maintenanceItem'
+          // },
+          {
+            title:'缁翠慨瑕佹眰',
+            align:"center",
+            dataIndex: 'maintenanceRequire'
+          },
+          {
+            title:'鏂规硶',
+            align:"center",
+            dataIndex: 'maintenanceWay'
+          },
+          {
+            title:'宸ュ叿',
+            align:"center",
+            dataIndex: 'maintenanceTooling'
+          },
+          {
+            title:'瀹夊叏瑕佹眰',
+            align:"center",
+            dataIndex: 'safetyRequirement'
+          },
+          // {
+          //   title:'缁翠慨鍛ㄦ湡',
+          //   align:"center",
+          //   dataIndex: 'repairCycle'
+          // },
+          {
+            title:'宸ユ椂瀹氶',
+            align:"center",
+            dataIndex: 'timeQuota'
+          },
+          {
+            title:'缁翠繚涓撲笟',
+            align:"center",
+            dataIndex: 'mamaintenanceSpecialtyId_dictText'
+          },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+        url: {
+          list: "/eam/repairOrder/pageRepairOrderDetailByMainId",
+          delete: "/eam/repairOrder/deleteRepairOrderDetail",
+          deleteBatch: "/eam/repairOrder/deleteBatchRepairOrderDetail",
+          exportXlsUrl: "/eam/repairOrder/exportRepairOrderDetail",
+          importUrl: "/eam/repairOrder/importRepairOrderDetail",
+        },
+        dictOptions:{
+        }
+      }
+    },
+    created() {
+    },
+    computed: {
+      importExcelUrl(){
+        return `${window._CONFIG['domianURL']}/${this.url.importUrl}/${this.mainId}`;
+      }
+    },
+    mounted() {
+    this.$bus.$on('repairOrderSelectionRows', (data) => {
+      this.repairOrderSelectionRows = data
+    })
+  },
+    methods: {
+      clearList(){
+        this.dataSource=[]
+        this.selectedRowKeys=[]
+        this.ipagination.current = 1
+      }
+
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less'
+</style>
diff --git a/src/views/eam/common/RepairOrderDetailModal.vue b/src/views/eam/common/RepairOrderDetailModal.vue
new file mode 100644
index 0000000..22cc468
--- /dev/null
+++ b/src/views/eam/common/RepairOrderDetailModal.vue
@@ -0,0 +1,289 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="閮ㄤ綅"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="location"
+            >
+              <a-input
+                v-model="model.location"
+                placeholder="璇疯緭鍏ラ儴浣�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="绀烘剰鍥�"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="sketchMap"
+            >
+              <j-image-upload
+                :isMultiple="false"
+                v-model="model.sketchMap"
+              ></j-image-upload>
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="24">
+            <a-form-model-item
+              label="缁翠慨椤圭洰"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="maintenanceItem"
+            >
+              <a-input
+                v-model="model.maintenanceItem"
+                placeholder="璇疯緭鍏ョ淮淇」鐩�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col> -->
+          <a-col :span="24">
+            <a-form-model-item
+              label="缁翠慨瑕佹眰"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="maintenanceRequire"
+            >
+              <a-input
+                v-model="model.maintenanceRequire"
+                placeholder="璇疯緭鍏ョ淮淇姹�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="鏂规硶"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="maintenanceWay"
+            >
+              <a-input
+                v-model="model.maintenanceWay"
+                placeholder="璇疯緭鍏ョ淮淇柟娉�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="宸ュ叿"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="maintenanceTooling"
+            >
+              <a-input
+                v-model="model.maintenanceTooling"
+                placeholder="璇疯緭鍏ョ淮淇伐鍏�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="瀹夊叏瑕佹眰"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="safetyRequirement"
+            >
+              <a-input
+                v-model="model.safetyRequirement"
+                placeholder="璇疯緭鍏ュ畨鍏ㄨ姹�"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="24">
+            <a-form-model-item
+              label="缁翠慨鍛ㄦ湡"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="repairCycle"
+            >
+              <a-input-number
+                style="width: 100%"
+                v-model="model.repairCycle"
+                placeholder="璇疯緭鍏ョ淮淇懆鏈�"
+                :min="0"
+                :max="99999"
+              ></a-input-number>
+            </a-form-model-item>
+          </a-col> -->
+          <a-col :span="24">
+            <a-form-model-item
+              label="宸ユ椂瀹氶"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="timeQuota"
+            >
+              <a-input-number
+                style="width: 100%"
+                v-model="model.timeQuota"
+                placeholder="璇疯緭鍏ュ伐鏃跺畾棰�"
+                :min="0"
+                :max="99999"
+              ></a-input-number>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="缁翠繚涓撲笟"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="mamaintenanceSpecialtyId"
+            >
+              <j-dict-select-tag
+                placeholder="璇烽�夋嫨缁翠繚涓撲笟"
+                :triggerChange="true"
+                dictCode="mom_eam_maintenance_specialty,name,id,del_flag!='1'"
+                v-model="model.mamaintenanceSpecialtyId"
+              />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+import { httpAction } from '@/api/manage'
+import { validateDuplicateValue } from '@/utils/util'
+
+export default {
+  name: "RepairOrderDetailModal",
+  components: {
+  },
+  props: {
+    mainId: {
+      type: String,
+      required: false,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      title: "鎿嶄綔",
+      width: 800,
+      visible: false,
+      model: {
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+
+      confirmLoading: false,
+      validatorRules: {
+        location: [
+          { required: true, message: '璇疯緭鍏ラ儴浣�!' },
+          { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        ],
+        sketchMap: [
+          { required: true, message: '璇蜂笂浼�!' },
+        ],
+        // maintenanceItem: [{ required: true, message: '璇疯緭鍏ョ淮淇」鐩�!' },
+        // { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        // ],
+        maintenanceRequire: [{ required: true, message: '璇疯緭鍏ョ淮淇姹�!' },
+        { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        ],
+        maintenanceTooling: [{ required: true, message: '璇疯緭鍏ョ淮淇伐鍏�!' },
+        { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        ],
+        safetyRequirement: [{ required: true, message: '璇疯緭鍏ュ畨鍏ㄨ姹�!' },
+        { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        ],
+        timeQuota: [{ required: true, message: '璇疯緭鍏ュ伐鏃跺畾棰�!' },
+
+        ],
+        // repairCycle: [{ required: true, message: '璇疯緭鍏ョ淮淇懆鏈�!' }],
+        // mamaintenanceSpecialtyId: [{ required: true, message: '璇烽�夋嫨缁翠繚涓撲笟!' },
+        // ],
+        maintenanceWay: [{ required: true, message: '璇疯緭鍏ユ柟娉�!' },
+        { max: 32, message: '瓒呰繃鏈�澶ц緭鍏ラ檺鍒�,璇风缉鍑忛暱搴�' }
+        ],
+      },
+      url: {
+        add: "/eam/repairOrder/addRepairOrderDetail",
+        edit: "/eam/repairOrder/editRepairOrderDetail",
+      }
+
+    }
+  },
+  created() {
+    //澶囦唤model鍘熷鍊�
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    close() {
+      this.$emit('close');
+      this.visible = false;
+      this.$refs.form.clearValidate();
+    },
+    handleOk() {
+      const that = this;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          that.confirmLoading = true;
+          let httpurl = '';
+          let method = '';
+          if (!this.model.id) {
+            httpurl += this.url.add;
+            method = 'post';
+          } else {
+            httpurl += this.url.edit;
+            method = 'put';
+          }
+          this.model['repairOrderId'] = this.mainId
+          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;
+            that.close();
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    handleCancel() {
+      this.close()
+    },
+
+
+  }
+}
+</script>
diff --git a/src/views/eam/modules/predictiveWorkPlan/ParameterSelect.vue b/src/views/eam/modules/predictiveWorkPlan/ParameterSelect.vue
new file mode 100644
index 0000000..81ed20c
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/ParameterSelect.vue
@@ -0,0 +1,225 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1000"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <!-- 鏌ヨ鍖哄煙 -->
+        <div class="table-page-search-wrapper">
+          <a-form
+            layout="inline"
+            @keyup.enter.native="searchQuery"
+          >
+            <a-row :gutter="24">
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="鍙傛暟浠g爜">
+                  <j-input
+                    placeholder="璇疯緭鍏ュ弬鏁颁唬鐮�"
+                    v-model="queryParam.parameterCode"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="鍙傛暟鍚嶇О">
+                  <j-input
+                    placeholder="璇疯緭鍏ュ弬鏁板悕绉�"
+                    v-model="queryParam.parameterName"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-button
+                  type="primary"
+                  @click="searchQuery"
+                  icon="search"
+                >鏌ヨ
+                </a-button>
+                <a-button
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left:8px;"
+                >閲嶇疆
+                </a-button>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :span="24">
+
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <div style="margin-top:8px;">
+          <a-table
+            ref="table"
+            bordered
+            size="middle"
+            rowKey="parameterId"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="false"
+            :loading="loading"
+            :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: 'radio'}"
+            @change="handleTableChange"
+            :customRow="clickThenCheck"
+          >
+          </a-table>
+        </div>
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+  import { getAction } from '@/api/manage'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import JInput from '@/components/jeecg/JInput'
+
+  export default {
+    name: 'ParameterSelect',
+    mixins: [JeecgListMixin],
+    components: {
+      JInput
+    },
+    data() {
+      return {
+        title: '鎿嶄綔',
+        visible: false,
+        model: {},
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 50,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鍙傛暟浠g爜',
+            dataIndex: 'parameterCode',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟鍚嶇О',
+            dataIndex: 'parameterName',
+            align: 'center'
+          },
+          {
+            title: '琛ㄥ悕',
+            dataIndex: 'saveTableName',
+            align: 'center'
+          },
+        ],
+        url: {
+          list: '/eam/predictiveworkplanparameter/listPredictiveWorkPlanParameter'
+        }
+      }
+    },
+    methods: {
+
+      searchQuery() {
+        this.loadData()
+      },
+
+      list(equipmentId) {
+        this.queryParam.equipmentId = equipmentId
+        this.visible = true
+        this.loadData()
+      },
+      loadData() {
+        let that = this
+        getAction(this.url.list, this.queryParam).then((res) => {
+          if (res.success) {
+            that.dataSource = res.result
+          }
+        })
+      },
+      clickThenCheck(record) {
+        return {
+          on: {
+            click: (e) => {
+              this.selectedRowRecord = record
+              this.onSelectChange(record.id.split(','), [record])
+            }
+          }
+        }
+      },
+
+      onSelectChange(selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys
+        this.selectedRowRecord = selectedRows[0]
+      },
+
+      close() {
+        this.queryParam = {}
+        this.$emit('close')
+        this.visible = false
+        this.selectedRowKeys = []
+      },
+
+      handleOk() {
+        const that = this
+        // 瑙﹀彂琛ㄥ崟楠岃瘉
+        if (that.selectedRowKeys.length > 0) {
+          if (that.selectedRowRecord.parameterId != null && that.selectedRowRecord.parameterId != '') {
+            that.$emit('sendParameter', { record: that.selectedRowRecord })
+            that.close()
+          } else {
+            that.$message.error('璇烽�夋嫨鍙傛暟锛�')
+          }
+        } else {
+          that.$message.error('璇烽�夋嫨鍙傛暟锛�')
+        }
+      },
+
+      handleCancel() {
+        this.close()
+      }
+
+    }
+  }
+</script>
+<style>
+  @import '~@assets/less/common.less';
+
+  .frozenRowClass {
+    color: #c9c9c9;
+  }
+
+  .fontweight {
+    font-weight: bold;
+  }
+
+  .fontweightfrozen {
+    font-weight: bold;
+    color: #c9c9c9;
+  }
+
+  .success {
+    color: green;
+  }
+
+  .error {
+    color: red;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveParameterModal.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveParameterModal.vue
new file mode 100644
index 0000000..6ce61c5
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveParameterModal.vue
@@ -0,0 +1,281 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="900"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row style="width: 100%">
+
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="鏉′欢"
+            >
+              <j-dict-select-tag
+                allow-clear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇烽�夋嫨鏉′欢'"
+                :triggerChange="true"
+                dictCode="conditional_relation"
+                v-decorator="['parameterCondition', validatorRules.parameterCondition]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="鍙傛暟浠g爜"
+            >
+              <a-input-search
+                placeholder="璇烽�夋嫨鍙傛暟浠g爜"
+                enter-button
+                @search="onSearchParameterCode()"
+                v-decorator="['parameterCode',validatorRules.parameterCode]"
+                :read-only="true"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鍙傛暟鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['parameterName', validatorRules.parameterName]"
+                       placeholder="璇疯緭鍏ュ弬鏁板悕绉�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="琛ㄥ悕" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['saveTableName', validatorRules.saveTableName]"
+                       placeholder="璇疯緭鍏ヨ〃鍚�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-model-item label='鍙傛暟鍗曚綅' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='mainUnitId'>
+              <j-dict-select-tag
+                allow-clear
+                :placeholder="'璇烽�夋嫨鍙傛暟鍗曚綅'"
+                v-model='model.parameterUnit'
+                dictCode="mom_base_unit,name,id,del_flag!='1'"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鍙傛暟涓婇檺鍊�" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ュ弬鏁颁笂闄愬��"
+                v-decorator="['upperLimitValue', validatorRules.upperLimitValue]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鍙傛暟涓嬮檺鍊�" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ュ弬鏁颁笅闄愬��"
+                v-decorator="['lowerLimitValue', validatorRules.lowerLimitValue]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-spin>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel"
+      >
+        鍏抽棴
+      </a-button>
+      <a-button
+        :disabled="disableSubmit || confirmLoading"
+        :loading="confirmLoading"
+        @click="handleOk"
+        type="primary"
+      >纭畾
+      </a-button>
+    </template>
+    <parameter-select ref="parameterSelect" @sendParameter='sendParameter'></parameter-select>
+  </a-modal>
+</template>
+
+<script>
+  import pick from 'lodash.pick'
+  import { postAction, requestPut } from '@/api/manage'
+  import ParameterSelect from './ParameterSelect'
+
+  export default {
+    name: 'PredictiveSparePartsModal',
+    components: {
+      ParameterSelect
+    },
+    data() {
+      return {
+        title: '鎿嶄綔',
+        visible: false,
+        codeDisable: true,
+        disableSubmit: false,
+        model: {},
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 6 }
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 18 }
+        },
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules: {
+          parameterCondition: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨鏉′欢!' }
+            ]
+          },
+          parameterCode: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ュ弬鏁颁唬鐮�!' }
+            ]
+          },
+          upperLimitValue: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ュ弬鏁颁笂闄愬��!' }
+            ]
+          },
+          lowerLimitValue: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ュ弬鏁颁笅闄愬��!' }
+            ]
+          }
+        },
+        url: {
+          add: '/eam/predictiveworkplanparameter/add',
+          edit: '/eam/predictiveworkplanparameter/edit'
+        },
+        //鏂板銆佺紪杈戙�佸垹闄ゃ�佹壒閲忓垹闄ゆ搷浣滄敼鍙樻暟鎹悗鍒锋柊鍏宠仈鐨勭粍浠剁殑鐩戝惉灞炴��
+        alterFlag: '',
+        planId: '',
+        equipmentId: ''
+      }
+    },
+    created() {
+    },
+    methods: {
+
+      add() {
+        this.edit({})
+      },
+
+      edit(record) {
+        this.form.resetFields()
+        this.model = Object.assign({}, record)
+        this.visible = true
+        this.disableSubmit = false
+        this.model.sparePartId = record.sparePartId
+        this.$nextTick(() => {
+          this.form.setFieldsValue(pick(this.model,
+            'sparePartNum',
+            'sparePartName',
+            'sparePartModel',
+            'sparePartSpecification',
+            'mainUnitName',
+            'constructorName',
+            'supportingQuantity',
+            'ratedLife',
+            'lifeWarning'))
+        })
+        if (record.id) {
+          this.codeDisable = true
+        } else {
+          this.codeDisable = false
+        }
+      },
+
+      close() {
+        this.$emit('close')
+        this.visible = false
+      },
+
+      //淇濆瓨骞舵柊澧炴寜閽Е鍙�
+
+      handleOk() {
+        const that = this
+        // 瑙﹀彂琛ㄥ崟楠岃瘉
+        this.form.validateFields((err, values) => {
+          if (!err) {
+            that.confirmLoading = true
+            let formData = Object.assign(this.model, values)
+            formData.workPlanId = this.planId
+            let obj
+            if (!this.model.id) {
+              obj = postAction(this.url.add, formData)
+            } else {
+              obj = requestPut(this.url.edit, formData, { id: this.model.id })
+            }
+            obj.then((res) => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+                that.alterFlag = new Date()
+              } else {
+                that.$message.warning(res.message)
+              }
+            }).finally(() => {
+              that.confirmLoading = false
+              that.close()
+            })
+          }
+        })
+      },
+
+      onSearchParameterCode() {
+        this.$refs.parameterSelect.list(this.equipmentId)
+        this.$refs.parameterSelect.title = '閫夋嫨澶囦欢'
+      },
+      sendParameter(data) {
+        let record = data.record
+        this.model.parameterId = record.parameterId
+        this.form.setFieldsValue({
+          parameterName: record.parameterName,
+          parameterCode: record.parameterCode,
+          saveTableName: record.saveTableName
+        })
+      },
+
+      handleCancel() {
+        this.close()
+      }
+
+    }
+  }
+</script>
+
+<style scoped>
+  .ant-btn {
+    padding: 0 10px;
+    margin-left: 3px;
+  }
+
+  .ant-form-item-control {
+    line-height: 0px;
+  }
+
+  /** 涓昏〃鍗曡闂磋窛 */
+  .ant-form .ant-form-item {
+    margin-bottom: 10px;
+  }
+
+  /** Tab椤甸潰琛岄棿璺� */
+  .ant-tabs-content .ant-form-item {
+    margin-bottom: 0px;
+  }
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveParameters.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveParameters.vue
new file mode 100644
index 0000000..e42f96e
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveParameters.vue
@@ -0,0 +1,194 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="planId != '' && isAdd "
+    >鏂板
+    </a-button>
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+    <predictive-parameter-modal ref="modalForm" @ok="modalFormOk"></predictive-parameter-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { deleteAction } from '@/api/manage'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import PredictiveParameterModal from './PredictiveParameterModal'
+
+  export default {
+    name: 'PredictiveParameters',
+    components: {
+      Tooltip,
+      PredictiveParameterModal
+    },
+    mixins: [JeecgListMixin],
+    props: {
+      planId: {
+        type: String,
+        required: false
+      },
+      equipmentId: {
+        type: String,
+        required: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mounted() {
+
+    },
+    watch: {
+      planId: function(val) {
+        this.clearList()
+        if (this.planId) {
+          this.queryParam.planId = val
+          this.queryParam.delFlag = 0
+          this.loadData(1)
+        }
+      }
+    },
+    data() {
+      return {
+        disableMixinCreated: true,
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 60,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鏉′欢',
+            dataIndex: 'conditionalRelationName',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟浠g爜',
+            dataIndex: 'parameterCode',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟鍚嶇О',
+            dataIndex: 'parameterName',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟鍗曚綅',
+            dataIndex: 'unitName',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟涓婇檺',
+            dataIndex: 'upperLimitValue',
+            align: 'center'
+          },
+          {
+            title: '鍙傛暟涓嬮檺',
+            dataIndex: 'lowerLimitValue',
+            align: 'center'
+          },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align: 'center',
+            fixed: 'right',
+            width: 250,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: '/eam/predictiveworkplanparameter/pagePredictiveWorkPlanParameter',
+          delete: '/eam/predictiveworkplanparameter/delete'
+        }
+      }
+    },
+
+    methods: {
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '鍙傛暟鎺у埗'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.planId = this.planId
+        this.$refs.modalForm.equipmentId = this.equipmentId
+      },
+
+      handleDelete: function(id) {
+        if (!this.url.delete) {
+          this.$message.error('璇疯缃畊rl.delete灞炴��!')
+          return
+        }
+        var that = this
+        deleteAction(that.url.delete, { id: id }).then((res) => {
+          if (res.success) {
+            //閲嶆柊璁$畻鍒嗛〉闂
+            that.reCalculatePage(1)
+            that.$message.success(res.message)
+            that.loadData()
+            that.alterFlag = new Date()
+          } else {
+            that.$message.warning(res.message)
+          }
+        })
+      },
+      clearList() {
+        this.dataSource = []
+        this.selectedRowKeys = []
+        this.ipagination.current = 1
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveSpareParts.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveSpareParts.vue
new file mode 100644
index 0000000..7728307
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveSpareParts.vue
@@ -0,0 +1,204 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="planId != '' && isAdd "
+    >鏂板
+    </a-button>
+    <div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+    <predictive-spare-parts-modal ref="modalForm" @ok="modalFormOk"></predictive-spare-parts-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { getAction, deleteAction } from '@/api/manage'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import PredictiveSparePartsModal from './PredictiveSparePartsModal'
+
+  export default {
+    name: 'PredictiveSpareParts',
+    components: {
+      Tooltip,
+      PredictiveSparePartsModal
+    },
+    mixins: [JeecgListMixin],
+    props: {
+      planId: {
+        type: String,
+        required: false
+      },
+      isEdit: {
+        type: Boolean,
+        default: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mounted() {
+
+    },
+    watch: {
+      planId: function(val) {
+        this.clearList()
+        if (this.planId) {
+          this.queryParam.planId = val
+          this.queryParam.delFlag = 0
+          this.loadData(1)
+        }
+      }
+    },
+    data() {
+      return {
+        disableMixinCreated: true,
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 60,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '澶囦欢缂栧彿',
+            dataIndex: 'sparePartNum',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢鍚嶇О',
+            dataIndex: 'sparePartName',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢瑙勬牸',
+            dataIndex: 'sparePartSpecification',
+            align: 'center'
+          },
+          {
+            title: '澶囦欢鍨嬪彿',
+            dataIndex: 'sparePartModel',
+            align: 'center'
+          },
+          {
+            title: '鍗曚綅',
+            dataIndex: 'mainUnitName',
+            align: 'center'
+          },
+          {
+            title: '閰嶅鏁伴噺',
+            dataIndex: 'supportingQuantity',
+            align: 'center'
+          },
+          {
+            title: '棰濆畾瀵垮懡/灏忔椂',
+            dataIndex: 'ratedLife',
+            align: 'center'
+          },
+          {
+            title: '瀵垮懡鎺у埗闄�',
+            dataIndex: 'lifeWarning',
+            align: 'center'
+          },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align: 'center',
+            fixed: 'right',
+            width: 250,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: '/eam/predictiveworkplansparepart/pagePredictiveWorkPlanSparePart',
+          delete: '/eam/predictiveworkplansparepart/delete'
+        }
+      }
+    },
+
+    methods: {
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '璁″垝鐢ㄦ枡'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.planId = this.planId
+      },
+
+      handleDelete: function(id) {
+        if (!this.url.delete) {
+          this.$message.error('璇疯缃畊rl.delete灞炴��!')
+          return
+        }
+        var that = this
+        deleteAction(that.url.delete, { id: id }).then((res) => {
+          if (res.success) {
+            //閲嶆柊璁$畻鍒嗛〉闂
+            that.reCalculatePage(1)
+            that.$message.success(res.message)
+            that.loadData()
+            that.alterFlag = new Date()
+          } else {
+            that.$message.warning(res.message)
+          }
+        })
+      },
+      clearList() {
+        this.dataSource = []
+        this.selectedRowKeys = []
+        this.ipagination.current = 1
+      },
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveSparePartsModal.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveSparePartsModal.vue
new file mode 100644
index 0000000..4574759
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveSparePartsModal.vue
@@ -0,0 +1,302 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="900"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row style="width: 100%">
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="澶囦欢缂栧彿"
+            >
+              <a-input-search
+                placeholder="璇烽�夋嫨澶囦欢"
+                enter-button
+                @search="onSearchSparePart()"
+                v-decorator="['sparePartNum',validatorRules.sparePartNum]"
+                :read-only="true"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="澶囦欢鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['sparePartName', validatorRules.sparePartName]"
+                       placeholder="璇疯緭鍏ヨ澶囧悕绉�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="澶囦欢鍨嬪彿" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['sparePartModel', validatorRules.sparePartModel]"
+                       placeholder="璇疯緭鍏ヨ澶囧瀷鍙�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="澶囦欢瑙勬牸" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['sparePartSpecification', validatorRules.sparePartSpecification]"
+                       placeholder="璇疯緭鍏ヨ澶囪鏍�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鍒堕�犲晢" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['constructorName', validatorRules.constructorName]"
+                       placeholder="璇疯緭鍏ュ埗閫犲晢"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鍗曚綅" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['mainUnitName', validatorRules.mainUnitName]"
+                       placeholder="璇疯緭鍏ュ崟浣�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item
+              :labelCol="labelCol" :wrapperCol="wrapperCol"
+              label="閰嶅鏁伴噺"
+            >
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ラ厤濂楁暟閲�"
+                v-decorator="['supportingQuantity', validatorRules.supportingQuantity]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item
+              :labelCol="labelCol" :wrapperCol="wrapperCol"
+              label="棰濆畾瀵垮懡/灏忔椂"
+            >
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ラ瀹氬鍛�/灏忔椂"
+                v-decorator="['ratedLife', validatorRules.ratedLife]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item
+              :labelCol="labelCol" :wrapperCol="wrapperCol"
+              label="瀵垮懡鎺у埗闄�"
+            >
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ュ鍛芥帶鍒堕檺"
+                v-decorator="['lifeWarning', validatorRules.lifeWarning]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-spin>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel"
+      >
+        鍏抽棴
+      </a-button>
+      <a-button
+        :disabled="disableSubmit || confirmLoading"
+        :loading="confirmLoading"
+        @click="handleOk"
+        type="primary"
+      >纭畾
+      </a-button>
+    </template>
+
+    <plan-spare-part-select ref="planSparePartSelect"
+                            @sendSparePartRecord='sendSparePartRecord'></plan-spare-part-select>
+  </a-modal>
+</template>
+
+<script>
+  import pick from 'lodash.pick'
+  import { postAction, requestPut } from '@/api/manage'
+  import PlanSparePartSelect from '@/views/eam/common/PlanSparePartSelect'
+
+  export default {
+    name: 'PredictiveSparePartsModal',
+    components: {
+      PlanSparePartSelect
+    },
+    props: {
+      mainId: {
+        type: String,
+        required: false,
+        default: ''
+      }
+    },
+    data() {
+      return {
+        title: '鎿嶄綔',
+        visible: false,
+        codeDisable: true,
+        disableSubmit: false,
+        model: {},
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 6 }
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 18 }
+        },
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules: {
+          sparePartName: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨澶囦欢!' }
+            ]
+          },
+          supportingQuantity: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ラ厤濂楁暟閲�!' }
+            ]
+          },
+          ratedLife: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ラ瀹氬鍛�/灏忔椂!' }
+            ]
+          },
+          lifeWarning: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ュ鍛芥帶鍒堕檺/灏忔椂!' }
+            ]
+          }
+        },
+        url: {
+          add: '/eam/predictiveworkplansparepart/add',
+          edit: '/eam/predictiveworkplansparepart/edit'
+        },
+        //鏂板銆佺紪杈戙�佸垹闄ゃ�佹壒閲忓垹闄ゆ搷浣滄敼鍙樻暟鎹悗鍒锋柊鍏宠仈鐨勭粍浠剁殑鐩戝惉灞炴��
+        alterFlag: '',
+        planId: ''
+      }
+    },
+    created() {
+    },
+    methods: {
+
+      add() {
+        this.edit({})
+      },
+
+      edit(record) {
+        this.form.resetFields()
+        this.model = Object.assign({}, record)
+        this.visible = true
+        this.disableSubmit = false
+        this.$nextTick(() => {
+          this.form.setFieldsValue(pick(this.model,
+            'sparePartNum',
+            'sparePartName',
+            'sparePartModel',
+            'sparePartSpecification',
+            'mainUnitName',
+            'constructorName',
+            'supportingQuantity',
+            'ratedLife',
+            'lifeWarning'))
+        })
+        if (record.id) {
+          this.codeDisable = true
+        } else {
+          this.codeDisable = false
+        }
+      },
+
+      close() {
+        this.$emit('close')
+        this.visible = false
+      },
+
+      //淇濆瓨骞舵柊澧炴寜閽Е鍙�
+
+      handleOk() {
+        const that = this
+        // 瑙﹀彂琛ㄥ崟楠岃瘉
+        this.form.validateFields((err, values) => {
+          if (!err) {
+            that.confirmLoading = true
+            let formData = Object.assign(this.model, values)
+            formData.workPlanId = this.planId
+            let obj
+            if (!this.model.id) {
+              obj = postAction(this.url.add, formData)
+            } else {
+              obj = requestPut(this.url.edit, formData, { id: this.model.id })
+            }
+            obj.then((res) => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+                that.alterFlag = new Date()
+              } else {
+                that.$message.warning(res.message)
+              }
+            }).finally(() => {
+              that.confirmLoading = false
+              that.close()
+            })
+          }
+        })
+      },
+
+      onSearchSparePart() {
+        this.$refs.planSparePartSelect.list()
+        this.$refs.planSparePartSelect.title = '閫夋嫨澶囦欢'
+      },
+      sendSparePartRecord(data) {
+        let record = data.record
+        this.model.sparePartId = record.id
+        this.form.setFieldsValue({
+          sparePartId: record.id,
+          sparePartNum: record.num,
+          sparePartName: record.name,
+          sparePartModel: record.model,
+          sparePartSpecification: record.specification,
+          mainUnitId: record.mainUnitId,
+          mainUnitName: record.mainUnitId_dictText,
+          constructorName: record.constructorId_dictText
+        })
+      },
+
+      handleCancel() {
+        this.close()
+      }
+
+    }
+  }
+</script>
+
+<style scoped>
+  .ant-btn {
+    padding: 0 10px;
+    margin-left: 3px;
+  }
+
+  .ant-form-item-control {
+    line-height: 0px;
+  }
+
+  /** 涓昏〃鍗曡闂磋窛 */
+  .ant-form .ant-form-item {
+    margin-bottom: 10px;
+  }
+
+  /** Tab椤甸潰琛岄棿璺� */
+  .ant-tabs-content .ant-form-item {
+    margin-bottom: 0px;
+  }
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveWarn.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveWarn.vue
new file mode 100644
index 0000000..7f4c05c
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveWarn.vue
@@ -0,0 +1,194 @@
+<template>
+  <a-card
+    :bordered="false"
+    :class="'cust-erp-sub-tab'"
+  >
+    <!-- 鏌ヨ鍖哄煙 -->
+    <div class="table-page-search-wrapper">
+      <a-form
+        layout="inline"
+        @keyup.enter.native="searchQuery"
+      >
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <a-button
+      @click="handleAdd"
+      type="primary"
+      icon="plus"
+      v-if="planId != '' && isAdd "
+    >鏂板
+    </a-button>
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        @change="handleTableChange"
+      >
+        <span
+          slot="action"
+          slot-scope="text, record"
+        >
+          <a-popconfirm
+            title="纭畾鍒犻櫎鍚�?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>鍒犻櫎</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+    <predictive-warn-modal ref="modalForm" @ok="modalFormOk"></predictive-warn-modal>
+  </a-card>
+</template>
+
+<script>
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { deleteAction } from '@/api/manage'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  import PredictiveWarnModal from './PredictiveWarnModal'
+
+  export default {
+    name: 'PredictiveWarn',
+    components: {
+      Tooltip,
+      PredictiveWarnModal
+    },
+    mixins: [JeecgListMixin],
+    props: {
+      planId: {
+        type: String,
+        required: false
+      },
+      equipmentId: {
+        type: String,
+        required: false
+      },
+      isAdd: {
+        type: Boolean,
+        default: false
+      },
+      isDel: {
+        type: Boolean,
+        default: false
+      }
+    },
+    mounted() {
+
+    },
+    watch: {
+      planId: function(val) {
+        this.clearList()
+        if (this.planId) {
+          this.queryParam.planId = val
+          this.queryParam.delFlag = 0
+          this.loadData(1)
+        }
+      }
+    },
+    data() {
+      return {
+        disableMixinCreated: true,
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 60,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鏉′欢',
+            dataIndex: 'conditionalRelationName',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ浠g爜',
+            dataIndex: 'warnCode',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ鍚嶇О',
+            dataIndex: 'warnName',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ鍛ㄦ湡',
+            dataIndex: 'warnCycle',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ鍛ㄦ湡鍗曚綅',
+            dataIndex: 'cycleUnitName',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ娆℃暟',
+            dataIndex: 'times',
+            align: 'center'
+          },
+          {
+            title: '鎿嶄綔',
+            dataIndex: 'action',
+            align: 'center',
+            fixed: 'right',
+            width: 250,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: '/eam/predictiveworkplanwarn/pagePredictiveWorkPlanWarn',
+          delete: '/eam/predictiveworkplanwarn/delete'
+        }
+      }
+    },
+
+    methods: {
+      handleAdd: function() {
+        this.$refs.modalForm.add()
+        this.$refs.modalForm.title = '鎶ヨ鎺у埗'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.planId = this.planId
+        this.$refs.modalForm.equipmentId = this.equipmentId
+      },
+
+      handleDelete: function(id) {
+        if (!this.url.delete) {
+          this.$message.error('璇疯缃畊rl.delete灞炴��!')
+          return
+        }
+        var that = this
+        deleteAction(that.url.delete, { id: id }).then((res) => {
+          if (res.success) {
+            //閲嶆柊璁$畻鍒嗛〉闂
+            that.reCalculatePage(1)
+            that.$message.success(res.message)
+            that.loadData()
+            that.alterFlag = new Date()
+          } else {
+            that.$message.warning(res.message)
+          }
+        })
+      },
+      clearList() {
+        this.dataSource = []
+        this.selectedRowKeys = []
+        this.ipagination.current = 1
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveWarnModal.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveWarnModal.vue
new file mode 100644
index 0000000..1ac7403
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveWarnModal.vue
@@ -0,0 +1,277 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="900"
+    :visible="visible"
+    :maskClosable="false"
+    :confirmLoading="confirmLoading"
+    :okButtonProps="{ props: {disabled: disableSubmit} }"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row style="width: 100%">
+
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="鏉′欢"
+            >
+              <j-dict-select-tag
+                allow-clear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇烽�夋嫨鏉′欢'"
+                :triggerChange="true"
+                dictCode="conditional_relation"
+                v-decorator="['parameterCondition', validatorRules.parameterCondition]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              label="鎶ヨ浠g爜"
+            >
+              <a-input-search
+                placeholder="璇烽�夋嫨鎶ヨ浠g爜"
+                enter-button
+                @search="onSearchWarnCode()"
+                v-decorator="['warnCode',validatorRules.warnCode]"
+                :read-only="true"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鎶ヨ鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input :disabled="true" v-decorator="['warnName', validatorRules.warnName]"
+                       placeholder="璇疯緭鍏ユ姤璀﹀悕绉�"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鎶ヨ鍛ㄦ湡" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ユ姤璀﹀懆鏈�"
+                v-decorator="['warnCycle', validatorRules.warnCycle]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-model-item label='鎶ヨ鍛ㄦ湡鍗曚綅' :labelCol='labelCol' :wrapperCol='wrapperCol' prop='mainUnitId'>
+              <j-dict-select-tag
+                allow-clear
+                :placeholder="'璇烽�夋嫨鎶ヨ鍛ㄦ湡鍗曚綅'"
+                v-decorator="['cycleUnit', validatorRules.cycleUnit]"
+                dictCode="warn_cycle_unit"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24/2">
+            <a-form-item label="鎶ヨ娆℃暟" :labelCol="labelCol" :wrapperCol="wrapperCol">
+              <a-input-number
+                style="width: 100%"
+                placeholder="璇疯緭鍏ユ姤璀︽鏁�"
+                v-decorator="['times', validatorRules.times]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-spin>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel"
+      >
+        鍏抽棴
+      </a-button>
+      <a-button
+        :disabled="disableSubmit || confirmLoading"
+        :loading="confirmLoading"
+        @click="handleOk"
+        type="primary"
+      >纭畾
+      </a-button>
+    </template>
+    <warn-select ref="warnSelect" @sendWarn='sendWarn'></warn-select>
+  </a-modal>
+</template>
+
+<script>
+  import pick from 'lodash.pick'
+  import { postAction, requestPut } from '@/api/manage'
+  import WarnSelect from './WarnSelect'
+
+  export default {
+    name: 'PredictiveWarnModal',
+    components: {
+      WarnSelect
+    },
+    data() {
+      return {
+        title: '鎿嶄綔',
+        visible: false,
+        codeDisable: true,
+        disableSubmit: false,
+        model: {},
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 6 }
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 18 }
+        },
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules: {
+          parameterCondition: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨鏉′欢!' }
+            ]
+          },
+          warnCode: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ユ姤璀︿唬鐮�!' }
+            ]
+          },
+          warnCycle: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ユ姤璀﹀懆鏈�!' }
+            ]
+          },
+          cycleUnit: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨鎶ヨ鍛ㄦ湡鍗曚綅!' }
+            ]
+          },
+          times: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ユ姤璀︽鏁�!' }
+            ]
+          }
+        },
+        url: {
+          add: '/eam/predictiveworkplanwarn/add',
+          edit: '/eam/predictiveworkplanwarn/edit'
+        },
+        //鏂板銆佺紪杈戙�佸垹闄ゃ�佹壒閲忓垹闄ゆ搷浣滄敼鍙樻暟鎹悗鍒锋柊鍏宠仈鐨勭粍浠剁殑鐩戝惉灞炴��
+        alterFlag: '',
+        planId: '',
+        equipmentId: ''
+      }
+    },
+    created() {
+    },
+    methods: {
+      add() {
+        this.edit({})
+      },
+      edit(record) {
+        this.form.resetFields()
+        this.model = Object.assign({}, record)
+        this.visible = true
+        this.disableSubmit = false
+        this.$nextTick(() => {
+          this.form.setFieldsValue(pick(this.model,
+            'sparePartNum',
+            'sparePartName',
+            'sparePartModel',
+            'sparePartSpecification',
+            'mainUnitName',
+            'constructorName',
+            'supportingQuantity',
+            'ratedLife',
+            'lifeWarning'))
+        })
+        if (record.id) {
+          this.codeDisable = true
+        } else {
+          this.codeDisable = false
+        }
+      },
+
+      close() {
+        this.$emit('close')
+        this.visible = false
+      },
+
+      //淇濆瓨骞舵柊澧炴寜閽Е鍙�
+
+      handleOk() {
+        const that = this
+        // 瑙﹀彂琛ㄥ崟楠岃瘉
+        this.form.validateFields((err, values) => {
+          if (!err) {
+            that.confirmLoading = true
+            let formData = Object.assign(this.model, values)
+            formData.workPlanId = this.planId
+            let obj
+            if (!this.model.id) {
+              obj = postAction(this.url.add, formData)
+            } else {
+              obj = requestPut(this.url.edit, formData, { id: this.model.id })
+            }
+            obj.then((res) => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+                that.alterFlag = new Date()
+              } else {
+                that.$message.warning(res.message)
+              }
+            }).finally(() => {
+              that.confirmLoading = false
+              that.close()
+            })
+          }
+        })
+      },
+
+      onSearchWarnCode() {
+        this.$refs.warnSelect.list(this.equipmentId)
+        this.$refs.warnSelect.title = '閫夋嫨澶囦欢'
+      },
+      sendWarn(data) {
+        let record = data.record
+        this.model.warnId = record.warnCode
+        this.model.mdcEquipmentId = record.mdcEquipmentId
+        this.form.setFieldsValue({
+          warnCode: record.warnCode,
+          warnName: record.warnName
+        })
+      },
+
+      handleCancel() {
+        this.close()
+      }
+
+    }
+  }
+</script>
+
+<style scoped>
+  .ant-btn {
+    padding: 0 10px;
+    margin-left: 3px;
+  }
+
+  .ant-form-item-control {
+    line-height: 0px;
+  }
+
+  /** 涓昏〃鍗曡闂磋窛 */
+  .ant-form .ant-form-item {
+    margin-bottom: 10px;
+  }
+
+  /** Tab椤甸潰琛岄棿璺� */
+  .ant-tabs-content .ant-form-item {
+    margin-bottom: 0px;
+  }
+</style>
diff --git a/src/views/eam/modules/predictiveWorkPlan/PredictiveWorkPlanModal.vue b/src/views/eam/modules/predictiveWorkPlan/PredictiveWorkPlanModal.vue
new file mode 100644
index 0000000..5fcc5e4
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/PredictiveWorkPlanModal.vue
@@ -0,0 +1,448 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1500"
+    :visible="visible"
+    :maskClosable="false"
+    @ok="handleOk"
+    cancelText="鍏抽棴"
+    @cancel="handleCancel"
+    :confirmLoading="confirmLoading"
+  >
+
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <a-row :gutter="24">
+          <a-col :span="12">
+            <a-form-item
+              label="鏂规缂栫爜"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input
+                allowClear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇疯緭鍏ユ柟妗堢紪鐮�'"
+                v-decorator="[ 'num', validatorRules.num]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              label="鏂规鍚嶇О"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input
+                allowClear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇疯緭鍏ユ柟妗堝悕绉�'"
+                v-decorator="[ 'name', validatorRules.name]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="12">
+            <a-form-item
+              label="鐩戞帶绫诲瀷"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <j-dict-select-tag
+                allow-clear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇烽�夋嫨鐩戞帶绫诲瀷'"
+                :triggerChange="true"
+                dictCode="monitor_type"
+                v-decorator="['monitorType', validatorRules.monitorType]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              label="璁惧鍚嶇О"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input-search
+                :disabled="disableSubmit"
+                placeholder="璇烽�夋嫨璁惧"
+                enter-button
+                @search="onEquipmentList()"
+                :read-only="true"
+                v-decorator="['equipmentName', validatorRules.equipmentName]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="12">
+            <a-form-item
+              label="缁翠繚鏂瑰紡"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <j-dict-select-tag
+                allow-clear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇烽�夋嫨缁翠繚鏂瑰紡'"
+                :triggerChange="true"
+                dictCode="maintenance_method"
+                v-decorator="['maintenanceMethod', validatorRules.maintenanceMethod]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              label="娲惧伐鏂瑰紡"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <j-dict-select-tag
+                allow-clear
+                :disabled="disableSubmit"
+                :placeholder="disableSubmit?'':'璇烽�夋嫨娲惧伐鏂瑰紡'"
+                :triggerChange="true"
+                dictCode="assign_mode"
+                v-decorator="['assignMode', validatorRules.assignMode]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="24">
+          <a-col :span="12">
+            <a-form-item
+              label="璐d换鐝粍"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input
+                allow-clear
+                :disabled="true"
+                :placeholder="disableSubmit?'':'璇疯緭鍏ヨ矗浠荤彮缁�'"
+                v-decorator="['teamName', {} ]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-item
+              label="鐗堟湰"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input
+                allowClear
+                :disabled="true"
+                :placeholder="disableSubmit?'':'璇疯緭鍏ョ増鏈彿'"
+                v-decorator="[ 'planVersion', validatorRules.planVersion]"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col
+            v-if="this.isRevise == true"
+            :span="12"
+          >
+            <a-form-item
+              label="鍘嗗彶鐗堟湰"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-input
+                allowClear
+                :disabled="true"
+                :placeholder="disableSubmit?'':'璇疯緭鍏ュ巻鍙茬増鏈彿'"
+                v-decorator="[ 'historyVersion', validatorRules.historyVersion]"
+              />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-spin>
+
+    <template slot="footer">
+      <a-button
+        :style="{marginRight: '8px'}"
+        @click="handleCancel()"
+      >
+        鍏抽棴
+      </a-button>
+
+      <a-button
+        @click="handleOk()"
+        type="primary"
+        :loading="confirmLoading"
+      >纭畾
+      </a-button>
+    </template>
+
+    <equipment-list
+      ref="EquipmentList"
+      @sendEquipmentRecord='sendEquipmentRecord'
+    ></equipment-list>
+
+    <!--    <j-select-maintenance-standard-modal ref="maintenanceStandardModalForm"></j-select-maintenance-standard-modal>-->
+  </a-modal>
+
+</template>
+
+<script>
+  import { getAction, postAction, requestPut, deleteAction } from '@/api/manage'
+  import pick from 'lodash.pick'
+  import JMultiSelectTag from '@/components/dict/JMultiSelectTag'
+  import { duplicateCheck } from '@/api/api'
+  import Tooltip from 'ant-design-vue/es/tooltip'
+  // import JSelectMaintenanceStandardModal from './JSelectMaintenanceStandardModal'
+
+  import { preview } from 'vue-photo-preview'
+  import { ACCESS_TOKEN } from '@/store/mutation-types'
+  import Vue from 'vue'
+  import PdfView from '@views/common/PdfView'
+  import { getFileAccessHttpUrl } from '@/api/manage'
+  import EquipmentList from '.././dailyInspectionStandard/EquipmentList'
+
+  export default {
+    name: 'MaintenanceStandardModal',
+    components: {
+      JMultiSelectTag,
+      Tooltip,
+      // JSelectMaintenanceStandardModal,
+      // UploadModel,
+      PdfView,
+      preview,
+      EquipmentList
+    },
+    data() {
+      return {title: '鎿嶄綔',
+        visible: false,
+        visible4Confirm: false,
+        disableSubmit: false,
+        codeDisable: true,
+        isRevise: false,
+        model: {},
+        upload: {},
+        treeData: [],
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 6 }
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 18 }
+        },
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        validatorRules: {
+          num: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ョ紪鐮�!' }
+            ]
+          },
+          teamName: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨璐d换鐝粍!' }
+            ]
+          },
+          useDepartName: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨瀵硅薄閮ㄩ棬!' }
+            ]
+          },
+          equipmentName: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨璁惧!' }
+            ]
+          },
+          assignMode: {
+            rules: [
+              { required: true, message: '璇烽�夋嫨娲惧伐鏂瑰紡!' }
+            ]
+          },
+          version: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ョ増鏈�!' }
+            ]
+          },
+          historyVersion: {
+            rules: [
+              { required: true, message: '璇疯緭鍏ュ巻鍙茬増鏈�!' }
+            ]
+          }
+        },
+        url: {
+          list: '/eam/maintenanceStandardDetail/getMaintenanceStandardDetailListByIds',
+          add: '/eam/predictiveworkplan/add',
+          edit: '/eam/predictiveworkplan/edit',
+          addDetail: '/eam/maintenanceStandardDetail/add',
+          revise: '/eam/maintenanceStandard/revise',
+          getReviseVersion: '/eam/maintenanceStandard/getReviseVersion',
+          loadOptions: '/sys/sysDepart/loadDepartTreeOptions'
+        },
+
+        dataSource: [],
+        departId: ''
+      }
+    },
+
+    mounted() {
+
+    },
+
+    created() {
+    },
+
+    methods: {
+
+      add() {
+        this.edit({ maintenanceStandardDetaillist: [] })
+      },
+
+      edit(record) {
+        let that = this
+        this.initOptions()
+        this.dataSource = []
+        this.form.resetFields()
+        this.model = Object.assign({}, record)
+        this.visible = true
+        if (record.maintenanceStandardDetaillist != undefined) {
+          const temp = [...record.maintenanceStandardDetaillist]
+          // for (let i = 0; i < temp.length; i++) {
+          //   let r = temp[i].upload;
+          //   r.src = this.getSrc(temp[i].upload);
+          // }
+          that.dataSource = temp
+        }
+        that.$nextTick(() => {
+          that.model.equipmentId = record.id
+          that.model.teamId = record.teamId
+          if (!record.status) {
+            that.model.status = 1
+          }
+          that.form.setFieldsValue(pick(that.model, 'num', 'equipmentName', 'useDepartName', 'teamName', 'assignMode', 'planVersion', 'remark'))
+        })
+        if (record.id) {
+          this.codeDisable = true
+          that.$nextTick(() => {
+            if (that.isRevise) {
+              requestPut(that.url.getReviseVersion, record).then((res) => {
+                if (res.success) {
+                  that.form.setFieldsValue({ planVersion: res.result, historyVersion: record.version })
+                }
+              })
+            }
+          }, 200)
+        } else {
+          this.codeDisable = false
+          that.$nextTick(() => {
+            that.form.setFieldsValue({ 'planVersion': '1.0' })
+          })
+        }
+      },
+
+      initOptions() {
+        getAction(this.url.loadOptions).then(res => {
+          if (res.success) {
+            this.treeData = res.result
+          } else {
+            this.$message.warning(res.message)
+          }
+        })
+      },
+
+      onEquipmentList() {
+        this.$refs.EquipmentList.list()
+        this.$refs.EquipmentList.title = '閫夋嫨璁惧淇℃伅'
+      },
+      sendEquipmentRecord(data) {
+        this.dataSource = []
+        let record = data.record
+        this.model.equipmentId = record.id
+        this.model.teamId = record.teamId
+        this.form.setFieldsValue({
+          equipmentName: record.num + '/' + record.name + '/' + record.model,
+          teamName: record.teamId_dictText
+        })
+      },
+
+      close() {
+        this.$emit('close')
+        this.visible = false
+      },
+
+      handleCancel() {
+        this.close()
+      },
+
+      handleOk() {
+        const that = this
+        this.form.validateFields((err, values) => {
+          if (!err) {
+            that.confirmLoading = true
+            let formData = Object.assign(this.model, values)
+            let obj
+            if (!this.model.id) {
+              formData.planVersion = '1'
+              obj = postAction(this.url.add, formData)
+            } else {
+              if (this.isRevise) {
+                formData.planVersion = '1'
+                obj = postAction(this.url.revise, formData)
+              } else {
+                obj = requestPut(this.url.edit, formData, { id: this.model.id })
+              }
+            }
+            obj.then((res) => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+              } else {
+                that.$message.warning(res.message)
+              }
+            }).finally(() => {
+              that.confirmLoading = false
+              that.close()
+            })
+          }
+        })
+      },
+
+      getUuiD(randomLength) {
+        return Number(
+          Math.random()
+            .toString()
+            .substr(2, randomLength) + Date.now()
+        ).toString(36)
+      }
+
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  /deep/ .frozenRowClass {
+    color: #c9c9c9;
+  }
+
+  .fontweight {
+    font-weight: bold;
+  }
+
+  .ant-btn {
+    padding: 0 10px;
+    margin-left: 3px;
+  }
+
+  .ant-form-item-control {
+    line-height: 0px;
+  }
+
+  /** 涓昏〃鍗曡闂磋窛 */
+  .ant-form .ant-form-item {
+    margin-bottom: 10px;
+  }
+
+  /** Tab椤甸潰琛岄棿璺� */
+  .ant-tabs-content .ant-form-item {
+    margin-bottom: 0px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/eam/modules/predictiveWorkPlan/WarnSelect.vue b/src/views/eam/modules/predictiveWorkPlan/WarnSelect.vue
new file mode 100644
index 0000000..6a8dfe5
--- /dev/null
+++ b/src/views/eam/modules/predictiveWorkPlan/WarnSelect.vue
@@ -0,0 +1,220 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1000"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="鍏抽棴"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form :form="form">
+        <!-- 鏌ヨ鍖哄煙 -->
+        <div class="table-page-search-wrapper">
+          <a-form
+            layout="inline"
+            @keyup.enter.native="searchQuery"
+          >
+            <a-row :gutter="24">
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="鎶ヨ浠g爜">
+                  <j-input
+                    placeholder="璇疯緭鍏ユ姤璀︿唬鐮�"
+                    v-model="queryParam.warnCode"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-form-item label="鎶ヨ鍚嶇О">
+                  <j-input
+                    placeholder="璇疯緭鍏ユ姤璀﹀悕绉�"
+                    v-model="queryParam.warnName"
+                  ></j-input>
+                </a-form-item>
+              </a-col>
+              <a-col
+                :md="6"
+                :sm="8"
+              >
+                <a-button
+                  type="primary"
+                  @click="searchQuery"
+                  icon="search"
+                >鏌ヨ
+                </a-button>
+                <a-button
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left:8px;"
+                >閲嶇疆
+                </a-button>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :span="24">
+
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <div style="margin-top:8px;">
+          <a-table
+            ref="table"
+            bordered
+            size="middle"
+            rowKey="warnCode"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="false"
+            :loading="loading"
+            :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: 'radio'}"
+            @change="handleTableChange"
+            :customRow="clickThenCheck"
+          >
+          </a-table>
+        </div>
+      </a-form>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+  import { getAction } from '@/api/manage'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import JInput from '@/components/jeecg/JInput'
+
+  export default {
+    name: 'WarnSelect',
+    mixins: [JeecgListMixin],
+    components: {
+      JInput
+    },
+    data() {
+      return {
+        title: '鎿嶄綔',
+        visible: false,
+        model: {},
+        confirmLoading: false,
+        form: this.$form.createForm(this),
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key: 'rowIndex',
+            width: 50,
+            align: 'center',
+            customRender: function(t, r, index) {
+              return parseInt(index) + 1
+            }
+          },
+          {
+            title: '鎶ヨ浠g爜',
+            dataIndex: 'warnCode',
+            align: 'center'
+          },
+          {
+            title: '鎶ヨ鍚嶇О',
+            dataIndex: 'warnName',
+            align: 'center'
+          },
+        ],
+        url: {
+          list: '/eam/predictiveworkplanwarn/listPredictiveWorkPlanWarn'
+        }
+      }
+    },
+    methods: {
+
+      searchQuery() {
+        this.loadData()
+      },
+
+      list(equipmentId) {
+        this.queryParam.equipmentId = equipmentId
+        this.visible = true
+        this.loadData()
+      },
+      loadData() {
+        let that = this
+        getAction(this.url.list, this.queryParam).then((res) => {
+          if (res.success) {
+            that.dataSource = res.result
+          }
+        })
+      },
+      clickThenCheck(record) {
+        return {
+          on: {
+            click: (e) => {
+              this.selectedRowRecord = record
+              this.onSelectChange(record.id.split(','), [record])
+            }
+          }
+        }
+      },
+
+      onSelectChange(selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys
+        this.selectedRowRecord = selectedRows[0]
+      },
+
+      close() {
+        this.queryParam = {}
+        this.$emit('close')
+        this.visible = false
+        this.selectedRowKeys = []
+      },
+
+      handleOk() {
+        const that = this
+        // 瑙﹀彂琛ㄥ崟楠岃瘉
+        if (that.selectedRowKeys.length > 0) {
+          if (that.selectedRowRecord.warnCode != null && that.selectedRowRecord.warnCode != '') {
+            that.$emit('sendWarn', { record: that.selectedRowRecord })
+            that.close()
+          } else {
+            that.$message.error('璇烽�夋嫨鍙傛暟锛�')
+          }
+        } else {
+          that.$message.error('璇烽�夋嫨鍙傛暟锛�')
+        }
+      },
+
+      handleCancel() {
+        this.close()
+      }
+
+    }
+  }
+</script>
+<style>
+  @import '~@assets/less/common.less';
+
+  .frozenRowClass {
+    color: #c9c9c9;
+  }
+
+  .fontweight {
+    font-weight: bold;
+  }
+
+  .fontweightfrozen {
+    font-weight: bold;
+    color: #c9c9c9;
+  }
+
+  .success {
+    color: green;
+  }
+
+  .error {
+    color: red;
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.3