This commit is contained in:
2022-11-07 14:54:47 +08:00
commit 8cfe73aaef
1227 changed files with 194899 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
<!--
* @Author:
* @Date:
* @LastEditors: lb
* @LastEditTime: 2022-6.7 16:00:00
* @Description: 物料管理-物料批次-新增
-->
<template>
<el-dialog
:visible.sync="visible"
:title="isedit ? 'btn.edit' : 'btn.add' | i18nFilter"
:append-to-body="false"
class="dialog"
width="45%"
:close-on-click-modal="false"
@close="close"
>
<!-- <small-title slot="title">{{ isedit ? 'btn.edit' : 'btn.add' | i18nFilter }}</small-title> -->
<el-form ref="dataForm" :model="dataForm" :rules="rules" label-position="top">
<el-row :gutter="20">
<!-- 物料名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.materialManager.materialbatch.materialName')" prop="materialId">
<el-select
v-model="dataForm.materialId"
clearable
filterable
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.materialbatch.materialName')])"
@change="materialChange"
>
<el-option v-for="item in materialList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<!-- 物料编码 -->
<el-col :span="12">
<el-form-item :label="$t('module.materialManager.materialbatch.materialCode')" prop="materialCode">
<el-input
v-model="materialCode"
disabled
:placeholder="$t('module.basicData.visual.hints.selectMaterialFirst')"
/>
<!-- :placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbatch.materialCode')])" -->
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 批次号 -->
<el-col :span="12">
<el-form-item :label="$t('module.materialManager.materialbatch.externalCode')" prop="code">
<el-input
v-model="dataForm.code"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbatch.externalCode')])"
/>
</el-form-item>
</el-col>
<!-- 批次名称 -->
<el-col :span="12">
<el-form-item :label="$t('module.materialManager.materialbatch.name')" prop="name">
<el-input
v-model="dataForm.name"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbatch.name')])"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 备注 -->
<el-col>
<el-form-item
:label="$t('module.materialManager.materialbatch.remark')"
prop="remark"
:style="{ width: '100%' }"
>
<el-input
v-model="dataForm.remark"
type="textarea"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbatch.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row style="text-align: right">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.save' | i18nFilter }}</el-button>
</el-row>
</el-dialog>
</template>
<script>
import { find } from 'lodash'
import { add, getInfo, update, getMaterialList } from '@/api/material-manage/batch.js'
import i18n from '@/lang'
// import SmallTitle from '@/components/BaseDrawer/components/SmallTitle.vue'
import { refineData } from '@/utils/helpers'
export default {
name: 'BatchAddDiagog',
// components: {
// SmallTitle
// },
data() {
return {
visible: false,
isedit: false,
materialCode: '',
dataForm: {
description: '',
code: '', // required
id: null,
materialId: null, // required
name: '', // required
remark: ''
},
materialList: [],
rules: {
name: [
{
required: true,
message: i18n.t('module.materialManager.materialbatch.placeholderbatchname'),
trigger: 'blur'
}
// { min: 1, message: '长度在3个字符以上', trigger: 'blur' }
],
code: [
{
required: true,
message: i18n.t('module.materialManager.materialbatch.placeholderbatchnumber'),
trigger: 'blur'
},
{ min: 1, message: i18n.t('module.materialManager.materialbatch.placeholderLength'), trigger: 'blur' }
],
materialId: [
{
required: true,
message: i18n.t('module.materialManager.materialbatch.placeholderMinNumOfMaterial'),
trigger: 'change'
}
]
}
}
},
methods: {
initDataForm() {
this.dataForm = {
id: null,
name: '',
code: '',
materialId: null,
description: '',
remark: ''
}
this.materialCode = ''
},
init(data) {
this.initDataForm()
getMaterialList().then(res => {
this.materialList = res.data
})
if (data) {
this.dataForm.id = data.id
getInfo({ id: this.dataForm.id }).then(res => {
this.dataForm = res.data
this.materialCode = this.dataForm.materialCode
})
}
this.visible = true
},
confirm() {
this.$refs.dataForm.validate(valid => {
if (valid) {
const ajaxAction = this.dataForm.id ? update : add
ajaxAction(refineData(this.dataForm, ['id', 'name', 'code', 'materialId', 'description', 'remark'])).then(
res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.close()
}
})
}
)
}
})
},
// handleSubmit(formName) {
// this.$refs[formName].validate(valid => {
// if (!valid) {
// return false
// }
// if (this.id) {
// update(this.dataForm).then(res => {
// this.close()
// })
// } else {
// add(this.dataForm).then(res => {
// this.close()
// })
// }
// })
// },
close() {
// this.$router.push({ path: this.$route.query.redirect })
this.$emit('refreshDataList')
this.visible = false
},
materialChange(item) {
const material = find(this.materialList, m => m.id === item)
this.materialCode = material && material.code
}
}
}
</script>

View File

@@ -0,0 +1,219 @@
<!--
* @Author:
* @Date:
* @LastEditors: gtz
* @LastEditTime: 2022-07-25 10:34:24
* @Description: 物料管理-物料批次
-->
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:top-btn-config="topBtnConfig"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="tableDataList"
:is-loading="listLoading"
@clickTopBtn="clickTopBtn"
>
<method-btn
slot="handleBtn"
:width="calculateWidth"
:method-list="tableBtn"
@clickBtn="handleClick"
/>
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<batch-add v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getList" />
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import { list, del } from '@/api/material-manage/batch.js'
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import BatchAdd from './components/add-panel.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,、
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [
{
type: 'edit',
btnName: 'btn.edit'
},
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'createTime',
label: i18n.t('module.materialManager.materialbatch.createTime'),
filter: timeFormatter
},
{
prop: 'code',
label: i18n.t('module.materialManager.materialbatch.externalCode')
},
{
prop: 'name',
label: i18n.t('module.materialManager.materialbatch.name')
},
{
prop: 'materialCode',
label: i18n.t('module.materialManager.materialbatch.materialCode')
},
{
prop: 'materialName',
label: i18n.t('module.materialManager.materialbatch.materialName')
}
]
export default {
name: 'BatchIndex',
components: { HeadForm, Pagination, BaseTable, MethodBtn, BatchAdd },
data() {
return {
topBtnConfig,
tableBtn,
trueWidth: 240,
tableProps,
tableDataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.cache.Keywords'),
placeholder: this.$t('module.materialManager.materialbatch.placeholderkeywords'),
param: 'keywords',
width: 300
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {},
addOrUpdateVisible: false
}
},
computed: {
calculateWidth() {
return this.tableBtn.length * 40 // 操作列的每个按钮宽度40
}
},
created() {
this.getList()
},
methods: {
getList() {
list({ ...this.listQuery, key: this.headFormValue.keywords || '' }).then(res => {
if (res.data.records) {
this.tableDataList = res.data.records
} else {
this.tableDataList.splice(0)
}
this.total = res.data.total
})
},
addNew(data) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(data)
})
},
// handleAdd() {
// this.$router.push({
// path: 'batch/add',
// query: {
// redirect: '/material-manage/batch',
// title: this.$t('module.materialManager.materialbatch.add')
// }
// })
// },
// handleEdit(id) {
// this.$router.push({
// path: 'batch/add',
// query: {
// redirect: '/material-manage/batch',
// title: this.$t('module.materialManager.materialbatch.edit'),
// id
// }
// })
// },
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
del({ id: raw.data.id }).then(res => {
this.listQuery.current = 1
this.getList()
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg')
})
})
})
} else {
// edit
this.addNew(raw.data)
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
// this.handleAdd() // 新增
this.addNew()
}
}
}
}
</script>

View File

