zhangherong
2025-03-31 49da1f79aa5cd4acf1462d28922d4e8f80c00309
art: 设备管理-保养标准-新增
已添加3个文件
700 ■■■■■ 文件已修改
src/views/eam/base/EamMaintenanceStandardList.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/base/modules/EamMaintenanceStandardModal.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/equipment/modules/LxSearchEquipmentSelect.vue 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/eam/base/EamMaintenanceStandardList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,199 @@
<template>
  <a-card :bordered="false">
    <!-- æŸ¥è¯¢åŒºåŸŸ -->
    <div class="table-page-search-wrapper">
      <a-form layout="inline" @keyup.enter.native="searchQuery">
        <a-row :gutter="24">
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="标准编码">
              <a-input placeholder="请输入标准编码" v-model="queryParam.standardCode"></a-input>
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="标准名称">
              <a-input placeholder="请输入标准名称" v-model="queryParam.standardName"></a-input>
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <a-form-item label="设备编号">
              <a-input placeholder="请输入设备编号" v-model="queryParam.equipmentCode"></a-input>
            </a-form-item>
          </a-col>
          <template v-if="toggleSearchStatus">
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
              <a-form-item label="保养分类">
                <a-input placeholder="请输入保养分类" v-model="queryParam.maintenanceCategory"></a-input>
              </a-form-item>
            </a-col>
          </template>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
              <a-button type="info" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
              <a @click="handleToggleSearch" style="margin-left: 8px">
                {{ toggleSearchStatus ? '收起' : '展开' }}
                <a-icon :type="toggleSearchStatus ? 'up' : 'down'" />
              </a>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <div class="table-operator">
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-button type="primary" icon="download" @click="handleExportXls('保养标准')">导出</a-button>
      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl"
                @change="handleImportExcel">
        <a-button type="primary" icon="import">导入</a-button>
      </a-upload>
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="batchDel">
            <a-icon type="delete" />
            åˆ é™¤
          </a-menu-item>
        </a-menu>
        <a-button style="margin-left: 8px"> æ‰¹é‡æ“ä½œ
          <a-icon type="down" />
        </a-button>
      </a-dropdown>
    </div>
    <!-- table区域-begin -->
    <div>
      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
        <i class="anticon anticon-info-circle ant-alert-icon"></i> å·²é€‰æ‹© <a
        style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
      </div>
      <a-table
        ref="table"
        size="middle"
        bordered
        rowKey="id"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        class="j-table-force-nowrap"
        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
        @change="handleTableChange">
        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">编辑</a>
          <a-divider type="vertical" />
          <a-dropdown>
            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
            <a-menu slot="overlay">
              <a-menu-item>
                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                  <a>删除</a>
                </a-popconfirm>
              </a-menu-item>
            </a-menu>
          </a-dropdown>
        </span>
      </a-table>
    </div>
    <!-- table区域-end -->
    <!-- è¡¨å•区域 -->
    <eamMaintenanceStandard-modal ref="modalForm" @ok="modalFormOk"></eamMaintenanceStandard-modal>
  </a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import EamMaintenanceStandardModal from './modules/EamMaintenanceStandardModal'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
  name: 'EamMaintenanceStandardList',
  mixins: [JeecgListMixin],
  components: {
    EamMaintenanceStandardModal
  },
  data() {
    return {
      description: '保养标准管理页面',
      // è¡¨å¤´
      columns: [
        {
          title: '#',
          dataIndex: '',
          key: 'rowIndex',
          width: 60,
          align: 'center',
          customRender: function(t, r, index) {
            return parseInt(index) + 1
          }
        },
        {
          title: '标准编码',
          align: 'center',
          dataIndex: 'standardCode'
        },
        {
          title: '标准名称',
          align: 'center',
          dataIndex: 'standardName'
        },
        {
          title: '保养周期',
          align: 'center',
          dataIndex: 'maintenancePeriod'
        },
        {
          title: '保养分类',
          align: 'center',
          dataIndex: 'maintenanceCategory'
        },
        {
          title: '设备编号',
          align: 'center',
          dataIndex: 'equipmentCode'
        },
        {
          title: '标准状态',
          align: 'center',
          dataIndex: 'standardStatus'
        },
        {
          title: '标准版本',
          align: 'center',
          dataIndex: 'standardVersion'
        },
        {
          title: '操作',
          dataIndex: 'action',
          align: 'center',
          scopedSlots: { customRender: 'action' }
        }
      ],
      url: {
        list: '/eam/maintenanceStandard/list',
        delete: '/eam/maintenanceStandard/delete',
        deleteBatch: '/eam/maintenanceStandard/deleteBatch',
        exportXlsUrl: 'eam/maintenanceStandard/exportXls',
        importExcelUrl: 'eam/maintenanceStandard/importExcel'
      }
    }
  },
  computed: {
    importExcelUrl: function() {
      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
    }
  },
  methods: {}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
