Explorar o código

设备档案列表同步dev1

wy hai 1 ano
pai
achega
8ba574622a

+ 115 - 0
src/api/platform/device/device.js

@@ -0,0 +1,115 @@
+import request from '@/utils/request'
+import { BUSINESS_BASE_URL } from '@/api/baseUrl'
+
+/**
+ * 根据id查询设备档案卡
+ * @param {*} params
+ */
+export function getequipmentCard (params) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/equipmentCard/get',
+        method: 'get',
+        params: params
+    })
+}
+/**
+ * 设备档案卡列表(分页条件查询)数据
+ * @param {*} data
+ * @returns
+ */
+export function queryequipmentCard (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/equipmentCard/query',
+        method: 'post',
+        data: data
+    })
+}
+
+/**
+ * 保存设备档案卡信息
+ * @param {*} data
+ * @returns
+ */
+export function saveEquipmentCard (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/equipmentCard/save',
+        method: 'post',
+        data: data
+    })
+}
+
+/**
+ * 删除设备档案卡
+ * @param {*} params
+ * @returns
+ */
+export function removeEquipmentCard (params) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/equipmentCard/remove',
+        method: 'post',
+        params: params
+    })
+}
+
+/**
+ * 根据id查询设备停用报废记录表
+ * @param {*} params
+ * @returns
+ */
+export function getScrappedRecord (params) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/scrappedRecord/get',
+        method: 'get',
+        params: params
+    })
+}
+
+/**
+ * 设备停用报废记录表列表(分页条件查询)数据
+ * @param {*} data
+ * @returns
+ */
+export function queryScrappedRecord (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/scrappedRecord/query',
+        method: 'post',
+        data: data
+    })
+}
+
+/**
+ * 设备维护记录表列表(分页条件查询)数据
+ * @param {*} data
+ * @returns
+ */
+export function queryMaintenanceRecord (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/maintenanceRecord/query',
+        method: 'post',
+        data: data
+    })
+}
+/**
+ * 检定校准实施记录表列表(分页条件查询)数据
+ * @param {*} data
+ * @returns
+ */
+export function queryCalibrationCheckRecord (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/calibrationCheckRecord/query',
+        method: 'post',
+        data: data
+    })
+}
+/**
+ * 设备维修记录表列表(分页条件查询)数据
+ * @param {*} data
+ * @returns
+ */
+export function queryRepairRecord (data) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/equipment/repairRecord/query',
+        method: 'post',
+        data: data
+    })
+}

BIN=BIN
src/assets/images/device/01.png


BIN=BIN
src/assets/images/device/02.png


BIN=BIN
src/assets/images/device/03.png


BIN=BIN
src/assets/images/device/04.png


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 110 - 0
src/utils/query.js


+ 123 - 0
src/views/component/device/calibrationCheckRecord.vue