@@ -0,0 +1,217 @@
<template>
<div :class="$style.container">
<SearchBar :placeholder="$t('module.materialManager.materialbom.materialCodeOrName')" @on-search="handleSearch">
<el-button v-if="!$route.query.disable" type="success" icon="el-icon-plus" @click="handleAdd()">
{{ 'btn.add' | i18nFilter }}
</el-button>
</SearchBar>
<el-table
:data="tableDataList"
:class="$style.table"
:stripe="true"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
size="mini"
>
<el-table-column prop="index" :label="$t('module.materialManager.materialbom.index')" width="80" />
<el-table-column prop="createTime" :label="$t('module.materialManager.materialbom.createTime')" width="180">
<template slot-scope="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column prop="name" :label="$t('module.materialManager.materialbom.detailname')" width="180" />
<el-table-column prop="code" :label="$t('module.materialManager.materialbom.code')" width="180" />
<el-table-column prop="unit" :label="$t('module.materialManager.materialbom.unit2')" width="180">
<template slot-scope="scope">
<el-input
v-model="scope.row.unit"
:disabled="$route.query.disable"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.unit')])"
/>
</template>
</el-table-column>
<el-table-column prop="quantity" :label="$t('module.materialManager.materialbom.quantity')" width="180">
<template slot-scope="scope">
<el-input
v-model="scope.row.quantity"
type="number"
min="1"
:disabled="$route.query.disable"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.quantity')])"
/>
</template>
</el-table-column>
<el-table-column prop="remark" :label="$t('module.materialManager.materialbom.remark')">
<template slot-scope="scope">
<el-input
v-model="scope.row.remark"
:class="$style.remark"
:disabled="$route.query.disable"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.remark')])"
/>
</template>
</el-table-column>
<el-table-column
v-if="!$route.query.disable"
:label="$t('module.materialManager.materialbom.operation')"
width="280"
fixed="right"
>
<template slot-scope="scope">
<el-button v-if="!$route.query.disable" type="primary" size="mini" @click="handleSave(scope.row.id)">
{{ 'btn.save' | i18nFilter }}
</el-button>
<el-button v-if="!$route.query.disable" type="danger" size="mini" @click="handleDelete(scope.row.id)">
{{ 'btn.delete' | i18nFilter }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:hide-on-single-page="false"
background
:class="$style.table"
:current-page="page.current"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<AddDialog
v-if="addDialogVisible"
:class="$style.dialog"
:is-edit="isEdit"
:bom-id="bomId"
:visible="addDialogVisible"
@on-success="handleAddSuccess()"
@on-close="addDialogVisible = false"
/>
</div>
</template>
<script>
import moment from 'moment'
import { list, del, update } from '@/api/material-manage/bom-list.js'
import SearchBar from '@/views/art/components/search-bar'
import AddDialog from '@/views/material-manage/bom/components/add-dialog'
import i18n from '@/lang'
export default {
components: { SearchBar, AddDialog },
props: {
bomId: {
type: String,
default: null
}
},
data() {
return {
moment,
isEdit: false,
tableDataList: [],
page: {
total: 40,
current: 1,
size: 10
},
addDialogVisible: false,
param: {}
}
},
created() {
this.handleSearch()
},
methods: {
handleSearch(param) {
this.param = param
list({ ...param, ...this.page, bomId: this.bomId }).then(res => {
this.page.total = res.data.total
if (!res.data.records) {
this.tableDataList = []
return
}
this.tableDataList = res.data.records.map((m, index) => ({
...m,
index: this.page.size * (this.page.current - 1) + index + 1
}))
})
},
handleAdd() {
this.addDialogVisible = true
this.isEdit = false
},
handleSave(id) {
const target = this.tableDataList.find((o, i) => {
return o.id === id
})
update({
id,
bomId: target.bomId,
materialId: target.materialId,
remark: target.remark,
quantity: target.quantity,
unit: target.unit
}).then(response => {
if (response.data) {
// 更新成功,重新获取列表
this.$message({
type: 'success',
message: this.$t('module.materialManager.materialbom.successMessage'),
onClose: () => {
this.handleSearch()
}
})
}
})
},
handleAddSuccess() {
this.addDialogVisible = false
this.handleSearch(this.param)
},
handleEdit() {
this.addDialogVisible = true
this.isEdit = true
},
handleSizeChange(val) {
console.log(`每页 ${val}`)
this.page.size = val
this.handleSearch(this.param)
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`)
this.page.current = val
this.handleSearch(this.param)
},
handleDelete(id) {
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(() => {
del({ id }).then(res => {
this.handleSearch(this.param)
this.param.current = 1
this.$message({
type: 'info',
message: i18n.t('deleteMsgBox.doneMsg')
})
})
})
}
}
}
</script>
<style lang="scss" module>
.container {
.table {
margin: 16px;
}
}
.remark {
outline: none;
border: none;
background-color: unset;
padding: 8px 20px;
}
</style>

View File

@@ -0,0 +1,219 @@
<!--
@Author:
@Date:
@LastEditors: lb
@LastEditTime: 2022-6-6 13:00:00
@Description: 物料管理 - BOM - BOM明细编辑新增
-->
<template>
<el-dialog
:visible.sync="visible"
:title="
isedit
? $t('module.materialManager.materialbom.editDialogTitle')
: $t('module.materialManager.materialbom.addDialogTitle')
"
width="40%"
:append-to-body="true"
class="dialog"
:close-on-click-modal="false"
@close="close"
>
<el-form ref="dataForm" :model="dataForm" :rules="rules" label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<!-- 物料名称 -->
<el-form-item :label="$t('module.materialManager.materialbom.mname')" prop="materialId">
<el-select
v-model="dataForm.materialId"
clearable
filterable
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.materialbom.mname')])"
@change="handelMaterialChange"
>
<el-option v-for="item in materialList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 数量 -->
<el-form-item :label="$t('module.materialManager.materialbom.quantity')" prop="quantity">
<el-input
v-model="dataForm.quantity"
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.materialbom.quantity')])"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<!-- 物料单位 -->
<el-form-item :label="$t('module.materialManager.materialbom.unit')" prop="unit">
<!-- <span class="el-form-item__label">
<strong>{{ currentUnitLabel }}</strong>
</span> -->
<el-input v-model="currentUnitLabel" placeholder="请先选择物料" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 备注 -->
<el-form-item :label="$t('module.materialManager.materialbom.remark')" prop="remark">
<el-input
v-model="dataForm.remark"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row :gutter="20">
<el-col :span="12"></el-col>
<el-col :span="12"></el-col>
</el-row> -->
<el-row style="text-align: right">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.save' | i18nFilter }}</el-button>
</el-row>
</el-form>
</el-dialog>
</template>
<script>
import { add, update } from '@/api/material-manage/bom-list.js'
import { list as getMaterialList } from '@/api/material-manage/material'
import i18n from '@/lang'
import { refineData } from '@/utils/helpers'
import newBasicData from '@/filters/newBasicData'
// import SmallTitle from '@/components/BaseDrawer/components/SmallTitle.vue'
export default {
name: 'BomDetailsAddDialog',
// components: { SmallTitle },
data() {
return {
isedit: false,
visible: false,
dataForm: {
id: null,
bomId: this.bomId,
materialId: null,
unit: '',
quantity: 1,
remark: ''
},
currentUnitLabel: '',
materialList: [],
unitList: [],
rules: {
materialId: [
{
required: true,
message: i18n.t('module.materialManager.materialbom.placeholderMinNumOfMaterial'),
trigger: 'change'
}
],
quantity: [
{ required: true, message: i18n.t('module.materialManager.materialbom.noEmptyNumber'), trigger: 'blur' },
{
type: 'integer',
transform: val => Number(val),
message: i18n.t('module.basicData.visual.typeValidation.number')
}
],
unit: [{ required: true, message: i18n.t('module.materialManager.materialbom.noEmptyUnit'), trigger: 'blur' }]
}
}
},
methods: {
initDataForm() {
this.dataForm = {
id: null,
bomId: null,
materialId: null,
unit: '',
quantity: 1,
remark: ''
}
this.currentUnitLabel = ''
},
init(data) {
this.isedit = false
this.initDataForm()
// this.fetchList('unit')
this.fetchList('material').then(res => {
if (res.data.records) {
this.materialList = res.data.records
} else {
this.materialList.splice(0)
}
})
if (data) {
if (data.id) this.isedit = true
this.dataForm = refineData(data, ['id', 'bomId', 'materialId', 'unit', 'quantity', 'remark'])
this.currentUnitLabel = newBasicData('1')(this.dataForm.unit)
}
this.visible = true
},
fetchList(type) {
switch (type) {
case 'material':
return getMaterialList()
case 'unit': {
this.unitList = this.$store.getters.dictList.find(item => item.dictTypeId === '1')?.dataList
}
}
},
handelMaterialChange(mid) {
const currentMaterial = this.materialList.find(item => item.id === mid)
if (currentMaterial && currentMaterial.unit) {
this.currentUnitLabel = newBasicData('1')(currentMaterial.unit)
this.dataForm.unit = currentMaterial.unit
} else {
this.currentUnitLabel = ''
this.dataForm.unit = ''
}
},
confirm() {
this.$refs.dataForm.validate(valid => {
if (valid) {
if (!this.dataForm.materialId) {
this.$message.error(this.$t('module.materialManager.materialbom.placeholderMinNumOfMaterial'))
return false
}
const ajaxAction = this.isedit ? update : add
// 修改整数类型
this.dataForm.quantity = parseInt(this.dataForm.quantity)
ajaxAction(this.dataForm).then(res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.close()
}
})
})
}
})
},
close() {
this.visible = false
this.$emit('refreshDataList')
}
}
}
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
</style>

View File

@@ -0,0 +1,378 @@
<!--
@Author:
@Date:
@LastEditors: lb
@LastEditTime: 2022-6-6 13:00:00
@Description: 物料管理 - BOM - BOM编辑新增详情页面
-->
<template>
<el-drawer :visible.sync="visible" :show-close="false" :wrapper-closable="false" class="drawer" size="60%">
<small-title slot="title" :no-padding="true">
BOM {{ isdetail ? 'btn.detail' : isedit ? 'btn.edit' : 'btn.add' | i18nFilter }}
</small-title>
<div class="content">
<div class="visual-part">
<!-- form -->
<el-form ref="dataForm" :model="dataForm" :rules="dataFormRules" label-position="top" label-width="100px">
<el-row :gutter="20">
<!-- 物料BOM编码 -->
<el-col :span="8">
<el-form-item :label="$t('module.materialManager.materialbom.bomcode_long')" prop="code">
<el-input
v-model="dataForm.code"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.bomcode_long')])"
/>
</el-form-item>
</el-col>
<!-- 物料BOM名称 -->
<el-col :span="8">
<el-form-item :label="$t('module.materialManager.materialbom.name_long')" prop="name">
<el-input
v-model="dataForm.name"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.name_long')])"
/>
</el-form-item>
</el-col>
<!-- 备注 -->
<el-col :span="8">
<el-form-item :label="$t('module.materialManager.materialbom.remark')" prop="remark">
<el-input
v-model="dataForm.remark"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template v-if="isedit || isdetail">
<small-title style="padding-left: 8px;">
{{ $t('module.materialManager.materialbom.subtitle') }}
</small-title>
<div class="attr-list">
<base-table
:top-btn-config="!isdetail ? topBtnConfig : []"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="dataList"
:is-loading="listLoading"
@clickTopBtn="clickTopBtn"
>
<method-btn
v-if="!isdetail"
slot="handleBtn"
:width="trueWidth"
:method-list="tableBtn"
@clickBtn="handleClick"
/>
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
</div>
</template>
</div>
<bom-detail-add v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getList" />
<div style="position: absolute; bottom: 24px; right: 24px;">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</div>
</div>
</el-drawer>
</template>
<script>
import SmallTitle from '@/components/BaseDrawer/components/SmallTitle.vue'
import BaseTable from '@/components/BaseTable'
import { add, getInfo, update, getCode } from '@/api/material-manage/bom.js'
import { list as getBomDetailList, del } from '@/api/material-manage/bom-list.js'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
// import BomList from '@/views/material-manage/bom/bom-list'
import i18n from '@/lang'
import Pagination from '@/components/Pagination'
import { refineData } from '@/utils/helpers'
import { timeFormatter } from '@/filters'
import newBasicData from '@/filters/newBasicData'
import BomDetailAdd from './add-dialog.vue'
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [
{
type: 'edit',
btnName: 'btn.edit'
},
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'createTime',
label: i18n.t('module.materialManager.materialbom.createTime'),
width: 180,
filter: timeFormatter
},
{
prop: 'name',
label: i18n.t('module.materialManager.materialbom.detailname')
},
{
prop: 'code',
label: i18n.t('module.materialManager.materialbom.code'),
width: 200
},
{
prop: 'unit',
label: i18n.t('module.materialManager.materialbom.unit2'),
filter: newBasicData('1')
},
{
prop: 'quantity',
label: i18n.t('module.materialManager.materialbom.quantity')
},
{
prop: 'remark',
label: i18n.t('module.materialManager.materialbom.remark')
}
]
export default {
name: 'BomAddDrawer',
components: {
SmallTitle,
BaseTable,
Pagination,
MethodBtn,
BomDetailAdd
},
props: {},
data() {
return {
listLoading: false,
addOrUpdateVisible: false,
visible: false,
isdetail: false,
isedit: false,
tableProps,
tableBtn,
topBtnConfig,
trueWidth: 80,
dataForm: {
id: null, // 主键,更新时需要填写,示例值(1)
name: '',
code: '', // 编码
remark: '' // 备注
},
dataList: [],
dataFormRules: {
name: [
{
required: true,
message: i18n.t('module.materialManager.materialbom.placeholderbomName'),
trigger: 'change'
}
],
code: [
{
required: true,
message: i18n.t('module.materialManager.materialbom.placeholderbomcode'),
trigger: 'change'
}
]
},
listQuery: {
current: 1,
size: 10
},
total: 0
}
},
methods: {
initDataForm() {
this.dataForm = {
id: null,
name: '',
code: '',
remark: ''
}
},
init(data, isdetail) {
this.initDataForm()
this.dataList = []
this.listQuery = {
current: 1,
size: 10
}
this.isdetail = isdetail || false
this.isedit = false
this.$nextTick(() => {
this.$refs.dataForm.clearValidate()
if (data) {
this.isedit = true
this.dataForm.id = data.id
getInfo({ id: this.dataForm.id })
.then(res => {
this.dataForm = refineData(res.data, ['id', 'name', 'code', 'remark'])
})
.then(() => {
this.getList()
})
} else {
getCode().then(res => {
this.dataForm.code = res.data
})
}
})
this.visible = true
},
fetchList(type) {
switch (type) {
case 'bom-list':
return getBomDetailList({ ...this.listQuery, bomId: this.dataForm.id })
}
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`${this.$t('module.basicData.visual.TipsBefore')}[${raw.data.name}]?`,
this.$t('module.basicData.visual.Tips'),
{
confirmButtonText: this.$t('module.basicData.visual.confirmButtonText'),
cancelButtonText: this.$t('module.basicData.visual.cancelButtonText'),
type: 'warning'
}
)
.then(() => {
del({ id: raw.data.id }).then(response => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.listQuery.current = 1
this.getList()
}
})
})
})
.catch(() => {})
} else if (raw.type === 'edit') {
this.addNew(raw.data, false)
}
},
getList() {
this.fetchList('bom-list').then(res => {
if (res.data.records) {
this.dataList = res.data.records
} else {
this.dataList.splice(0)
}
this.total = res.data.total
})
},
close() {
this.visible = false
},
confirm() {
this.$refs.dataForm.validate(valid => {
if (valid) {
const ajaxAction = this.isedit ? update : add
ajaxAction(this.dataForm).then(res => {
this.$message({
type: 'success',
message: this.$t('module.materialManager.materialbom.successMessage'),
duration: 1500,
onClose: () => {
this.$emit('refreshDataList')
this.close()
}
})
})
}
})
},
addNew(data) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init({ ...data, bomId: this.dataForm.id })
})
},
clickTopBtn(val) {
if (val === 'add') {
this.addNew()
}
}
}
}
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
margin-bottom: 30px;
}
.drawer >>> .content {
padding: 0 24px 30px;
display: flex;
flex-direction: column;
height: 100%;
}
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
.drawer >>> .el-form,
.drawer >>> .attr-list {
padding: 0 16px;
}
</style>

View File

@@ -0,0 +1,191 @@
<!--
@Author:
@Date:
@LastEditors: lb
@LastEditTime: 2022-6-6 13:00:00
@Description: 物料管理 - BOM - BOM编辑新增详情页面
-->
<template>
<el-dialog
:visible.sync="visible"
:title="isdetail ? 'btn.detail' : isedit ? 'btn.edit' : 'btn.add' | i18nFilter"
width="50%"
:close-on-click-modal="false"
>
<!-- <small-title slot="title" :no-padding="true">
BOM {{ isdetail ? 'btn.detail' : isedit ? 'btn.edit' : 'btn.add' | i18nFilter }}
</small-title> -->
<!-- form -->
<el-form ref="dataForm" :model="dataForm" :rules="dataFormRules" label-position="top">
<el-row :gutter="20">
<!-- 物料BOM编码 -->
<el-col :span="24">
<el-form-item :label="$t('module.materialManager.materialbom.bomcode_long')" prop="code">
<el-input
v-model="dataForm.code"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.bomcode_long')])"
/>
</el-form-item>
</el-col>
<!-- 物料BOM名称 -->
<el-col :span="24">
<el-form-item :label="$t('module.materialManager.materialbom.name_long')" prop="name">
<el-input
v-model="dataForm.name"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.name_long')])"
/>
</el-form-item>
</el-col>
<!-- 备注 -->
<el-col :span="24">
<el-form-item :label="$t('module.materialManager.materialbom.remark')" prop="remark">
<el-input
v-model="dataForm.remark"
:disabled="isdetail"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.materialbom.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row style="text-align: right;">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</el-row>
</el-dialog>
</template>
<script>
import { add, getInfo, update, getCode } from '@/api/material-manage/bom.js'
// import BomList from '@/views/material-manage/bom/bom-list'
import i18n from '@/lang'
import { refineData } from '@/utils/helpers'
export default {
name: 'BomAddDialog',
components: {},
props: {},
data() {
return {
listLoading: false,
addOrUpdateVisible: false,
visible: false,
isdetail: false,
isedit: false,
dataForm: {
id: null, // 主键,更新时需要填写,示例值(1)
name: '',
code: '', // 编码
remark: '' // 备注
},
dataList: [],
dataFormRules: {
name: [
{
required: true,
message: i18n.t('module.materialManager.materialbom.placeholderbomName'),
trigger: 'change'
}
],
code: [
{
required: true,
message: i18n.t('module.materialManager.materialbom.placeholderbomcode'),
trigger: 'change'
}
]
},
listQuery: {
current: 1,
size: 10
},
total: 0
}
},
methods: {
initDataForm() {
this.dataForm = {
id: null,
name: '',
code: '',
remark: ''
}
},
init(data, isdetail) {
this.initDataForm()
this.dataList = []
this.listQuery = {
current: 1,
size: 10
}
this.isdetail = isdetail || false
this.isedit = false
this.$nextTick(() => {
this.$refs.dataForm.clearValidate()
if (data) {
this.isedit = true
this.dataForm.id = data.id
getInfo({ id: this.dataForm.id })
.then(res => {
this.dataForm = refineData(res.data, ['id', 'name', 'code', 'remark'])
})
.then(() => {
this.getList()
})
} else {
getCode().then(res => {
this.dataForm.code = res.data
})
}
})
this.visible = true
},
close() {
this.visible = false
},
confirm() {
this.$refs.dataForm.validate(valid => {
if (valid) {
const ajaxAction = this.isedit ? update : add
ajaxAction(this.dataForm).then(res => {
this.$message({
type: 'success',
message: this.$t('module.materialManager.materialbom.successMessage'),
duration: 1500,
onClose: () => {
this.$emit('refreshDataList')
this.close()
}
})
})
}
})
},
addNew(data) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init({ ...data, bomId: this.dataForm.id })
})
},
clickTopBtn(val) {
if (val === 'add') {
this.addNew()
}
}
}
}
</script>

View File

@@ -0,0 +1,227 @@
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:top-btn-config="topBtnConfig"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="tableDataList"
:is-loading="listLoading"
@clickTopBtn="clickTopBtn"
@emitFun="handleTableEvents"
>
<method-btn slot="handleBtn" :width="calculateWidth" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<bom-add-drawer v-if="updateVisible" ref="updateRef" @refreshDataList="getList" />
<bom-add-dialog v-if="addVisible" ref="addRef" @refreshDataList="getList" />
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import { list, del } from '@/api/material-manage/bom.js'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import BomAddDrawer from './components/add-panel.vue'
import BomAddDialog from './components/bom-add-dialog.vue'
import commonBtn from '@/components/BaseTable/subcomponents/CommonBtn.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [
{
type: 'edit',
btnName: 'btn.edit'
},
// {
// type: 'detail',
// btnName: 'btn.detail'
// },
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'createTime',
label: i18n.t('module.materialManager.materialbom.createTime'),
filter: timeFormatter
},
{
prop: 'code',
label: i18n.t('module.materialManager.materialbom.bomcode_long')
},
{
prop: 'name',
label: i18n.t('module.materialManager.materialbom.name_long')
},
{
prop: 'remark',
label: i18n.t('module.materialManager.materialbom.remark')
},
{
prop: '详情',
label: i18n.t('module.materialManager.materialbom.viewDetail'),
subcomponent: commonBtn,
buttonContent: i18n.t('module.materialManager.materialbom.viewDetail'),
emitFullData: true
}
]
export default {
components: { HeadForm, Pagination, BaseTable, MethodBtn, BomAddDrawer, BomAddDialog },
data() {
return {
topBtnConfig,
updateVisible: false,
addVisible: false,
tableBtn,
trueWidth: 240,
tableProps,
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
tableDataList: [],
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.cache.Keywords'),
placeholder: this.$t('module.materialManager.materialbom.bomCodeOrName'),
param: 'keyName',
width: 300
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
computed: {
calculateWidth() {
return this.tableBtn.length * 40 // 操作列的每个按钮宽度40
}
},
created() {
this.getList()
},
methods: {
getList() {
const key = this.headFormValue.keyName ? this.headFormValue.keyName : ''
list({ ...this.listQuery, key }).then(res => {
this.total = res.data.total
if (res.data.records) {
this.tableDataList = res.data.records
} else {
this.tableDataList.splice(0)
}
})
},
addNew(data, isdetail) {
if (data) {
this.updateVisible = true
this.$nextTick(() => {
this.$refs.updateRef.init(data, isdetail)
})
} else {
this.addVisible = true
this.$nextTick(() => {
this.$refs.addRef.init()
})
}
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`${this.$t('module.basicData.visual.TipsBefore')}[${raw.data.name}]?`,
this.$t('module.basicData.visual.Tips'),
{
confirmButtonText: this.$t('module.basicData.visual.confirmButtonText'),
cancelButtonText: this.$t('module.basicData.visual.cancelButtonText'),
type: 'warning'
}
)
.then(() => {
del({ id: raw.data.id }).then(response => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.listQuery.current = 1
this.getList()
}
})
})
})
.catch(() => {})
} else if (raw.type === 'edit') {
this.addNew(raw.data, false)
} else {
// detail
this.addNew(raw.data, true)
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
this.addNew(null, false)
}
},
handleTableEvents({ action, data }) {
switch (action) {
case 'view-detail-action':
this.addNew(data, true)
}
}
}
}
</script>

View File

@@ -0,0 +1,145 @@
<!--
* @Author: gtz
* @Date: 2022-01-19 15:58:17
* @LastEditors: zhp
* @LastEditTime: 2022-01-24 09:18:01
* @Description: file content
* @FilePath: \mt-bus-fe\src\views\OperationalOverview\components\baseContainer\index.vue
-->
<template>
<div class="base-container" :style="{height: height * beilv + 'px', fontSize: 12 * beilv + 'px'}">
<div class="line" />
<div class="line line-vertical" />
<div class="line line-right" />
<div class="line line-right-vertical" />
<div class="line line-bottom" />
<div class="line line-bottom-vertical" />
<div class="line line-bottom-right" />
<div class="line line-bottom-right-vertical" />
<div class="bar-item">
<div v-if="title" class="bar-title">
<span>
<svg-icon :icon-class="titleIcon" style="font-size: 1.5em; position: relative; top: .08em" />
{{ title }}
</span>
</div>
<div class="bar-content">
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'BaseContainer',
props: {
title: {
type: String,
default: ''
},
titleIcon: {
type: String,
default: ''
},
height: {
type: Number,
default: 200
},
baseSize: {
type: Number,
default: 12
},
beilv: {
type: Number,
default: 1
}
},
data() {
return {
curIndex: 0
}
},
mounted() {
},
methods: {
changeTab(num) {
this.curIndex = num
this.$emit('tabSelect', num)
}
}
}
</script>
<style lang="scss" scoped>
.base-container {
color: #fff;
width: 100%;
background-color: rgba($color: #061027, $alpha: 0.15);
position: relative;
border: 2px solid;
border-image: linear-gradient(90deg, rgba(82, 255, 241, 0.6), rgba(95, 190, 249, 0), rgba(82, 255, 241, 0.6)) 2 2;
box-shadow: inset 0px 0px 20px 0px rgba(255,255,255,0.15);
.line {
position: absolute;
border-top: 4px solid #52FFF1;
width: 2em;
top: -.25em;
left: -.25em;
&-vertical {
top: calc(-5em / 12);
left: calc(-1em / 12);
transform: rotate(90deg);
transform-origin: left;
}
&-right {
top: -.25em;
right: -.25em;
left: inherit;
}
&-right-vertical {
top: calc(-5em / 12);
right: calc(-1em / 12);
left: inherit;
transform: rotate(-90deg);
transform-origin: right;
}
&-bottom {
top: inherit;
left: -.25em;
bottom: -.25em;
}
&-bottom-vertical {
top: inherit;
left: calc(-1em / 12);
bottom: calc(-5em / 12);
transform: rotate(-90deg);
transform-origin: left;
}
&-bottom-right {
top: inherit;
left: inherit;
right: -.25em;
bottom: -.25em;
}
&-bottom-right-vertical {
top: inherit;
left: inherit;
right: calc(-1em / 12);
bottom: calc(-5em / 12);
transform: rotate(90deg);
transform-origin: right;
}
}
.bar-title {
width: 100%;
color: #52FFF1;
font-size: 1.5em;
padding: .67em;
}
// .bar-content{
// padding: 1em;
// }
}
</style>

View File

@@ -0,0 +1,176 @@
<!--
* @Date: 2020-12-14 09:07:03
* @LastEditors: gtz
* @LastEditTime: 2022-06-14 11:12:39
* @FilePath: \mt-bus-fe\src\views\OperationalOverview\components\baseTable.vue
* @Description:
-->
<template>
<div class="visual-base-table-container">
<el-table
v-loading="isLoading"
:header-cell-style="{background:'rgba(79,114,136,0.29)',color:'#fff',height: 28 * beilv + 'px',lineHeight: 28 * beilv + 'px',padding: 0,fontSize: 12 * beilv + 'px'}"
:row-style="setRowStyle"
:data="renderData"
border
style="width: 100%; background: transparent"
>
<el-table-column v-if="page && limit && showIndex" prop="_pageIndex" :label="'tableHeader.index' | i18nFilter" :width="70 * beilv" align="center" />
<el-table-column
v-for="item in renderTableHeadList"
:key="item.prop"
:show-overflow-tooltip="showOverflow"
v-bind="item"
>
<template slot-scope="scope">
<component :is="item.subcomponent" v-if="item.subcomponent" :inject-data="{...scope.row, ...item}" @emitData="emitData" />
<span v-else>{{ scope.row[item.prop] | commonFilter(item.filter) }}</span>
</template>
</el-table-column>
<slot name="content" />
</el-table>
</div>
</template>
<script>
import { isObject, isString } from 'lodash'
export default {
name: 'BaseTable',
filters: {
commonFilter: (source, filterType = a => a) => {
return filterType(source)
}
},
props: {
tableData: {
type: Array,
required: true,
validator: val => val.filter(item => !isObject(item)).length === 0
},
tableConfig: {
type: Array,
required: true,
validator: val => val.filter(item => !isString(item.prop) || !isString(item.label)).length === 0
},
isLoading: {
type: Boolean,
required: false
},
page: {
type: Number,
required: false,
default: 1
},
limit: {
type: Number,
required: false,
default: 5
},
beilv: {
type: Number,
default: 1
},
showOverflow: {
type: Boolean,
default: true
},
showIndex: {
type: Boolean,
default: true
}
},
data() {
return {
tableConfigBak: [],
selectedBox: new Array(100).fill(true)
}
},
computed: {
renderData() {
if (this.tableData.length && !this.tableData[0]._pageIndex) {
this.tableData.forEach((item, index) => {
item._pageIndex = (this.page - 1) * this.limit + index + 1
})
}
return this.tableData.slice((this.page - 1) * this.limit, this.page * this.limit)
},
renderTableHeadList() {
return this.tableConfig.filter((item, index) => {
return this.selectedBox[index]
})
}
},
beforeMount() {
this.selectedBox = new Array(100).fill(true)
},
methods: {
emitData(val) {
this.$emit('emitFun', val)
},
setRowStyle(v) {
if (v.rowIndex % 2 === 0) {
return {
background: 'rgba(76,97,123,0.2)',
color: 'rgba(255,255,255,0.5)',
height: 26 * this.beilv + 'px',
lineHeight: 26 * this.beilv + 'px',
padding: 0,
fontSize: 12 * this.beilv + 'px'
}
} else {
return {
background: 'rgba(79,114,136,0.29)',
color: 'rgba(255,255,255,0.5)',
height: 26 * this.beilv + 'px',
lineHeight: 26 * this.beilv + 'px',
padding: 0,
fontSize: 12 * this.beilv + 'px'
}
}
},
setCellStyle(v) {
return {
lineHeight: 23 * this.beilv + 'px'
}
}
}
}
</script>
<style lang="scss">
@import "~@/styles/index.scss";
.visual-base-table-container {
.el-table {
border: 0;
}
.el-table::before,.el-table--border::after {
background-color: transparent;
}
.el-table th,td{
border-color: #0D1728 !important;
padding: 0;
}
.el-table tr {
background: transparent;
}
.el-table__row:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
.el-table__row--striped:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
}
.setting {
text-align: right;
padding: 15px;
.setting-box {
width: 100px;
}
i {
color: #aaa;
@extend .pointer;
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<div :style="{ padding: 8 * beilv + 'px ' + 24 * beilv + 'px '+ 24 * beilv + 'px' }" class="box">
<div v-for="(item, i) in bomMsg" :key="i" class="bom-box" :style="{ marginBottom: 11 * beilv + 'px'}">
<img src="./../../../../assets/img/cockpit/bom.png" alt="" :width="355 * beilv + 'px'" :height="280 * beilv + 'px'">
<p class="bom-name" :style="{ bottom: 10 * beilv + 'px', fontSize: 16 * beilv + 'px'}">
<span class="leftTriangle" />
<span>{{ item.name }}</span>
<span class="rightTriangle" />
</p>
</div>
</div>
</template>
<script>
export default {
name: 'BomList',
props: {
bomMsg: {
type: Array,
default: () => []
},
beilv: {
type: Number,
default: 1
}
}
}
</script>
<style lang="scss" scoped>
.box {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
.bom-box {
position: relative;
.bom-name {
position: absolute;
width: 100%;
text-align: center;
.leftTriangle,
.rightTriangle {
display: inline-block;
width: 0px;
height: 0px;
border: 5px solid transparent;
}
.leftTriangle {
border-right-color: #fff;
margin-right: 10px;
}
.rightTriangle {
border-left-color: #fff;
margin-left: 10px;
}
}
}
}
</style>

View File

@@ -0,0 +1,276 @@
<template>
<div id="container" ref="container" class="visual-container material-cockpit">
<el-row
class="container-title"
:style="{
height: beilv * 88 + 'px',
lineHeight: beilv * 88 + 'px',
fontSize: beilv * 30 + 'px'
}"
>
<div :style="{ paddingLeft: 645 * beilv + 'px' }">
<img src="../../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt="">
合肥新能源数字工厂物料管理驾驶舱
</div>
<el-button
type="text"
class="title-button"
:style="{ right: 33 * beilv + 'px', top: 37 * beilv + 'px' }"
@click="changeFullScreen"
>
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
<svg-icon v-else icon-class="fullScreenView" />
</el-button>
</el-row>
<el-row class="container-main" :style="{ padding: '0 ' + 16 * beilv + 'px' }" :gutter="16 * beilv">
<!-- -->
<el-col :span="10" :style="{ margin: 16 * beilv + 'px' + ' 0' }">
<base-container :beilv="beilv" :height="958" :title="'BOM清单管理'" :title-icon="'cockpit_2_1'">
<bom-list :beilv="beilv" :bom-msg="bomMsg" />
</base-container>
</el-col>
<el-col :span="14">
<!-- 右上 -->
<el-row>
<el-col :style="{ marginTop: 16 * beilv + 'px' }">
<base-container :beilv="beilv" :height="470" :title="'在途原片'" :title-icon="'cockpit_2_2'">
<div class="box-padding specil-table1">
<base-table
:page="1"
:limit="14"
:show-index="false"
:beilv="beilv"
:table-config="originalFilm"
:table-data="originalFilmList"
/>
</div>
</base-container>
</el-col>
</el-row>
<!-- 右下 -->
<el-row>
<el-col :style="{ margin: 16 * beilv + 'px' + ' 0' }">
<base-container :beilv="beilv" :height="470" :title="'在途辅料'" :title-icon="'cockpit_2_3'">
<div class="box-padding specil-table1">
<base-table
:page="1"
:limit="14"
:show-index="false"
:beilv="beilv"
:table-config="material"
:table-data="materialList"
/>
</div>
</base-container>
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
import baseContainer from './components/baseContainer'
import screenfull from 'screenfull'
import BaseTable from './components/baseTable.vue'
import moment from 'moment'
import bomList from './components/bomList.vue'
const originalFilm = [
{
prop: 'time',
label: '上线时间',
minWidth: 35
},
{
prop: 'productLine',
label: '产线',
minWidth: 33
},
{
prop: 'spec',
label: '原片规格',
minWidth: 32.4
},
{
prop: 'batch',
label: '批次',
minWidth: 35
},
{
prop: 'num',
label: '数量',
minWidth: 28
}
]
const material = [
{
prop: 'time',
label: '上线时间',
minWidth: 35
},
{
prop: 'eqName',
label: '设备名称',
minWidth: 33
},
{
prop: 'spec',
label: '辅料规格',
minWidth: 32.4
},
{
prop: 'batch',
label: '批次',
minWidth: 35
},
{
prop: 'num',
label: '数量',
minWidth: 28
}
]
export default {
name: 'Cockpit',
components: {
baseContainer,
BaseTable,
bomList
},
data() {
return {
beilv: 1,
isFullScreen: false,
originalFilm,
originalFilmList: [],
material,
materialList: [],
bomMsg: []
}
},
watch: {
isFullScreen: function(val) {
if (val) {
this.beilv = document.body.offsetWidth / 1920
} else {
this.beilv = document.getElementById('container').offsetWidth / 1920
}
},
'sidebar.opened': function(val) {
console.log(val)
if (!this.isFullScreen) {
setTimeout(() => {
this.beilv = document.getElementById('container').offsetWidth / 1920
}, 300)
}
}
},
mounted() {
this.beilv = document.getElementById('container').offsetWidth / 1920
window.addEventListener('resize', () => {
if (this.isFullScreen) {
this.beilv = document.body.offsetWidth / 1920
} else {
this.beilv = document.getElementById('container').offsetWidth / 1920
}
})
this.getMsg()
},
methods: {
getMsg() {
const arr = []
const temp = []
for (let i = 0; i < 20; i++) {
const obj = {}
const sj = parseInt(Math.random() * 200)
obj.time = moment().add(sj, 'days').add(sj, 'hours').add(sj, 'minute').add(sj, 'second').format('YYYY-MM-DD HH:mm:ss')
obj.productLine = '产线A'
obj.spec = '光伏玻璃2.0'
obj.batch = moment().subtract(sj, 'days').format('YYYYMMDD') + '0000' + parseInt(Math.random() * 89 + 10)
obj.num = parseInt(Math.random() * 800 + 100)
arr.push(obj)
}
this.originalFilmList = arr
const eqList = ['清洗机', 'A1一次冷却机', 'A1下片机', 'A1一次固化机', 'A1一次镀膜机', 'A1二次固化机', 'A1二次镀膜机', 'A1磨边机', 'A1磨边清洗机', 'A1预热机', 'A2一次冷却机', 'A2一次固化机', 'A2一次镀膜机', 'A2下片机', 'A2二次固化机', 'A2磨边机', 'A2磨边清洗机', 'A储片机206']
const spcList = ['200*231*0.5', '100*120*0.2', '70*80', '100*100']
for (let i = 0; i < 20; i++) {
const obj = {}
const sj = parseInt(Math.random() * 200)
obj.time = moment().add(sj, 'days').add(sj, 'hours').add(sj, 'minute').add(sj, 'second').format('YYYY-MM-DD HH:mm:ss')
obj.eqName = eqList[parseInt(Math.random() * eqList.length)]
obj.spec = spcList[parseInt(Math.random() * spcList.length)]
obj.batch = moment().subtract(sj, 'days').format('YYYYMMDD') + '0000' + parseInt(Math.random() * 89 + 10)
obj.num = parseInt(Math.random() * 800 + 100)
temp.push(obj)
}
this.materialList = temp
this.bomMsg = [
{ name: '隔离纸' },
{ name: '异丙醇' },
{ name: '镀膜液' },
{ name: '磨轮' },
{ name: '包装辅材' },
{ name: '网板' }
]
},
change() {
this.isFullScreen = screenfull.isFullscreen
},
init() {
if (screenfull.enabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.enabled) {
screenfull.off('change', this.change)
}
},
changeFullScreen() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
this.isFullScreen = !this.isFullScreen
screenfull.toggle(this.$refs.container)
}
}
}
</script>
<style lang="scss" scoped>
.visual-container {
width: 100%;
min-width: 960px;
background: url('../../../assets/img/cockpit/cockpit-back.png') no-repeat;
background-size: cover;
.container-title {
width: 100%;
background: url('../../../assets/img/cockpit/title.png') no-repeat;
background-size: 100% 100%;
color: #fff;
.title-button {
color: #00fff0;
font-size: 20px;
position: absolute;
}
}
.box-padding {
padding: 0 16px;
}
}
</style>
<style lang="scss">
.material-cockpit {
.specil-table1 {
.el-table .cell {
padding-left: 40px;
padding-right: 40px;
}
.el-table--border th:first-child .cell,
.el-table--border td:first-child .cell {
padding-left: 40px;
}
}
}
</style>

View File

@@ -0,0 +1,37 @@
<template>
<el-page-header :class="$style.container" :content="$route.query.title" @back="handleBack()">
<div slot="title" slot-scope="{data}">
<slot name="title" :data="data" />
</div>
<div slot="content" slot-scope="{data}">
<slot name="content" :data="data" />
</div>
</el-page-header>
</template>
<script>
export default {
props: { },
data() {
return {}
},
created() {
console.log(this.$route.query.title)
},
methods: {
handleBack() {
this.$router.push({ path: this.$route.query.redirect })
}
}
}
</script>
<style lang="scss" module>
.container {
display: flex;
align-items: center;
width: 100%;
height: 40px;
padding: 4px 40px;
border-radius: 4px;
background-color: #eee;
}
</style>

View File

@@ -0,0 +1,97 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:18:27
* @LastEditors: gtz
* @LastEditTime: 2021-04-28 11:25:15
* @Description:
-->
<template>
<el-form :inline="true" @keyup.enter.native="getDataList()">
<el-form-item v-for="(item, index) in keyName" :key="index" :label="item.name">
<el-input v-if="item.type === 'input'" v-model="key[index]" style="width:200px" :placeholder="placeholderName[index]" clearable />
<el-select v-if="item.type === 'select'" v-model="key[index]" style="width:200px" :placeholder="placeholderName[index]" filterable clearable>
<el-option v-for="i in item.option" :key="i.id" :value="i.id" :label="i.name" />
</el-select>
<el-date-picker
v-if="item.type === 'datePicker'"
v-model="key[index]"
type="daterange"
align="right"
unlink-panels
:range-separator="'formItem.to' | i18nFilter"
:start-placeholder="'formItem.beginTime' | i18nFilter"
:end-placeholder="'formItem.endTime' | i18nFilter"
:picker-options="pickerOptions"
/>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">{{ 'btn.search' | i18nFilter }}</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
keyName: {
type: Array,
default: () => {
return []
}
},
placeholderName: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
key: [],
pickerOptions: {
shortcuts: [{
text: this.$t('datePickerOption.lastWeek'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
}, {
text: this.$t('datePickerOption.lastMonth'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
}, {
text: this.$t('datePickerOption.lastThreeMonths'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
}]
}
}
},
mounted() {
this.keyName.map(() => {
this.key.push(null)
})
},
methods: {
getDataList() {
this.$emit('getDataList', this.key)
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,193 @@
<!--
* @Author: gtz
* @Date: 2021-04-28 10:42:54
* @LastEditors: juzi
* @LastEditTime: 2022-04-21
* @Description: file content
-->
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="tableDataList"
:is-loading="listLoading"
/>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import { list, getMaterialBatchList } from '@/api/material-manage/currentConsume.js'
import { getDictDevice, getDictMaterial } from '@/api/dict'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'equipmentName',
label: i18n.t('module.materialManager.currentConsume.eqName')
},
{
prop: 'materialName',
label: i18n.t('module.materialManager.currentConsume.materialName')
},
{
prop: 'materialCode',
label: i18n.t('module.materialManager.currentConsume.materialCode')
},
{
prop: 'materialDateCode',
label: i18n.t('module.materialManager.currentConsume.materialBatch')
},
{
prop: 'beginTime',
label: i18n.t('module.materialManager.currentConsume.beginTime'),
filter: timeFormatter
},
{
prop: 'endTime',
label: i18n.t('module.materialManager.currentConsume.endTime'),
filter: timeFormatter
},
{
prop: 'materialNowCon',
label: i18n.t('module.materialManager.currentConsume.materialNowCon')
},
{
prop: 'MaterialConThr',
label: i18n.t('module.materialManager.currentConsume.MaterialConThr')
},
{
prop: 'remark',
label: i18n.t('module.materialManager.currentConsume.remark')
}
]
export default {
components: { HeadForm, Pagination, BaseTable },
props: {},
data() {
return {
trueWidth: 240,
tableProps,
tableDataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'select',
label: this.$t('module.materialManager.currentConsume.eqName'),
selectOptions: [],
param: 'equipmentName',
width: 200
},
{
type: 'select',
label: this.$t('module.materialManager.currentConsume.materialName'),
selectOptions: [],
param: 'materialName',
width: 200
},
{
type: 'select',
label: this.$t('module.materialManager.currentConsume.materialBatch'),
selectOptions: [],
param: 'materialDateCode',
width: 200
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getDict()
this.getList()
},
methods: {
getList() {
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.materialName = this.headFormValue.materialName
this.listQuery.materialDateCode = this.headFormValue.materialDateCode
list({ ...this.listQuery }).then(res => {
this.total = res.data.total
if (!res.data.records) {
this.tableDataList = []
return
}
this.tableDataList = res.data.records
})
},
getDict() {
this.getEq()
this.getMaterial()
this.getMaterialBatch()
},
async getEq() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.headFormConfig[0].selectOptions = result
},
async getMaterial() {
const result = await getDictMaterial()
this.headFormConfig[1].selectOptions = result
},
async getMaterialBatch() {
const result = await getMaterialBatchList({
current: 1,
size: 999
})
this.headFormConfig[2].selectOptions = result.data.records.map(item => {
return {
id: item.code,
name: item.code
}
})
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,112 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:18:27
* @LastEditors: lb
* @LastEditTime: 2022-03-30 16:25:15
* @Description:
-->
<template>
<el-form :inline="true" @keyup.enter.native="getDataList()">
<el-form-item v-for="(item, index) in keyName" :key="index" :label="item.name">
<el-input
v-if="item.type === 'input'"
v-model="queryParams[item.modalName]"
style="width:200px"
:placeholder="placeholderName[index]"
clearable
/>
<el-select
v-if="item.type === 'select'"
v-model="queryParams[item.modalName]"
style="width:200px"
:placeholder="placeholderName[index]"
filterable
clearable
>
<el-option v-for="i in item.option" :key="i.id" :value="i.name" :label="i.name" />
</el-select>
<el-date-picker
v-if="item.type === 'datePicker'"
v-model="queryParams[item.modalName]"
type="daterange"
align="right"
unlink-panels
:range-separator="'formItem.to' | i18nFilter"
:start-placeholder="'formItem.beginTime' | i18nFilter"
:end-placeholder="'formItem.endTime' | i18nFilter"
:picker-options="pickerOptions"
/>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">{{ 'btn.search' | i18nFilter }}</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="add()">{{ 'btn.add' | i18nFilter }}</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
keyName: {
type: Array,
default: () => {
return []
}
},
placeholderName: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
queryParams: {},
pickerOptions: {
shortcuts: [
{
text: this.$t('datePickerOption.lastWeek'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
},
{
text: this.$t('datePickerOption.lastMonth'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
},
{
text: this.$t('datePickerOption.lastThreeMonths'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
}
]
}
}
},
methods: {
getDataList() {
this.$emit('getDataList', this.queryParams)
},
add() {
this.$emit('add')
}
}
}
</script>
<style></style>

View File

@@ -0,0 +1,437 @@
<template>
<el-dialog
:visible.sync="visible"
:title="isedit ? 'btn.edit' : 'btn.add' | i18nFilter"
:close-on-click-modal="false"
>
<el-form ref="dataForm" :model="dataForm" :rules="dataFormRules" label-position="top">
<!-- hidden -->
<el-form-item style="position:absolute; top: 0; left: 0; height: 0; width: 0; overflow: hidden">
<el-select v-model="dataForm.id">
<el-option value="1" />
</el-select>
<!-- 加上上面这个空select把自动出现下拉框屏蔽掉代价多渲染一个无用的组件 -->
</el-form-item>
<el-row :gutter="20">
<el-col :span="8">
<!-- 设备名称id -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.equipmentName')" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
filterable
clearable
:placeholder="
$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.equipmentName')])
"
:style="{ width: '100%' }"
@change="handleChangeEquipment"
>
<el-option v-for="option in equipmentList" :key="option.id" :value="option.id" :label="option.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- 设备编码 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.equipmentCode')">
<el-input
v-model="dataForm.equipmentCode"
:disabled="true"
:placeholder="$t('module.basicData.visual.hints.selectEqFirst')"
/>
<!-- $i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.equipmentCode')]) -->
</el-form-item>
</el-col>
<el-col :span="8">
<!-- 使用人 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.user')" prop="userName">
<el-input
v-model="dataForm.userName"
clearable
:placeholder="
$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.userPlaceholder')])
"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<!-- 物料名称id -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.materialName')" prop="materialId">
<el-select
v-model="dataForm.materialId"
filterable
clearable
:placeholder="
$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.materialName')])
"
:style="{ width: '100%' }"
@change="handleChangeMaterial"
>
<el-option v-for="option in materialList" :key="option.id" :value="option.id" :label="option.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- 物料编码 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.materialCode')">
<el-input
v-model="dataForm.materialCode"
:disabled="true"
:placeholder="$t('module.basicData.visual.hints.selectMaterialFirst')"
/>
<!-- $i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.materialCode')]) -->
</el-form-item>
</el-col>
<el-col :span="8">
<!-- 物料批次 -->
<!-- <el-form-item
:label="$t('module.materialManager.currentUsageRecord.materialPatch')"
prop="materialDateId"
>
<el-select
v-model="dataForm.materialDateId"
filterable
clearable
:disabled="!materialSelected"
:placeholder="
$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.materialPatch')])
"
:style="{ width: '100%' }"
>
<el-option
v-for="option in materialBatchList"
:key="option.id"
:value="option.id"
:label="option.code"
/>
</el-select>
</el-form-item> -->
<!-- 单位 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.unit')">
<!-- <span class="el-form-item__label"><strong>{{ currentUnitLabel }}</strong></span> -->
<el-select
v-model="dataForm.unit"
disabled
:placeholder="$t('module.materialManager.currentUsageRecord.unit')"
:style="{ width: '100%' }"
>
<!-- :placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.unit')])" -->
<el-option
v-for="option in unitList"
:key="option.dataCode"
:value="option.dataCode"
:label="option.dataName"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<!-- 物料使用时间 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.materialUseTime')" prop="useTime">
<el-date-picker
v-model="dataForm.useTime"
clearable
:placeholder="
$i18nForm(['placeholder.select', $t('module.materialManager.currentUsageRecord.materialUseTime')])
"
type="datetime"
:style="{ width: '100%' }"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- 数量 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.num')" prop="num">
<el-input
v-model.number="dataForm.num"
clearable
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.num')])"
/>
</el-form-item>
</el-col>
<el-col :span="8" />
</el-row>
<el-row :gutter="20">
<el-col>
<!-- 备注 -->
<el-form-item :label="$t('module.materialManager.currentUsageRecord.remark')">
<el-input
v-model="dataForm.remark"
type="textarea"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.currentUsageRecord.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row style="text-align: right;">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.confirm' | i18nFilter }}</el-button>
</el-row>
</el-dialog>
</template>
<script>
import {
add,
update,
// getInfo,
getEquipmentList,
getMaterialList
} from '@/api/material-manage/usageRecord.js'
import i18n from '@/lang'
// import SmallTitle from '@/components/BaseDrawer/components/SmallTitle.vue'
import { refineData } from '@/utils/helpers'
// import newBasicData from '@/filters/newBasicData'
export default {
name: 'CurrentUsageRecord',
data() {
return {
visible: false,
isedit: false,
dataForm: {
id: null, // 记录id
equipmentId: null,
equipmentCode: '',
materialId: null,
materialCode: '',
num: 1,
remark: '',
unit: null,
useTime: null,
userName: ''
},
materialList: [],
equipmentList: [],
dataFormRules: {
equipmentId: [
{
required: true,
message: i18n.t('module.materialManager.currentUsageRecord.equipmentNamePlaceholder'),
trigger: 'blur'
}
],
materialId: [
{
required: true,
message: i18n.t('module.materialManager.currentUsageRecord.materialNamePlaceholder'),
trigger: 'blur'
}
],
materialDateId: [
{
required: true,
message: i18n.t('module.materialManager.currentUsageRecord.materialPatchPlaceholder'),
trigger: 'blur'
}
],
useTime: [
{
required: true,
message: i18n.t('module.materialManager.currentUsageRecord.materialUseTimePlaceholder'),
trigger: 'blur'
}
],
num: [
{
required: true,
type: 'integer',
min: 1,
message: i18n.t('module.materialManager.currentUsageRecord.numPlaceholder'),
trigger: 'blur'
}
]
},
temporaryDataForm: null,
allowFillinTheForm: false,
arrivedRequest: 0,
unitList: [] // 单位 数据字典列表
}
},
watch: {
arrivedRequest: function(val, oldVal) {
if (val && val === 2) {
this.$emit('all-data-loaded')
}
},
'dataForm.equipmentId': function(val) {
return this.handleChangeEquipment(val)
}
},
mounted() {
this.fetchList('unit')
this.$on('data-ready', () => {
if (this.allowFillinTheForm && this.temporaryDataForm) {
this.dataForm = this.temporaryDataForm
}
})
this.$on('all-data-loaded', () => {
// 如果是编辑页面,就复制数据
if (this.isedit) {
// 如果此时 temporaryDataForm 有数据了,就直接填充
if (this.temporaryDataForm) this.dataForm = this.temporaryDataForm
// 否则就设置标志位
else this.allowFillinTheForm = true
}
})
},
methods: {
initDataForm() {
this.dataForm = {
id: null, // 记录id
equipmentId: null,
materialId: null, // 物料id
num: 1,
remark: '',
unit: '',
useTime: null,
userName: ''
}
},
init(data) {
// 数据初始化
this.arrivedRequest = 0
this.initDataForm()
this.temporaryDataForm = null
// 异步数据加载
this.fetchList('equipment').then(res => {
if (res.data) this.equipmentList = res.data
else this.equipmentList.splice(0)
this.arrivedRequest += 1
})
this.fetchList('material').then(res => {
if (res.data.records) {
this.materialList = res.data.records.map(item => ({
id: item.id,
name: item.name,
code: item.code,
unit: item.unit || ''
}))
} else this.materialList.splice(0)
this.arrivedRequest += 1
})
if (data) {
this.isedit = true
// console.log('data: ', data)
// 编辑
this.temporaryDataForm = refineData(data, [
'id',
'equipmentId',
'materialId',
'materialCode',
'num',
'code',
'remark',
'unit',
'useTime',
'userName'
])
this.$emit('data-ready')
}
this.visible = true
},
fetchList(type) {
switch (type) {
case 'material':
return getMaterialList()
case 'equipment':
return getEquipmentList()
case 'unit': {
this.unitList = this.$store.getters.dictList.find(item => item.dictTypeId === '1')?.dataList
}
}
},
handleChangeMaterial(mid) {
const currentMaterial = this.materialList.find(item => item.id === mid)
if (currentMaterial) {
const code = currentMaterial.code || ''
const unitCode = currentMaterial.unit || ''
this.dataForm.materialCode = code
// this.dataForm.unit = newBasicData('1')(unitCode)
this.dataForm.unit = unitCode
}
},
handleChangeEquipment(eid) {
const currentEquipment = this.equipmentList.find(item => item.id === eid)
if (currentEquipment) {
this.dataForm.equipmentCode = currentEquipment.code || ''
}
},
close() {
this.visible = false
this.$emit('destroy-me')
},
confirm() {
// 验证 - 提交表单
this.$refs.dataForm.validate(valid => {
if (valid) {
const ajaxAction = this.dataForm.id ? update : add
ajaxAction(this.dataForm).then(res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.$emit('refreshDataList')
this.close()
}
})
})
}
})
}
}
}
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer >>> .el-drawer__header {
padding: 0;
margin: 32px 0 8px 32px;
}
.drawer >>> .content {
padding: 0 24px 30px;
display: flex;
flex-direction: column;
height: 100%;
}
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
</style>

View File

@@ -0,0 +1,284 @@
<!--
* @Author: lb
* @Date: 2022-03-30 14:28:54
* @LastEditors: gtz
* @LastEditTime: 2022-07-25 10:34:36
* @Description: 在线物料使用记录
-->
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:top-btn-config="topBtnConfig"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="dataList"
:is-loading="listLoading"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="calculateWidth" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<record-add-drawer
v-if="addOrUpdateVisible"
ref="addOrUpdate"
@refreshDataList="getList"
@destroy-me="handleDestroyDrawer"
/>
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import newBasicData from '@/filters/newBasicData'
import { list, del, getMaterialList, getEquipmentList } from '@/api/material-manage/usageRecord'
import RecordAddDrawer from './components/add-panel.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [
{
type: 'edit',
btnName: 'btn.edit'
},
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'equipmentName',
label: i18n.t('module.materialManager.currentUsageRecord.equipmentName')
},
{
prop: 'materialName',
label: i18n.t('module.materialManager.currentUsageRecord.materialName')
},
{
prop: 'materialCode',
label: i18n.t('module.materialManager.currentUsageRecord.materialCode'),
width: 180
},
{
prop: 'num',
label: i18n.t('module.materialManager.currentUsageRecord.num')
},
{
prop: 'unit',
label: i18n.t('module.materialManager.currentUsageRecord.unit'),
filter: newBasicData('1')
},
// {
// prop: 'materialDateCode',
// label: i18n.t('module.materialManager.currentUsageRecord.materialPatch')
// },
{
prop: 'userName',
// label: '使用人'
label: i18n.t('module.materialManager.currentUsageRecord.user')
},
{
prop: 'useTime',
label: i18n.t('module.materialManager.currentUsageRecord.materialUseTime'),
filter: timeFormatter
},
{
prop: 'remark',
label: i18n.t('module.materialManager.currentUsageRecord.remark')
}
]
export default {
components: { HeadForm, Pagination, BaseTable, MethodBtn, RecordAddDrawer },
data() {
return {
addOrUpdateVisible: false,
topBtnConfig,
tableBtn,
trueWidth: 240,
tableProps,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'select',
label: this.$t('module.materialManager.currentUsageRecord.equipmentName'),
selectOptions: [],
param: 'equipmentName',
valueField: 'name',
width: 200
},
{
type: 'select',
label: this.$t('module.materialManager.currentUsageRecord.materialName'),
selectOptions: [],
param: 'materialName',
valueField: 'name',
width: 200
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
computed: {
calculateWidth() {
return this.tableBtn.length * 40 // 操作列的每个按钮宽度40
}
},
created() {
const DEFAULT_QUERY_PARAM = {
current: 1,
size: 1000
}
getEquipmentList(DEFAULT_QUERY_PARAM).then(response => {
this.headFormConfig[0].selectOptions = response.data
})
getMaterialList(DEFAULT_QUERY_PARAM).then(response => {
this.headFormConfig[1].selectOptions = response.data?.records || []
})
this.getList()
},
methods: {
getList() {
const equipmentName = this.headFormValue.equipmentName ? this.headFormValue.equipmentName : ''
const materialName = this.headFormValue.materialName ? this.headFormValue.materialName : ''
list({ ...this.listQuery, equipmentName, materialName }).then(response => {
if (response.data.records) {
this.dataList = response.data.records
this.total = response.data.total
} else {
this.total = 0
this.dataList = []
}
})
setTimeout(() => {
this.addOrUpdateVisible = false
}, 300)
},
addNew(data) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(data)
})
},
handleEdit(id) {
this.$router.push({
path: 'currentUsageRecord/add',
query: {
redirect: '/material-manage/currentUsageRecord',
title: this.$t('module.materialManager.currentUsageRecord.edit'),
id
}
})
},
handleDelete(id) {
del({ id }).then(response => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500
})
this.handleSearch()
})
},
handleDestroyDrawer() {
setTimeout(() => {
this.addOrUpdateVisible = false
}, 300)
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`${this.$t('module.basicData.visual.TipsBefore')}${this.$t(
'module.materialManager.currentUsageRecord.thisRecord'
)}?`,
this.$t('module.basicData.visual.Tips'),
{
confirmButtonText: this.$t('module.basicData.visual.confirmButtonText'),
cancelButtonText: this.$t('module.basicData.visual.cancelButtonText'),
type: 'warning'
}
)
.then(() => {
del({ id: raw.data.id }).then(response => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.listQuery.current = 1
this.getList()
}
})
})
})
.catch(() => {})
} else if (raw.type === 'edit') {
// console.log('editing raw data: ', raw.data)
this.addNew(raw.data)
}
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
this.addNew(null)
}
}
}
}
</script>

View File

@@ -0,0 +1,97 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:18:27
* @LastEditors: gtz
* @LastEditTime: 2021-04-28 11:32:22
* @Description:
-->
<template>
<el-form :inline="true" @keyup.enter.native="getDataList()">
<el-form-item v-for="(item, index) in keyName" :key="index" :label="item.name">
<el-input v-if="item.type === 'input'" v-model="key[index]" style="width:200px" :placeholder="placeholderName[index]" clearable />
<el-select v-if="item.type === 'select'" v-model="key[index]" style="width:200px" :placeholder="placeholderName[index]" filterable clearable>
<el-option v-for="i in item.option" :key="i.id" :value="i.id" :label="i.name" />
</el-select>
<el-date-picker
v-if="item.type === 'datePicker'"
v-model="key[index]"
type="daterange"
align="right"
unlink-panels
:range-separator="'formItem.to' | i18nFilter"
:start-placeholder="'formItem.beginTime' | i18nFilter"
:end-placeholder="'formItem.endTime' | i18nFilter"
:picker-options="pickerOptions"
/>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">{{ 'btn.search' | i18nFilter }}</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
keyName: {
type: Array,
default: () => {
return []
}
},
placeholderName: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
key: [],
pickerOptions: {
shortcuts: [{
text: this.$t('datePickerOption.lastWeek'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
}, {
text: this.$t('datePickerOption.lastMonth'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
}, {
text: this.$t('datePickerOption.lastThreeMonths'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
}]
}
}
},
mounted() {
this.keyName.map(() => {
this.key.push(null)
})
},
methods: {
getDataList() {
this.$emit('getDataList', this.key)
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,184 @@
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="tableDataList"
:is-loading="listLoading"
/>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import { list, getMaterialBatchList } from '@/api/material-manage/historyConsume.js'
import { getDictDevice, getDictMaterial } from '@/api/dict'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableProps = [
{
prop: 'equipmentName',
label: i18n.t('module.materialManager.historyConsume.eqName')
},
{
prop: 'materialName',
label: i18n.t('module.materialManager.historyConsume.materialName')
},
{
prop: 'materialCode',
label: i18n.t('module.materialManager.historyConsume.materialCode')
},
{
prop: 'materialDateCode',
label: i18n.t('module.materialManager.historyConsume.materialBatch')
},
{
prop: 'beginTime',
label: i18n.t('module.materialManager.historyConsume.beginTime'),
filter: timeFormatter
},
{
prop: 'endTime',
label: i18n.t('module.materialManager.historyConsume.endTime'),
filter: timeFormatter
},
{
prop: 'materialNowCon',
label: i18n.t('module.materialManager.historyConsume.materialNowCon')
},
{
prop: 'MaterialConThr',
label: i18n.t('module.materialManager.historyConsume.MaterialConThr')
},
{
prop: 'remark',
label: i18n.t('module.materialManager.historyConsume.remark')
}
]
export default {
components: { HeadForm, Pagination, BaseTable },
props: {},
data() {
return {
trueWidth: 240,
tableProps,
tableDataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'select',
label: this.$t('module.materialManager.historyConsume.eqName'),
selectOptions: [],
param: 'equipmentName',
width: 200
},
{
type: 'select',
label: this.$t('module.materialManager.historyConsume.materialName'),
selectOptions: [],
param: 'materialName',
width: 200
},
{
type: 'select',
label: this.$t('module.materialManager.historyConsume.materialBatch'),
selectOptions: [],
param: 'materialDateCode',
width: 200
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
created() {
this.getDict()
this.getList()
},
methods: {
getList() {
this.listQuery.equipmentName = this.headFormValue.equipmentName
this.listQuery.materialName = this.headFormValue.materialName
this.listQuery.materialDateCode = this.headFormValue.materialDateCode
list({ ...this.listQuery }).then(res => {
this.total = res.data.total
if (!res.data.records) {
this.tableDataList = []
return
}
this.tableDataList = res.data.records
})
},
getDict() {
this.getEq()
this.getMaterial()
this.getMaterialBatch()
},
async getEq() {
const result = await getDictDevice({
current: 1,
size: 999
})
this.headFormConfig[0].selectOptions = result
},
async getMaterial() {
const result = await getDictMaterial()
this.headFormConfig[1].selectOptions = result
},
async getMaterialBatch() {
const result = await getMaterialBatchList({
current: 1,
size: 999
})
this.headFormConfig[2].selectOptions = result.data.records.map(item => {
return {
id: item.code,
name: item.code
}
})
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
}
}
}
</script>

View File

@@ -0,0 +1,423 @@
<!--
* @Author:
* @Date:
* @LastEditors: lb
* @LastEditTime: 2022-6-8 10:00:00
* @Description: 物料管理-换料操作-新增编辑
-->
<template>
<el-dialog
:visible.sync="visible"
:title="isedit ? 'btn.edit' : 'btn.add' | i18nFilter"
:append-to-body="false"
class="dialog"
width="45%"
:close-on-click-modal="false"
@close="close"
>
<!-- <small-title slot="title">{{ isedit ? 'btn.edit' : 'btn.add' | i18nFilter }}</small-title> -->
<el-form ref="dataForm" :model="dataForm" :rules="rules" label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<!-- 物料名称 -->
<el-form-item :label="$t('module.materialManager.refluelling.materialName')" prop="materialId">
<el-select
v-model="dataForm.materialId"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.refluelling.materialName')])"
clearable
filterable
@change="handleMaterialChange"
>
<el-option v-for="m in materialList" :key="m.id" :label="m.name" :value="m.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 物料编码 -->
<el-form-item :label="$t('module.materialManager.refluelling.materialCode')" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
:placeholder="$t('module.materialManager.refluelling.materialCode')"
disabled
/>
<!-- :placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.refluelling.materialCode')])" -->
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<!-- 数量 -->
<el-form-item :label="$t('module.materialManager.refluelling.num')" prop="num">
<el-input
v-model="dataForm.num"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.refluelling.num')])"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 换料时间 -->
<el-form-item :label="$t('module.materialManager.refluelling.replaceTime')" prop="replaceTime">
<el-date-picker v-model="dataForm.replaceTime" :style="{ width: '100%' }" type="datetime" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<!-- 设备名 -->
<el-form-item :label="$t('module.materialManager.refluelling.equipmentNameShort')" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.refluelling.equipmentName')])"
filterable
clearable
>
<el-option v-for="item in equipmentList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 来源 -->
<el-form-item :label="$t('module.materialManager.refluelling.source')" prop="source">
<el-select
v-model="dataForm.source"
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.refluelling.source')])"
filterable
clearable
>
<el-option v-for="item in sources" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<!-- 操作员 -->
<el-form-item :label="$t('module.materialManager.refluelling.operator2')" prop="operator">
<el-select
v-model="selectOperatorsBuffer"
:placeholder="$i18nForm(['placeholder.select', $t('module.materialManager.refluelling.operator2')])"
multiple
>
<el-option v-for="item in operators" :key="item.id" :label="item.name" :value="item.name" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<!-- 备注 -->
<el-form-item :label="$t('module.materialManager.refluelling.remark')" prop="remark">
<el-input
v-model="dataForm.remark"
:placeholder="$i18nForm(['placeholder.input', $t('module.materialManager.refluelling.remark')])"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row style="text-align: right">
<el-button @click="close">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="confirm">{{ 'btn.save' | i18nFilter }}</el-button>
</el-row>
</el-dialog>
</template>
<script>
import {
add,
update,
getInfo,
getOperators,
// getBatchByCode,
getEquipmentList,
getMaterialList,
getBatchList
} from '@/api/material-manage/refueling.js'
import i18n from '@/lang'
export default {
name: 'RefuelingAdd',
data() {
return {
isedit: false,
visible: false,
selectOperatorsBuffer: [], // 选择的操作员
materialList: [],
batchList: [],
materialCode: '',
dataForm: {
equipmentId: null, // 设备ID,示例值(1)
code: '', // 外部编码
id: null, // 主键,更新时需要填写,示例值(1)
materialId: null,
materialCode: '',
operator: '', // String, 操作员名称,多个,用顿号拼接
remark: '', // 备注
source: 'PDA',
num: 0, // 数量
replaceTime: new Date() // 换料时间
},
sources: null,
equipmentList: [],
rules: {
materialId: [
{ required: true, message: i18n.t('module.materialManager.refluelling.placeholdermaterialid'), trigger: 'blur' }
],
replaceTime: [
{ required: true, message: i18n.t('module.materialManager.refluelling.placeholdertime'), trigger: 'blur' }
],
operators: [
{ required: true, message: i18n.t('module.materialManager.refluelling.placeholderoperator'), trigger: 'blur' }
],
code: [
{
required: true,
message: i18n.t('module.materialManager.refluelling.placeholderbatchnumber'),
trigger: 'blur'
},
{ min: 1, message: i18n.t('module.materialManager.refluelling.placeholderLength'), trigger: 'blur' }
],
num: [
{
required: true,
message: i18n.t('module.materialManager.refluelling.placeholdernumrequired'),
trigger: 'blur'
},
{
type: 'number',
transform: val => Number(val),
message: i18n.t('module.materialManager.refluelling.placeholdernumnumber'),
trigger: 'blur'
}
],
equipmentId: [
{
required: true,
message: i18n.t('module.materialManager.refluelling.placeholderEquipment'),
trigger: 'blur'
}
]
},
batch: {
id: null,
code: '',
materialId: null,
materialName: '',
materialCode: ''
},
operators: [],
arrivedRequest: 0,
allowFillinTheForm: false,
temporaryDataForm: null
}
},
watch: {
arrivedRequest: function(val) {
if (val === 3) {
this.$emit('all-data-loaded')
}
}
},
mounted() {
this.$on('all-data-loaded', function() {
console.log('all-data-loaded')
if (this.temporaryDataForm) {
this.$refs.dataForm.resetFields()
this.dataForm = this.temporaryDataForm
// 恢复操作员选项
this.recoverOperatorsNameToSelectOptions(this.dataForm.operator)
// this.querySearchAsync()
} else {
this.allowFillinTheForm = true
}
})
this.$on('data-ready', function() {
console.log('data-ready')
if (this.allowFillinTheForm) {
this.$refs.dataForm.resetFields()
this.dataForm = this.temporaryDataForm
// 恢复操作员选项
this.recoverOperatorsNameToSelectOptions(this.dataForm.operator)
// this.querySearchAsync()
}
})
},
methods: {
initDataForm() {
this.dataForm = {
id: null,
code: '', // 外部编码
materialId: null,
materialCode: '',
equipmentId: null, // 设备ID,示例值(1)
operator: '', // 操作员名称,多个用顿号拼接
remark: '',
source: 'PDA',
unit: 0,
replaceTime: new Date() // 换料时间,默认当前时间
}
this.temporaryDataForm = null
this.selectOperatorsBuffer = []
},
initSource() {
const sources =
this.$store.getters.dictList.find(item => item.dictTypeId === '1523941494259912706')?.dataList || []
this.sources = sources.map(o => ({ label: o.dataName, value: o.dataName }))
},
init(data) {
this.initSource()
this.initDataForm()
this.arrivedRequest = 0
this.allowFillinTheForm = false
this.isedit = false
this.fetchList('material').then(res => {
if (res.data && res.data.records) {
this.materialList = res.data.records.map(item => ({ id: item.id, name: item.name, code: item.code }))
} else {
this.materialList.splice(0)
}
this.arrivedRequest += 1
})
this.fetchList('equipment').then(response => {
if (response.data) {
this.equipmentList = response.data
} else {
this.equipmentList = this.equipmentList.splice(0, this.equipmentList.length)
}
this.arrivedRequest += 1
})
this.fetchList('operator').then(response => {
if (response.data.records) {
this.operators = response.data.records.map(o => ({ id: o.id, name: o.name }))
} else {
this.operators.splice(0)
}
this.arrivedRequest += 1
})
if (data) {
this.isedit = true
this.dataForm.id = data.id
this.fetchList('refueling-detail').then(res => {
this.temporaryDataForm = res.data
this.$emit('data-ready')
})
}
this.visible = true
},
fetchList(type) {
switch (type) {
case 'material':
return getMaterialList()
case 'batch':
return getBatchList()
case 'equipment':
return getEquipmentList()
case 'operator':
return getOperators({ current: 1, size: 999 })
case 'refueling-detail':
return getInfo({ id: this.dataForm.id })
}
},
recoverOperatorsNameToSelectOptions(nameString) {
if (nameString) {
// 如果不为空,就转,格式应该为"A、B、C"的形式
nameString.split('、').forEach(name => {
this.selectOperatorsBuffer.push(name)
})
}
},
// querySearchAsync() {
// // console.log("exec to here...")
// const queryString = this.dataForm.code
// if (!queryString) {
// return
// }
// getBatchByCode({ current: 1, size: 999, externalCode: queryString }).then(res => {
// this.batch = res.data || {}
// // console.log('exec to here!!!!', this.batch)
// if (!this.batch.code) {
// this.dataForm.materialCode = ''
// this.dataForm.materialName = ''
// this.$message({
// type: 'error',
// message: this.$t('module.materialManager.refluelling.warning')
// })
// } else {
// this.dataForm.materialCode = this.batch.materialCode
// this.dataForm.materialName = this.batch.materialName
// this.$message({
// type: 'success',
// message: this.$t('module.materialManager.refluelling.validBatch')
// })
// }
// })
// },
confirm() {
this.$refs.dataForm.validate(valid => {
if (valid) {
// 将操作员拼接为字符串
this.dataForm.operator = this.selectOperatorsBuffer.join('、')
const ajaxAction = this.isedit ? update : add
ajaxAction({ ...this.dataForm, num: +this.dataForm.num }).then(res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.close()
}
})
})
}
})
},
close() {
this.$emit('refreshDataList')
this.visible = false
},
handleMaterialChange(mid) {
const currentMaterial = this.materialList.find(item => item.id === mid)
if (currentMaterial && currentMaterial.code) {
this.dataForm.materialCode = currentMaterial.code
} else {
this.dataForm.materialCode = ''
}
}
}
}
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
</style>

View File

@@ -0,0 +1,50 @@
<template>
<el-select v-model="selectResult" v-lazyload="emitLoadmore" multiple :placeholder="placeholder">
<el-option v-for="option in optionsStack" :key="option.id" :value="option.id" :label="option.name" />
</el-select>
</template>
<script>
export default {
directives: {
'lazyload': {
bind(el, binding) {
const SELECT_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
SELECT_DOM.addEventListener('scroll', function() {
const loadCondition = this.scrollHeight - this.scrollTop <= this.clientHeight
console.log('lazyload: ', loadCondition)
if (loadCondition) {
binding.value()
}
})
}
}
},
props: {
listFn: Function, // 获取数据的函数
options: Array,
placeholder: String
},
data() {
return {
optionsStack: [], // options 栈
total: 0,
selectResult: []
}
},
watch: {
options(val) {
// 有数据量过大,内存不够用的风险
this.optionsStack.splice(this.optionsStack.length, 0, ...val)
}
},
created() {
this.$emit('prepared')
},
methods: {
emitLoadmore() {
this.$emit('loadmore')
}
}
}
</script>

View File

@@ -0,0 +1,245 @@
<!--
* @Author:
* @Date:
* @LastEditors: gtz
* @LastEditTime: 2022-07-25 10:23:44
* @Description: 物料管理-换料操作
-->
<template>
<div class="app-container">
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
<base-table
:top-btn-config="topBtnConfig"
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="tableDataList"
:is-loading="listLoading"
@clickTopBtn="clickTopBtn"
>
<method-btn slot="handleBtn" :width="calculateWidth" :method-list="tableBtn" @clickBtn="handleClick" />
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
<refueling-add v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getList" />
</div>
</template>
<script>
import HeadForm from '@/components/basicData/HeadForm'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import { list, del } from '@/api/material-manage/refueling.js'
import i18n from '@/lang'
import { timeFormatter } from '@/filters'
import RefuelingAdd from './components/add-panel.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const topBtnConfig = [
{
type: 'add',
btnName: 'btn.add'
}
]
const tableBtn = [
{
type: 'edit',
btnName: 'btn.edit'
},
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'replaceTime',
label: i18n.t('module.materialManager.materialbatch.createTime'),
filter: timeFormatter,
width: 160
},
// {
// prop: 'materialDateCode',
// label: i18n.t('module.materialManager.refluelling.materialDateCode')
// },
// {
// prop: 'materialDateName',
// label: i18n.t('module.materialManager.refluelling.materialDateName'),
// width: 150
// },
{
prop: 'materialCode',
label: i18n.t('module.materialManager.refluelling.materialCode'),
width: 180
},
{
prop: 'materialName',
label: i18n.t('module.materialManager.refluelling.materialName')
},
{
prop: 'num',
label: i18n.t('module.materialManager.refluelling.num')
},
{
prop: 'source',
label: i18n.t('module.materialManager.refluelling.source')
},
{
prop: 'equipmentName',
label: i18n.t('module.materialManager.refluelling.equipmentNameShort')
},
{
prop: 'operator',
label: i18n.t('module.materialManager.refluelling.operator')
},
{
prop: 'remark',
label: i18n.t('module.materialManager.refluelling.remark')
}
]
export default {
components: { HeadForm, Pagination, BaseTable, MethodBtn, RefuelingAdd },
props: {},
data() {
return {
topBtnConfig,
tableBtn,
addOrUpdateVisible: false,
trueWidth: 240,
tableProps,
tableDataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'input',
label: i18n.t('module.basicData.cache.Keywords'),
placeholder: this.$t('module.materialManager.refluelling.placeholderSearch'),
param: 'keywords',
width: 300
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
}
],
headFormValue: {}
}
},
computed: {
calculateWidth() {
return this.tableBtn.length * 40 // 操作列的每个按钮宽度40
}
},
created() {
this.getList()
},
methods: {
getList() {
list({ ...this.listQuery, key: this.headFormValue.keywords || '' }).then(res => {
if (res.data.records) {
this.tableDataList = res.data.records
} else {
this.tableDataList.splice(0)
}
this.total = res.data.total
})
},
// handleAdd() {
// this.$router.push({
// path: 'refueling/add',
// query: {
// redirect: '/material-manage/refueling',
// title: this.$t('module.materialManager.refluelling.add')
// }
// })
// },
// handleEdit(id) {
// this.$router.push({
// path: 'refueling/add',
// query: {
// redirect: '/material-manage/refueling',
// title: this.$t('module.materialManager.refluelling.edit'),
// id
// }
// })
// },
handleDelete(id) {
this.$confirm(i18n.t('deleteMsgBox.content'), i18n.t('deleteMsgBox.hint'), {
confirmButtonText: i18n.t('btn.confirm'),
cancelButtonText: i18n.t('btn.cancel'),
type: 'warning'
}).then(async() => {
del({ id }).then(res => {
this.$message({
type: 'success',
message: i18n.t('deleteMsgBox.doneMsg'),
duration: 1500,
onClose: () => {
this.getList()
}
})
})
})
},
handleClick(row) {
const id = row.data.id
if (row.type === 'delete') {
this.handleDelete(id)
} else {
this.addNew(row.data)
}
},
addNew(data) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(data)
})
},
btnClick(val) {
this.headFormValue = val
// 如果点击的是搜索栏的其他按钮在这里继续写判断
if (this.headFormValue.btnName === 'search') {
this.getList()
}
},
clickTopBtn(val) {
if (val === 'add') {
this.addNew()
}
}
}
}
</script>

View File

@@ -0,0 +1,96 @@
<!--
* @Date: 2020-12-14 09:07:03
* @LastEditors: zwq
* @LastEditTime: 2021-06-22 14:55:19
* @FilePath: \basic-admin\src\components\BaseTable\index.vue
* @Description:
-->
<template>
<div>
<el-table
v-loading="isLoading"
:data="renderData"
:stripe="true"
:header-cell-style="{background:'#eef1f6',color:'#606266',height: '56px'}"
border
fit
highlight-current-row
style="width: 100%"
>
<el-table-column v-if="page && limit" prop="_pageIndex" :label="'tableHeader.index' | i18nFilter" width="70" align="center" />
<el-table-column
v-for="item in tableConfig"
:key="item.prop"
v-bind="item"
>
<template slot-scope="scope">
<component :is="item.subcomponent" v-if="item.subcomponent" :inject-data="{...scope.row, ...item}" @emitData="emitData" />
<span v-else>{{ scope.row[item.prop] | commonFilter(item.filter) }}</span>
</template>
</el-table-column>
<slot name="content" />
<slot name="handleBtn" />
</el-table>
</div>
</template>
<script>
import { isObject, isString } from 'lodash'
export default {
name: 'BaseTable',
filters: {
commonFilter: (source, filterType = a => a) => {
return filterType(source)
}
},
props: {
tableData: {
type: Array,
required: true,
validator: val => val.filter(item => !isObject(item)).length === 0
},
tableConfig: {
type: Array,
required: true,
validator: val => val.filter(item => !isString(item.prop) || !isString(item.label)).length === 0
},
isLoading: {
type: Boolean,
required: false
},
page: {
type: Number,
required: false,
default: 0
},
limit: {
type: Number,
required: false,
default: 0
}
},
data() {
return {
}
},
computed: {
renderData() {
return this.tableData.map((item, index) => {
return {
...item,
_pageIndex: (this.page - 1) * this.limit + index + 1
}
})
}
},
methods: {
emitData(val) {
this.$emit('emitFun', val)
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,76 @@
<!--
* @Author: your name
* @Date: 2021-04-26 12:55:21
* @LastEditTime: 2021-05-25 16:41:39
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\material-manage\report\components\search-bar.vue
-->
<template>
<div class="container">
<span class="label-name">{{ $t('module.materialManager.report.Keyword') }}</span>
<el-input
v-model="key"
:placeholder="$t('module.materialManager.report.placeholderkeywords')"
:clearable="true"
:style="{
width: inputWidth + 'px',
maxWidth: '100%',
marginRight: '16px'
}"
/>
<el-button type="primary" icon="el-icon-search" @click="handleSearch()">
{{ "btn.search" | i18nFilter }}
</el-button>
</div>
</template>
<script>
export default {
props: {
showTime: {
type: Boolean,
default: false
},
lableName: {
type: String,
default: '关键字'
},
placeholder: {
type: String,
default: '请输入'
},
inputWidth: {
type: Number,
default: 180
}
},
data() {
return {
key: '',
dts: ['', '']
}
},
methods: {
handleSearch() {
const param = {
key: this.key
}
this.$emit('on-search', param)
}
}
}
</script>
<style lang="scss" scoped>
.container {
display: flex;
align-items: center;
width: 100%;
height: 50px;
padding: 4px 40px;
background-color: #eee;
.label-name {
margin-right: 8px;
font-size: 14px;
}
}
</style>

View File

@@ -0,0 +1,87 @@
<!--
* @Author: your name
* @Date: 2021-04-26 11:27:45
* @LastEditTime: 2021-04-27 15:13:57
* @LastEditors: gtz
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\material-manage\report\components\tree.vue
-->
<!--
* @Author: gtz
* @Date: 2021-04-25 09:07:28
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-04-26 11:05:18
* @Description: file content
-->
<template>
<div class="app-tree">
<el-input v-model="filterText" :placeholder="'placeholder.treeSearch' | i18nFilter" />
<el-tree
ref="tree"
:data="treeList"
:show-checkbox="showCheck"
:filter-node-method="filterNode"
@node-click="handleNodeClick"
@check-change="handleCheckChange"
/>
</div>
</template>
<script>
import { getTreeList } from '@/api/material-manage/report.js'
export default {
props: {
showCheck: {
type: Boolean,
default: () => false
},
treeType: {
type: String,
default: () => ''
}
},
data() {
return {
filterText: null,
treeList: []
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getTree()
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
async getTree() {
const result = await getTreeList()
if (result.code === 0) {
this.treeList = [result.data]
console.log(this.treeList)
}
},
handleNodeClick(data, node, components) {
this.$emit('handleNodeClick', data, node, components)
},
handleCheckChange(data, checked, indeterminate) {
this.$emit('handleCheckChange', data, checked, indeterminate)
}
}
}
</script>
<style lang="scss" scoped>
.app-tree {
border: 2px solid rgb(228, 228, 228);
padding: 10px;
border-radius: 5px;
min-height: 500px;
}
</style>

View File

@@ -0,0 +1,122 @@
<!--
* @Author: your name
* @Date: 2021-04-26 09:15:28
* @LastEditTime: 2021-05-25 16:37:33
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mt-bus-fe\src\views\material-manage\report\index.vue
-->
<template>
<el-container style="margin:30px">
<el-row style="width: 100%">
<el-col :span="4">
<side-tree @handleNodeClick="handleNodeClick" />
</el-col>
<el-col :span="20">
<el-main v-if="showDialog" style="border:2px solid #E4E4E4;border-radius:10px;margin-left:10px">
<SearchBar :placeholder="'基板编码'" :input-width="200" @on-search="handleSearch" />
<base-table :table-config="tableProps" :table-data="list" :is-loading="listLoading" :page="listQuery.current" :limit="listQuery.size" />
</el-main>
</el-col>
</el-row>
</el-container>
</template>
<script>
const tableProps = [{
prop: 'name',
label: i18n.t('module.materialManager.report.eqName'),
align: 'center'
},
{
prop: 'code',
label: i18n.t('module.materialManager.report.code'),
align: 'center'
}]
import sideTree from '@/components/Tree'
import moment from 'moment'
import BaseTable from './components/index.bak'
import SearchBar from './components/search-bar'
import i18n from '@/lang'
// import i18n from '@/lang'
import { getTreeList, getData } from '@/api/material-manage/report.js'
export default {
components: { sideTree, SearchBar, BaseTable },
props: {},
data() {
return {
moment,
tableDataList: [],
tableData: [],
tableProps,
treeList: [],
dataForm: {
id: 0,
current: 1,
size: 20,
level: 0,
key: ''
},
param: {},
list: [],
total: 0,
listLoading: false,
showDialog: false,
curEditId: null,
showEditDialog: false,
listQuery: {
current: 1,
size: 10,
name: ''
}
}
},
created() {
this.handleSearch()
},
methods: {
async getTreeList() {
// edit here
this.treeList.splice(0, this.treeList.length)
const res = await getTreeList()
if (res.code === 0) {
this.treeList = res.data.records
console.log(this.treeList)
}
},
handleNodeClick(data) {
this.dataForm.id = data.id
this.showDialog = true
this.getList()
},
async getList() {
const result = await getData(this.dataForm)
if (result.code === 0) {
this.list = result.data
}
},
async handleSearch(param) {
if (param !== '') {
this.dataForm.key = param.key
}
const result = await getData(this.dataForm)
if (result.code === 0) {
this.list = result.data
this.dataForm.key = ''
}
}
}
}
</script>
<style lang="scss" module>
.container {
.table {
margin: 16px;
width: 98.5%;
}
}
.one{
color: black;
}
</style>