src/views/eam/base/modules/EamMaintenanceStandardModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,278 @@
<template>
  <j-modal
    :title="title"
    :width="1200"
    :visible="visible"
    :confirmLoading="confirmLoading"
    switchFullscreen
    @ok="handleOk"
    @cancel="handleCancel"
    cancelText="关闭">
    <a-spin :spinning="confirmLoading">
      <a-form-model ref="form" :model="model" :rules="validatorRules">
        <a-row :gutter="24">
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="standardCode" label="标准编码">
              <a-input placeholder="编码系统自动生成" v-model="model.standardCode" disabled />
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="standardName" label="标准名称">
              <a-input placeholder="请输入标准名称" v-model="model.standardName" />
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="maintenanceCategory" label="保养分类">
              <j-dict-select-tag dict-code="maintenance_category" placeholder="请选择保养分类" v-model="model.maintenanceCategory" />
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24">
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="fileCode" label="文件编号">
              <a-input placeholder="请输入保养标准文件编号" v-model="model.fileCode"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="initialDate" label="初始日期">
              <a-date-picker placeholder="请选择初始日期" v-model="model.initialDate" format="yyyy-MM-dd" style="width: 100%"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="maintenancePeriod" label="保养周期">
              <a-input-number v-model="model.maintenancePeriod" :min="1" :precision="0" style="width: 100%"/>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24">
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentId" label="设备编号">
              <lx-search-equipment-select placeholder="请输入设备编号或名称搜索" v-model="model.equipmentId"></lx-search-equipment-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="standardStatus" label="标准状态">
              <j-dict-select-tag dict-code="maintenance_standard_status" v-model="model.standardStatus" disabled/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="standardVersion" label="标准版本">
              <a-input-number v-model="model.standardVersion" style="width: 100%" disabled/>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24">
          <a-col :span="8">
            <a-form-model-item
              label="参考文件"
              :labelCol="labelCol"
              :wrapperCol="wrapperCol"
              prop="fileList">
              <lx-upload :returnUrl="false"
                         :isMultiple="false"
                         v-model="model.fileList"
                         biz="EamMaintenanceStandard">
              </lx-upload>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24">
          <j-vxe-table
            ref="editableDetailTable"
            :rowNumber="true"
            :rowSelection="true"
            :bordered="true"
            :alwaysEdit="true"
            :toolbar="true"
            :toolbarConfig="detail.toolbarConfig"
            keep-source
            :height="300"
            :loading="detail.loading"
            :dataSource="detail.dataSource"
            :columns="detail.columns"
            style="margin-top: 8px;"/>
        </a-row>
      </a-form-model>
    </a-spin>
  </j-modal>
</template>
<script>
  import { httpAction } from '@/api/manage'
  import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
  import { JVXETypes } from '@/components/jeecg/JVxeTable'
  import LxSearchEquipmentSelect from '@views/eam/equipment/modules/LxSearchEquipmentSelect'
  export default {
    name: "EamMaintenanceStandardModal",
    mixins: [JVxeTableModelMixin],
    components: {
      LxSearchEquipmentSelect,
    },
    data () {
      return {
        title:"操作",
        visible: false,
        model: {},
        labelCol: {
          xs: { span: 24 },
          sm: { span: 5 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 16 },
        },
        confirmLoading: false,
        validatorRules: {
          standardName: [
            { required: true, message: '请输入标准名称!' }
          ],
          maintenanceCategory: [
            { required: true, message: '请选择保养分类!' }
          ],
          initialDate: [
            { required: true, message: '请选择初始日期!' }
          ],
          maintenancePeriod: [
            { required: true, message: '请输入保养周期,单位:天!' }
          ],
          equipmentId: [
            { required: true, message: '请选择设备!' }
          ]
        },
        url: {
          add: "/eam/maintenanceStandard/add",
          edit: "/eam/maintenanceStandard/edit",
        },
        detail: {
          loading: false,
          dataSource: [],
          columns: [
            {
              title: 'ID',
              key: 'id',
              type: JVXETypes.hidden,
            },
            {
              title: 'standardId',
              key: 'standardId',
              type: JVXETypes.hidden,
            },
            {
              title: '序号',
              key: 'itemCode',
              type: JVXETypes.inputNumber,
              width: '10%',
              align:"center",
              validateRules: [
                {required : true, unique: true, message: '序号不能重复'}
              ]
            },
            {
              title: '保养项',
              key: 'itemName',
              type: JVXETypes.textarea,
              width: '20%',
              align:"center",
              validateRules: [
                {required : true}
              ]
            },
            {
              title: '子保养项',
              key: 'subItemName',
              type: JVXETypes.textarea,
              width: '25%',
              align:"center",
            },
            {
              title: '保养要求',
              key: 'itemDemand',
              type: JVXETypes.textarea,
              width: '30%',
              align:"center",
              validateRules: [
                {required : true}
              ]
            },
          ],
          toolbarConfig: {
            // prefix å‰ç¼€ï¼›suffix åŽç¼€
            slot: ['prefix', 'suffix'],
            // add æ–°å¢žæŒ‰é’®ï¼›remove åˆ é™¤æŒ‰é’®ï¼›clearSelection æ¸…空选择按钮
            btn: ['add', 'remove', 'clearSelection']
          },
        }
      }
    },
    created () {
    },
    methods: {
      add () {
        //初始化默认值
        this.edit({});
      },
      edit (record) {
        this.model = Object.assign({}, record);
        this.visible = true;
      },
      close () {
        this.$emit('close');
        this.visible = false;
        this.$refs.form.clearValidate();
      },
      async handleOk () {
        const that = this;
        let errMap = await that.$refs.editableDetailTable.validateTable();
        if(errMap){
          this.$message.warning("数据校验失败!");
          return;
        }
        // è§¦å‘表单验证
         this.$refs.form.validate(valid => {
          if (valid) {
            debugger;
            let tableData = that.$refs.editableDetailTable.getTableData();
            let newData = that.$refs.editableDetailTable.getNewData();
            let removeData = that.$refs.editableDetailTable.getDeleteData();
            that.confirmLoading = true;
            let httpurl = '';
            let method = '';
            if(!this.model.id){
              httpurl+=this.url.add;
              method = 'post';
            }else{
              httpurl+=this.url.edit;
               method = 'put';
            }
            httpAction(httpurl,this.model,method).then((res)=>{
              if(res.success){
                that.$message.success(res.message);
                that.$emit('ok');
                that.close();
              }else{
                that.$message.warning(res.message);
              }
            }).finally(() => {
              that.confirmLoading = false;
            })
          }else{
             return false;
          }
        })
      },
      handleCancel () {
        this.close()
      },
    }
  }
</script>
<style lang="less" scoped>
</style>
src/views/eam/equipment/modules/LxSearchEquipmentSelect.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,223 @@
<template>
  <a-select
    showSearch
    labelInValue
    :disabled="disabled"
    :getPopupContainer="getParentContainer"
    @search="loadData"
    :placeholder="placeholder"
    v-model="selectedAsyncValue"
    style="width: 100%"
    :filterOption="false"
    @change="handleAsyncChange"
    allowClear
    :notFoundContent="loading ? undefined : null"
    :mode="mode"
  >
    <template #suffixIcon>
      <a-icon type="search" />
    </template>
    <a-spin v-if="loading" slot="notFoundContent" size="small"/>
    <a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
  </a-select>
</template>
<script>
import { ajaxGetDictItems,getDictItemsFromCache } from '@/api/api'
import debounce from 'lodash/debounce';
import { getAction } from '@/api/manage'
export default {
  name: 'LxSearchEquipmentSelect',
  props:{
    disabled: Boolean,
    value: [String, Number],
    dictOptions: Array,
    placeholder:{
      type:String,
      default:"请选择",
      required:false
    },
    pageSize:{
      type: Number,
      default: 20,
      required: false
    },
    mode:{
      type: String,
      default: '',
    },
  },
  data(){
    this.loadData = debounce(this.loadData, 800);//消抖
    this.lastLoad = 0;
    return {
      loading:false,
      selectedValue:[],
      selectedAsyncValue:[],
      options: [],
    }
  },
  created(){
    this.initDictData();
  },
  watch:{
    "value":{
      immediate:true,
      handler(val){
        if(!val){
          if(val==0){
            this.initSelectValue()
          }else{
            this.selectedValue=[]
            this.selectedAsyncValue=[]
          }
        }else{
          this.initSelectValue()
        }
      }
    },
  },
  methods:{
    initSelectValue(){
      if(!this.selectedAsyncValue || !this.selectedAsyncValue.key || this.selectedAsyncValue.key!=this.value){
        console.log("这才请求后台")
        //update-begin-author:taoyan date:20220112 for: æ–¹æ³•initSelectValue æ ¹æ®ä¸‹æ‹‰æ¡†å®žé™…值查询下拉框的显示的文本 å› åŽå°æŽ¥å£åªå¤„理3个参数,所以将过滤条件去掉
        // TODO é𐿂£ æŸ¥è¯¢æ•ˆçŽ‡é—®é¢˜ è¿˜æ˜¯åº”该在后台作筛选
        let itemDictStr = this.dict
        let arr = itemDictStr.split(',')
        if(arr && arr.length==4){
          // åˆ é™¤æœ€åŽä¸€ä¸ªå…ƒç´ 
          arr.pop();
          itemDictStr = arr.join(',')
        }
        //update-end-author:taoyan date:20220112 for: æ–¹æ³•initSelectValue æ ¹æ®ä¸‹æ‹‰æ¡†å®žé™…值查询下拉框的显示的文本 å› åŽå°æŽ¥å£åªå¤„理3个参数,所以将过滤条件去掉
        getAction(`/eam/equipment/asyncLoadEquipment`,{key:this.value}).then(res=>{
          if(res.success){
            //update-begin---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选------------
            //判断是否多选
            if(this.mode === 'multiple'){
              if(res.result && res.result.length>0){
                let itemArray = [];
                let valueArray = this.value.split(",")
                for (let i = 0; i < res.result.length; i++) {
                  itemArray.push({
                    key:valueArray[i],
                    label:res.result[i]
                  })
                }
                this.selectedAsyncValue = itemArray
              }else{
                this.selectedAsyncValue = []
                this.selectedValue = []
              }
            }else{
              let obj = {
                key:this.value,
                label:res.result
              }
              this.selectedAsyncValue = {...obj}
            }
            //update-end---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选--------------
          }
        })
      }
    },
    loadData(value){
      console.log("数据加载",value)
      this.lastLoad +=1
      const currentLoad = this.lastLoad
      this.options = []
      this.loading=true
      // å­—å…¸code格式:table,text,code
      getAction(`/eam/equipment/asyncLoadEquipment`,{keyword:value, pageSize: this.pageSize}).then(res=>{
        this.loading=false
        if(res.success){
          if(currentLoad!=this.lastLoad){
            return
          }
          this.options = res.result
          console.log("我是第一个",res)
        }else{
          this.$message.warning(res.message)
        }
      })
    },
    initDictData(){
      //异步一开始也加载一点数据
      this.loading=true
      getAction(`/eam/equipment/asyncLoadEquipment`,{pageSize: this.pageSize, keyword:''}).then(res=>{
        this.loading=false
        if(res.success){
          this.options = res.result
        }else{
          this.$message.warning(res.message)
        }
      })
    },
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    handleChange (selectedValue) {
      console.log("selectedValue",selectedValue)
      this.selectedValue = selectedValue
      this.callback()
    },
    handleAsyncChange(selectedObj){
      //update-begin-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
      if(selectedObj){
        this.selectedAsyncValue = selectedObj
        //update-begin---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选------------
        if(this.mode ==='multiple'){
          let keyArray = []
          for (let i = 0; i < selectedObj.length; i++) {
            keyArray.push(selectedObj[i].key)
          }
          this.selectedValue = keyArray
        }else{
          this.selectedValue = selectedObj.key
        }
        //update-end---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选------------
      }else{
        this.selectedAsyncValue = null
        this.selectedValue = null
        this.options = null
        this.loadData("")
      }
      this.callback()
      //update-end-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
    },
    callback(){
      //update-begin---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选------------
      if(this.mode === 'multiple'){
        this.$emit('change',  this.selectedValue.join(","));
      }else{
        this.$emit('change', this.selectedValue);
      }
      //update-end---author:wangshuai ---date:20221115  for:[issues/4213]JSearchSelectTag改造支持多选------------
    },
    getParentContainer(node){
      if(typeof this.getPopupContainer === 'function'){
        return this.getPopupContainer(node)
      } else if(!this.popContainer){
        return node.parentNode
      }else{
        return document.querySelector(this.popContainer)
      }
    },
  },
  model: {
    prop: 'value',
    event: 'change'
  }
}
</script>
<style scoped>
</style>