@@ -0,0 +1,123 @@
+<!-- 校准记录 -->
+<template>
+    <div v-loading="loading" class="table">
+        <el-table :data="listData">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="bianHaoZhongWe" label="设备编号" width="120" />
+            <el-table-column prop="sheBeiMingChen" label="设备名称" />
+            <el-table-column prop="sheBeiLeiXing" label="设备类型" width="140" />
+            <el-table-column prop="xingHaoGuiGe" label="型号/规格" />
+            <el-table-column prop="chuChangBianHa" label="有效期至" />
+            <el-table-column prop="zhunQueDu" label="证书编号" />
+            <el-table-column prop="jianDingDanWei" label="检定单位" />
+            <el-table-column prop="shiShiRiQi" label="实施日期" />
+            <el-table-column prop="xiuZhengYinZi" label="修正因子" width="80" />
+            <el-table-column prop="beiZhu" label="附件" width="260">
+                <template slot-scope="{row}">
+                    <ibps-attachment
+                        v-model="row.beiZhu"
+                        :download="true"
+                        multiple
+                        accept="*"
+                        :readonly="true"
+                    />
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="requestPage.pageNo"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="requestPage.limit"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+    </div>
+</template>
+
+<script>
+import IbpsAttachment from '@/business/platform/file/attachment/selector'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import { queryCalibrationCheckRecord } from '@/api/platform/device/device'
+export default {
+    components: {
+        ibpsUserSelector, IbpsAttachment
+    },
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        }
+    },
+    data () {
+        return {
+            listData: [],
+            loading: false,
+            total: 0,
+            requestPage: {
+                limit: 10,
+                pageNo: 1
+            }
+        }
+    },
+    async mounted () {
+        this.getData()
+    },
+    methods: {
+        async getData () {
+            this.loading = true
+            const { data: { dataResult, pageResult }} = await queryCalibrationCheckRecord({
+                requestPage: this.requestPage,
+                parameters: [
+                    { key: 'Q^she_bei_bian_hao_^S', value: this.params.id },
+                    { key: 'Q^marks_^S', value: 'record' },
+                    { key: 'Q^shi_shi_ri_qi_^SNE', value: 'value' } // 过滤空值 value需有值
+                ],
+                sorts: [
+                    { field: 'bian_zhi_shi_jian', order: 'desc' }
+                ]
+            })
+            this.listData = dataResult
+            this.total = pageResult.totalCount
+            this.loading = false
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.requestPage.pageNo = val
+            this.getData()
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.requestPage.limit = val
+            this.requestPage.pageNo = 1
+            this.getData()
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.requestPage.pageNo - 1) * this.requestPage.limit
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 1357 - 0
src/views/component/device/deviceDialog.vue

@@ -0,0 +1,1357 @@
+<template>
+    <el-dialog
+        v-loading="loading"
+        :title="title"
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :show-close="false"
+        append-to-body
+        fullscreen
+        class="dialog paper-detail-dialog"
+        top="0"
+    >
+        <div slot="title" class="dialog-title">
+            <span class="dialogtitle">{{ title }}</span>
+            <div>
+                <ibps-toolbar :actions="toolbars" @action-event="handleActionEvent" />
+            </div>
+        </div>
+        <div class="container">
+            <div class="left" :style="{width:initWidth}">
+                <div class="form">
+                    <el-form ref="form" label-width="100px" :model="form" :rules="rules" :hide-required-asterisk="true">
+                        <el-row type="flex" justify="center" :gutter="20">
+                            <el-col :span="16">
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="设备验收记录:" prop="sheBeiMingChen">
+                                            <ibps-custom-dialog
+                                                v-model="form.sheBeiMingChen"
+                                                size="mini"
+                                                template-key="sbysdhk"
+                                                :disabled="false"
+                                                type="dialog"
+                                                class="custom-dialog"
+                                                placeholder="请选择"
+                                                icon="el-icon-search"
+                                                style="width:100%"
+                                                @change-link-data="sheBeiMingChenChange"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="设备名称:" prop="sheBeiMingCheng">
+                                            <template slot="label">
+                                                <span class="required">设备名称:</span>
+                                            </template>
+                                            <el-input v-model="form.sheBeiMingCheng" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="建档部门:" prop="bianZhiBuMen">
+                                            <template slot="label">
+                                                <span class="required">建档部门:</span>
+                                            </template>
+                                            <ibps-user-selector
+                                                v-model="form.bianZhiBuMen"
+                                                type="position"
+                                                readonly-text="text"
+                                                :disabled="false"
+                                                :multiple="false"
+                                                size="mini"
+                                                :filter="filter"
+                                                filtrate
+                                                style="width:100%"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="建档人:" prop="bianZhiRen">
+                                            <ibps-user-selector
+                                                v-model="form.bianZhiRen"
+                                                type="user"
+                                                readonly-text="text"
+                                                :disabled="true"
+                                                :multiple="false"
+                                                size="mini"
+                                                style="width:100%"
+                                                :filter="filter"
+                                                filtrate
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="建档时间:" prop="bianZhiShiJian">
+                                            <template slot="label">
+                                                <span class="required">建档时间:</span>
+                                            </template>
+                                            <el-date-picker
+                                                v-model="form.bianZhiShiJian"
+                                                style="width:100%"
+                                                type="datetime"
+                                                placeholder="选择日期时间"
+                                                default-time="12:00:00"
+                                                :readonly="readonly"
+                                                value-format="yyyy-MM-dd HH:mm"
+                                                size="mini"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="设备编号:" prop="sheBeiShiBieH">
+                                            <template slot="label">
+                                                <span>设备编号</span>
+                                                <el-tooltip effect="dark" content="设备编号由系统自动生成。" placement="top">
+                                                    <i class="el-icon-question question-icon">:</i>
+                                                </el-tooltip>
+                                            </template>
+                                            <span>{{ form.sheBeiShiBieH }}</span>
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="原设备编号:" prop="yuanSheBeiBian">
+                                            <template slot="label">
+                                                <span class="required">原设备编号:</span>
+                                            </template>
+                                            <el-input v-model="form.yuanSheBeiBian" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="设备状态:" prop="sheBeiZhuangTa">
+                                            <span>{{ showState }}</span>
+                                        </el-form-item>
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="设备类型:" prop="sheBeiLeiXing">
+                                            <el-select v-model="form.sheBeiLeiXing" placeholder="请选择" size="mini" style="width:100%">
+                                                <el-option
+                                                    v-for="item in ['检验系统','通用设备','软件','信息系统']"
+                                                    :key="item"
+                                                    :label="item"
+                                                    :value="item"
+                                                />
+                                            </el-select>
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="规格型号:" prop="guiGeXingHao">
+                                            <template slot="label">
+                                                <span class="required">规格型号:</span>
+                                            </template>
+                                            <el-input v-model="form.guiGeXingHao" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="接收时状态:" prop="jieShouZhuangTai">
+                                            <template slot="label">
+                                                <span class="required">接收时状态:</span>
+                                            </template>
+                                            <el-select v-model="form.jieShouZhuangTai" placeholder="请选择" size="mini" style="width:100%">
+                                                <el-option
+                                                    v-for="item in ['新设备','二手或翻新设备']"
+                                                    :key="item"
+                                                    :label="item"
+                                                    :value="item"
+                                                />
+                                            </el-select>
+                                        </el-form-item>
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="保管人:" prop="guanLiRen">
+                                            <template slot="label">
+                                                <span class="required">保管人:</span>
+                                            </template>
+                                            <ibps-user-selector
+                                                v-model="form.guanLiRen"
+                                                type="user"
+                                                readonly-text="text"
+                                                :disabled="false"
+                                                :multiple="false"
+                                                size="mini"
+                                                :filter="filter"
+                                                filtrate
+                                                style="width:100%"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="放置地点:" prop="cunFangWeiZhi">
+                                            <template slot="label">
+                                                <span class="required">放置地点:</span>
+                                            </template>
+                                            <ibps-custom-dialog
+                                                v-model="form.cunFangWeiZhi"
+                                                size="mini"
+                                                template-key="fjxzkdd"
+                                                :disabled="false"
+                                                type="dialog"
+                                                class="custom-dialog"
+                                                placeholder="请选择"
+                                                icon="el-icon-search"
+                                                style="width:100%"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="固定资产号:">
+                                            <el-input v-model="form.ziChanBianHao" size="mini" />
+                                        </el-form-item>
+
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="厂家/品牌:">
+                                            <el-input v-model="form.changShang" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="出厂日期:" prop="chuChangRiQi">
+                                            <template slot="label">
+                                                <span class="required">出厂日期</span>
+                                            </template>
+                                            <el-date-picker
+                                                v-model="form.chuChangRiQi"
+                                                style="width:100%"
+                                                type="date"
+                                                placeholder="选择日期"
+                                                :readonly="readonly"
+                                                value-format="yyyy-MM-dd"
+                                                size="mini"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="出厂编号:">
+                                            <el-input v-model="form.jiShenXuHao" size="mini" />
+                                        </el-form-item>
+
+                                    </el-col>
+                                </el-row>
+                                <el-row :gutter="20">
+                                    <el-col :span="8">
+                                        <el-form-item label="供应商:">
+                                            <ibps-custom-dialog
+                                                v-model="form.shiFouQiJianH"
+                                                size="mini"
+                                                template-key="gysxxdhk"
+                                                :disabled="false"
+                                                type="dialog"
+                                                class="custom-dialog"
+                                                placeholder="请选择"
+                                                icon="el-icon-search"
+                                                style="width:100%"
+                                                @change-link-data="shiFouQiJianHChange"
+                                            />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="供应商电话:">
+                                            <el-input v-model="form.lianXiFangShi" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                    <el-col :span="8">
+                                        <el-form-item label="注册证号:">
+                                            <el-input v-model="form.zhuCeZhengHao" size="mini" />
+                                        </el-form-item>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-row v-if="photos.length>0">
+                                    <el-col>
+                                        <el-carousel trigger="click" height="250px" indicator-position="none">
+                                            <el-carousel-item v-if="photos.length==0">
+                                                <el-empty description="暂无图片" />
+                                            </el-carousel-item>
+                                            <template v-else>
+                                                <el-carousel-item v-for="item in photos" :key="item.id">
+                                                    <el-image
+                                                        style="width: 100%; height: 100%"
+                                                        :src="item.url"
+                                                        fit="contain"
+                                                        :preview-src-list="photos.map(item=>item.url)"
+                                                    />
+                                                </el-carousel-item>
+                                            </template>
+
+                                        </el-carousel>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                        </el-row>
+                    </el-form>
+                </div>
+                <div class="tabs">
+                    <el-row>
+                        <el-col>
+                            <el-tabs v-model="activeName" @tab-click="handleClick">
+                                <el-tab-pane label="基本信息" name="one">
+                                    <el-form label-width="100px" :model="form" :hide-required-asterisk="true">
+                                        <el-row :gutter="20">
+                                            <!-- 第一列 -->
+                                            <el-col :span="8">
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="购进日期:">
+                                                            <el-date-picker
+                                                                v-model="form.gouJinRiQi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="接收日期:">
+                                                            <el-date-picker
+                                                                v-model="form.jieShouRiQi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="验收日期:">
+                                                            <el-date-picker
+                                                                v-model="form.yanShouRiQi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="投入日期:">
+                                                            <el-date-picker
+                                                                v-model="form.qiYongRiQi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="核查日期:">
+                                                            <el-date-picker
+                                                                v-model="form.biXuSheShi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="核查人:">
+                                                            <ibps-user-selector
+                                                                v-model="form.biXuDeHuanJin"
+                                                                type="user"
+                                                                readonly-text="text"
+                                                                :disabled="false"
+                                                                :multiple="false"
+                                                                size="mini"
+                                                                style="width:100%"
+                                                                :filter="filter"
+                                                                filtrate
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="电源要求:">
+                                                            <el-input v-model="form.dianYuanYaoQiu" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="环境要求:">
+                                                            <el-input v-model="form.huanJingYaoQiu" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="使用年限(年):">
+                                                            <el-input v-model="form.heChaXiaoZhun" size="mini" type="number" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="资产原值(元):">
+                                                            <el-input v-model="form.ziChanYuanZhi" size="mini" type="number" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                            </el-col>
+                                            <!-- 第二列 -->
+                                            <el-col :span="8">
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="是否维护:">
+                                                            <el-select v-model="form.shiFouWeiHu" placeholder="请选择" size="mini" style="width:100%">
+                                                                <el-option
+                                                                    v-for="item in ['是','否']"
+                                                                    :key="item"
+                                                                    :label="item"
+                                                                    :value="item"
+                                                                />
+                                                            </el-select>
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="设备分组:">
+                                                            <ibps-custom-dialog
+                                                                v-model="form.weiHuFangShi"
+                                                                size="mini"
+                                                                template-key="sbbqdhk"
+                                                                multiple
+                                                                :disabled="false"
+                                                                type="dialog"
+                                                                class="custom-dialog"
+                                                                placeholder="请选择"
+                                                                icon="el-icon-search"
+                                                                style="width:100%"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="是否24H开机:">
+                                                            <el-select v-model="form.jianKongYiJu" placeholder="请选择" size="mini" style="width:100%">
+                                                                <el-option
+                                                                    v-for="item in ['是','否']"
+                                                                    :key="item"
+                                                                    :label="item"
+                                                                    :value="item"
+                                                                />
+                                                            </el-select>
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.jianKongYiJu==='否'">
+                                                    <el-col>
+                                                        <el-form-item label="开机时间:">
+                                                            <el-time-picker
+                                                                v-model="form.kaiShiShiYong"
+                                                                placeholder="任意时间点"
+                                                                size="mini"
+                                                                style="width:100%"
+                                                                value-format="HH:mm:ss"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.jianKongYiJu==='否'">
+                                                    <el-col>
+                                                        <el-form-item label="关机时间:">
+                                                            <el-time-picker
+                                                                v-model="form.shiJiShiYongF"
+                                                                placeholder="任意时间点"
+                                                                size="mini"
+                                                                style="width:100%"
+                                                                value-format="HH:mm:ss"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <!-- <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="是否限用:">
+                                                            <el-select v-model="form.xiaoZhunWuCha" placeholder="请选择" size="mini" style="width:100%">
+                                                                <el-option
+                                                                    v-for="item in ['是','否']"
+                                                                    :key="item"
+                                                                    :label="item"
+                                                                    :value="item"
+                                                                />
+                                                            </el-select>
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.xiaoZhunWuCha==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="限用范围:">
+                                                            <el-input v-model="form.caiGouHeTong" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row> -->
+                                                <el-row>
+                                                    <!-- todo -->
+                                                    <el-col>
+                                                        <el-alert
+                                                            title="开关机时间配置说明"
+                                                            type="success"
+                                                            description="日保养、按需保养、这些周期,如果配置了开关机时间,在设备使用与维护时会自动带出"
+                                                            :closable="false"
+                                                        />
+                                                    </el-col>
+                                                </el-row>
+                                            </el-col>
+                                            <!-- 第三列 -->
+                                            <el-col :span="8">
+                                                <el-row>
+                                                    <el-col>
+                                                        <el-form-item label="是否校准:" prop="shiFouXiaoZhun">
+                                                            <el-select v-model="form.shiFouXiaoZhun" placeholder="请选择" size="mini" style="width:100%">
+                                                                <el-option
+                                                                    v-for="item in ['是','否']"
+                                                                    :key="item"
+                                                                    :label="item"
+                                                                    :value="item"
+                                                                />
+                                                            </el-select>
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="检定/校准周期(月):" label-width="140">
+                                                            <el-input v-model="form.xiaoZhunZQ" size="mini" type="number" style="width:100%" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="检定/校准单位:">
+                                                            <ibps-custom-dialog
+                                                                v-model="form.shiYongKeShi"
+                                                                size="mini"
+                                                                template-key="gysxxdhk"
+                                                                :disabled="false"
+                                                                type="dialog"
+                                                                class="custom-dialog"
+                                                                placeholder="请选择"
+                                                                icon="el-icon-search"
+                                                                style="width:100%"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="最近校准时间:">
+                                                            <el-date-picker
+                                                                v-model="form.yiXiaoRiQi"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="校准有效期至:">
+                                                            <el-date-picker
+                                                                v-model="form.xiaoZhunYouXia"
+                                                                style="width:100%"
+                                                                type="date"
+                                                                placeholder="选择日期"
+                                                                :readonly="readonly"
+                                                                value-format="yyyy-MM-dd"
+                                                                size="mini"
+                                                            />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是'">
+                                                    <el-col>
+                                                        <el-form-item label="校准证书编号:">
+                                                            <el-input v-model="form.zhengShuBianHa" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="false">
+                                                    <el-col>
+                                                        <el-form-item label="校准机构:">
+                                                            <el-input v-model="form.shiWuShuoMing" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是' && !isSheKou">
+                                                    <el-col>
+                                                        <el-form-item label="检定/校准参数:">
+                                                            <el-input v-model="form.jianDingXiao" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是' && !isSheKou">
+                                                    <el-col>
+                                                        <el-form-item label="测量范围:">
+                                                            <el-input v-model="form.ceLiangGongZuo" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是' && !isSheKou">
+                                                    <el-col>
+                                                        <el-form-item label="U/精确度/最大允差:" label-width="130">
+                                                            <el-input v-model="form.zuiDaYunCha" size="mini" style="width:100%" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+                                                <el-row v-if="form.shiFouXiaoZhun==='是' && !isSheKou">
+                                                    <el-col>
+                                                        <el-form-item label="修正值:">
+                                                            <el-input v-model="form.xiuZhengZhiXiu" size="mini" />
+                                                        </el-form-item>
+                                                    </el-col>
+                                                </el-row>
+
+                                            </el-col>
+                                        </el-row>
+                                        <el-row :gutter="20">
+                                            <el-col :span="24">
+                                                <el-alert :closable="false" type="success" style="margin-bottom:20px">设备照片及相关附件</el-alert>
+                                            </el-col>
+                                            <el-col :span="24">
+                                                <el-form-item label="设备图片:">
+                                                    <ibps-image
+                                                        v-model="form.beiZhu"
+                                                        height="160"
+                                                        width="160"
+                                                        accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
+                                                        multiple
+                                                        download
+                                                        :disabled="readonly"
+                                                        size=""
+                                                    />
+                                                </el-form-item>
+                                            </el-col>
+                                            <el-col :span="24">
+                                                <el-form-item label="附件上传:">
+                                                    <ibps-attachment
+                                                        v-model="form.yqzp"
+                                                        :download="true"
+                                                        multiple
+                                                        accept="*"
+                                                        :readonly="false"
+                                                        style="width:100%"
+                                                    />
+                                                </el-form-item>
+                                            </el-col>
+                                            <el-col :span="24">
+                                                <el-form-item label="资质证书:">
+                                                    <ibps-attachment
+                                                        v-model="form.faPiao"
+                                                        :download="true"
+                                                        multiple
+                                                        accept="*"
+                                                        :readonly="false"
+                                                        style="width:100%"
+                                                    />
+                                                </el-form-item>
+                                            </el-col>
+                                            <el-col :span="24">
+                                                <el-form-item label="设备说明书:">
+                                                    <ibps-attachment
+                                                        v-model="form.fuJianShang"
+                                                        :download="true"
+                                                        multiple
+                                                        accept="*"
+                                                        :readonly="false"
+                                                        style="width:100%"
+                                                    />
+                                                </el-form-item>
+                                            </el-col>
+                                            <!-- <el-col :span="24">
+                                                <el-form-item label="说明书分类:">
+                                                    <SelectType :field="{}" @change-data="changeData" />
+                                                </el-form-item>
+                                            </el-col>
+                                            <el-col :span="24">
+                                                <el-form-item label="文件路径:">
+                                                    <span>{{ form.wenJianXiLei }}</span>
+                                                </el-form-item>
+                                            </el-col> -->
+                                        </el-row>
+                                    </el-form>
+
+                                </el-tab-pane>
+
+                                <el-tab-pane v-for="item in tabItems" :key="item.name" :label="item.label" :name="item.name" :disabled="item.isKeepAlive&&!isEdit">
+                                    <template v-if="item.isKeepAlive">
+                                        <!-- 使用 v-if 配合 keep-alive 实现按需加载 -->
+                                        <keep-alive>
+                                            <component :is="item.component" v-if="activeName===item.name" :params="form" />
+                                        </keep-alive>
+                                    </template>
+                                    <template v-else>
+                                        <component :is="item.component" :ref="item.ref" :list-data="form[item.data]" />
+                                    </template>
+                                </el-tab-pane>
+                            </el-tabs>
+                        </el-col>
+                    </el-row>
+                </div>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import { getSetting } from '@/utils/query'
+import dayjs from 'dayjs'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import { getequipmentCard, saveEquipmentCard } from '@/api/platform/device/device'
+import Maintenance from './maintenance.vue'
+import MoreDevices from './moreDevices.vue'
+import ScrappedRecord from './scrappedRecord.vue'
+import MaintenanceRecord from './maintenanceRecord.vue'
+import RepairRecord from './repairRecord.vue'
+import CalibrationCheckRecord from './calibrationCheckRecord.vue'
+import IbpsAttachment from '@/business/platform/file/attachment/selector'
+import SelectType from '@/views/component/selectType.vue'
+import { getImage } from '@/api/platform/file/attachment'
+export default {
+    components: {
+        ibpsUserSelector, Maintenance, MoreDevices, ScrappedRecord, MaintenanceRecord, RepairRecord, CalibrationCheckRecord, IbpsAttachment, SelectType,
+        IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog'),
+        IbpsImage: () => import('@/business/platform/file/image')
+    },
+    props: {
+        params: {
+            type: Object,
+            default: function () {
+                return {}
+            }
+        },
+        stateList: {
+            type: Object,
+            default: function () {
+                return { '停用': '停用', '报废': '报废', '合格': '合格' }
+            }
+        }
+    },
+    data () {
+        const { userId, position, level, deptList } = this.$store.getters
+        return {
+            tabItems: [
+                { label: '维护项目', name: 'two', ref: 'MaintenanceRef', data: 'maintenanceItemPoList', component: 'Maintenance', isKeepAlive: false },
+                { label: '附属设备及配件', name: 'three', ref: 'MoreDevicesRef', data: 'accessoriesDevicePoList', component: 'MoreDevices', isKeepAlive: false },
+                { label: '使用与维护记录', name: 'four', component: 'MaintenanceRecord', isKeepAlive: true },
+                { label: '校准记录', name: 'five', component: 'CalibrationCheckRecord', isKeepAlive: true },
+                { label: '维修记录', name: 'six', component: 'RepairRecord', isKeepAlive: true },
+                { label: '停用、报废记录', name: 'seven', component: 'ScrappedRecord', isKeepAlive: true }
+            ],
+            tabList: {},
+            filter: [{
+                descVal: '1',
+                includeSub: true,
+                old: 'position',
+                partyId: this.$store.getters.userInfo.employee.positions,
+                partyName: '',
+                scriptContent: '',
+                type: 'user',
+                userType: 'position'
+            }],
+            isFirstyiXiaoRiQi: true,
+            isFirstbianZhiBuMen: true,
+            isSheKou: false,
+            readonly: false,
+            activeName: 'one',
+            dialogVisible: true,
+            userId: userId,
+            position: position,
+            deptList: deptList,
+            level: level.second || level.first,
+            org: level.first || '',
+            loading: false,
+            title: '设备档案卡',
+            toolbars: [
+                { key: 'save', label: '保存' },
+                { key: 'cancel', label: '退出', type: 'danger', icon: 'ibps-icon-close' }
+            ],
+            initWidth: '1480px',
+            isEdit: false,
+            isFinished: false,
+            preParams: {},
+            Ids: [],
+            form: {
+                gouJinRiQi: '', // 购进日期
+                changShang: '', // 厂家/品牌
+                guiGeXingHao: '', // 规格型号
+                jieShouRiQi: '', // 接收日期
+                qiYongRiQi: '', // 投入日期
+                cunFangDiDian: '',
+                cunFangWeiZhi: '', // 放置地点
+                jieShouZhuangTai: '', // 接收时状态
+                guanLiRen: '', // 保管人
+                weiHuFangShi: '', // 设备分组
+                bianZhiRen: '', // 建档人
+                bianZhiBuMen: '', // 建档部门
+                bianZhiShiJian: '', // 建档时间
+                shiFouGuoShen: '',
+                sheBeiLeiXing: '', // 设备类型
+                sheBeiZhuangTa: '', // 设备状态
+                sheBeiShiBieH: '', // 设备编号
+                shiFouXiaoZhun: '', // 是否校准
+                gongYingShang: '',
+                shiFouQiJianH: '', // 供应商id
+                lianXiFangShi: '', // 供应商电话
+                xiaoZhunYouXia: '', // 校准有效期至
+                chuChangRiQi: '', // 出厂日期
+                sheBeiMingCheng: '', // 设备名称
+                sheBeiMingChen: '', // 设备名称id
+                yiXiaoRiQi: '', // 最近校准时间
+                heChaXiaoZhun: '', // 使用年限
+                shiJiShiYongF: '', // 关机时间
+                kaiShiShiYong: '', // 开机时间
+                zhengShuBianHa: '', // 校准证书编号
+                xiaoZhunWuCha: '', // 是否限用
+                xiaoZhunZQ: '', // 检定/校准周期
+                shiYongKeShi: '', // 检定/校准单位
+                yuanSheBeiBian: '', // 原设备编号
+                jianKongYiJu: '', // 是否24H开机
+                biXuDeHuanJin: '', // 核查人
+                biXuSheShi: '', // 核查日期
+                ziChanYuanZhi: '', // 资产原值
+                ziChanBianHao: '', // 固定资产号
+                shiFouWeiHu: '', // 是否维护
+                jiShenXuHao: '', // 出厂编号
+                yanShouRiQi: '', // 验收日期
+                huanJingYaoQiu: '', // 环境要求
+                dianYuanYaoQiu: '', // 电源要求
+                zhuCeZhengHao: '', // 注册证号
+                yqzp: '', // 附件上传
+                faPiao: '', // 资质证书
+                fuJianShang: '', // 设备使用说明书
+                beiZhu: '', // 设备图片
+                caiGouHeTong: '', // 限用范围
+                zhuanYeBuMen: '',
+                wenJianXiLei: '', // 附件细类
+                xiLeiId: '',
+                quanXianLeiXing: '',
+                diDian: '',
+                buMen: '', // 图片id
+                ceLiangGongZuo: '', // 测量范围
+                jianDingXiao: '', // 检定/校准参数
+                xiuZhengZhiXiu: '', // 修正值
+                zuiDaYunCha: '', // U/精确度/最大允差
+                shiWuShuoMing: '' // 校准机构
+
+            },
+            rules: {
+                sheBeiMingCheng: [
+                    { required: true, message: '设备名称不能为空', trigger: 'blur' }
+                ],
+                sheBeiShiBieH: [
+                    { required: true, message: '设备编号不能为空', trigger: 'blur' }
+                ],
+                yuanSheBeiBian: [
+                    { required: true, message: '原设备编号不能为空', trigger: 'blur' }
+                ],
+                sheBeiLeiXing: [
+                    { required: true, message: '设备类型不能为空', trigger: 'blur' }
+                ],
+                sheBeiZhuangTa: [
+                    { required: true, message: '设备状态不能为空', trigger: 'blur' }
+                ],
+                guiGeXingHao: [
+                    { required: true, message: '规格型号不能为空', trigger: 'blur' }
+                ],
+                bianZhiBuMen: [
+                    { required: true, message: '建档部门不能为空', trigger: 'blur' }
+                ],
+                bianZhiRen: [
+                    { required: true, message: '建档人不能为空', trigger: 'blur' }
+                ],
+                bianZhiShiJian: [
+                    { required: true, message: '建档时间不能为空', trigger: 'blur' }
+                ],
+                jieShouZhuangTai: [
+                    { required: true, message: '接收时状态不能为空', trigger: 'blur' }
+                ],
+                guanLiRen: [
+                    { required: true, message: '保管人不能为空', trigger: 'blur' }
+                ],
+                cunFangWeiZhi: [
+                    { required: true, message: '放置地点不能为空', trigger: 'blur' }
+                ],
+                shiFouXiaoZhun: [
+                    { required: true, message: '是否校准不能为空', trigger: 'blur' }
+                ],
+                chuChangRiQi: [
+                    { required: true, message: '出厂日期不能为空', trigger: 'blur' }
+                ]
+
+            }
+        }
+    },
+    computed: {
+        photos () {
+            if (this.form.beiZhu) {
+                const photos = JSON.parse(this.form.beiZhu)
+                photos.forEach(item => {
+                    item.url = getImage(item.id)
+                })
+                return photos
+            }
+            return []
+        },
+        showState () {
+            return this.stateList[this.form.sheBeiZhuangTa] || this.form.sheBeiZhuangTa
+        }
+    },
+    watch: {
+        photos: {
+            handler (val) {
+                this.form.buMen = val.map(item => item.id).join(',')
+            }
+        },
+        'form.xiaoZhunWuCha': {
+            handler (val, old) {
+                if (!old) return
+                if (val === '否') {
+                    this.form.sheBeiZhuangTa = '合格'
+                } else if (val === '是') {
+                    this.form.caiGouHeTong = ''
+                    this.form.sheBeiZhuangTa = '限用'
+                }
+            }
+        },
+        'form.cunFangWeiZhi': {
+            async handler (val) {
+                if (!val) return
+                const sql = `select fang_jian_ming_ha from t_jjqfjb where id_='${val}'`
+                const { variables: { data }} = await this.$common.request('sql', sql)
+                this.form.cunFangDiDian = data[0].fang_jian_ming_ha
+            }
+        },
+        // 根据编制部门动态获取对应文件存放处数据
+        // 'form.bianZhiBuMen': {
+        //     handler (value) {
+        //         if (value) {
+        //             if (this.isFirstbianZhiBuMen) {
+        //                 this.isFirstbianZhiBuMen = false
+        //                 return
+        //             }
+        //             this.handleData(value)
+        //         }
+        //     }
+        // },
+        // 根据最近检定时间动态计算对应有效期至
+        'form.yiXiaoRiQi': {
+            handler (value) {
+                if (value) {
+                    if (this.isFirstyiXiaoRiQi) {
+                        this.isFirstyiXiaoRiQi = false
+                        return
+                    }
+                    const zhouQi = this.form.xiaoZhunZQ || 0
+                    const result = this.$common.getFormatDate('string', 10, this.$common.getDate('month', Number(zhouQi), value))
+                    this.form.xiaoZhunYouXia = result
+                }
+            }
+        }
+    },
+
+    async mounted () {
+        const tabList = await getSetting('device', 'tabList')
+        if (tabList) {
+            console.debug(tabList)
+            this.tabList = tabList
+        }
+        this.init()
+    },
+    methods: {
+        sheBeiMingChenChange (key, data) {
+            this.form.sheBeiMingCheng = data.ming_cheng_str_
+            this.form.guiGeXingHao = data.xing_hao_gui_ge_
+            this.form.jiShenXuHao = data.chu_chang_bian_ha
+            this.form.changShang = data.sheng_chan_chang_
+            this.form.yuanSheBeiBian = data.she_bei_bian_hao_
+        },
+        // 根据供应商自动带出供应商名称和电话
+        shiFouQiJianHChange (key, data) {
+            this.form.lianXiFangShi = data.lian_xi_dian_hua_
+            this.form.gongYingShang = data.gong_ying_shang_m
+        },
+        changeData (...args) {
+            this.form[args[0]] = args[1]
+        },
+        handleData (departmentId) {
+        // JSON_UNQUOTE( JSON_EXTRACT( AUTHORITY_NAME, '$.chaYue' ) )
+            const sql = `select
+                        id_ AS leiXingId,
+                        AUTHORITY_NAME AS chaYueValue 
+                    FROM
+                        ibps_cat_type 
+                    WHERE
+                        category_key_ = 'FILE_TYPE' 
+                        AND AUTHORITY_NAME LIKE '%"${departmentId}"%' 
+                        AND name_ = '设备使用说明书'`
+            // console.log(sql)
+            const { deptList = [] } = this.$store.getters || {}
+            const dept = deptList.find((i) => i.positionId === departmentId)
+            this.$common.request('sql', sql).then((res) => {
+                const { data = [] } = res.variables || {}
+                this.form.wenJianXiLei = `外部文件 / ${dept?.positionName} / 设备使用说明书`
+                if (!data.length) {
+                    return
+                }
+                const { leiXingId, chaYueValue } = data[0] || {}
+                this.form.xiLeiId = leiXingId
+                this.form.quanXianLeiXing = JSON.parse(chaYueValue).chaYue
+                this.form.zhuanYeBuMen = departmentId
+            })
+        },
+        handleClick () {
+
+        },
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'cancel':
+                    this.closeDialog(true)
+                    break
+                case 'save':
+                    this.goSave('close')
+                    break
+                default:
+                    break
+            }
+        },
+
+        // 获取人员部门
+        getPersonPosition (id) {
+            const userList = this.$store.getters.userList
+            const bianzhiUserid = userList.find(i => i.userId === id)
+            if (bianzhiUserid) {
+                return bianzhiUserid.positionId
+            }
+        },
+        isDateMoreThenSecondDay (firstTime, secondTime) {
+            if (!firstTime || !secondTime) {
+                return false
+            }
+            return new Date(firstTime).getTime() > new Date(secondTime).getTime()
+        },
+        async checkRequired (flag) {
+            if (this.form.xiaoZhunWuCha === '是' && !this.form.caiGouHeTong) {
+                throw new Error('请填写限用范围!')
+            }
+            if (this.form.accessoriesDevicePoList.length > 0) {
+                for (let i = 0; i < this.form.accessoriesDevicePoList.length; i++) {
+                    const item = this.form.accessoriesDevicePoList[i]
+                    if (!item.mingCheng) {
+                        throw new Error(`附属设备及配件第${i + 1}行名称缺失!`)
+                    }
+                    if (!item.guiGeXingHao1) {
+                        throw new Error(`附属设备及配件第${i + 1}行规格型号缺失!`)
+                    }
+                    if (!item.danWei) {
+                        throw new Error(`附属设备及配件第${i + 1}行单位缺失!`)
+                    }
+                    if (!item.shuLiang) {
+                        throw new Error(`附属设备及配件第${i + 1}行数量缺失!`)
+                    }
+                }
+            }
+
+            const sysDeviceNo = this.form.sheBeiShiBieH
+            const originalDeviceNo = this.form.yuanSheBeiBian
+            const position = this.form.diDian
+            const sql = `select count(1) as num from t_sbdj where yuan_she_bei_bian = '${originalDeviceNo}' and di_dian_ = '${position}' and she_bei_shi_bie_h <> '${sysDeviceNo}' limit 1`
+            const result = await this.$common.request('sql', sql)
+            const { data = [] } = result.variables || {}
+            if (data[0].num > 0) {
+                throw new Error(`系统当前已经存在此原设备编号,请更换另一个编号!`)
+            }
+
+            const exFactoryTime = this.form.chuChangRiQi
+            const reviceTime = this.form.jieShouRiQi
+            const useTime = this.form.qiYongRiQi
+            // 如果有出厂日期,则接收日期必须在出厂日期之后,投入日期必须在出厂日期之后
+            // 校验接收日期是否在投入日期之前
+            if (exFactoryTime && reviceTime) {
+                if (this.isDateMoreThenSecondDay(exFactoryTime, reviceTime)) {
+                    throw new Error(`该设备的接收日期不得早于出厂日期!`)
+                }
+            }
+            if (exFactoryTime && useTime) {
+                if (this.isDateMoreThenSecondDay(exFactoryTime, useTime)) {
+                    throw new Error(`该设备的投入日期不得早于出厂日期!`)
+                }
+            }
+            if (reviceTime && useTime) {
+                if (this.isDateMoreThenSecondDay(reviceTime, useTime)) {
+                    throw new Error(`该设备的投入日期不得早于接收日期!`)
+                }
+            }
+        },
+        async goAdd () {
+            try {
+                this.loading = true
+                await saveEquipmentCard(this.form)
+                this.$message.success('添加成功')
+                this.closeDialog(true)
+                this.loading = false
+            } catch (error) {
+                console.log(error)
+                this.$message.warning('添加失败')
+                this.loading = false
+            }
+        },
+        async subForm (id, table, parentData) {
+            const sql1 = `select id_ from ${table} where parent_id_='${id}'`
+            const { variables: { data }} = await this.$common.request('sql', sql1)
+            const pre_list = data.length > 0 ? data.map(item => item.id_) : []
+            const update_list = []
+            const add_list = []
+            parentData.forEach(item => {
+                if (item.id) {
+                    update_list.push(item)
+                } else {
+                    add_list.push(item)
+                }
+            })
+            const delete_list = pre_list.filter(id => !update_list.map(item => item.id).includes(id))
+            return {
+                add_list,
+                update_list,
+                delete_list
+            }
+        },
+        async goEdit (flag) {
+            try {
+                this.loading = true
+                await saveEquipmentCard(this.form)
+                this.$message.success('修改成功')
+                this.closeDialog(true)
+                this.loading = false
+            } catch (error) {
+                this.$message.warning(error.message)
+                this.loading = false
+                throw new Error(error.message)
+            }
+        },
+        goSave (flag) {
+            this.$refs.form.validate(async (valid) => {
+                if (valid) {
+                    try {
+                        // 维护项目
+                        this.form.maintenanceItemPoList = this.$refs.MaintenanceRef?.[0]?.listDataCopy || this.form.maintenanceItemPoList || []
+                        // 附属设备及配件
+                        this.form.accessoriesDevicePoList = this.$refs.MoreDevicesRef?.[0]?.listDataCopy || this.form.accessoriesDevicePoList || []
+                        await this.checkRequired()
+                        if (this.isEdit) {
+                            this.goEdit(flag)
+                        } else {
+                            this.goAdd()
+                        }
+                    } catch (error) {
+                        this.$message.warning(error.message)
+                    }
+                } else {
+                    return this.$message.warning('请填写必填项!')
+                }
+            })
+        },
+        // 刷新
+        async goRefresh () {
+        },
+        // 关闭当前窗口
+        closeDialog (needRefresh) {
+            this.dialogVisible = false
+            if (needRefresh) {
+                this.$emit('close')
+            }
+        },
+        // 检查设备编号是否重复
+        async checkIsRepeat (id) {
+            const sql = `select id_ from t_sbdj where she_bei_shi_bie_h='${id}' limit 1`
+            const { variables: { data }} = await this.$common.request('sql', sql)
+            return data.length > 0
+        },
+        generateRandomString () {
+            return `JYK-${Math.floor(Math.random() * 88888) + 10000}`
+        },
+        async init () {
+            this.loading = true
+            this.isEdit = !!(this.params && this.params.id)
+            this.isSheKou = this.deptList[0].positionId === '1166372468122714112' // 判断是否是蛇口医院
+
+            // 根据全局配置动态生成tab
+            const newTab = []
+            for (const key in this.tabList) {
+                if (Object.hasOwnProperty.call(this.tabList, key)) {
+                    const newLabel = this.tabList[key]
+                    const t = this.tabItems.find(i => i.label === key)
+                    if (t) {
+                        t.label = newLabel
+                        newTab.push(t)
+                    }
+                }
+            }
+            if (newTab.length > 0) {
+                this.tabItems = newTab
+            }
+
+            if (this.isEdit) {
+                const { data } = await getequipmentCard({ id: this.params.id })
+                this.form = data
+            } else {
+                this.isFirstbianZhiBuMen = false
+                this.isFirstyiXiaoRiQi = false
+                // 随机生成一个不重复的设备编号
+                this.form.sheBeiShiBieH = this.generateRandomString()
+                for (; await this.checkIsRepeat(this.form.sheBeiShiBieH);) {
+                    this.form.sheBeiShiBieH = this.generateRandomString()
+                }
+                this.form.jieShouRiQi = dayjs().format('YYYY-MM-DD')
+                this.form.qiYongRiQi = dayjs().format('YYYY-MM-DD')
+                this.form.xiaoZhunWuCha = '否'
+                this.form.jieShouZhuangTai = '新设备'
+                this.form.bianZhiRen = this.userId
+                const pos = this.position.split(',')
+                this.form.bianZhiBuMen = pos[pos.length - 1]
+                this.form.bianZhiShiJian = dayjs().format('YYYY-MM-DD HH:mm')
+                this.form.shiFouGuoShen = '已完成'
+                this.form.sheBeiLeiXing = '检验系统'
+                this.form.sheBeiZhuangTa = '合格'
+                this.form.shiFouXiaoZhun = '是'
+                this.form.jianKongYiJu = '否'
+                this.form.shiFouWeiHu = '是'
+                this.form.diDian = this.level
+            }
+            this.loading = false
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.paper-detail-dialog {
+    ::v-deep {
+        .el-dialog__header {
+            text-align: center;
+        }
+    }
+.dialog-title{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    div{
+        z-index: 99999999;
+        position: absolute;
+        right:8vw;
+    }
+    .dialogtitle{
+        font-size: 22px;
+        font-family: SimHei;
+        font-weight: bold;
+        color: #222;
+    }
+}
+.container {
+        display: flex;
+        width: 100%;
+        justify-content: center;
+        .el-row{
+            margin: 0 !important;
+        }
+        .required{
+            color: #606266 !important;
+            &::before{
+                content: '*';
+                margin: 0 4px 0 -7.5px;
+                color: #F56C6C;
+            }
+        }
+        .left{
+            height: calc(100vh - 100px);
+            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+            padding:20px;
+            overflow-y: auto;
+            .form{
+                margin-left: -20px;
+            }
+            .item{
+                width: 100%;
+            }
+            .title{
+                margin: 16px 0 6px -16px;
+            }
+            .tabs{
+                margin-top: 40px;
+            }
+            .question-icon{
+                margin-left: 2px;
+            }
+
+        }
+    }
+}
+    ::v-deep {
+        .el-form-item__label{
+            text-align: left;
+            font-size: 12px !important;
+        }
+        .el-form-item__content{
+            font-size: 12px !important;
+            display: flex;
+        }
+        .el-table th {
+            background-color:#f5f7fa !important;
+        }
+        .el-tabs__header {
+            margin: 0 0 30px !important;
+        }
+        .ibps-image{
+            width: 100%;
+            .ibps-p-0{
+                width: 100%;
+                .list-group{
+                    display: flex;
+                    align-items: center;
+                    gap: 20px;
+                    flex-wrap: wrap;
+                }
+            }
+        }
+    }
+
+</style>

+ 1665 - 0
src/views/component/device/index.vue

@@ -0,0 +1,1665 @@
+<template>
+    <div class="main-container">
+        <ibps-container
+            class="page"
+        >
+            <template>
+                <ibps-crud
+                    key="istree"
+                    ref="crud"
+                    :data="listData"
+                    :toolbars="listConfig.toolbars"
+                    :search-form="listConfig.searchForm"
+                    :pk-key="pkKey"
+                    :columns="listConfig.columns"
+                    :loading="loading"
+                    :pagination="pagination"
+                    :display-field="tableTitle"
+                    :index-row="false"
+                    @sort-change="handleSortChange"
+                    @action-event="handleAction"
+                    @pagination-change="handlePaginationChange"
+                >
+                    <template
+                        slot="posSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-user-selector
+                            v-model="row.bianZhiBuMen"
+                            type="position"
+                            readonly-text="text"
+                            :multiple="true"
+                            :disabled="true"
+                        />
+
+                    </template>
+                    <template
+                        slot="userSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-user-selector
+                            v-model="row.guanLiRen"
+                            type="user"
+                            readonly-text="text"
+                            :multiple="true"
+                            :disabled="true"
+                        />
+
+                    </template>
+
+                    <template
+                        slot="deviceSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-custom-dialog
+                            v-model="row.weiHuFangShi"
+                            size="mini"
+                            template-key="sbbqdhk"
+                            multiple
+                            :disabled="true"
+                            type="dialog"
+                            class="custom-dialog"
+                            placeholder="请选择"
+                            icon="el-icon-search"
+                        />
+
+                    </template>
+
+                    <template
+                        slot="deviceStateSlot"
+                        slot-scope="{row}"
+                    >
+                        <span>{{ stateList[row.sheBeiZhuangTa] || row.sheBeiZhuangTa }}</span>
+                    </template>
+
+                    <template
+                        slot="placeSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-custom-dialog
+                            v-model="row.cunFangWeiZhi"
+                            size="mini"
+                            template-key="fjxzkdd"
+                            multiple
+                            :disabled="true"
+                            type="dialog"
+                            class="custom-dialog"
+                            placeholder="请选择"
+                            icon="el-icon-search"
+                        />
+
+                    </template>
+
+                    <template
+                        slot="customButton"
+                        slot-scope="{row}"
+                    >
+                        <el-button type="text" icon="el-icon-edit-outline" @click="goEdit(row)">修改</el-button>
+                        <!-- <el-button type="text" icon="el-icon-view" @click="goLook(row)">查阅</el-button> -->
+                        <el-button type="text" icon="ibps-icon-table" @click="goLookForm(row)">表单</el-button>
+
+                    </template>
+                    <template
+                        slot="expandSlot"
+                        slot-scope="{row}"
+                    >
+                        <el-row :gutter="20" style="height:145px;padding:0 20px 0 0" type="flex" align="middle">
+                            <el-col :span="5" :push="2">
+                                <el-row>
+                                    <el-col :span="3">
+                                        <el-image
+                                            class="icon-image"
+                                            :src="images[0]"
+                                            fit="contain"
+                                        />
+                                    </el-col>
+                                    <el-col :span="21">
+                                        <div class="title">验收信息</div>
+                                        <div class="ctx">
+                                            <div class="item">接收日期:{{ row.jieShouRiQi || '/' }}</div>
+                                            <div class="item">验收日期:{{ row.yanShouRiQi || '/' }}</div>
+                                            <div class="item">核查日期:{{ row.biXuSheShi || '/' }}</div>
+                                        </div>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                            <el-col :span="5" :push="2">
+                                <el-row>
+                                    <el-col :span="3">
+                                        <el-image
+                                            class="icon-image"
+                                            :src="images[1]"
+                                            fit="contain"
+                                        />
+                                    </el-col>
+                                    <el-col :span="21">
+                                        <div class="title">建档信息</div>
+                                        <div class="ctx">
+                                            <div class="item">
+                                                <div class="cusitem">
+                                                    <span class="span">建档人:</span>
+                                                    <ibps-user-selector
+                                                        :value="row.bianZhiRen"
+                                                        type="user"
+                                                        readonly-text="text"
+                                                        :multiple="true"
+                                                        :disabled="true"
+                                                        size="mini"
+                                                        style="width:100px"
+                                                    />
+                                                </div>
+                                            </div>
+                                            <div class="item">
+                                                <div class="cusitem">
+                                                    <span class="span">建档部门:</span>
+                                                    <ibps-user-selector
+                                                        :value="row.bianZhiBuMen"
+                                                        type="position"
+                                                        readonly-text="text"
+                                                        :disabled="true"
+                                                        :multiple="false"
+                                                        size="mini"
+                                                        style="width:100px"
+                                                    />
+                                                </div>
+                                            </div>
+                                            <div class="item">建档时间:{{ row.bianZhiShiJian || '/' }}</div>
+                                        </div>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                            <el-col :span="5" :push="2">
+                                <el-row>
+                                    <el-col :span="3">
+                                        <el-image
+                                            class="icon-image"
+                                            :src="images[2]"
+                                            fit="contain"
+                                        />
+                                    </el-col>
+                                    <el-col :span="21">
+                                        <div class="title">维护信息</div>
+                                        <div class="ctx">
+                                            <div class="item">是否维护:{{ row.shiFouWeiHu || '/' }}</div>
+                                            <div class="item">是否24H开机:{{ row.jianKongYiJu || '/' }}</div>
+                                            <div class="item">是否限用:{{ row.xiaoZhunWuCha || '/' }}</div>
+                                        </div>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                            <el-col :span="5" :push="2">
+                                <el-row>
+                                    <el-col :span="3">
+                                        <el-image
+                                            class="icon-image"
+                                            :src="images[3]"
+                                            fit="contain"
+                                        />
+                                    </el-col>
+                                    <el-col :span="21">
+                                        <div class="title">校准信息</div>
+                                        <div class="ctx">
+                                            <div class="item">是否校准:{{ row.shiFouXiaoZhun || '/' }}</div>
+                                            <div class="item">校准周期:{{ row.xiaoZhunZQ?`${row.xiaoZhunZQ}月` : '/' }}</div>
+                                            <div class="item">最近校准时间:{{ row.yiXiaoRiQi || '/' }}</div>
+                                        </div>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                            <el-col :span="4" :push="1">
+                                <el-row>
+                                    <el-col :span="24">
+                                        <el-image
+                                            class="device-image"
+                                            :src="ImageUrl(row)"
+                                            fit="fill"
+                                            :preview-src-list="ImageAllUrl(row)"
+                                            :title="`[${row.sheBeiMingCheng}]设备首图,点击查看更多`"
+                                        >
+                                            <div slot="error" class="image-slot">
+                                                <el-empty class="device-image" description="暂无图片" :image-size="70" />
+                                            </div>
+                                        </el-image>
+                                    </el-col>
+                                </el-row>
+                            </el-col>
+                        </el-row>
+                    </template>
+                    <!-- 搜索条件 -->
+                    <template slot="pos">
+                        <ibps-user-selector
+                            v-model="search.pos"
+                            type="position"
+                            readonly-text="text"
+                            :multiple="true"
+                            size="mini"
+                            :filter="filter"
+                            filtrate
+                        />
+                    </template>
+                    <template slot="time">
+                        <el-date-picker
+                            v-model="search.time"
+                            size="mini"
+                            type="daterange"
+                            :picker-options="pickerOptions"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            align="right"
+                            value-format="yyyy-MM-dd"
+                        />
+                    </template>
+                    <template slot="nowNumber">
+                        <el-input v-model="search.nowNumber" size="mini" />
+                    </template>
+                    <template slot="preNumber">
+                        <el-input v-model="search.preNumber" size="mini" />
+                    </template>
+                    <template slot="deviceName">
+                        <el-input v-model="search.deviceName" size="mini" />
+                    </template>
+                    <template slot="deviceType">
+                        <el-select v-model="search.deviceType" placeholder="请选择" size="mini" :clearable="true">
+                            <el-option
+                                v-for="item in ['检验系统','通用设备','软件','信息系统']"
+                                :key="item"
+                                :label="item"
+                                :value="item"
+                            />
+                        </el-select>
+                    </template>
+                    <template slot="deviceStatus">
+                        <el-select v-model="search.deviceStatus" placeholder="请选择" size="mini" :clearable="true">
+                            <el-option
+                                v-for="(v,k) in stateList"
+                                :key="k"
+                                :label="v"
+                                :value="k"
+                            />
+                        </el-select>
+                    </template>
+                    <template slot="place">
+                        <el-input v-model="search.place" size="mini" />
+                    </template>
+                    <template slot="managePeople">
+                        <ibps-user-selector
+                            v-model="search.managePeople"
+                            type="user"
+                            readonly-text="text"
+                            :multiple="true"
+                            size="mini"
+                            :filter="filter"
+                            filtrate
+                        />
+                    </template>
+                    <template slot="deviceClass">
+                        <ibps-custom-dialog
+                            v-model="search.deviceClass"
+                            size="mini"
+                            template-key="sbbqdhk"
+                            multiple
+                            :disabled="false"
+                            type="dialog"
+                            class="custom-dialog"
+                            placeholder="请选择"
+                            icon="el-icon-search"
+                        />
+                    </template>
+                </ibps-crud>
+            </template>
+        </ibps-container>
+        <DeviceDialog v-if="deviceDialogShow" :params="params" :state-list="stateList" @close="close" />
+        <input id="" ref="file1" type="file" name="" accept=".xlsx,.xls" @change="handleUploadChange1">
+        <input id="" ref="file2" type="file" name="" accept=".xlsx,.xls" @change="handleUploadChange2">
+
+        <custom-dialog
+            :visible="customDialogVisible"
+            :value="[]"
+            template-key="sbfzpz"
+            :dynamic-params="{}"
+            @close="(visible) => (customDialogVisible = visible)"
+        />
+
+        <bpmn-formrender
+            :visible="npmDialogFormVisible"
+            def-id="1120718364969271296"
+            @close="visible => npmDialogFormVisible = visible"
+        />
+        <DeviceTag :scan-visible="printVisible" :obj="printObj" :state-list="stateList" @scanOff="scanOff" />
+        <el-dialog
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+            :top="'3vh'"
+            :width="'90%'"
+            class="js-custom-dialog"
+            append-to-body
+            :fullscreen="false"
+            :visible.sync="iframeVisible"
+        >
+            <iframe :src="srcUrl" :height="'100%'" :width="'100%'" frameborder="0" scrolling="no" />
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { getSetting } from '@/utils/query'
+import image01 from '@/assets/images/device/01.png'
+import image02 from '@/assets/images/device/02.png'
+import image03 from '@/assets/images/device/03.png'
+import image04 from '@/assets/images/device/04.png'
+import { getImage } from '@/api/platform/file/attachment'
+
+import xlsx from 'xlsx'
+import fs from 'file-saver'
+import DataTemplateFormrenderDialog from '@/business/platform/data/templaterender/form/dialog.vue'
+import ActionUtils from '@/utils/action'
+import FixHeight from '@/mixins/height'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import DeviceDialog from './deviceDialog.vue'
+import { queryequipmentCard, removeEquipmentCard, getequipmentCard, saveEquipmentCard } from '@/api/platform/device/device'
+import CustomDialog from '@/business/platform/data/templaterender/custom-dialog/dialog'
+import dayjs from 'dayjs'
+import DeviceTag from '@/views/system/jbdScan/goods/deviceTag.vue'
+export default {
+    components: {
+        DeviceTag,
+        DataTemplateFormrenderDialog,
+        DeviceDialog,
+        ibpsUserSelector,
+        CustomDialog,
+        IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog')
+    },
+    mixins: [FixHeight],
+    data () {
+        const { userId, level = {}, position } = this.$store.getters || {}
+        return {
+            filter: [{
+                descVal: '1',
+                includeSub: true,
+                old: 'position',
+                partyId: this.$store.getters.userInfo.employee.positions,
+                partyName: '',
+                scriptContent: '',
+                type: 'user',
+                userType: 'position'
+            }],
+            images: [image01, image02, image03, image04],
+            ImportDeviceType: '',
+            iframeVisible: false,
+            srcUrl: '',
+            printObj: [],
+            printVisible: false,
+            DialogVisible: true,
+            npmDialogFormVisible: false,
+            customDialogVisible: false,
+            pickerOptions: {
+                shortcuts: [{
+                    text: '最近一周',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+                        picker.$emit('pick', [start, end])
+                    }
+                }, {
+                    text: '最近一个月',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+                        picker.$emit('pick', [start, end])
+                    }
+                }, {
+                    text: '最近三个月',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+                        picker.$emit('pick', [start, end])
+                    }
+                }]
+            },
+            params: {},
+            deviceDialogShow: false,
+            position: position,
+            level: level.second || level.first,
+            userId: userId,
+            search: {
+                pos: '',
+                time: [],
+                nowNumber: '',
+                preNumber: '',
+                deviceName: '',
+                deviceType: '',
+                deviceStatus: '',
+                place: '',
+                managePeople: '',
+                deviceClass: ''
+            },
+            loading: false,
+            pkKey: 'id', // 主键  如果主键不是pk需要传主键
+            pkValue: '',
+            templateKey: '',
+            visible: false,
+            categoryKey: '',
+            tableTitle: '设备基本信息列表', // 标题
+            listData: [],
+            selectListData: [], // 全部数据
+            bianlistData: {
+                dataResult: [],
+                pageResult: {
+                    limit: 0,
+                    page: 0,
+                    totalCount: 0,
+                    totalPages: 0
+                }
+            },
+            listConfig: {
+                // 工具栏
+                toolbars: [
+                    { key: 'search' },
+                    { key: 'customAdd', label: '设备建档', icon: 'ibps-icon-plus', type: 'success' },
+                    { key: 'customBpm', label: '设备台账', icon: 'ibps-icon-file-text', type: 'info' },
+                    { key: 'customPrint', label: '打印标签', icon: 'ibps-icon-cog', type: 'warning' },
+                    { key: 'customExport', label: '导出数据', icon: 'ibps-icon-sign-in', type: 'primary' },
+                    { key: 'customImport', label: '导入数据', icon: 'ibps-icon-sign-in', type: 'primary' },
+                    { key: 'customSetting', label: '设置分组配置', icon: 'ibps-icon-cogs', type: 'info' },
+                    { key: 'customRemove', label: '删除', icon: 'ibps-icon-close', type: 'danger' }
+                ],
+                // 查询条件
+                searchForm: {
+                    forms: [
+                        { prop: '', label: '部门', fieldType: 'slot', slotName: 'pos' }, // user 插槽
+                        { prop: '', label: '建档时间', fieldType: 'slot', slotName: 'time' },
+                        { prop: '', label: '设备编号', fieldType: 'slot', slotName: 'nowNumber' },
+                        { prop: '', label: '原设备编号', fieldType: 'slot', slotName: 'preNumber' },
+                        { prop: '', label: '设备名称', fieldType: 'slot', slotName: 'deviceName' },
+                        { prop: '', label: '设备类型', fieldType: 'slot', slotName: 'deviceType' },
+                        { prop: '', label: '设备状态', fieldType: 'slot', slotName: 'deviceStatus' },
+                        { prop: '', label: '放置地点', fieldType: 'slot', slotName: 'place' },
+                        { prop: '', label: '管理人', fieldType: 'slot', slotName: 'managePeople' },
+                        { prop: '', label: '设备分组', fieldType: 'slot', slotName: 'deviceClass' }
+
+                    ]
+                },
+                // 表格字段配置
+                columns: [
+                    { type: 'expand', slotName: 'expandSlot' },
+                    { prop: 'bianZhiBuMen', label: '部门', slotName: 'posSlot', sortable: true },
+                    { prop: 'bianZhiShiJian', label: '建档时间', sortable: true },
+                    { prop: 'sheBeiShiBieH', label: '设备编号', sortable: true },
+                    { prop: 'yuanSheBeiBian', label: '原设备编号', sortable: true },
+                    { prop: 'sheBeiMingCheng', label: '设备名称', sortable: true },
+                    { prop: 'sheBeiLeiXing', label: '设备类型', sortable: true },
+                    { prop: 'guiGeXingHao', label: '规格型号', sortable: true },
+                    { prop: 'sheBeiZhuangTa', label: '设备状态', sortable: true, slotName: 'deviceStateSlot' },
+                    { prop: 'guanLiRen', label: '保管人', slotName: 'userSlot', sortable: true },
+                    { prop: 'weiHuFangShi', label: '设备分组', slotName: 'deviceSlot', sortable: true },
+                    { prop: 'cunFangWeiZhi', label: '放置地点', slotName: 'placeSlot', sortable: true },
+                    { prop: '', label: '操作', width: 130, slotName: 'customButton' }
+                ]
+            },
+            pagination: {
+                limit: 20, page: 1
+            },
+            sorts: [{ field: 'BIAN_ZHI_SHI_JIAN', order: 'desc' }],
+            sqlWhere: {},
+            searchWhere: {},
+            deviceColumns: {
+                bianZhiBuMen: '部门',
+                sheBeiMingCheng: '设备名称',
+                // sheBeiShiBieH: '设备编号(导入无需填写)',
+                yuanSheBeiBian: '原设备编号(必填,且不可重复)',
+                sheBeiZhuangTa: '设备状态(合格/停用/限用)',
+                sheBeiLeiXing: '设备类型(检验系统/通用设备/软件/信息系统)',
+                shiFouWeiHu: '是否维护(是/否)',
+                shiFouXiaoZhun: '是否校准(是/否)',
+                weiHuFangShi: '设备分组',
+                guiGeXingHao: '规格型号',
+                cunFangDiDian: '存放地点(格式:房间号+空格+房间名)',
+                guanLiRen: '保管人',
+                ziChanBianHao: '资产编号',
+                gongYingShang: '供应商',
+                lianXiFangShi: '联系方式',
+                changShang: '厂商',
+                jiShenXuHao: '机身序号',
+                zhuCeZhengHao: '注册证号',
+                chuChangRiQi: '出厂日期',
+                yanShouRiQi: '验收日期',
+                jieShouRiQi: '接收日期',
+                qiYongRiQi: '投入日期',
+                yiXiaoRiQi: '已校日期',
+                xiaoZhunZQ: '检定/校准周期(以月为单位)',
+                xiaoZhunYouXia: '校准有效期至',
+                shiYongKeShi: '检定/校准单位',
+                ceLiangGongZuo: '测量/工作范围',
+                huanJingYaoQiu: '环境要求',
+                dianYuanYaoQiu: '电源要求',
+                jieShouZhuangTai: '接收时状态(新设备/二手或翻新设备)',
+                jianDingXiao: '检定/校准参数',
+                zuiDaYunCha: 'U/精确度/最大允差',
+                zhengShuBianHa: '证书编号',
+                xiuZhengZhiXiu: '修正值/修正因子',
+                wenDuYingYong: '温度应用修正值',
+                shiDuYingYong: '湿度应用修正值',
+                biXuDeHuanJin: '核查人',
+                biXuSheShi: '核查日期',
+                heChaXiaoZhun: '使用年限(年)'
+            },
+            projectColums: {
+                yuanSheBeiBian: '设备编号*',
+                sheBeiMingCheng: '设备名称*',
+                weiHuLeiXing: '维护类型*(日保养/周保养/月保养/季度保养/半年保养/年保养/按需保养)',
+                weiHuRiQi: '维护日期*',
+                weiHuXiangMuC: '维护项目*'
+            },
+            dateFieldRange: ['chuChangRiQi', 'yanShouRiQi', 'jieShouRiQi', 'qiYongRiQi', 'yiXiaoRiQi', 'xiaoZhunYouXia', 'biXuSheShi'],
+            requiredFieldMap: {
+                bianZhiBuMen: '部门',
+                sheBeiMingCheng: '设备名称',
+                yuanSheBeiBian: '原设备编号',
+                sheBeiZhuangTa: '设备状态',
+                sheBeiLeiXing: '设备类型',
+                shiFouWeiHu: '是否维护',
+                shiFouXiaoZhun: '是否校准'
+            },
+            dateFieldsMap: {
+                'chuChangRiQi': '出厂日期',
+                'yanShouRiQi': '验收日期',
+                'jieShouRiQi': '接收日期',
+                'qiYongRiQi': '投入日期',
+                'yiXiaoRiQi': '已校日期',
+                'xiaoZhunYouXia': '校准有效期至',
+                'biXuSheShi': '核查日期'
+            },
+            validationRules: {
+                '设备状态': {
+                    field: 'sheBeiZhuangTa',
+                    range: ['合格', '停用', '限用']
+                },
+                '设备类型': {
+                    field: 'sheBeiLeiXing',
+                    range: ['检验系统', '通用设备', '软件', '信息系统']
+                },
+                '接收时状态': {
+                    field: 'jieShouZhuangTai',
+                    range: ['新设备', '二手或翻新设备']
+                },
+                '是否校准': {
+                    field: 'shiFouXiaoZhun',
+                    range: ['是', '否']
+                },
+                '是否维护': {
+                    field: 'shiFouWeiHu',
+                    range: ['是', '否']
+                }
+            },
+            numberFieldsMap: {
+                'xiaoZhunZQ': '检定/校准周期(以月为单位)',
+                'heChaXiaoZhun': '使用年限(年)'
+            },
+            maintenanceRequiredFieldMap: {
+                yuanSheBeiBian: '原设备编号',
+                sheBeiMingCheng: '设备名称',
+                weiHuLeiXing: '维护类型',
+                weiHuRiQi: '维护日期',
+                weiHuXiangMuC: '维护项目'
+            },
+            maintenanceValidationRules: {
+                '维护类型': {
+                    field: 'weiHuLeiXing',
+                    range: ['日保养', '周保养', '月保养', '季度保养', '半年保养', '年保养', '按需保养']
+                }
+            },
+            maintenanceDateValidationRules: {
+                '日保养': this.generateDayRule(),
+                '周保养': this.generateRule(7, `每周`, ``),
+                '月保养': this.generateRule(28, `每月第`, `日`),
+                '半年保养': this.generateRule(6, `每半年第`, `个月`),
+                '季度保养': this.generateRule(3, `每季度第`, `个月`),
+                '年保养': this.generateRule(12, `每年第`, `个月`),
+                '按需保养': ['/']
+            },
+            stateList: { '停用': '停用', '报废': '报废', '合格': '合格' }
+        }
+    },
+    async mounted () {
+        const stateList = await getSetting('device', 'stateList')
+        if (stateList) {
+            console.debug(stateList)
+            this.stateList = stateList
+        }
+        this.getDatas()
+    },
+    methods: {
+        ImageAllUrl (row) {
+            if (row && row.buMen) {
+                const imgId = row.buMen.split(',')
+                return imgId.map(item => getImage(item))
+            }
+            return []
+        },
+        ImageUrl (row) {
+            if (row && row.buMen) {
+                const imgId = row.buMen.split(',')[0]
+                return getImage(imgId)
+            }
+            return ''
+        },
+        async getDatas () {
+            this.loading = true
+            const parameters = {
+                relation: 'AND',
+                parameters: []
+            }
+            // 增加地点过滤
+            const obj = { relation: 'AND', parameters: [] }
+            obj.parameters.push({ key: 'Q^di_dian_^S', value: this.level, param: this.$utils.guid() })
+            parameters.parameters.push(obj)
+
+            // 部门搜索(可多选)
+            if (this.search.pos) {
+                const obj = { relation: 'OR', parameters: [] }
+                this.search.pos.split(',').forEach(item => {
+                    obj.parameters.push({ key: 'Q^bian_zhi_bu_men_^S', value: item, param: this.$utils.guid() })
+                })
+                parameters.parameters.push(obj)
+            }
+            // 建档时间搜索
+            if (this.search.time && this.search.time.length === 2) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^bian_zhi_shi_jian^DL^yyyy-MM-dd', value: this.search.time[0], param: this.$utils.guid() })
+                obj.parameters.push({ key: 'Q^bian_zhi_shi_jian^DG^yyyy-MM-dd', value: this.search.time[1], param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 设备编号搜索
+            if (this.search.nowNumber) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^she_bei_shi_bie_h^SL', value: this.search.nowNumber, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 原设备编号搜索
+            if (this.search.preNumber) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^yuan_she_bei_bian^SL', value: this.search.preNumber, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 设备名称搜索
+            if (this.search.deviceName) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^she_bei_ming_cheng_^SL', value: this.search.deviceName, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 设备类型搜索
+            if (this.search.deviceType) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^she_bei_lei_xing_^S', value: this.search.deviceType, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 设备状态搜索
+            if (this.search.deviceStatus) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^she_bei_zhuang_ta^S', value: this.search.deviceStatus, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 放置地点搜索
+            if (this.search.place) {
+                const obj = { relation: 'AND', parameters: [] }
+                obj.parameters.push({ key: 'Q^cun_fang_di_dian_^SL', value: this.search.place, param: this.$utils.guid() })
+                parameters.parameters.push(obj)
+            }
+            // 保管人搜索(可多选)
+            if (this.search.managePeople) {
+                const obj = { relation: 'OR', parameters: [] }
+                this.search.managePeople.split(',').forEach(item => {
+                    obj.parameters.push({ key: 'Q^guan_li_ren_^S', value: item, param: this.$utils.guid() })
+                })
+                parameters.parameters.push(obj)
+            }
+            // 设备分组搜索(可多选)
+            if (this.search.deviceClass) {
+                const obj = { relation: 'OR', parameters: [] }
+                this.search.deviceClass.split(',').forEach(item => {
+                    obj.parameters.push({ key: 'Q^wei_hu_fang_shi_^S', value: item, param: this.$utils.guid() })
+                })
+                parameters.parameters.push(obj)
+            }
+            const params = {
+                requestPage: {
+                    pageNo: this.pagination.page,
+                    limit: this.pagination.limit
+                },
+                sorts: this.sorts
+            }
+            if (parameters.parameters.length > 0) {
+                params.parameters = [parameters]
+            }
+
+            const { data: { dataResult, pageResult }} = await queryequipmentCard(params)
+
+            this.bianlistData.pageResult = pageResult
+            this.bianlistData.dataResult = dataResult
+            ActionUtils.handleListData(this, this.bianlistData) // 调用内置方法
+            this.loading = false
+        },
+        // 查看表单
+        goLookForm (row) {
+            const first = this.$store.getters.level.first
+            this.srcUrl = this.$reportPath.replace('show', 'pdf') + '设备/设备档案卡.rpx&id_=' + row.id + '&org_=' + first
+            this.iframeVisible = true
+        },
+        // 按钮事件处理
+        handleAction (command, position, selection, data, index, button) {
+            switch (command) {
+                case 'search':// 查询
+                    this.getDatas()
+                    break
+                case 'customAdd':
+                    this.handleCustomAdd()
+                    break
+                case 'customSetting':
+                    this.handleCustomSetting()
+                    break
+                case 'customRemove':
+                    this.handleCustomRemove(selection)
+                    break
+                case 'customExport':
+                    this.handleCustomExport(selection, data)
+                    break
+                case 'customImport':
+                    this.handleCustomImport()
+                    break
+                case 'customBpm':
+                    this.handleCustomBpm()
+                    break
+                case 'customPrint':
+                    this.handleCustomPrint(selection)
+                    break
+                default:
+                    break
+            }
+        },
+        // 打印标签
+        handleCustomPrint (selection = []) {
+            if (selection.length === 0) {
+                return this.$message.warning('请先选择需要打印标签的数据!')
+            }
+            this.printObj = selection
+            this.printVisible = true
+        },
+        // 关闭标签
+        scanOff () {
+            this.printVisible = false
+        },
+        // 设备台账
+        handleCustomBpm () {
+            this.npmDialogFormVisible = true
+        },
+        // 处理分页事件
+        async handlePaginationChange (page) {
+            ActionUtils.setPagination(this.pagination, page)
+            this.getDatas()
+        },
+        // 处理排序
+        handleSortChange (sort) {
+            function removeUnderscores (str) {
+                return str.replace(/^_+|_+$/g, '')
+            }
+            const { order, sortBy } = sort
+            let s = ''
+            switch (sortBy) {
+                case 'BIAN_ZHI_SHI_JIAN_':
+                case 'SHE_BEI_SHI_BIE_H_':
+                case 'YUAN_SHE_BEI_BIAN_':
+                case 'SHE_BEI_ZHUANG_TA_':
+                    s = removeUnderscores(sortBy)
+                    break
+                default:
+                    s = sortBy
+            }
+            let o = null
+            if (order === 'descending') {
+                o = 'desc'
+            } else if (order === 'ascending') {
+                o = 'asc'
+            }
+            this.sorts = [{ field: s, order: o }]
+            this.getDatas()
+        },
+        handleCustomAdd () {
+            this.params = {}
+            this.deviceDialogShow = true
+        },
+        close () {
+            this.deviceDialogShow = false
+            this.getDatas()
+        },
+        goEdit (row) {
+            this.params = row
+            this.deviceDialogShow = true
+        },
+        handleCustomSetting () {
+            this.customDialogVisible = true
+        },
+        handleCustomRemove (selection) {
+            console.log('selection', selection)
+            if (!selection || selection.length === 0) {
+                return this.$message.warning('请选择要删除的数据!')
+            }
+            this.$confirm('确定删除所选项?删除后无法恢复!', '提示', {
+                confirmButtonText: '继续',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(async () => {
+                await removeEquipmentCard({
+                    ids: selection + ''
+                })
+                // 删除后刷新
+                await this.getDatas()
+                this.$message.success('删除成功!')
+            }).catch(() => {})
+        },
+        // 导出
+        handleCustomExport (selection, data) {
+            this.$confirm('请选择导出的类型', '提示', {
+                confirmButtonText: '导出设备',
+                cancelButtonText: '导出维护项目',
+                closeOnClickModal: false,
+                closeOnPressEscape: false,
+                distinguishCancelAndClose: true,
+                type: 'info'
+            }).then(() => {
+                this.ExportDevice(selection, data)
+            }).catch((action) => {
+                if (action === 'close') return
+                if (action === 'cancel') {
+                    this.ExportProject(selection, data)
+                }
+            })
+        },
+        // 导入
+        handleCustomImport () {
+            this.$confirm('确请选择导入的类型', '提示', {
+                confirmButtonText: '导入设备',
+                cancelButtonText: '导入维护项目',
+                closeOnClickModal: false,
+                closeOnPressEscape: false,
+                distinguishCancelAndClose: true,
+                type: 'info'
+            }).then(() => {
+                this.ImportDevice()
+            }).catch((action) => {
+                if (action === 'close') return
+                if (action === 'cancel') {
+                    this.$confirm('请选择设备维护项目导入类型', '提示', {
+                        confirmButtonText: '增量添加',
+                        cancelButtonText: '全量替换',
+                        closeOnClickModal: false,
+                        closeOnPressEscape: false,
+                        distinguishCancelAndClose: true,
+                        type: 'info'
+                    }).then(() => {
+                        this.ImportDeviceType = '增量添加'
+                        this.ImportProject()
+                    }).catch((action) => {
+                        if (action === 'close') return
+                        if (action === 'cancel') {
+                            this.ImportDeviceType = '全量替换'
+                            this.ImportProject()
+                        }
+                    })
+                }
+            })
+        },
+        // 导入设备
+        ImportDevice () {
+            this.$refs.file1.click()
+            console.log('导入设备')
+        },
+        // 导入维护项目
+        ImportProject () {
+            this.$refs.file2.click()
+            console.log('导入维护项目')
+        },
+        getTimeStamp () {
+            return dayjs().format('YYYYMMDDHHmmss')
+        },
+        xlsx (json, fields, filename = '.xlsx') { // 导出xlsx
+            json.forEach(item => {
+                for (const i in item) {
+                    if (fields.hasOwnProperty(i)) {
+                        item[fields[i]] = item[i]
+                    }
+                    delete item[i] // 删除原先的对象属性
+                }
+            })
+            const sheetName = filename // excel的文件名称
+            const wb = xlsx.utils.book_new() // 工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
+            const ws = xlsx.utils.json_to_sheet(json, { header: Object.values(fields) }) // 将JS对象数组转换为工作表。
+            wb.SheetNames.push(sheetName)
+            wb.Sheets[sheetName] = ws
+            const defaultCellStyle = { font: { name: 'Verdana', sz: 13, color: 'FF00FF88' }, fill: { fgColor: { rgb: 'FFFFAA00' }}}// 设置表格的样式
+            const wopts = { bookType: 'xlsx', bookSST: false, type: 'binary', cellStyles: true, defaultCellStyle: defaultCellStyle, showGridLines: false } // 写入的样式
+            const wbout = xlsx.write(wb, wopts)
+            const blob = new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' })
+            fs.saveAs(blob, filename + '.xlsx')
+        },
+        s2ab (s) {
+            let buf
+            if (typeof ArrayBuffer !== 'undefined') {
+                buf = new ArrayBuffer(s.length)
+                const view = new Uint8Array(buf)
+                for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
+                return buf
+            } else {
+                buf = new Array(s.length)
+                for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF
+                return buf
+            }
+        },
+        async switchExportData (data) {
+            const deviceGroupSql = `select id_,wei_hu_gang_wei_ from t_sbwhgwpzb` // 设备分组信息
+            const supplierSql = `select id_,gong_ying_shang_m from t_gysxxb` // 供应商信息
+            const { variables: { data: deviceGroupData }} = await this.$common.request('sql', deviceGroupSql)
+            const { variables: { data: gysData }} = await this.$common.request('sql', supplierSql)
+            const exportData = JSON.parse(JSON.stringify(data))
+            for (let i = 0; i < exportData.length; i++) {
+                const item = exportData[i]
+                item.bianZhiBuMen = this.switchIdToDept(item.bianZhiBuMen.split(',')[0])
+                item.guanLiRen = this.switchIdToUserName(item.guanLiRen.split(',')[0])
+                item.biXuDeHuanJin = this.switchIdToUserName(item.biXuDeHuanJin.split(',')[0])
+                item.weiHuFangShi = this.switchDeviceIdToName(item.weiHuFangShi, deviceGroupData)
+                item.shiYongKeShi = this.switchGYSIdToName(item.shiYongKeShi, gysData)
+                if (this.stateList[item.sheBeiZhuangTa]) {
+                    item.sheBeiZhuangTa = this.stateList[item.sheBeiZhuangTa]
+                }
+            }
+            return exportData
+        },
+        // 设备分组id 转 设备分组名称
+        switchDeviceIdToName (val, deviceGroupList) {
+            const result = []
+            const valList = val?.split(',') || []
+            valList.forEach(item => result.push((deviceGroupList?.find(i => i.id_ === item)?.wei_hu_gang_wei_) || ''))
+            return result.join(',')
+        },
+        // 供应商id 转 供应商名称 检定/校准单位
+        switchGYSIdToName (val, gysList) {
+            const result = gysList.find(item => item.id_ === val)?.gong_ying_shang_m || ''
+            return result
+        },
+        // 部门id 转 部门名称
+        switchIdToDept (id) {
+            const { deptList } = this.$store.getters
+            const temp = deptList.find(item => item.positionId === id)
+            return temp ? temp.positionName : ''
+        },
+        // 部门名称 转 部门id
+        switchDeptToId (dep) {
+            const { deptList } = this.$store.getters
+            const temp = deptList.find(item => item.positionName === dep)
+            return temp ? temp.positionId : ''
+        },
+        // 人员id 转人员名称
+        switchIdToUserName (id) {
+            const { userList } = this.$store.getters
+            const temp = userList.find(item => item.userId === id)
+            return temp ? temp.userName : ''
+        },
+        // 人员名称 转 人员id
+        switchUserNameToId (name) {
+            const { userList } = this.$store.getters
+            const temp = userList.find(item => item.userName === name)
+            return temp ? temp.userId : ''
+        },
+        // 导出设备
+        async ExportDevice (selection, data = []) {
+            const exportData = await this.switchExportData(data)
+            this.xlsx(exportData, this.deviceColumns, '设备档案卡基本数据' + this.getTimeStamp())
+            this.$message.success('导出设备成功!')
+        },
+        // 导出维护项目
+        async ExportProject (selection = []) {
+            let exportData = []
+            console.log('导出维护项目')
+            if (selection.length > 0) {
+                const sql = `select b.yuan_she_bei_bian as yuanSheBeiBian,b.she_bei_ming_cheng_ as sheBeiMingCheng,a.parent_id_,a.wei_hu_xiang_mu_c as weiHuXiangMuC,a.wei_hu_ri_qi_ as weiHuRiQi,a.wei_hu_lei_xing_ as weiHuLeiXing,a.ri_qi_shu_zi_ as riQiShuZi from t_whzqjxm a,t_sbdj b where a.parent_id_=b.id_ and a.parent_id_ in (${selection.map(i => `'${i}'`).join(',')})`
+                const { variables: { data }} = await this.$common.request('sql', sql)
+                exportData = data
+            }
+            this.xlsx(exportData, this.projectColums, '设备维护项目数据' + this.getTimeStamp())
+            this.$message.success('导出维护项目成功!')
+        },
+        // value 转 key
+        switchV2K (value, obj) {
+            const key = Object.keys(obj).find(key => obj[key] === value)
+            return key || ''
+        },
+        // 转换对象的key
+        switchDeviceObj (data, originalObj) {
+            const result = []
+            // data.forEach(item => {
+            //     const obj = {}
+            //     for (const key in item) {
+            //         obj[this.switchV2K(key, originalObj)] = item[key]
+            //     }
+            //     result.push(obj)
+            // })
+            data.forEach(item => {
+                const obj = {}
+                for (const key in originalObj) {
+                    // 对日期格式的数据做兼容处理
+                    if (item[originalObj[key]] instanceof Date) {
+                        obj[key] = dayjs(item[originalObj[key]]).add(8, 'hour').format('YYYY-MM-DD') || ''
+                    } else {
+                        obj[key] = String(item[originalObj[key]] || '')
+                    }
+                }
+                result.push(obj)
+            })
+            return result
+        },
+        /* 读取文件 将文件转换为二进制 */
+        readFile (file) {
+            return new Promise(resolve => {
+                const reader = new FileReader()
+                reader.readAsBinaryString(file)
+                reader.onload = ev => {
+                    resolve(ev.target.result)
+                }
+            })
+        },
+        checkDeviceRequiredFieldsIfEmpty (list, requiredMap) {
+            const msgList = []
+            list.forEach((item, index) => {
+                const invalidFieldNames = []
+                Object.entries(requiredMap).forEach(([field, name]) => {
+                    if (item.weiHuLeiXing === '按需保养' && field === 'weiHuRiQi') {
+                        console.log('按需pass1')
+                    } else {
+                        if (!item[field]) {
+                            invalidFieldNames.push(name)
+                        }
+                    }
+                })
+                if (invalidFieldNames.length > 0) {
+                    msgList.push({ row: index + 2, field: invalidFieldNames })
+                }
+            })
+            return msgList
+        },
+        /**
+     * 专门发送提示
+     * @param {*} allResult
+     * @returns
+     */
+        sendWarningMessages (allResult, mark = 'range') {
+            if (allResult.length < 1) {
+                return
+            }
+            console.log('%c Msg Obj %c', 'background:#FF5733; padding: 1px; border-radius: 0 3px 3px 0; color: #fff;', 'background:transparent', allResult)
+            const item = allResult[0]
+            switch (mark) {
+                case 'required':
+                    this.$message.warning(`第${item.row}行,字段【${item.field.join(',')}】的值不能为空!`)
+                    break
+                case 'range':
+                    this.$message.warning(`第${item.row}行,字段【${item.field}】的值【${item.value}】不在限定范围内!`)
+                    break
+                case 'dateFormat':
+                    this.$message.warning(`第${item.row}行,字段【${item.field}】日期格式错误!格式支持【2024-01-01】、【2024/01/01】,请检查您的数据!`)
+                    break
+                case 'duplicateOriginalDevice':
+                    this.$message.warning(`${item.field}!`)
+                    break
+                default:
+                    throw new Error(`${mark}类型未定义!`)
+            }
+        },
+        /**
+     * 根据规则校验字段的限定范围
+     * @param {*} list
+     */
+        checkFieldsRange (list, rules) {
+            const msgList = []
+            for (const ruleKey in rules) {
+                const rule = rules[ruleKey]
+                const fieldName = ruleKey
+                list.forEach((item, index) => {
+                    const fieldValue = item[rule.field]
+                    if (fieldValue && !rule.range.includes(fieldValue)) {
+                        msgList.push({ row: index + 2, field: fieldName, value: fieldValue })
+                    }
+                })
+            }
+            return msgList
+        },
+        /**
+     * 校验日期字段填写的格式
+     * @param {*} list
+     * @returns
+     */
+        checkDateFields (list) {
+            const dateRegex = /^(\d{4})[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12]\d|3[01])$/
+            for (let i = 0; i < list.length; i++) {
+                const row = list[i]
+                for (const field in this.dateFieldsMap) {
+                    if (row[field] && !dateRegex.test(row[field])) {
+                        console.error('error field:', row[field])
+                        return [{ row: i + 2, field: this.dateFieldsMap[field] }]
+                    }
+                }
+            }
+            return []
+        },
+        checkDuplicateOriginalDeviceNo (arr) {
+            const occurrences = {}
+            arr.forEach((item, index) => {
+                const key = item.yuanSheBeiBian
+                if (occurrences[key]) {
+                    occurrences[key].push(index + 2)
+                } else {
+                    occurrences[key] = [index + 2]
+                }
+            })
+            // 检查是否有重复项(数组长度大于1)
+            for (const [key, indices] of Object.entries(occurrences)) {
+                if (indices.length > 1) {
+                    return [{ field: `发现重复的原设备编号:${key} 在第 ${indices.join(', ')} 行` }]
+                }
+            }
+            return []
+        },
+        /**
+     * 负责导入设备数据的第一部分校验,全部成功则返回true
+     * @param {*} data
+     * @returns
+     */
+        deviceInvalidPartOne (data) {
+        // 校验必填信息
+            const invalidResult = this.checkDeviceRequiredFieldsIfEmpty(data, this.requiredFieldMap)
+            if (invalidResult.length > 0) {
+                this.sendWarningMessages(invalidResult, 'required')
+                return false
+            }
+            // 根据规则校验字段的限定范围
+            const allResult = this.checkFieldsRange(data, this.validationRules)
+            if (allResult.length > 0) {
+                this.sendWarningMessages(allResult, 'range')
+                return false
+            }
+            // 校验日期字段是否符合要求
+            const dateResult = this.checkDateFields(data)
+            if (dateResult.length > 0) {
+                this.sendWarningMessages(dateResult, 'dateFormat')
+                return false
+            }
+            // 校验是否存在重复的原设备编号
+            const duplicateOriginalDeviceResult = this.checkDuplicateOriginalDeviceNo(data)
+            if (duplicateOriginalDeviceResult.length > 0) {
+                this.sendWarningMessages(duplicateOriginalDeviceResult, 'duplicateOriginalDevice')
+                return false
+            }
+            return true
+        },
+        /**
+     * 将日期字段信息格式化为 yyyy-MM-dd
+     * @param {*} list
+     * @returns
+     */
+        formatDateFieldsToReal (list) {
+            list.forEach(item => {
+                this.dateFieldRange.forEach(field => {
+                    item[field] = item[field]?.replace(/\//g, '-')
+                })
+            })
+            return list
+        },
+        getNextAlias () {
+            return new Promise((resolve, reject) => {
+                this.$common.getNextIdByAlias({
+                    'alias': 'sbbh'
+                }).then(response => {
+                    resolve(response.data)
+                }).catch((error) => {
+                    reject(error)
+                })
+            })
+        },
+        /**
+     * 过滤出来excel 的原设备编号存在当前数据库中的数据
+     * @param {*} list 导入的数据
+     */
+        async filterOriginalDeviceNo (list, currentPosition) {
+            const uniqueArr = Array.from(new Set(list.map(i => i.yuanSheBeiBian.trim())))
+            const sql = `select id_,yuan_she_bei_bian from t_sbdj where find_in_set(yuan_she_bei_bian,'${uniqueArr.join(',')}')and di_dian_ = '${currentPosition}'`
+            const res = await this.$common.request('sql', sql)
+            const { data = [] } = res.variables || {}
+            const originalDeviceNoList = data.map(i => i.yuan_she_bei_bian.trim())
+            // 给要更新的数据加上id (接口需要!!!)
+            data.forEach(item => {
+                const temp = list.find(i => i.yuanSheBeiBian === item.yuan_she_bei_bian)
+                temp.id = item.id_
+            })
+            return originalDeviceNoList || ''
+        },
+        /**
+     *
+     * @param {*} list excel数据
+     * @param {*} currentTime 当前时间
+     * @param {*} currentApartment 当前部门ID
+     * @param {*} currentUser 当前用户ID
+     * @param {*} currentPosition 当前地点ID
+     */
+        async handleBasicData (list, currentTime, currentApartment, currentUser, currentPosition, deptList) {
+            // 使用map生成一个异步操作的数组
+            const promises = list.map(async (element) => {
+                element.bianZhiShiJian = currentTime
+                element.bianZhiRen = currentUser
+                element.diDian = currentPosition
+                element.shiFouGuoShen = '已完成'
+                const o = deptList?.find(i => i.positionName === element.bianZhiBuMen.trim())
+                const { positionId = currentApartment } = o || {}
+                element.bianZhiBuMen = positionId
+                if (!element.id) {
+                    // 获取下一个编号
+                    element.sheBeiShiBieH = await this.getNextAlias()
+                }
+            })
+            // 使用Promise.all并发执行所有异步操作
+            await Promise.all(promises)
+        },
+
+        /**
+     *
+     * @param {*} list excel数据
+     * @param {*} positionList 现有房间信息
+     * @param {*} supplierList 现有供应商信息
+     * @param {*} employeeList 现有人员信息
+     * @returns
+     */
+        handleExcelData (list, positionList, supplierList, employeeList, deviceGroupList) {
+            if (list.length < 1) {
+                return
+            }
+            this.handleSupplierInfo(list, supplierList)
+            this.handlePositionInfo(list, positionList)
+            this.handlePersonInfo(list, employeeList)
+            this.handleDeviceGroupInfo(list, deviceGroupList)
+        },
+        /**
+     *
+     * @param {*} list excel数据
+     * @param {*} supplierList 现有供应商信息
+     */
+        handleSupplierInfo (list, supplierList) {
+            list.forEach(element => {
+                if (element.gongYingShang.trim()) {
+                    const supplier = supplierList.find(i => i.gong_ying_shang_m === element.gongYingShang.trim())
+                    if (supplier) {
+                        element.shiFouQiJianH = supplier.id_
+                    } else {
+                        element.shiFouQiJianH = ''
+                        element.gongYingShang = ''
+                    }
+                } else {
+                    element.shiFouQiJianH = ''
+                }
+
+                if (element.shiYongKeShi.trim()) {
+                    const supplier = supplierList.find(i => i.gong_ying_shang_m === element.shiYongKeShi.trim())
+                    if (supplier) {
+                        element.shiYongKeShi = supplier.id_
+                    } else {
+                        element.shiYongKeShi = ''
+                    }
+                } else {
+                    element.shiYongKeShi = ''
+                }
+            })
+        },
+        /**
+     *
+     * @param {*} list excel数据
+     * @param {*} positionList 现有房间信息
+     */
+        handlePositionInfo (list, positionList) {
+            list.forEach(element => {
+                if (element.cunFangDiDian !== '') {
+                    const postion = positionList.find(i => (i.fang_jian_ming_ha.trim() || '') === element.cunFangDiDian.trim())
+                    if (postion) {
+                        const positionId = postion.id_
+                        element.cunFangWeiZhi = positionId
+                    } else {
+                        element.cunFangWeiZhi = ''
+                        element.cunFangDiDian = ''
+                    }
+                } else {
+                    element.cunFangWeiZhi = ''
+                }
+            })
+        },
+        handlePersonInfo (list, employeeList) {
+            list.forEach(element => {
+            // 处理保管人
+                if (element.guanLiRen !== '') {
+                    const person = employeeList.find(i => i.userName === element.guanLiRen.trim())
+                    if (person) {
+                        const personId = person.userId
+                        element.guanLiRen = personId
+                    } else {
+                        element.guanLiRen = ''
+                    }
+                } else {
+                    element.guanLiRen = ''
+                }
+                // 处理核查人
+                if (element.biXuDeHuanJin !== '') {
+                    const checkPerson = employeeList.find(i => i.userName === element.biXuDeHuanJin.trim())
+                    if (checkPerson) {
+                        const checkPersonId = checkPerson.userId
+                        element.biXuDeHuanJin = checkPersonId
+                    } else {
+                        element.biXuDeHuanJin = ''
+                    }
+                } else {
+                    element.biXuDeHuanJin = ''
+                }
+            })
+        },
+        handleDeviceGroupInfo (list, deviceGroupList) {
+            list.forEach(element => {
+                const result = []
+                const { weiHuFangShi } = element
+                const valList = weiHuFangShi.trim()?.split(',')
+                valList.forEach(item => result.push((deviceGroupList?.find(i => i.wei_hu_gang_wei_ === item)?.id_) || ''))
+                element.weiHuFangShi = result.join(',')
+            })
+        },
+        async handleUploadChange1 (file) {
+            const dataBinary = await this.readFile(file.target.files[0])
+            file.target.value = null // 注意上传后要将input的值设为空
+            const workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
+            const workSheet = workBook.Sheets[workBook.SheetNames[0]]
+            const data = xlsx.utils.sheet_to_json(workSheet)
+            let importData = this.switchDeviceObj(data, this.deviceColumns)
+            importData.forEach(i => {
+                delete i.sheBeiShiBieH // 设备编号需自动生成
+                // i.sheBeiZhuangTa = '合格'
+                const keyFound = Object.entries(this.stateList).find(([key, value]) => value === i.sheBeiZhuangTa)
+                if (keyFound) {
+                    i.sheBeiZhuangTa = keyFound[0]
+                }
+            })
+            const currentPosition = this.level
+            const { userList = [], deptList = [] } = this.$store.getters || {}
+            const positionSql = `select id_,fang_jian_ming_ha from t_jjqfjb where di_dian_ = ${currentPosition}` // 房间信息
+            const supplierSql = `select id_,gong_ying_shang_m from t_gysxxb where di_dian_ = ${currentPosition}` // 供应商信息
+            const deviceGroupSql = `select id_,suo_shu_bu_men_,wei_hu_gang_wei_ from t_sbwhgwpzb where di_dian_ =  ${currentPosition}` // 设备分组信息
+            const currentTime = dayjs().format('YYYY-MM-DD HH:mm')
+            const currentApartment = this.$store.getters.userInfo.employee.positions
+            const currentUser = this.userId
+
+            const partOneInvalidResult = this.deviceInvalidPartOne(importData)
+            if (!partOneInvalidResult) return
+
+            importData = this.formatDateFieldsToReal(importData)
+            console.log('%c partOne doCheck is completed! %c the result is %c', 'background:#35495E; padding: 1px; border-radius: 3px 0 0 3px; color: #fff;', 'background:#FF5733; padding: 1px; border-radius: 0 3px 3px 0; color: #fff;', 'background:transparent', importData)
+            this.loading = true
+            Promise.all([this.$common.request('sql', positionSql), this.$common.request('sql', supplierSql), this.$common.request('sql', deviceGroupSql)]).then(async ([res1, res2, res3]) => {
+                const { data: positionList = [] } = res1.variables || {}
+                const { data: supplierList = [] } = res2.variables || {}
+                const { data: deviceGroupList = [] } = res3.variables || {}
+                // 根据原设备编号去重,检验原设备编号是否在数据库中存在
+                const originalDeviceNoList = await this.filterOriginalDeviceNo(importData, currentPosition)
+                await this.handleBasicData(importData, currentTime, currentApartment, currentUser, currentPosition, deptList)
+                this.handleExcelData(importData, positionList, supplierList, userList, deviceGroupList)
+                // 分离出 已存在的设备,和新设备
+                const newDeviceList = importData.filter(i => !originalDeviceNoList.includes(i.yuanSheBeiBian.trim()))
+                const existDeviceList = importData.filter(i => originalDeviceNoList.includes(i.yuanSheBeiBian.trim()))
+                console.log('%c new device %c', 'background:#FF5733; padding: 1px; border-radius: 0 3px 3px 0; color: #fff;', 'background:transparent', newDeviceList)
+                console.log('%c already exist device %c', 'background:#43f80c; padding: 1px; border-radius: 0 3px 3px 0; color: #fff;', 'background:transparent', existDeviceList)
+                this.loading = false
+                this.$confirm(`<span style="color:#f56c6c; font-size: 18px; font-weight: 600;">
+                                        经系统判定</span><br>1.预期新导入设备的数量为 ${newDeviceList.length} 台!<br>
+                                        2.预期更新已存在的设备数量为 ${existDeviceList.length} 台!<br>
+                                        <span style="color:#f56c6c;">Tips:请确认数据无误再点击确定进行导入</span><br><span style="color:#f56c6c; font-size: 18px; font-weight: 600;">请谨慎操作!</span>`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    dangerouslyUseHTMLString: true,
+                    type: 'warning'
+                }).then(async () => {
+                    await this.doImportDevice(importData)
+                    this.loading = true
+                    setTimeout(() => {
+                        this.loading = false
+                        this.$message.success('设备数据导入成功!')
+                        this.getDatas()
+                    }, 1000)
+                }).catch(() => { })
+            }).catch(() => {
+                this.loading = false
+            })
+        },
+        async doImportDevice (existDeviceList, currentPosition) {
+            this.loading = true
+            const allRequests = []
+            for (let index = 0; index < existDeviceList.length; index++) {
+                const item = existDeviceList[index]
+                let params = {}
+                if (item.id) {
+                    // 获取设备数据
+                    const { data: itemData } = await getequipmentCard({ id: item.id })
+                    params = { ...itemData, ...item } // 合并数据
+                } else {
+                    params = item // 直接使用当前 item
+                }
+                console.log(params)
+                // 将每个 saveEquipmentCard 请求加入到 allRequests 数组中
+                allRequests.push(saveEquipmentCard(params))
+            }
+            // 等待所有异步请求完成
+            await Promise.all(allRequests)
+            this.loading = false
+        },
+        generateDayRule () {
+            const days = ['每周1', '每周2', '每周3', '每周4', '每周5', '每周6', '每周7']
+            let combinations = []
+            for (let length = 1; length <= days.length; length++) {
+                this.generateCombinations([], days, combinations)
+            }
+            combinations = combinations.map(comb => '每周' + comb.map(item => item.slice(2)).join(','))
+            combinations.push('每天')
+            return combinations
+        },
+        generateRule (num, prefix, suffix) {
+            return Array.from({ length: num }, (_, i) => prefix + `${i + 1}` + suffix)
+        },
+        generateCombinations (current, remaining, results) {
+            if (remaining.length === 0) {
+                results.push(current)
+                return
+            }
+            const first = remaining[0]
+            const rest = remaining.slice(1)
+            // 包括当前数字和不包括当前数字两种情况
+            this.generateCombinations(current.concat([first]), rest, results)
+            this.generateCombinations(current, rest, results)
+        },
+        /**
+     * 负责导入设备维护项目数据的第一部分校验,全部成功则返回true
+     * @param {*} data
+     * @returns
+     */
+        maintenanceInvalidPartOne (data) {
+        // 1、对数据进行清洗校验(设备编号不能为空,维护周期、维护项目亦不可为空)
+            const invalidResult = this.checkDeviceRequiredFieldsIfEmpty(data, this.maintenanceRequiredFieldMap)
+            if (invalidResult.length > 0) {
+                this.sendWarningMessages(invalidResult, 'required')
+                return false
+            }
+            // 根据规则校验字段的限定范围
+            const allResult = this.checkFieldsRange(data, this.maintenanceValidationRules)
+            if (allResult.length > 0) {
+                this.sendWarningMessages(allResult, 'range')
+                return false
+            }
+            // 根据规则校验维护周期对应的维护日期的限定范围
+            const result = this.checkMaintenanceDateRange(data, this.maintenanceDateValidationRules)
+            if (result.length > 0) {
+                this.sendWarningMessages(result, 'range')
+                return false
+            }
+            return true
+        },
+        /**
+     * 根据规则校验维护周期对应的维护日期的限定范围
+     */
+        checkMaintenanceDateRange (list, rules) {
+            const msgList = []
+            list.forEach(({ weiHuLeiXing: type, weiHuRiQi: exactDate }, index) => {
+                if (type === '按需保养') {
+                    console.log('按需pass2')
+                } else {
+                    if (!rules[type].includes(exactDate)) {
+                        msgList.push({ row: index + 2, field: '维护日期', value: exactDate })
+                    }
+                }
+            })
+            return msgList
+        },
+        async handleUploadChange2 (file) {
+            const dataBinary = await this.readFile(file.target.files[0])
+            file.target.value = null // 注意上传后要将input的值设为空
+            const workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
+            const workSheet = workBook.Sheets[workBook.SheetNames[0]]
+            const data = xlsx.utils.sheet_to_json(workSheet)
+            const importData = this.switchDeviceObj(data, this.projectColums)
+            console.log(importData)
+            importData.forEach(item => {
+                if (item.weiHuLeiXing === '按需保养') {
+                    item.weiHuRiQi = '/'
+                }
+            })
+            const currentPosition = this.level
+            const { userList = [], deptList = [] } = this.$store.getters || {}
+            const positionSql = `select id_,fang_jian_ming_ha from t_jjqfjb where di_dian_ = ${currentPosition}` // 房间信息
+            const supplierSql = `select id_,gong_ying_shang_m from t_gysxxb where di_dian_ = ${currentPosition}` // 供应商信息
+            const deviceGroupSql = `select id_,suo_shu_bu_men_,wei_hu_gang_wei_ from t_sbwhgwpzb where di_dian_ =  ${currentPosition}` // 设备分组信息
+            const currentTime = dayjs().format('YYYY-MM-DD HH:mm')
+            const currentApartment = this.$store.getters.userInfo.employee.positions
+            const currentUser = this.userId
+
+            const partOneInvalidResult = this.maintenanceInvalidPartOne(importData)
+            if (!partOneInvalidResult) return
+
+            // 2、根据原设备编号去重,检验原设备编号是否在数据库中存在,如有不存在的数据,不进行导入,并提示用户
+            const uniqueArr = Array.from(new Set(importData.map(i => i.yuanSheBeiBian.trim())))
+            /* 3、根据去重的设备编号去查对应的设备ID,然后拼接data数据,赋值设备ID*/
+            const sql = `select id_,yuan_she_bei_bian from t_sbdj where find_in_set(yuan_she_bei_bian,'${uniqueArr.join(',')}')and di_dian_ = ${currentPosition}`
+            this.$common.request('sql', sql).then(async res => {
+                const deviceNoWithIdlist = res.variables.data
+                console.log(deviceNoWithIdlist, ' <=> ', uniqueArr)
+                const deviceNoSet = new Set(deviceNoWithIdlist.map(i => i.yuan_she_bei_bian))
+                const missStr = uniqueArr.filter(i => !deviceNoSet.has(i)).join(',') || ''
+                if (missStr !== '') {
+                    this.$message.error(`设备维护项目数据中包含不存在于设备档案的原设备编号!具体原设备编号为:${missStr}`)
+                    return
+                }
+                importData.forEach(item => {
+                    item.id = deviceNoWithIdlist.find(i => i.yuan_she_bei_bian === item.yuanSheBeiBian).id_
+                })
+
+                const resultList = []
+                importData.forEach(item => {
+                    const flag = item.weiHuLeiXing === '日保养'
+                    const match = item.weiHuRiQi?.match(/\d+/g)
+                    const o = {
+                        id: item.id,
+                        weiHuLeiXing: item.weiHuLeiXing.trim(),
+                        weiHuRiQi: item.weiHuRiQi?.trim() || '',
+                        weiHuXiangMuC: item.weiHuXiangMuC.trim(),
+                        riQiShuZi: match ? (flag ? match.join(',') : match[0]) : ''
+                    }
+                    if (o.weiHuLeiXing === '日保养' && o.weiHuRiQi === '每天') o.riQiShuZi = '1,2,3,4,5,6,7'
+                    resultList.push(o)
+                })
+                // 4、根据用户选择 进行全量替换|增量添加
+                await this.doProjectImport(deviceNoWithIdlist, resultList, this.ImportDeviceType)
+                this.$message.success('维护项目数据' + this.ImportDeviceType + '成功!')
+            })
+        },
+        async doProjectImport (deviceNoWithIdlist, resultList, type) {
+            this.loading = true
+            const allRequests = []
+            deviceNoWithIdlist.forEach(async item => {
+                const { data: itemData } = await getequipmentCard({ id: item.id_ })
+                const temp = resultList.filter(i => i.id === item.id_).map(ii => {
+                    delete ii.id
+                    return ii
+                })
+                let params = {}
+                if (type === '增量添加') { // 增量
+                    params = {
+                        ...itemData,
+                        maintenanceItemPoList: [...itemData.maintenanceItemPoList, ...temp]
+                    }
+                } else if (type === '全量替换') { // 全量
+                    params = {
+                        ...itemData,
+                        maintenanceItemPoList: temp
+                    }
+                }
+                console.log('params', params)
+                allRequests.push(saveEquipmentCard(params))
+            })
+            await Promise.all(allRequests)
+            this.loading = false
+        }
+    }
+}
+
+</script>
+
+<style lang="scss" scoped>
+    .icon-image{
+        width: 36px;
+    }
+    .device-image{
+        width: 152px;
+        height: 110px;
+    }
+    .title{
+        font-size: 12px;
+        font-weight: 900;
+        color: #333;
+        margin: 0 0 14px 20px;
+
+    }
+    .ctx{
+        margin: 0 0 0 20px;
+        .item{
+            .cusitem{
+                margin: -8px 0;
+                display: flex;
+                align-items: center;
+            }
+            .span{
+                min-width:60px
+            }
+            margin: 6px 0;
+            color: #999;
+        }
+
+    }
+  ::v-deep {
+        .el-form-item__label{
+            text-align: left;
+            font-size: 12px !important;
+        }
+        .el-form-item__ctx{
+            font-size: 12px !important;
+        }
+    }
+</style>

+ 149 - 0
src/views/component/device/maintenance.vue

@@ -0,0 +1,149 @@
+<template>
+    <div class="table">
+        <div class="button">
+            <el-button size="mini" icon="el-icon-plus" type="success" @click="goAdd">添加</el-button>
+            <el-button size="mini" icon="el-icon-close" type="danger" @click="goDelete">删除</el-button>
+        </div>
+        <el-table :data="listDataCopy" @selection-change="handleSelectionChange">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="weiHuLeiXing" label="维护类型" width="120" />
+            <el-table-column prop="weiHuRiQi" label="维护日期" width="200" />
+            <el-table-column prop="weiHuXiangMuC" label="维护项目" />
+            <el-table-column prop="" label="操作" width="140">
+                <template slot-scope="{row, $index}">
+                    <el-button size="mini" type="text" icon="el-icon-edit-outline" @click="goEdit(row, $index)">编辑</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="pagination.currentPage"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="pagination.pageSize"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="listDataCopy.length"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+        <DeviceSubtableDialog
+            v-if="visible"
+            :dynamic-params="dynamicParams"
+            :visible="visible"
+            @close="close"
+            @submit="getSonData"
+        />
+    </div>
+</template>
+
+<script>
+import DeviceSubtableDialog from '@/views/component/deviceSubtableDialog.vue'
+export default {
+    components: {
+        DeviceSubtableDialog
+    },
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        },
+        listData: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data () {
+        return {
+            pagination: {
+                pageSize: 10,
+                currentPage: 1
+            },
+            listDataCopy: this.listData,
+            visible: false,
+            dynamicParams: {
+                editFromType: '添加',
+                customComponent: true
+            },
+            multipleSelection: []
+        }
+    },
+    watch: {
+        listData: {
+            handler (val) {
+                this.listDataCopy = this.listData
+            }
+        }
+    },
+    methods: {
+        mounted () {
+
+        },
+        // 子组件的提交事件
+        getSonData (val) {
+            this.$set(this.listDataCopy, typeof val.index === 'undefined' ? this.listDataCopy.length : val.index, {
+                ...this.listDataCopy[val.index],
+                weiHuLeiXing: val.weiHuLeiXing,
+                weiHuRiQi: val.weiHuRiQi,
+                weiHuXiangMuC: val.weiHuXiangMuC,
+                riQiShuZi: val.riQiShuZi,
+                kaiShiShiJian: val.kaiShiShiJian
+            })
+        },
+        handleSelectionChange (val) {
+            this.multipleSelection = val
+        },
+        goDelete () {
+            this.listDataCopy = this.listDataCopy.filter(item => !this.multipleSelection.includes(item))
+        },
+        goAdd () {
+            this.dynamicParams.editFromType = '添加'
+            delete this.dynamicParams.row
+            delete this.dynamicParams.index
+            this.visible = true
+        },
+        goEdit (row, index) {
+            this.dynamicParams.editFromType = '修改'
+            this.dynamicParams.row = row
+            this.dynamicParams.index = index
+            this.visible = true
+        },
+        // 弹窗关闭事件回调
+        close () {
+            this.visible = false
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.pagination.currentPage = val
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.pagination.pageSize = val
+            this.pagination.currentPage = 1
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.pagination.currentPage - 1) * this.pagination.pageSize
+        }
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 152 - 0
src/views/component/device/maintenanceRecord.vue

@@ -0,0 +1,152 @@
+<!-- 使用与维护记录 -->
+<template>
+    <div v-loading="loading" class="table">
+        <el-table :data="listData">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="bianZhiBuMen" label="部门" width="120">
+                <template slot-scope="{row}">
+                    <ibps-user-selector
+                        :value="row.bianZhiBuMen"
+                        type="position"
+                        readonly-text="text"
+                        :disabled="true"
+                        :multiple="true"
+                        size="mini"
+                    />
+                </template>
+            </el-table-column>
+            <el-table-column prop="jiHuaShiJian" label="计划时间" />
+            <el-table-column prop="riQi" label="设备编号" width="120" />
+            <el-table-column prop="sheBeiMingChen" label="设备名称" />
+            <el-table-column prop="shengXiaoRiQi" label="放置位置" />
+            <el-table-column prop="zhuZhouQi" label="周期" />
+            <el-table-column prop="bianZhiRen" label="操作人" width="120">
+                <template slot-scope="{row}">
+                    <ibps-user-selector
+                        :value="row.bianZhiRen"
+                        type="user"
+                        readonly-text="text"
+                        :disabled="true"
+                        :multiple="true"
+                        size="mini"
+                    />
+                </template>
+            </el-table-column>
+            <el-table-column prop="neiRongQingKua" label="操作内容及情况" />
+            <el-table-column prop="" label="操作" width="80">
+                <template slot-scope="{row}">
+                    <el-button size="mini" type="text" icon="el-icon-view" @click="look(row)">查阅</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="requestPage.pageNo"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="requestPage.limit"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+        <data-template-formrender-dialog
+            :visible="DialogVisible"
+            form-key="yqsbwhbyjlb"
+            :pk-value="pkValue"
+            :readonly="true"
+            @close="visible => DialogVisible = visible"
+        />
+    </div>
+</template>
+
+<script>
+import DataTemplateFormrenderDialog from '@/business/platform/data/templaterender/form/dialog.vue'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import { queryMaintenanceRecord } from '@/api/platform/device/device'
+export default {
+    components: {
+        ibpsUserSelector, DataTemplateFormrenderDialog
+    },
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        }
+    },
+    data () {
+        return {
+            pkValue: '',
+            DialogVisible: false,
+            listData: [],
+            loading: false,
+            total: 0,
+            requestPage: {
+                limit: 10,
+                pageNo: 1
+            }
+        }
+    },
+    async mounted () {
+        this.getData()
+    },
+    methods: {
+        // 查阅
+        look (row) {
+            console.log(row.id)
+            this.pkValue = row.id
+            this.DialogVisible = true
+        },
+        async getData () {
+            this.loading = true
+            const { data: { dataResult, pageResult }} = await queryMaintenanceRecord({
+                requestPage: this.requestPage,
+                parameters: [
+                    { key: 'Q^ri_qi_^S', value: this.params.sheBeiShiBieH },
+                    { key: 'Q^shi_fou_guo_shen_^S', value: '已完成' }
+                ],
+                sorts: [
+                    { field: 'bian_zhi_shi_jian', order: 'desc' }
+                ]
+            })
+            this.listData = dataResult
+            this.total = pageResult.totalCount
+            this.loading = false
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.requestPage.pageNo = val
+            this.getData()
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.requestPage.limit = val
+            this.requestPage.pageNo = 1
+            this.getData()
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.requestPage.pageNo - 1) * this.requestPage.limit
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 135 - 0
src/views/component/device/moreDevices.vue

@@ -0,0 +1,135 @@
+<template>
+    <div class="table">
+        <div class="button">
+            <el-button size="mini" icon="el-icon-plus" type="success" @click="goAdd">添加</el-button>
+            <el-button size="mini" icon="el-icon-close" type="danger" @click="goDelete">删除</el-button>
+        </div>
+        <el-table :data="listDataCopy" @selection-change="handleSelectionChange">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="mingCheng" label="名称">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.mingCheng" size="mini" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="guiGeXingHao1" label="规格型号" width="200">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.guiGeXingHao1" size="mini" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="danWei" label="单位" width="80">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.danWei" size="mini" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="shuLiang" label="数量" width="120">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.shuLiang" size="mini" type="number" />
+                </template>
+            </el-table-column>
+            <el-table-column prop="yonTu" label="用途">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.yonTu" size="mini" />
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="pagination.currentPage"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="pagination.pageSize"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="listDataCopy.length"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        },
+        listData: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data () {
+        return {
+            listDataCopy: [],
+            pagination: {
+                pageSize: 10,
+                currentPage: 1
+            },
+            multipleSelection: []
+        }
+    },
+    watch: {
+        listData: {
+            handler (val) {
+                this.listDataCopy = this.listData
+            }
+        }
+    },
+    methods: {
+        handleSelectionChange (val) {
+            this.multipleSelection = val
+        },
+        goDelete () {
+            this.listDataCopy = this.listDataCopy.filter(item => !this.multipleSelection.includes(item))
+        },
+        goAdd () {
+            this.listDataCopy.push({
+                mingCheng: '',
+                guiGeXingHao1: '',
+                danWei: '',
+                shuLiang: '',
+                yonTu: ''
+            })
+            // this.$set(this.listDataCopy, this.listDataCopy.length, {
+            //     mingCheng: '',
+            //     guiGeXingHao1: '',
+            //     danWei: '',
+            //     shuLiang: '',
+            //     yonTu: ''
+            // })
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.pagination.currentPage = val
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.pagination.pageSize = val
+            this.pagination.currentPage = 1
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.pagination.currentPage - 1) * this.pagination.pageSize
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 133 - 0
src/views/component/device/repairRecord.vue

@@ -0,0 +1,133 @@
+<!-- 维修记录 -->
+<template>
+    <div v-loading="loading" class="table">
+        <el-table :data="listData">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="sheBeiBianHao" label="设备编号" />
+            <el-table-column prop="sheBeiMingChen" label="设备名称" />
+            <el-table-column prop="guZhangShiJian" label="故障发生时间" />
+            <el-table-column prop="weiXiuRiQi" label="维修日期" />
+            <el-table-column prop="weiXiuDanWei" label="维修单位" />
+            <el-table-column prop="weiXiuFeiYong" label="维修费用" />
+            <el-table-column prop="gengHuanBeiJia" label="更换备件" />
+            <el-table-column prop="" label="操作" width="100">
+                <template slot-scope="{row}">
+                    <el-button size="mini" type="text" icon="ibps-icon-table" @click="goLookForm(row)">表单</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="requestPage.pageNo"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="requestPage.limit"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+        <el-dialog
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+            :top="'3vh'"
+            :width="'90%'"
+            class="js-custom-dialog"
+            append-to-body
+            :fullscreen="false"
+            :visible.sync="iframeVisible"
+        >
+            <iframe :src="srcUrl" :height="'100%'" :width="'100%'" frameborder="0" scrolling="no" />
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import ibpsUserSelector from '@/business/platform/org/selector'
+import { queryRepairRecord } from '@/api/platform/device/device'
+export default {
+    components: {
+        ibpsUserSelector
+    },
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        }
+    },
+    data () {
+        return {
+            iframeVisible: false,
+            srcUrl: '',
+            listData: [],
+            loading: false,
+            total: 0,
+            requestPage: {
+                limit: 10,
+                pageNo: 1
+            }
+        }
+    },
+    async mounted () {
+        this.getData()
+    },
+    methods: {
+        // 查看表单
+        goLookForm (row) {
+            const first = this.$store.getters.level.first
+            this.srcUrl = this.$reportPath.replace('show', 'pdf') + '设备/设备维修记录表.rpx&id_=' + row.id + '&org_=' + first
+            this.iframeVisible = true
+        },
+        async getData () {
+            this.loading = true
+            const { data: { dataResult, pageResult }} = await queryRepairRecord({
+                requestPage: this.requestPage,
+                parameters: [
+                    { key: 'Q^she_bei_bian_hao_^S', value: this.params.sheBeiShiBieH },
+                    { key: 'Q^shi_fou_guo_shen_^S', value: '已完成' }
+                ],
+                sorts: [
+                    { field: 'bian_zhi_shi_jian', order: 'desc' }
+                ]
+            })
+            this.listData = dataResult
+            this.total = pageResult.totalCount
+            this.loading = false
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.requestPage.pageNo = val
+            this.getData()
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.requestPage.limit = val
+            this.requestPage.pageNo = 1
+            this.getData()
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.requestPage.pageNo - 1) * this.requestPage.limit
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 172 - 0
src/views/component/device/scrappedRecord.vue

@@ -0,0 +1,172 @@
+<!-- 停用报废记录 -->
+<template>
+    <div v-loading="loading" class="table">
+        <el-table :data="listData">
+            <el-table-column
+                width="50"
+                type="selection"
+            />
+            <el-table-column
+                prop=""
+                label="序号"
+                width="50"
+                type="index"
+                :index="showIndex"
+            />
+            <el-table-column prop="bianZhiBuMen" label="部门" width="120">
+                <template slot-scope="{row}">
+                    <ibps-user-selector
+                        :value="row.bianZhiBuMen"
+                        type="position"
+                        readonly-text="text"
+                        :disabled="true"
+                        :multiple="true"
+                        size="mini"
+                    />
+                </template>
+            </el-table-column>
+            <el-table-column prop="bianZhiShiJian" label="日期" width="140" />
+            <el-table-column prop="yuanSheBeiBian" label="原设备编号" />
+            <el-table-column prop="sheBeiBianHao" label="设备编号" width="120" />
+            <el-table-column prop="sheBeiMingChen" label="设备名称" />
+            <el-table-column prop="chuLiLeiXing" label="处理类型" width="80" />
+            <el-table-column prop="bianZhiRen" label="记录人" width="120">
+                <template slot-scope="{row}">
+                    <ibps-user-selector
+                        :value="row.bianZhiRen"
+                        type="user"
+                        readonly-text="text"
+                        :disabled="true"
+                        :multiple="true"
+                        size="mini"
+                    />
+                </template>
+            </el-table-column>
+            <el-table-column prop="" label="操作" width="140">
+                <template slot-scope="{row}">
+                    <el-button size="mini" type="text" icon="el-icon-view" @click="look(row)">查阅</el-button>
+                    <el-button size="mini" type="text" icon="ibps-icon-table" @click="goLookForm(row)">表单</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-pagination
+            style="margin-top: 5px; padding-bottom: 10px"
+            :current-page="requestPage.pageNo"
+            :page-sizes="[10, 20,30, 50]"
+            :page-size="requestPage.limit"
+            layout="prev,pager,next,jumper,sizes,->,total"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+        <el-dialog
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+            :top="'3vh'"
+            :width="'90%'"
+            class="js-custom-dialog"
+            append-to-body
+            :fullscreen="false"
+            :visible.sync="iframeVisible"
+        >
+            <iframe :src="srcUrl" :height="'100%'" :width="'100%'" frameborder="0" scrolling="no" />
+        </el-dialog>
+        <data-template-formrender-dialog
+            :visible="DialogVisible"
+            form-key="sbtybfjlb"
+            :pk-value="pkValue"
+            :readonly="true"
+            @close="visible => DialogVisible = visible"
+        />
+    </div>
+</template>
+
+<script>
+import DataTemplateFormrenderDialog from '@/business/platform/data/templaterender/form/dialog.vue'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import { getScrappedRecord, queryScrappedRecord } from '@/api/platform/device/device'
+export default {
+    components: {
+        ibpsUserSelector, DataTemplateFormrenderDialog
+    },
+    props: {
+        params: {
+            type: Object,
+            default: () => {}
+        }
+    },
+    data () {
+        return {
+            pkValue: '',
+            DialogVisible: false,
+            iframeVisible: false,
+            srcUrl: '',
+            loading: false,
+            listData: [],
+            total: 0,
+            requestPage: {
+                limit: 10,
+                pageNo: 1
+            }
+        }
+    },
+    mounted () {
+        this.getData()
+    },
+    methods: {
+        // 查阅
+        look (row) {
+            console.log(row.id)
+            this.pkValue = row.id
+            this.DialogVisible = true
+        },
+        // 查看表单
+        goLookForm (row) {
+            const first = this.$store.getters.level.first
+            this.srcUrl = this.$reportPath.replace('show', 'pdf') + '设备/设备停用报废表.rpx&id_=' + row.id + '&org_=' + first
+            this.iframeVisible = true
+        },
+        async getData () {
+            this.loading = true
+            const { data: { dataResult, pageResult }} = await queryScrappedRecord({
+                requestPage: this.requestPage,
+                parameters: [
+                    { key: 'Q^she_bei_id_^S', value: this.params.id },
+                    { key: 'Q^shi_fou_guo_shen_^S', value: '已完成' }
+                ],
+                sorts: [
+                    { field: 'bian_zhi_shi_jian', order: 'desc' }
+                ]
+            })
+            this.listData = dataResult
+            this.total = pageResult.totalCount
+            this.loading = false
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.requestPage.pageNo = val
+            this.getData()
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.requestPage.limit = val
+            this.requestPage.pageNo = 1
+            this.getData()
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.requestPage.pageNo - 1) * this.requestPage.limit
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.table{
+    .button{
+        margin-bottom: 5px;
+        display: flex;
+        justify-content: flex-end;
+    }
+}
+</style>

+ 643 - 0
src/views/component/deviceSubtableDialog.vue

@@ -0,0 +1,643 @@
+<template>
+    <el-dialog ref="dialog" :visible.sync="dialogVisible" :close-on-click-modal="false" class="form-renderer-dialog" :width="width" :top="top" :title="dynamicParams.editFromType" :custom-class="customClass" append-to-body @close="closeDialog">
+        <div class="maintenanceCycle">
+            <div class="maintenanceFont">维护周期:</div>
+            <el-select v-model="cycleValue" clearable placeholder="请选择">
+                <el-option
+                    v-for="item in cycleOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                />
+            </el-select>
+        </div>
+        <div v-if="judgeShow===7" class="maintenanceCycle" style="align-items: baseline;">
+            <div class="maintenanceFont">间隔时间:</div>
+            <el-select v-if="judgeShow==7" v-model="sepValue" clearable placeholder="请选择">
+                <el-option
+                    v-for="item in 30"
+                    :key="item"
+                    :label="`每隔${item}天`"
+                    :value="item"
+                />
+            </el-select>
+        </div>
+        <div v-if="judgeShow===7" class="maintenanceCycle" style="align-items: baseline;">
+            <div class="maintenanceFont">开始保养时间:</div>
+            <el-date-picker
+                v-model="startTime"
+                :clearable="false"
+                type="date"
+                placeholder="选择保养开始时间"
+                :picker-options="pickerOptions"
+                value-format="yyyy-MM-dd"
+            />
+        </div>
+
+        <div v-if="judgeShow>0 && judgeShow<7" class="maintenanceCycle" style="align-items: baseline;">
+            <div class="maintenanceFont">{{ cycleOptions[judgeShow].label }}日期:</div>
+            <div>
+                <div v-if="judgeShow==1" class="maintenanceCycle marginNone">
+                    <el-checkbox-group v-for="(item,i) in weekList" :key="i" v-model="dayCheckList" style="margin-right:1%;">
+                        <el-checkbox class="rightMargin" :label="item" />
+                    </el-checkbox-group>
+                </div>
+                <el-select v-if="judgeShow==2" v-model="monthDateValue" clearable placeholder="请选择">
+                    <el-option
+                        v-for="item in monthDateOptions"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                    />
+                </el-select>
+                <el-radio-group v-if="judgeShow==3" v-model="weekDateValue">
+                    <el-radio v-for="(item,i) in weekList" :key="i" :label="item">{{ item }}</el-radio>
+                </el-radio-group>
+                <el-select v-if="judgeShow==4" v-model="quarterDateValue" clearable placeholder="请选择">
+                    <el-option
+                        v-for="item in qmonthDateOptions"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                    />
+                </el-select>
+                <el-select v-if="judgeShow==5" v-model="midyearDateValue" clearable placeholder="请选择">
+                    <el-option
+                        v-for="item in mymonthDateOptions"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                    />
+                </el-select>
+                <el-select v-if="judgeShow==6" v-model="yearDateValue" clearable placeholder="请选择">
+                    <el-option
+                        v-for="item in ymonthDateOptions"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                    />
+                </el-select>
+                <div v-if="periodDayDate!=''&&judgeShow==1" class="describe">下次维护日期为 <span class="fontColor">{{ periodDayDate }}</span></div>
+                <div v-if="periodWeekDate!=''&&judgeShow==3" class="describe">下次维护日期为 <span class="fontColor">{{ periodWeekDate }}</span></div>
+                <div v-if="periodMonthDate!=''&&judgeShow==2" class="describe">下次维护日期为 <span class="fontColor">{{ periodMonthDate }}</span></div>
+                <div v-if="periodQuarterDate!=''&&judgeShow==4" class="describe">下次维护日期为 <span class="fontColor">{{ periodQuarterDate }}</span></div>
+                <div v-if="periodMidYearDate!=''&&judgeShow==5" class="describe">下次维护日期为 <span class="fontColor">{{ periodMidYearDate }}</span></div>
+                <div v-if="periodYearDate!=''&&judgeShow==6" class="describe">下次维护日期为 <span class="fontColor">{{ periodYearDate }}</span></div>
+            </div>
+        </div>
+        <div class="maintenanceCycle" style="align-items: normal;">
+            <div class="maintenanceFont">维护项目:</div>
+            <el-input
+                v-model="maintenanceTextarea"
+                style="width:50%;"
+                type="textarea"
+                placeholder="请输入内容"
+                maxlength="500"
+                show-word-limit
+            />
+        </div>
+        <div slot="footer" class="el-dialog--center">
+            <ibps-toolbar :actions="editFromType != 'consult' ? toolbars : toolbarsConsult" @action-event="handleActionEvent" />
+        </div>
+    </el-dialog>
+</template>
+<script>
+import ActionUtils from '@/utils/action'
+import Vue from 'vue'
+// Vue.component('ibps-formrender', () => import('@/business/platform/form/formrender/index.vue'))
+
+export default {
+    props: {
+        visible: {
+            type: Boolean,
+            default: false
+        },
+        title: {
+            type: String
+        },
+        customClass: {
+            type: String
+        },
+        width: {
+            type: String,
+            default: '80%'
+        },
+        top: {
+            type: String,
+            default: '10%'
+        },
+        editFromType: {
+            type: String,
+            default: 'add'
+        },
+        dynamicParams: {
+            type: Object
+        },
+        templateKey: {
+            type: String,
+            default: ''
+        }
+    },
+    data () {
+        const lunarGeneration = (sum) => {
+            const arr = []
+            for (let i = 1; i < sum; i++) {
+                const mid = { value: '', label: '' }
+                mid.value = '第' + i + '日'
+                mid.label = '第' + i + '日'
+                arr.push(mid)
+            }
+            return arr
+        }
+        const monthLunarGeneration = (sum) => {
+            const arr = []
+            for (let i = 1; i < sum; i++) {
+                const mid = { value: '', label: '' }
+                mid.value = '第' + i + '个月'
+                mid.label = '第' + i + '个月'
+                arr.push(mid)
+            }
+            return arr
+        }
+        const formatCurrentDate = () => {
+            const today = new Date()
+            const year = today.getFullYear()
+            const month = (today.getMonth() + 1).toString().padStart(2, '0')
+            const day = today.getDate().toString().padStart(2, '0')
+            return `${year}-${month}-${day}`
+        }
+        return {
+            pickerOptions: {
+                disabledDate (time) {
+                    return time.getTime() < (Date.now() - (24 * 60 * 1000 * 60))
+                }
+            },
+            qrCode: '',
+            dialogVisible: this.visible,
+            cycleOptions: [{
+                value: '按需保养',
+                label: '按需保养'
+            }, {
+                value: '日保养',
+                label: '日保养'
+            }, {
+                value: '月保养',
+                label: '月保养'
+            }, {
+                value: '周保养',
+                label: '周保养'
+            }, {
+                value: '季度保养',
+                label: '季度保养'
+            }, {
+                value: '半年保养',
+                label: '半年保养'
+            }, {
+                value: '年保养',
+                label: '年保养'
+            }, {
+                value: '间隔保养',
+                label: '按时间间隔保养'
+            }],
+            cycleValue: '',
+            qmonthDateOptions: monthLunarGeneration(4),
+            ymonthDateOptions: monthLunarGeneration(13),
+            mymonthDateOptions: monthLunarGeneration(7),
+            monthDateOptions: lunarGeneration(29),
+            monthDateValue: '',
+            weekList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
+            quarterList: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],
+            midList: [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
+            dayCheckList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
+            maintenanceTextarea: '',
+            toolbars: [
+                { key: 'confirm', label: '确定' },
+                { key: 'cancel' }
+            ],
+            toolbarsConsult: [{ key: 'cancel' }],
+            weekDateValue: '',
+            quarterDateValue: '',
+            midyearDateValue: '',
+            yearDateValue: '',
+            sepValue: '',
+            startTime: '',
+            periodDayDate: '',
+            periodWeekDate: '',
+            periodMonthDate: '',
+            periodQuarterDate: '',
+            periodMidYearDate: '',
+            periodYearDate: '',
+            nowData: formatCurrentDate(),
+            judgeShow: 0,
+            daysOfWeek: [7, 1, 2, 3, 4, 5, 6]
+        }
+    },
+    watch: {
+        visible: {
+            handler: function (val, oldVal) {
+                this.dialogVisible = this.visible
+            },
+            immediate: true
+        },
+        cycleValue: {
+            handler: function (val, oldVal) {
+                if (val === '日保养') {
+                    this.judgeShow = 1
+                } else if (val === '月保养') {
+                    this.judgeShow = 2
+                } else if (val === '周保养') {
+                    this.judgeShow = 3
+                } else if (val === '季度保养') {
+                    this.judgeShow = 4
+                } else if (val === '半年保养') {
+                    this.judgeShow = 5
+                } else if (val === '年保养') {
+                    this.judgeShow = 6
+                } else if (val === '间隔保养') {
+                    this.judgeShow = 7
+                } else {
+                    this.judgeShow = 0
+                }
+            },
+            immediate: true
+        },
+        dayCheckList: {
+            handler: function (val, oldVal) {
+                const today = new Date()
+                const dayOfWeekNumber = this.daysOfWeek[today.getDay()]
+                const weekNum = []
+                val.forEach((item, i) => {
+                    const num = this.weekList.findIndex(e => e == item) + 1
+                    weekNum.push(num)
+                })
+                weekNum.sort(function (a, b) {
+                    return a - b
+                })
+                const num = weekNum.findIndex(e => e > dayOfWeekNumber)
+                if (val.length > 0 && num != -1) {
+                    this.periodDayDate = this.getDayDate(weekNum[num], 0)
+                } else if (val.length > 0 && num == -1) {
+                    this.periodDayDate = this.getDayDate(weekNum[0], 1)
+                } else {
+                    this.periodDayDate = ''
+                }
+            },
+            immediate: true
+        },
+        weekDateValue: {
+            handler: function (val, oldVal) {
+                const today = new Date()
+                const dayOfWeekNumber = this.daysOfWeek[today.getDay()]
+                const weekNum = []
+                const num1 = this.weekList.findIndex(e => e == val) + 1
+                weekNum.push(num1)
+                const num = weekNum.findIndex(e => e > dayOfWeekNumber)
+                if (val != '' && num != -1) {
+                    this.periodWeekDate = this.getDayDate(weekNum[0], 0)
+                } else if (val != '' && num == -1) {
+                    this.periodWeekDate = this.getDayDate(weekNum[0], 1)
+                } else {
+                    this.periodWeekDate = ''
+                }
+            },
+            immediate: true
+        },
+        monthDateValue: {
+            handler: function (val, oldVal) {
+                const turnVal = val.replace(/[^0-9]/ig, '')
+                const today = new Date()
+                const day = today.getDate()
+                const nextMonth = this.getNextMonthDate(today, turnVal, 1)
+                const currentMonth = this.getNextMonthDate(today, turnVal, 0)
+                this.periodMonthDate = turnVal > day ? currentMonth : nextMonth
+            }
+            // immediate: true
+        },
+        quarterDateValue: {
+            handler: function (val, oldVal) {
+                const turnVal = val.replace(/[^0-9]/ig, '')
+                const today = new Date()
+                const month = today.getMonth() + 1
+                const qu = this.getQuarter(today)
+                const nowM = this.quarterList[qu - 1][turnVal - 1]
+                const nextM = this.quarterList[qu % 4][turnVal - 1]
+
+                const endMonth = month >= nowM ? nextM : nowM
+                const yearPJ = today.getFullYear()
+                const monthPJ = endMonth > 9 ? endMonth : '0' + endMonth
+
+                this.periodQuarterDate = yearPJ + '-' + monthPJ + '-01'
+            }
+            // immediate: true
+        },
+        midyearDateValue: {
+            handler: function (val, oldVal) {
+                const turnVal = val.replace(/[^0-9]/ig, '')
+                const today = new Date()
+                const month = today.getMonth() + 1
+                const qu = month > 6 ? 2 : 1
+                const nowM = this.midList[qu - 1][turnVal - 1]
+                const nextM = this.midList[qu % 2][turnVal - 1]
+
+                const endMonth = month >= nowM ? nextM : nowM
+                const yearPJ = month >= nowM ? today.getFullYear() + 1 : today.getFullYear()
+                const monthPJ = endMonth > 9 ? endMonth : '0' + endMonth
+
+                this.periodMidYearDate = yearPJ + '-' + monthPJ + '-01'
+            }
+            // immediate: true
+        },
+        yearDateValue: {
+            handler: function (val, oldVal) {
+                const turnVal = val.replace(/[^0-9]/ig, '')
+                const today = new Date()
+                const month = today.getMonth() + 1
+                const year = today.getFullYear()
+                const qu = month >= turnVal ? year + 1 : year
+                const monthPJ = turnVal > 9 ? turnVal : '0' + turnVal
+
+                this.periodYearDate = qu + '-' + monthPJ + '-01'
+            }
+            // immediate: true
+        }
+    },
+    created () {
+        this.loadFormData()
+    },
+    methods: {
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'confirm':
+                    if (this.dynamicParams.customComponent) {
+                        this.handleConfirmV2(key)
+                    } else {
+                        this.handleConfirm(key)
+                    }
+                    break
+                case 'cancel':
+                    this.closeDialog()
+                    break
+                default:
+                    break
+            }
+        },
+        // 自定义组件中
+        handleConfirmV2 (key) {
+            const val = this.corresponding(this.cycleValue)
+            const valNum = this.correspondingNum(this.cycleValue)
+            if (this.cycleValue !== '按需保养' && this.cycleValue !== '' && val !== '' && valNum !== '' && this.maintenanceTextarea !== '') {
+                if (this.cycleValue === '间隔保养') {
+                    if (!this.startTime) {
+                        return this.$message.warning('请选择开始保养时间')
+                    } else {
+                        this.$emit('submit', { weiHuLeiXing: this.cycleValue, weiHuRiQi: val, riQiShuZi: valNum, weiHuXiangMuC: this.maintenanceTextarea, kaiShiShiJian: this.startTime, index: this.dynamicParams?.index })
+                        this.closeDialog()
+                    }
+                } else {
+                    this.$emit('submit', { weiHuLeiXing: this.cycleValue, weiHuRiQi: val, riQiShuZi: valNum, weiHuXiangMuC: this.maintenanceTextarea, index: this.dynamicParams?.index })
+                    this.closeDialog()
+                }
+            } else if (this.cycleValue === '按需保养' && this.cycleValue !== '' && this.maintenanceTextarea !== '') {
+                this.$emit('submit', { weiHuLeiXing: this.cycleValue, weiHuXiangMuC: this.maintenanceTextarea, index: this.dynamicParams?.index })
+                this.closeDialog()
+            } else {
+                this.$message.warning('请保证所有信息都已填写')
+            }
+        },
+        handleConfirm (key) {
+            const a = this.dynamicParams.formObj.getData(this.templateKey)
+            const val = this.corresponding(this.cycleValue)
+            const valNum = this.correspondingNum(this.cycleValue)
+            if (this.cycleValue != '按需保养' && this.cycleValue != '' && val != '' && valNum != '' && this.maintenanceTextarea != '') {
+                if (this.dynamicParams.position == 'manage') {
+                    this.$set(a, this.dynamicParams.params.index, { ...a[this.dynamicParams.params.index], weiHuLeiXing: this.cycleValue, weiHuRiQi: val, riQiShuZi: valNum, weiHuXiangMuC: this.maintenanceTextarea })
+                } else {
+                    a.push({ weiHuLeiXing: this.cycleValue, weiHuRiQi: val, riQiShuZi: valNum, weiHuXiangMuC: this.maintenanceTextarea })
+                }
+                // this.$nextTick(function(){
+                this.dynamicParams.formObj.setData(this.templateKey, a)
+                // })
+
+                this.closeDialog()
+            } else if (this.cycleValue == '按需保养' && this.cycleValue != '' && this.maintenanceTextarea != '') {
+                if (this.dynamicParams.position == 'manage') {
+                    this.$set(a, this.dynamicParams.params.index, { weiHuLeiXing: this.cycleValue, weiHuXiangMuC: this.maintenanceTextarea })
+                } else {
+                    a.push({ weiHuLeiXing: this.cycleValue, weiHuXiangMuC: this.maintenanceTextarea })
+                }
+                // this.$nextTick(function(){
+                this.dynamicParams.formObj.setData(this.templateKey, a)
+                // })
+
+                this.closeDialog()
+            } else {
+                this.dynamicParams.formObj.$message.warning('请保证所有信息都已填写')
+            }
+        },
+        corresponding (content) {
+            const that = this
+            if (content === '日保养') {
+                let str = '每周'
+                const numArr = []
+                that.dayCheckList.forEach((element, i) => {
+                    const ind = that.weekList.findIndex(item => item === element) != -1 ? that.weekList.findIndex(item => item === element) + 1 : ''
+                    numArr.push(ind)
+                })
+                numArr.sort(function (a, b) {
+                    return a - b
+                })
+                numArr.forEach((element, i) => {
+                    if (i === that.dayCheckList.length - 1) {
+                        str = str + element
+                    } else {
+                        str = str + element + ','
+                    }
+                })
+                return str === '每周1,2,3,4,5,6,7' ? '每天' : str
+            } else if (content === '月保养') {
+                return '每月' + that.monthDateValue
+            } else if (content === '周保养') {
+                const ind = that.weekList.findIndex(item => item === that.weekDateValue) !== -1 ? that.weekList.findIndex(item => item === that.weekDateValue) + 1 : ''
+                return '每周' + ind
+            } else if (content === '季度保养') {
+                return '每季度' + that.quarterDateValue
+            } else if (content === '半年保养') {
+                return '每半年' + that.midyearDateValue
+            } else if (content === '年保养') {
+                return '每年' + that.yearDateValue
+            } else if (content === '间隔保养') {
+                return `${this.startTime}起每隔${this.sepValue}天`
+            } else {
+                return ''
+            }
+        },
+        correspondingNum (content) {
+            const that = this
+            if (content === '日保养') {
+                let str = ''
+                const numArr = []
+                that.dayCheckList.forEach((element, i) => {
+                    const ind = that.weekList.findIndex(item => item === element) + 1
+                    numArr.push(ind)
+                })
+                numArr.sort(function (a, b) {
+                    return a - b
+                })
+                numArr.forEach((element, i) => {
+                    if (i === that.dayCheckList.length - 1) {
+                        str = str + element
+                    } else {
+                        str = str + element + ','
+                    }
+                })
+                return str
+            } else if (content === '月保养') {
+                const turnVal = that.monthDateValue.replace(/[^0-9]/ig, '')
+                return turnVal
+            } else if (content === '周保养') {
+                const ind = that.weekList.findIndex(item => item === that.weekDateValue) !== -1 ? that.weekList.findIndex(item => item === that.weekDateValue) + 1 : ''
+                return ind
+            } else if (content === '季度保养') {
+                const turnVal = that.quarterDateValue.replace(/[^0-9]/ig, '')
+                return turnVal
+            } else if (content === '半年保养') {
+                const turnVal = that.midyearDateValue.replace(/[^0-9]/ig, '')
+                return turnVal
+            } else if (content === '年保养') {
+                const turnVal = that.yearDateValue.replace(/[^0-9]/ig, '')
+                return turnVal
+            } else if (content === '间隔保养') {
+                const turnVal = that.sepValue
+                return turnVal
+            } else {
+                return ''
+            }
+        },
+        assignment (content) {
+            const that = this
+            if (content.weiHuLeiXing === '日保养') {
+                const strArr = []
+                const str = content.weiHuRiQi === '每天' ? '1,2,3,4,5,6,7' : content.weiHuRiQi.slice(2)
+                const partArr = str.split(',')
+                // console.log(partArr)
+                partArr.forEach((e, i) => {
+                    const num = e * 1 - 1
+                    strArr.push(this.weekList[num])
+                })
+                this.dayCheckList = strArr
+            } else if (content.weiHuLeiXing === '月保养') {
+                that.monthDateValue = content.weiHuRiQi.slice(2)
+            } else if (content.weiHuLeiXing === '周保养') {
+                const str = content.weiHuRiQi.slice(2)
+                const partArr = str.split(',')
+                // console.log(partArr*1-1)
+                that.weekDateValue = this.weekList[partArr * 1 - 1]
+            } else if (content.weiHuLeiXing === '季度保养') {
+                that.quarterDateValue = content.weiHuRiQi.slice(3)
+            } else if (content.weiHuLeiXing === '半年保养') {
+                that.midyearDateValue = content.weiHuRiQi.slice(3)
+            } else if (content.weiHuLeiXing === '年保养') {
+                that.yearDateValue = content.weiHuRiQi.slice(2)
+            } else if (content.weiHuLeiXing === '间隔保养') {
+                that.sepValue = +content.riQiShuZi || ''
+                that.startTime = content.kaiShiShiJian || ''
+            } else {
+
+            }
+        },
+        // 关闭当前窗口
+        closeDialog () {
+            this.$emit('close', false)
+        },
+        loadFormData () {
+            if (this.dynamicParams.position == 'manage') {
+                const a = this.dynamicParams.formObj.getData(this.templateKey)[this.dynamicParams.params.index]
+                this.assignment(a)
+                this.cycleValue = a.weiHuLeiXing
+                this.maintenanceTextarea = a.weiHuXiangMuC
+            }
+            if (this.dynamicParams.customComponent && this.dynamicParams.row) {
+                const a = this.dynamicParams.row
+                this.assignment(a)
+                this.cycleValue = a.weiHuLeiXing
+                this.maintenanceTextarea = a.weiHuXiangMuC
+            }
+        },
+        getDayDate (type, dates) {
+            const now = new Date()
+            const nowTime = now.getTime()
+            const day = now.getDay()
+            const longTime = 24 * 60 * 60 * 1000
+            const n = longTime * 7 * (dates || 0)
+            let dd = nowTime - (day - type) * longTime + n
+            dd = new Date(dd)
+            const y = dd.getFullYear()
+            let m = dd.getMonth() + 1
+            let d = dd.getDate()
+            m = m < 10 ? '0' + m : m
+            d = d < 10 ? '0' + d : d
+            const daynow = y + '-' + m + '-' + d
+            return daynow
+        },
+        // 获取往后几个月相应的日期
+        // currentDate:当前日期
+        // dayOfMonth:获取几号
+        // val:往后几个月
+        getNextMonthDate (currentDate, dayOfMonth, val) {
+            const currentYear = currentDate.getFullYear()
+            const currentMonth = currentDate.getMonth()
+            const nextMonth = currentMonth + val
+
+            const nextMonthDate = new Date(currentYear, nextMonth, dayOfMonth)
+            const formattedDate = nextMonthDate.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\//g, '-')
+            return formattedDate
+        },
+        // 获取当前季度
+        getQuarter (date) {
+            return Math.floor(date.getMonth() / 3) + 1
+        }
+
+    }
+}
+</script>
+<style lang="scss" >
+.form-renderer-dialog {
+    .el-dialog__body {
+        padding: 10px 0 5px 0;
+    }
+    .el-dialog__headerbtn {
+        z-index: 99999;
+    }
+    @media print {
+        .el-dialog__headerbtn {
+            display: none !important;
+        }
+        .hidden-print {
+            padding: 0;
+            margin: 0;
+        }
+    }
+}
+.maintenanceCycle{
+    display: flex;
+    align-items: center;
+    margin: 2%;
+}
+.maintenanceFont{
+    width: 10%;
+}
+.marginNone{
+    margin: 0;
+}
+.rightMargin{
+    margin-right: 2.5vh !important;
+}
+.describe{
+    margin-top: 2%;
+    font-size: 12px;
+    color: #808080;
+}
+.fontColor{
+    color: #409EFF;
+}
+</style>

+ 142 - 0
src/views/component/selectType.vue

@@ -0,0 +1,142 @@
+<!--
+ * @Descripttion: 文件修订选择文件归档路径
+ * @version: 1.0
+ * @Author: Liu_jiaYin
+ * @Date: 2024-04-01 15:45:19
+ * @LastEditors: Do not edit
+ * @LastEditTime: 2024-04-13 09:48:53
+-->
+<template>
+    <el-cascader ref="cascader" v-model="cascaderData" :disabled="readonly" :options="options" :props="props" @change="handleChange">
+        <template slot-scope="{ node, data }">
+            <span>{{ data.name_ }}</span>
+            <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+        </template>
+    </el-cascader>
+</template>
+<script>
+import curdPost from '@/business/platform/form/utils/custom/joinCURD.js'
+import Json from '@/business/platform/serv/components/json.vue'
+import TreeUtils from '@/utils/tree'
+
+export default {
+    props: {
+        value: { // value
+            type: [String, Number, Object, Array],
+            default () {
+                return this.multiple ? [] : {}
+            }
+        },
+        // 所有字段数据,(包含主主子表)
+        formData: [Object, Array],
+        field: {
+            type: Object,
+            required: true
+        },
+        readonly: {
+            type: Boolean,
+            default: false
+        },
+        readonlyStyle: {
+            type: String,
+            default: 'text'
+        }
+    },
+    data () {
+        const { first, second } = this.$store.getters.level
+        const levelInfos = second || first
+        return {
+            props: {
+                value: 'ID_', label: 'name_', children: 'children'
+            },
+            levelInfos,
+            cascaderData: [],
+            options: []
+        }
+    },
+    watch: {
+        value: {
+            handler (val, oldVal) {
+                if (val) {
+                    if (typeof val === 'string') {
+                        this.cascaderData = val.split(',')
+                    } else {
+                        this.cascaderData = val
+                    }
+                } else {
+                    this.cascaderData = []
+                }
+            },
+            immediate: true
+        }
+        // readonly: {
+        //     handler: function (val, oldVal) {
+        //         // console.log('65 formData', this.formData)
+        //         // console.log('65 readonly', val)
+        //         console.log('65 readonlyStyle', this.readonlyStyle)
+        //     },
+        //     immediate: true
+        // }
+    },
+    async created () {
+        await this.getCascaderOptions()
+    },
+    methods: {
+        handleChange (v) {
+            const nodesInfo = this.$refs['cascader'].getCheckedNodes()[0]
+            const xilei = []
+            const authorityBuMen = []
+            const authority = JSON.parse(nodesInfo.data.AUTHORITY_NAME)
+            const wenJianXiLeiArrs = nodesInfo.pathNodes.map((item) => item.label)
+            // 组件本身字段的回填值
+            this.$emit('update:value', nodesInfo.path.join(','))
+            this.$emit(
+                'change-data',
+                'guiDangLuJingXinX',
+                JSON.stringify({
+                    wenJianXiLei: wenJianXiLeiArrs.join(' / '),
+                    xiLeiId: nodesInfo.value,
+                    quanXianLeiXing: authority.chaYue })
+            )
+            this.$emit('change-data', 'wenJianXiLei', wenJianXiLeiArrs.join(' / '))
+            this.$emit('change-data', 'xiLeiId', nodesInfo.value)
+            this.$emit('change-data', 'quanXianLeiXing', authority.chaYue)
+            // eslint-disable-next-line no-redeclare
+            for (var i of authority.buMen) {
+                if (i[0] === this.levelInfos || i[1] === this.levelInfos) {
+                    authorityBuMen.push(i[i.length - 1])
+                }
+            }
+            this.$emit(
+                'change-data',
+                'quanXianXinXi',
+                authorityBuMen.join(',')
+            )
+            this.$emit('change-data', 'zhuanYeBuMen', authorityBuMen.join(','))
+            this.$emit('change-data', 'guiShu', authorityBuMen.join(','))
+        },
+        // 获取文件分类信息
+        async getCascaderOptions () {
+            const sql = `select *FROM ibps_cat_type WHERE  authority_name like '%${this.levelInfos}%' and CATEGORY_KEY_='FILE_TYPE' ORDER BY sn_ ASC`
+            curdPost('sql', sql).then((res) => {
+                if (res.state === 200) {
+                    const datas = res.variables.data
+                    this.sqlDatas = datas
+                    if (datas.length > 0) {
+                        this.options = this.toTree(datas)
+                    }
+                }
+            })
+        },
+        toTree (data) {
+            return TreeUtils.transformToTreeFormat(data, {
+                idKey: 'ID_',
+                pIdKey: 'PARENT_ID_',
+                childrenKey: 'children'
+            })
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped></style>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio