| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- <template>
- <a-card v-show="visible" :title="modalTitle">
- <template #extra>
- <span class="table-page-search-submitButtons" style="float: right">
- <a-button :loading="confirmLoading" type="primary" @click="save()">保存</a-button>
- <a-button style="margin-left: 8px" @click="handleCancel()">返回</a-button>
- </span>
- </template>
- <a-form :form="form">
- <a-form-item v-show="false">
- <a-input v-decorator="['sbId']" type="hidden" />
- </a-form-item>
- <row-list :col="2">
- <row-item>
- <a-form-item label="设备编号" :labelCol="BaseTool.Constant.labelCol" :wrapperCol="BaseTool.Constant.wrapperCol">
- <a-input disabled style="width: 80%" v-decorator="['sbNo', {rules: [{required: true, message: '请选择设备'}]}]" />
- <a-button type="primary" style="width: 20%" @click="handleSbSelect">选择</a-button>
- </a-form-item>
- </row-item>
- <row-item>
- <a-form-item label="标准类型" :labelCol="BaseTool.Constant.labelCol" :wrapperCol="BaseTool.Constant.wrapperCol">
- <a-tree-select style="width: 100%" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
- :treeData="treeData" :treeNodeFilterProp="'title'" :showSearch="true"
- v-decorator="['sbType', {rules: [{required: true, message: '请选择标准类型'}]}]"
- placeholder="请选择" @change="handleSbTypeChange">
- </a-tree-select>
- </a-form-item>
- </row-item>
- </row-list>
- </a-form>
- <div class="table-operator">
- <a-button style="margin:8px;" type="primary" @click="handleAdd">
- <a-icon type="plus" />
- 添加
- </a-button>
- </div>
- <a-table :data-source="data" :key="tableKey" :columns="columns" bordered ref="table" :scroll="{x: 1600 }">
- <span slot="level" slot-scope="text, record">
- <a-select style="width:100%" v-model="record.level" placeholder="请选择">
- <a-select-option v-for="(label,value) in levelMap" :key="value" :label="label" :value="parseInt(value)">{{ label }}
- </a-select-option>
- </a-select>
- </span>
- <span slot="checkUserType" slot-scope="text, record">
- <a-select style="width:100%" v-model="record.checkUserType" placeholder="请选择"
- @change="(val)=>handleCheckUserTypeChange(val, record)">
- <a-select-option v-for="(label,value) in checkUserTypeMap" :key="value" :label="label" :value="parseInt(value)">{{ label }}
- </a-select-option>
- </a-select>
- </span>
- <span slot="checkDeptId" slot-scope="text, record">
- <a-tree-select v-if="record.checkUserType === 4" style="width:100%"
- :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :treeData="deptTree"
- treeNodeFilterProp="title" :showSearch="true" v-model="record.checkDeptId" placeholder="请选择班组">
- </a-tree-select>
- <span v-else style="color:#bbb">-</span>
- </span>
- <span slot="period" slot-scope="text, record">
- <a-input-group compact>
- <a-input-number style="width: 50%" :min="1" v-model="record.period" />
- <a-select style="width: 50%" v-model="record.periodType" placeholder="请选择">
- <a-select-option v-for="(label,value) in periodTypeMap" :key="value" :label="label" :value="parseInt(value)">{{ label }}
- </a-select-option>
- </a-select>
- </a-input-group>
- </span>
- <span slot="standardHours" slot-scope="text, record">
- <a-input v-model="record.standardHours" suffix="小时" />
- </span>
- <span slot="sort" slot-scope="text, record">
- <a-input-number style="width: 100%" :step="1" v-model="record.sort" />
- </span>
- <span slot="lastDate" slot-scope="text, record">
- <a-date-picker style="width: 100%" :format="BaseTool.Date.PICKER_NORM_DATE_PATTERN" v-model="record.lastDate" />
- </span>
- <span slot="nextDate" slot-scope="text, record">
- <a-date-picker style="width: 100%" :format="BaseTool.Date.PICKER_NORM_DATE_PATTERN" v-model="record.nextDate" />
- </span>
- <span slot="requirementList" slot-scope="text, record">
- <a-select style="width: 100%" mode="multiple" v-model="record.requirementList"
- placeholder="请先选择标准类型" :filterOption="filterOption" :disabled="!sbType">
- <a-select-option v-for="item in currentRequirementOptions" :key="item.id" :label="item.stdName" :value="item.id">{{ item.stdName }}
- </a-select-option>
- </a-select>
- </span>
- <span slot="remark" slot-scope="text, record">
- <a-textarea :rows="2" v-model="record.remark" />
- </span>
- <span slot="action" slot-scope="_,record,index">
- <a-space>
- <a @click="handleCopy(record)">复制</a>
- <a-popconfirm title="是否要删除该条数据?" @confirm="handleDelOne(record,index)">
- <a>删除</a>
- </a-popconfirm>
- </a-space>
- </span>
- </a-table>
- <sb-info-select-modal ref="sbInfoSelectModal" @selected="handleSbSelectd" />
- </a-card>
- </template>
- <script>
- import SbInfoSelectModal from '@/views/sb/info/modules/SbInfoSelectModal'
- import { batch } from '@/api/check/checkstandard'
- import { queryCheckDetail } from '@/api/check/check-detail'
- import { fetchSbTypeTree } from '@/api/sb/type'
- import { getDeptTree } from '@/api/upms/dept'
- export default {
- components: {
- SbInfoSelectModal,
- },
- data() {
- return {
- visible: false,
- confirmLoading: false,
- modalTitle: '批量新增',
- form: this.$form.createForm(this),
- data: [{}],
- // 保养项字典:Map<sbType(设备类型ID), List<CheckRequirementVO>>
- checkDetailList: {},
- // 标准类型树
- treeData: [],
- // 部门(班组)树
- deptTree: [],
- // 当前选中的标准类型(设备类型ID),作用于所有行
- sbType: null,
- tableKey: 0,
- columns: [
- {
- title: '序号',
- dataIndex: 'index',
- width: '70px',
- checked: true,
- customRender: (text, record, index) => {
- return index + 1
- },
- },
- {
- title: () => {
- return <span style="color:red">维护等级</span>
- },
- dataIndex: 'level',
- width: '120px',
- checked: true,
- scopedSlots: { customRender: 'level' },
- },
- {
- title: () => {
- return <span style="color:red">执行人方式</span>
- },
- dataIndex: 'checkUserType',
- checked: true,
- width: '130px',
- scopedSlots: { customRender: 'checkUserType' },
- },
- {
- title: '执行班组',
- dataIndex: 'checkDeptId',
- checked: true,
- width: '180px',
- scopedSlots: { customRender: 'checkDeptId' },
- },
- {
- title: () => {
- return <span style="color:red">计划周期</span>
- },
- dataIndex: 'period',
- width: '160px',
- checked: true,
- scopedSlots: { customRender: 'period' },
- },
- {
- title: '标准工时',
- dataIndex: 'standardHours',
- checked: true,
- width: '120px',
- scopedSlots: { customRender: 'standardHours' },
- },
- {
- title: () => {
- return <span style="color:red">排序</span>
- },
- dataIndex: 'sort',
- checked: true,
- width: '80px',
- scopedSlots: { customRender: 'sort' },
- },
- {
- title: '上次实际执行日期',
- dataIndex: 'lastDate',
- checked: true,
- scopedSlots: { customRender: 'lastDate' },
- width: '150px',
- },
- {
- title: '下次预计执行日期',
- dataIndex: 'nextDate',
- checked: true,
- scopedSlots: { customRender: 'nextDate' },
- width: '150px',
- },
- {
- title: () => {
- return <span style="color:red">检查项目</span>
- },
- dataIndex: 'requirementList',
- checked: true,
- scopedSlots: { customRender: 'requirementList' },
- width: '300px',
- },
- {
- title: '检查标准',
- dataIndex: 'remark',
- checked: true,
- scopedSlots: { customRender: 'remark' },
- width: '300px',
- },
- {
- title: '操作',
- key: 'action',
- width: '160px',
- checked: true,
- fixed: 'right',
- align: 'center',
- scopedSlots: { customRender: 'action' },
- },
- ],
- levelMap: {},
- checkUserTypeMap: {},
- periodTypeMap: {},
- }
- },
- computed: {
- // 当前标准类型下可选的保养项列表
- currentRequirementOptions() {
- if (!this.sbType) {
- return []
- }
- return this.checkDetailList[this.sbType] || []
- },
- },
- created() {
- this.paramTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_STANDARD_PARAM_TYPE)
- this.typeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_STANDARD_TYPE)
- this.periodTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_PLAN_PERIOD_TYPE)
- this.actionTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_PLAN_ACTION_TYPE)
- this.enableMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.YES_NO)
- this.checkUserTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_USER_TYPE)
- this.levelMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.CHECK_PLAN_LEVEL)
- fetchSbTypeTree().then((res) => {
- this.treeData = res.data
- })
- getDeptTree({}).then((res) => {
- this.deptTree = res.data || []
- })
- },
- methods: {
- filterOption(input, option) {
- const text = option.componentOptions.children[0].text || ''
- return text.toLowerCase().indexOf(input.toLowerCase()) >= 0
- },
- base(record) {
- this.visible = true
- this.sbType = null
- this.data = [{}]
- this.tableKey = new Date().getTime()
- this.form.resetFields()
- // 加载保养项字典(按设备类型分组)
- queryCheckDetail().then((res) => {
- this.checkDetailList = res.data || {}
- })
- if (this.BaseTool.Object.isBlank(record)) {
- return
- }
- const {
- form: { setFieldsValue },
- } = this
- this.$nextTick(() => {
- setFieldsValue(
- Object.assign({
- sbId: record.id,
- sbNo: record.no,
- })
- )
- })
- },
- handleCancel() {
- this.data = [{}]
- this.visible = false
- this.confirmLoading = false
- this.sbType = null
- this.$emit('ok')
- this.form.resetFields()
- },
- handleAdd() {
- this.data.push({})
- },
- handleCopy(record) {
- const newVal = this.BaseTool.Object.copy(record)
- delete newVal.id
- this.data.push(newVal)
- },
- handleDelOne(record, i) {
- this.data.splice(i, 1)
- },
- // 切换标准类型:检查项目数据源随之变化,清空各行已选检查项目
- handleSbTypeChange(value) {
- this.sbType = value
- this.data.forEach((item) => {
- this.$set(item, 'requirementList', [])
- })
- this.tableKey = new Date().getTime()
- },
- // 切换执行人方式:非班组时清空执行班组
- handleCheckUserTypeChange(value, record) {
- if (value !== 4) {
- this.$set(record, 'checkDeptId', null)
- }
- this.tableKey = new Date().getTime()
- },
- handleSbSelectd(keys, rows) {
- const [key] = keys
- const [row] = rows
- const {
- form: { setFieldsValue },
- } = this
- this.sbId = key
- this.$nextTick(() => {
- setFieldsValue(
- Object.assign({
- sbId: key,
- sbNo: row.no,
- })
- )
- })
- // 批量新增为纯新增语义:切换设备后重置为一条空行,
- // 不加载设备已有标准,避免已有标准被当作新增行重复创建。
- this.data = [{}]
- this.tableKey = new Date().getTime()
- },
- handleSbSelect() {
- this.$refs.sbInfoSelectModal.base()
- },
- save() {
- const {
- form: { validateFieldsAndScroll },
- } = this
- this.confirmLoading = true
- validateFieldsAndScroll((errors, values) => {
- if (errors) {
- this.confirmLoading = false
- return
- }
- if (!this.sbType) {
- this.$message.error('请选择标准类型')
- this.confirmLoading = false
- return
- }
- if (!this.data || this.data.length === 0) {
- this.$message.error('请至少添加一条保养标准')
- this.confirmLoading = false
- return
- }
- let isReturn = false
- this.data.forEach((item, i) => {
- if (!item.level) {
- this.$message.error(`第${i + 1}行维护等级不能为空!`)
- isReturn = true
- }
- if (!item.checkUserType) {
- this.$message.error(`第${i + 1}行执行人方式不能为空!`)
- isReturn = true
- }
- if (item.checkUserType === 4 && !item.checkDeptId) {
- this.$message.error(`第${i + 1}行执行人方式为班组时,必须选择执行班组!`)
- isReturn = true
- }
- if (!item.period) {
- this.$message.error(`第${i + 1}行计划周期不能为空!`)
- isReturn = true
- }
- if (!item.periodType) {
- this.$message.error(`第${i + 1}行周期类型不能为空!`)
- isReturn = true
- }
- if (item.sort === null || item.sort === undefined) {
- this.$message.error(`第${i + 1}行排序不能为空!`)
- isReturn = true
- }
- if (!item.requirementList || item.requirementList.length === 0) {
- this.$message.error(`第${i + 1}行检查项目不能为空!`)
- isReturn = true
- }
- })
- if (isReturn) {
- this.confirmLoading = false
- return
- }
- const allRequirements = this.checkDetailList[this.sbType] || []
- // 构造提交数据:requirementList 由 ID 数组转为对象数组(含 id、sbType),
- // 与单条新增保持一致,后端据此关联保养项并生成首期任务。
- values.list = this.data.map((item) => {
- const selectedRequirements = allRequirements.filter((r) => item.requirementList.includes(r.id))
- return {
- ...item,
- sbType: this.sbType,
- requirementList: selectedRequirements,
- lastDate: item.lastDate
- ? this.BaseTool.Date.formatter(item.lastDate, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
- : null,
- nextDate: item.nextDate
- ? this.BaseTool.Date.formatter(item.nextDate, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
- : null,
- }
- })
- batch(values)
- .then(() => {
- this.$message.success('批量新增成功')
- this.handleCancel(values)
- })
- .catch(() => {
- this.confirmLoading = false
- })
- })
- },
- },
- }
- </script>
- <style>
- </style>
|