Commit fbba4694 authored by jingnan's avatar jingnan 👀

Merge branch 'dev' of http://94.191.100.41/tfmom/tf-mom-web into dev

parents e69f0855 530fe975
......@@ -93,37 +93,43 @@ export default {
return {
'subTypeName': 'InStorageRecallItem',
'reqStatus': 'Apply',
'outStorageId': r.inventory && r.inventory.jobResponseId || '',
'outStorageIdType': r.inventory && r.inventory.jobResponseIdType || '',
'inventoryId': r.inventoryId || '',
'inventoryIdType': r.inventoryIdType || '',
'purchaseUnitId': r.inventory && r.inventory.jobResponse.jobOrder.extMaterial.extUnitId || '',
'purchaseUnitIdType': r.inventory && r.inventory.jobResponse.jobOrder.extMaterial.extUnitIdType || '',
'extDxSipplierId': r.inventory && r.inventory.jobResponse.jobOrder.extDxSipplierId || '',
'extDxSipplierIdType': r.inventory && r.inventory.jobResponse.jobOrder.extDxSipplierIdType || '',
extDxSipplier: r.inventory && r.inventory.jobResponse.jobOrder.extDxSipplier || '',
extMaterial: r.inventory && r.inventory.jobResponse.jobOrder.extMaterial || '',
storageZone: r.inventory && r.inventory.jobResponse.jobOrder.storageZone || '',
storageCondition: r.inventory && r.inventory.jobResponse.jobOrder.storageCondition || '',
'extMaterialId': r.inventory && r.inventory.jobResponse.jobOrder.extMaterialId || '',
'extMaterialIdType': r.inventory && r.inventory.jobResponse.jobOrder.extMaterialIdType || '',
'arrivalDate': r.inventory && r.inventory.jobResponse.jobOrder.arrivalDate || '',
'reqAmount': r.inventory && r.inventory.jobResponse.jobOrder.reqAmount || '',
'airModel': r.inventory && r.inventory.jobResponse.jobOrder.airModel || '',
'sorties': r.inventory && r.inventory.jobResponse.jobOrder.sorties || '',
'manufacturer': r.inventory && r.inventory.jobResponse.jobOrder.manufacturer || '',
'contractNo': r.inventory && r.inventory.jobResponse.jobOrder.contractNo || '',
'stockPrice': r.inventory && r.inventory.jobResponse.jobOrder.stockPrice || '',
'lotNo': r.inventory && r.inventory.jobResponse.jobOrder.lotNo || '',
'taxRate': r.inventory && r.inventory.jobResponse.jobOrder.taxRate || '',
'taxUnitPrice': r.inventory && r.inventory.jobResponse.jobOrder.taxUnitPrice || '',
'taxPrice': r.inventory && r.inventory.jobResponse.jobOrder.taxPrice || '',
'stockUnitPrice': r.inventory && r.inventory.jobResponse.jobOrder.stockUnitPrice || '',
'purchaseOrderNo': r.inventory && r.inventory.jobResponse.jobOrder.purchaseOrderNo || '',
'inventory': {
'testNo': r.inventory.testNo,
'ispass': r.inventory.ispass,
'materialType': r.inventory.materialType,
'materialCode': r.inventory.materialCode,
'materialName': r.inventory.materialName,
'modelNo': r.inventory.modelNo,
'techspec': r.inventory.techspec,
'spce': r.inventory.spce,
'suppstatus': r.inventory.suppstatus,
'lotNo': r.inventory.lotNo,
'serno': r.inventory.serno,
'aircraftType': r.inventory.aircraftType,
'sorties': r.inventory.sorties,
// 'extUnit': { unitName: r.inventory.extUnit.unitName },
'workcenter': r.inventory.workcenter,
'workunit': r.inventory.workunit,
'suppname': r.inventory.suppname,
'arrDate': r.inventory.arrDate,
'madDate': r.inventory.madDate,
'qualityPeriod': r.inventory.qualityPeriod,
'longPeriod': r.inventory.longPeriod,
'spotCheckPeriod': r.inventory.spotCheckPeriod,
'arrDrawNo': r.inventory.arrDrawNo,
'taxRate': r.inventory.taxRate,
'stockUnitPrice': r.inventory.stockUnitPrice,
'stockPrice': r.inventory.stockPrice,
'applyUserName': r.inventory.applyUserName,
'contractNo': r.inventory.contractNo
},
'reqAmount': r.reqAmount,
'arrivalVer': r.arrivalVer,
'taxUnitPrice': r.taxUnitPrice,
'taxPrice': r.taxPrice,
'remark': r.remark,
'operator': 'ADD',
remark: r.inventory && r.inventory.jobResponse.jobOrder.remark || '',
'isRoot': r.inventory && r.inventory.jobResponse.jobOrder.isRoot
'isRoot': r.inventory.jobResponse.jobOrder.isRoot
}
})
this.$emit('submitEvent', { formData: data })
......
/**
* @Description: 移库入库库位选择
* @author xioln
* @date 2023-08-14
* @FilePath: applications/dee-mes/src/privateComponents/components/InStorageMoveWarehouseSelect/index.vue
*/
<template>
<div class="inStorageMoveWarehouse-select">
<el-select
v-model="selVal"
v-el-select-loadmore="loadmore"
:remote-method="remoteMethod"
:loading="loading"
clearable
filterable
remote
placeholder="请输入并选择"
size="mini"
@change="changeVal"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</template>
<script>
export default {
componentName: '移库入库库位选择',
name: 'InStorageMoveWarehouseSelect', // name写在组件的最前方,自定义组件为必填
components: {},
// 自定义指令(和method同级)
directives: {
// 下拉框懒加载(el-select-loadmore是自定义的指令,使用时前面加v-)
'el-select-loadmore': {
// el:使用自定义指令的元素(下拉框),
bind(el, binding) {
// 下拉框下拉的框
const SELECTWRAP_DOM = el.querySelector(
'.el-select-dropdown .el-select-dropdown__wrap'
)
// 增加滚动监听,
SELECTWRAP_DOM.addEventListener('scroll', function() {
// scrollHeight:当前所有选项的高度
// scrollTop:滚动的距离
// clientHeight:下拉框的高度
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight + 1
// 当滚动条滚动到最底下的时候执行接口加载下一页
if (condition) {
binding.value()
}
})
}
}
},
props: {
itemObj: {
type: Object,
default: null
},
form: {
type: Object,
default: () => { }
},
middleForm: {
type: Object,
default: () => { }
},
value: {
type: [Number, String, Object],
default: () => ''
}
},
data() {
return {
options: [],
selVal: '',
querys: '', // 远程搜索输入的内容
selectLoading: false, // select加载
stopLoading: false, // 最后一次加载之后,不再加载
pageData: {// 懒加载相关参数,这里代表从第一条数据开始加载,一次加载十项
pageNumber: 1,
pageSize: 10
},
loading: false
}
},
computed: {},
watch: {
'form.extWorkCenterId': {
immediate: true,
deep: true,
handler(val) {
if (val) {
// this.getdata()
}
}
}
},
created() {
},
methods: {
changeVal() {
this.$emit('input', this.selVal)
},
// 下拉框滚动分页加载
loadmore() {
if (!this.stopLoading) {
const querys = {
pageFrom: this.pageData.pageNumber++,
pageSize: 10,
searchItems: {
items: [
{ 'fieldName': 'extname', operator: 'LIKE', value: this.querys },
{ 'fieldName': 'extCenterId', operator: 'EQ', value: this.form.extWorkCenterId }
],
operator: 'AND'
}
}
this.getdatas(querys)// 调用接口获取下拉框数据
}
},
// 远程搜索物料类别
remoteMethod(query) {
this.querys = query// 保存搜索内容
let querys = {}
// 有内容则搜索
if (query !== '') {
querys = {
pageFrom: 1,
pageSize: 10,
searchItems: {
items: [
{ 'fieldName': 'extname', operator: 'LIKE', value: query },
{ 'fieldName': 'extCenterId', operator: 'EQ', value: this.form.extWorkCenterId }
],
operator: 'AND'
}
}
} else {
// 没有内容搜10
querys = {
pageFrom: 1,
pageSize: 10,
searchItems: {
items: [
{ 'fieldName': 'extCenterId', operator: 'EQ', value: this.form.extWorkCenterId }
],
operator: 'AND'
}
}
// 重置懒加载
this.stopLoading = false
this.pageData = {// 懒加载相关参数,这里代表从第一条数据开始加载,一次加载二十项
pageNumber: 1,
pageSize: 10
}
}
// 调用接口
this.selectLoading = true
this.getdata(querys)
},
getdata(querys) {
this.selectLoading = true
this.$api.searchApi('ExtDxProductWorkUnit', querys).then(res => {
this.options = res.items.content.map(row => {
return {
value: row.id,
label: row.extname
}
})
}).finally(() => {
this.selectLoading = false
})
},
getdatas(querys) {
if (!this.querys) {
return
}
this.selectLoading = true
this.$api.searchApi('ExtDxProductWorkUnit', querys).then(res => {
const arr = res.items.content
// 如果某次返回值是[],表示已经加载完了,不必再加载
if (arr.length === 0) {
this.stopLoading = true
return
}
// 保存数据
if (querys.pageNumber === 1) {
this.options = arr.map(row => {
return {
value: row.id,
label: row.extname
}
})
} else {
this.options = [...this.options, ...arr.map(row => {
return {
value: row.id,
label: row.extname
}
})]
}
}).finally(() => {
this.selectLoading = false
})
}
}
}
</script>
<style lang='scss'></style>
/**
* @Description: 作业令号根据机型架次选择
* @author xioln
* @date 2023-08-14
* @FilePath: applications/dee-mes/src/privateComponents/components/JobNumberSelect/index.vue
*/
<template>
<div class="jobNumber-select">
<el-select v-model="selVal" placeholder="请选择" size="mini" @change="changeVal">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</template>
<script>
export default {
componentName: '作业令号',
name: 'JobNumberSelect', // name写在组件的最前方,自定义组件为必填
components: {},
props: {
itemObj: {
type: Object,
default: null
},
form: {
type: Object,
default: () => {}
},
middleForm: {
type: Object,
default: () => {}
},
value: {
type: [Number, String, Object],
default: () => ''
}
},
data() {
return {
options: [],
selVal: ''
}
},
computed: {},
watch: {
'form.sorties': {
immediate: true,
deep: true,
handler(val) {
console.log('val', val)
if (val) {
const params = {
searchItems: {
items: [
{ 'fieldName': 'aircraftTypeId', operator: 'EQ', value: this.form.aircraftType.split('+')[0] },
{ 'fieldName': 'aircraftSortiesId', operator: 'EQ', value: val.split('+')[0] }
],
operator: 'AND'
}
}
this.$api.searchApi('ORProduction', params).then(res => {
this.options = res.items.content.map(row => {
return {
value: row.id,
label: row.jobNo
}
})
})
}
}
}
},
created() {
},
methods: {
changeVal() {
this.$emit('input', this.selVal)
}
}
}
</script>
<style lang='scss'>
</style>
......@@ -304,10 +304,10 @@ export default {
'小时<br><b>版本:</b> ' +
(task.edition || ' ') +
'<br><b>' +
task.$level ===
(task.$level ===
0
? 'CA/AO号'
: 'CA/AO号' + ':</b> ' + (task.right_text || ' ')
? ''
: 'CA/AO号' + ':</b> ' + (task.right_text || ' '))
return html
}
ganttAss.config.drag_resize = false
......
......@@ -150,7 +150,7 @@ export default {
}
this.currentId = this.node.id
this.gantt.clearAll()
if (!this.node || !this.node.children.length) {
if (!this.node || !this.node.children || !this.node.children.length) {
return
}
this.AOname = ''
......
......@@ -43,11 +43,12 @@ export default {
{ title: '牌号/型号/件号', key: 'extMaterial.modelNo', align: 'center', minWidth: '120' },
{ title: '规格', key: 'extMaterial.spec', align: 'center' },
{ title: '单位名称', key: 'extMaterial.extUnit.unitName', align: 'center' },
{ title: '申领数量', key: 'reqAmount', align: 'center', minWidth: '120',
{
title: '申领数量', key: 'reqAmount', align: 'center', minWidth: '120',
component: {
show: true,
render: (h, data, column, index) => {
return (<el-input-number size='small'v-model={data.reqAmount}
return (<el-input-number size='small' v-model={data.reqAmount}
on-change={(e) => {
this.tableData = this.tableData.map(item => {
if (item.extMaterialId === data.extMaterialId) {
......@@ -55,7 +56,7 @@ export default {
}
return item
})
}}/>)
}} />)
}
}
},
......@@ -113,6 +114,11 @@ export default {
created() {
// 初始化数据
},
mounted() {
if (this.$route.query.id) {
this.getEditData(this.$route.query.id)
}
},
methods: {
addData(data) {
console.log('data', data)
......@@ -126,8 +132,12 @@ export default {
this.dialogVisible = false
},
occupy() {
const form = { ...this.form }
form.aircraftType = form.aircraftType.split('+')[1]
form.sorties = form.sorties.split('+')[1]
const param = {
...this.form,
...form,
inStorageRequestItems: this.tableData,
subTypeName: 'OutStorageOut',
operator: 'ADD'
......@@ -173,6 +183,46 @@ export default {
})
})
},
getEditData(id) {
const param = {
'searchItems': {
'items': [
{ 'fieldName': 'subTypeName', 'operator': 'EQ', 'value': 'OutStorageOut' },
{ 'fieldName': 'id', 'operator': 'EQ', 'value': id }
]
},
openProps: [{
'name': 'inStorageRequestItems',
'openProps': [{
'name': 'extMaterial',
'openProps': [{
'name': 'resType2'
}, {
'name': 'extUnit'
}]
}, {
'name': 'extDxSipplier'
}, {
'name': 'creator'
}, {
'name': 'storageZone'
},
{
'name': 'inventoryJobResponses'
}]
}]
}
post('OutStorageRequest/search', param).then(res => {
console.log('res', res)
const data = res.items.content[0].inStorageRequestItems
data.forEach(item => {
item.allocatedAmount = this.sumArray(item.inventoryJobResponses, 'allocatedAmount')
})
this.tableData = data
}).catch((err) => {
console.log(err)
})
},
sumArray(array, key) {
let sum = 0
for (let i = 0; i < array.length; i++) {
......
/**
* @Description: 架次根据机型选择
* @author xioln
* @date 2023-08-14
* @FilePath: applications/dee-mes/src/privateComponents/components/getSortiesSelect/index.vue
*/
<template>
<div class="getSorties-select">
<el-select v-model="selVal" placeholder="请选择" size="mini" @change="changeVal">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</template>
<script>
export default {
componentName: '架次',
name: 'GetSortiesSelect', // name写在组件的最前方,自定义组件为必填
components: {},
props: {
itemObj: {
type: Object,
default: null
},
form: {
type: Object,
default: () => {}
},
middleForm: {
type: Object,
default: () => {}
},
value: {
type: [Number, String, Object],
default: () => ''
}
},
data() {
return {
options: [],
selVal: ''
}
},
computed: {},
watch: {
'form.aircraftType': {
immediate: true,
deep: true,
handler(val) {
if (val) {
const params = {
searchItems: {
items: [{ 'fieldName': 'aircraftTypeId', operator: 'EQ', value: val.split('+')[0] }],
operator: 'AND'
}
}
this.$api.searchApi('AircraftSorties', params).then(res => {
this.options = res.items.content.map(row => {
return {
value: row.id + '+' + row.defName,
label: row.defName
}
})
})
}
}
}
},
created() {
// 初始化数据
},
methods: {
changeVal() {
this.$emit('input', this.selVal)
}
}
}
</script>
<style lang='scss'>
</style>
<template>
<div>
<div :id="onlyUuid" :ref="onlyUuid" class="gantt" />
</div>
</template>
<script>
import CsvExportor from 'csv-exportor'
import { post } from '@/utils/http'
export default {
name: 'TfMomWebGantt',
props: {
form: {
type: Object,
default: () => {}
},
stateOptions: {
type: Array,
default: () => []
}
},
data() {
return {
tasks: {},
loading: false,
tooltipId: null,
tooltipLoading: true,
tooltipData: {},
start_date: null,
openTree: [],
seePdfShow: false,
onlyUuid: 'stationPlan-gantt',
// eslint-disable-next-line no-undef
gantt: Gantt.getGanttInstance()
}
},
watch: {
form: {
immediate: true,
deep: true,
handler(val) {
if (!val || !val.positionNumber) {
return
}
this.getData()
}
}
},
mounted() {
this.initGantt()
},
methods: {
initGantt() {
const that = this
const ganttStm = this.gantt
ganttStm.plugins({
tooltip: true
})
var zoomConfig = {
levels: [
[
{
unit: 'month',
step: 1,
format: '%Y-%m'
},
{
unit: 'day',
step: 1,
format: '%m-%d'
}
],
[
{
unit: 'day',
step: 1,
format: '%Y-%m-%d'
},
{
unit: 'hour',
step: 1,
format: '%H:%i:%s'
}
]
],
useKey: 'ctrlKey',
trigger: 'wheel',
element: function() {
return ganttStm.$root.querySelector('.gantt_task')
}
}
ganttStm.templates.tooltip_text = function(start, end, task) {
var html = null
if (task.$level === 0) {
html =
'<b>站位/装配单元:</b> ' +
task.text +
'<br><b>工期:</b> ' +
task.constPeriod +
'天' +
'<br/><b>计划开工时间:</b> ' +
that.formatDate(task.start_date) +
'<br/><b>计划完工时间:</b> ' +
that.formatDate(task.end_date) +
'<br><b>齐套率:</b> ' +
task.fitRates || 0
'<br><b>状态:</b> ' + task.status
'<br><b>问题状态:</b> ' + task.problemStatus
return html
} else {
const row = that.tooltipData[task.tooltipId]
html =
'<b>操作者:</b> ' +
(row && row.creator && row.creator.userName
? row.creator.userName
: '') +
'<br><b>检验员:</b> ' +
(row && row.testor && row.testor.userName
? row.testor.userName
: '') +
'<br><b>实际开始:</b> ' +
(row && row.actualStart ? row.actualStart : '') +
'<br><b>实际完成:</b> ' +
(row && row.actualEnd ? row.actualEnd : '') +
'<br><b>站位/装配单元:</b> ' +
task.text +
'<br><b>工期:</b> ' +
task.constPeriod +
'天' +
'<br/><b>计划开工时间:</b> ' +
that.formatDate(task.start_date) +
'<br/><b>计划完工时间:</b> ' +
that.formatDate(task.end_date) +
'<br><b>齐套率:</b> ' +
task.fitRates || 0
'<br><b>状态:</b> ' + task.status
'<br><b>问题状态:</b> ' + task.problemStatus
return html
// }
// return html
}
}
ganttStm.config.scroll_on_click = true
ganttStm.templates.link_class = function(link) {
if (link.isCritical) {
return 'critical_path'
}
}
ganttStm.templates.rightside_text = function(start, end, task) {
return '<b></b>' + (task.right_text || ' ')
}
ganttStm.templates.progress_text = function(start, end, task) {
return (
"<span style='text-align:left;'>" +
Math.round(task.progress * 100) +
'% </span>'
)
}
ganttStm.templates.timeline_cell_class = function(task, date) {
var isWorkTime =
new Date(date).getDay() === 0 || new Date(date).getDay() === 6
if (isWorkTime) {
return 'week_end'
}
return ''
}
ganttStm.templates.task_class = function(st, end, item) {
if (item.$level === 0) {
return 'level' + item.status || ''
} else {
return item.status || ''
}
}
ganttStm.attachEvent('onLinkDblClick', function(id, e) {
return false
})
ganttStm.attachEvent('onAfterTaskUpdate', function(id, item) {
var data = {
id: item.tooltipId,
scheduledStart: that.formatDate(item.start_date)
}
that.updatePlanTime(data)
})
// 当分支被打开时触发
ganttStm.attachEvent('onTaskOpened', function(id) {
that.openTree.push(Number(id))
})
// 当分支关闭时触发
ganttStm.attachEvent('onTaskClosed', function(id) {
var arr = that.openTree
arr.splice(
arr.findIndex((item) => item === Number(id)),
1
)
})
ganttStm.attachEvent('onTaskClick', function(id, e) {
if (e.target.classList[0] === 'seepdf') {
that.seePdf(id)
}
return true
})
// ganttStm.attachEvent('onBeforeTaskDrag', function(id, new_item) {
// // eslint-disable-next-line eqeqeq
// var links = ganttStm.getTableData().data.links.filter(p => p.target == id)
// links.forEach(p => {
// that.ganttStm.getLink(p.id).lag = 0
// that.ganttStm.refreshLink(p.id)
// })
// // 设置链接可修改
// return true
// })
// ganttStm.attachEvent('onAfterAutoSchedule', function(id, item) {
// that.diffLinks()
// })
ganttStm.config.columns = [
{
name: 'id',
label: '节点',
width: 80,
align: 'left',
resize: true,
template: function(task) {
return (
"<span class='gantt_grid_wbs'>" +
(ganttStm.getWBSCode(task) || '') +
'</span>'
)
}
},
{
name: 'fitRates',
label: '齐套率',
align: 'center',
width: 60,
resize: true
},
{
name: 'status',
label: '状态',
align: 'center',
width: 80,
resize: true,
template: function(task) {
if (task.$level === 0) {
const state = that.stateOptions.find(r => r.value === task.status)
return (
"<div class='ca color " +
task.status +
"'>" +
(state && state.label || task.status) +
'</div>'
)
} else {
const state = that.stateOptions.find(r => r.value === task.status)
return (
"<div class='ao " +
task.status +
"'>" +
(state && state.label || task.status) +
'</div>'
)
}
}
},
{
name: 'problemStatus',
label: '问题状态',
align: 'center',
width: 80,
resize: true
},
{
name: 'text',
label: '装配单元/AO号',
align: 'left',
width: 200,
tree: true,
resize: true,
template: function(obj) {
if (obj.$level === 1) {
return (
"<div class='seepdf'>" +
obj.text +
'</div>'
)
}
return obj.text
}
},
{
name: 'constPeriod',
label: '工期(时)',
align: 'center',
width: 60,
resize: true
},
{
name: 'start_date',
label: '计划开工时间',
align: 'center',
width: 120,
resize: true,
template: function(obj) {
return that.formatDate(obj.start_date)
}
},
{
name: 'end_date',
label: '计划完工时间',
align: 'center',
width: 120,
resize: true,
template: function(obj) {
return that.formatDate(obj.end_date)
}
},
{
name: 'predecessors',
label: '前置节点',
width: 100,
align: 'center',
resize: true,
template: function(task) {
var links = task.$target
var labels = []
for (var i = 0; i < links.length; i++) {
var link = ganttStm.getLink(links[i])
var label = ganttStm.getWBSCode(ganttStm.getTask(link.source))
labels.push(label)
}
return (
"<span class='gantt_grid_predecessors'>" +
labels.join(', ') +
'</span>'
)
}
}
]
ganttStm.config.date_format = '%Y-%m-%d %H:%i:%s'
ganttStm.config.duration_unit = 'minute'
ganttStm.config.scale_height = 70
ganttStm.config.min_column_width = 60
ganttStm.config.drag_progress = false
ganttStm.config.drag_resize = false
ganttStm.config.drag_links = false
ganttStm.config.details_on_dblclick = false
ganttStm.config.show_task_cells = true
// ganttStm.config.auto_scheduling = true
// ganttStm.config.auto_scheduling_initial = false
ganttStm.config.open_split_tasks = true
ganttStm.config.autoscroll = true
this.$nextTick(() => {
ganttStm.ext.zoom.init(zoomConfig)
ganttStm.init(this.$refs[this.onlyUuid])
})
},
/**
* 获取甘特提示数据
*/
async getTooltip(id) {
},
getData() {
const params = {
positionNumber: this.form.positionNumber,
sorties: this.form.sortiesName,
serialNumber: this.form.AOName || ''
}
if (this.form.state) {
params.state = this.form.state
}
if (this.form.searchTime && this.form.searchTime.length === 2) {
params.scheduledStart = this.form.searchTime[0]
params.scheduledEnd = this.form.searchTime[1]
}
this.gantt.clearAll()
this.loading = true
post(`/ExtProcessPlan/processPlanSearch`, params).then(res => {
if (res.items) {
this.refrehGantt(res.items)
}
}).finally(() => {
this.loading = false
})
},
refrehGantt(data) {
if (!data.length) {
return
}
const params = {
links: [],
data: []
}
data.forEach(p => {
this.addwrProduction(p, params)
})
this.$nextTick(() => {
this.gantt.parse(params)
this.start_date = this.getLongTime()
})
},
toWrProduction(p) {
return {
type: 'project',
id: p.id,
start_date: p.wrProduction[0].scheduledStart,
text: p.serialNumber,
right_text: p.name,
isLeaf: true,
materNo: p.materNo,
status: p.wrProduction[0].planState,
// 齐套率
fitRates: Math.round((p.fitRates || 0) * 1000) / 10 + '%',
// 问题状态
problemStatus: p.problemStatus,
progress:
Math.round((p.wrProduction[0].percentage || 0) * 10) / 1000,
wrStateCode: p.wrProduction[0].planState,
airModelId: p.wrProduction[0].aircraftTypeId,
sortiesId: p.wrProduction[0].aircraftSortiesId,
constPeriod: Number(p.wrProduction[0].costHours) || 0,
open: this.openTree.includes(p.id),
duration:
(new Date(p.wrProduction[0].scheduledEnd) -
new Date(p.wrProduction[0].scheduledStart)) /
1000 /
60
}
},
addwrProduction(p, params) {
if (p.wrProduction && p.wrProduction[0]) {
params.data.push(this.toWrProduction(p))
}
},
/**
* 获取最大的结束时间
*/
getLongTime() {
const data = this.gantt.getTableData().data.data
if (!data.length) return ''
let longTime = data[0].start_date
data.forEach((p) => {
if (new Date(p.start_date) < new Date(longTime)) {
longTime = p.start_date
}
})
var time =
new Date(longTime).toLocaleDateString().split('/').join('-') +
' ' +
new Date(longTime).toTimeString().split(' ')[0]
return time
},
exportGantt(mode) {
var dd = this.ganttStm.getTableData()
const that = this
const tableData = dd.data.data.map((p) => {
return {
_1: Object.values(p)
.filter((item) =>
(item + 'aaa').toString().includes('gantt_grid_wbs')
)[0]
.replace("<span class='gantt_grid_wbs'>", '')
.replace('</span>', ''),
fitRates: p.fitRates,
status: (function() {
if (p.isLeaf) {
return that.$parent.planStatusData.filter(
(t) => t.dictKey === p.status
)[0].dictValue
} else {
return that.$parent.joExecutePlanStateData.filter(
(t) => t.dictKey === p.status
)[0].dictValue
}
})(),
problemStatus: p.problemStatus,
text: p.text,
constPeriod: p.constPeriod,
start_date: that.formatDate(p.start_date),
end_date: that.formatDate(p.end_date),
predecessors: Object.values(p)
.filter((item) =>
(item + 'aaa').toString().includes('gantt_grid_predecessors')
)[0]
.replace("<span class='gantt_grid_predecessors'>", '')
.replace('</span>', '')
}
})
const header = [
'节点',
'齐套率',
'状态',
'问题状态',
'装配单元/AO号',
'工期(时)',
'计划开工时间',
'计划完工时间',
'前置节点'
]
CsvExportor.downloadCsv(tableData, { header }, '站位计划维护.csv')
},
formatDate(date) {
var text =
new Date(date).toLocaleDateString().split('/').join('-') +
' ' +
new Date(date).toTimeString().split(' ')[0]
return text
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="show-page-com stationPlan-maintenance-page">
<searchBar :state-options="stateOptions" @showStation="showStation" @search="search" />
<station v-show="headerShow" :state-options="stateOptions" :sorties-id="sortiesId" :form="form" @change="change" />
<gantt :form="form" :state-options="stateOptions" :class="[headerShow?'gantt-bar':'gantt-bar no-header']" />
</div>
</template>
<script>
import searchBar from './searchBar.vue'
import station from './station.vue'
import gantt from './gantt.vue'
export default {
name: 'StationPlanMaintenance',
components: { searchBar, station, gantt },
data() {
return {
sortiesId: '',
positionNumber: '',
form: {},
stateOptions: [],
headerShow: true
}
},
mounted() {
this.getStateOptions()
},
methods: {
getStateOptions() {
this.$utils.getDicListByCode('PlanState').then(res => {
this.stateOptions = res
})
},
search(form) {
this.form = { ...form }
this.form.positionNumber = this.positionNumber
this.sortiesId = form.sorties
},
change(positionNumber) {
this.positionNumber = positionNumber
this.form.positionNumber = this.positionNumber
},
showStation(flag) {
this.headerShow = flag
}
}
}
</script>
<style lang="scss">
.stationPlan-maintenance-page{
margin: 4px;
margin-top: 0px;
padding: 8px;
height: calc(100% - 20px);
width: calc(100% - 24px);
background-color: #fff;
.color{
&.Not{
background-color: #cccccc;
}
&.Yes{
background-color: #59c4e6;
}
&.Delivery{
background-color: #e87c25;
}
&.Run{
background-color: #fcce10;
}
&.Finish{
background-color: #97b552;
}
&.Paused{
background-color: #8a7ca8;
}
&.Reserved{
background-color: #c1232b;
}
&.Issued{
background-color: #bd0b9f;
}
&.TF_ZF{
background-color: #666;
}
}
.gantt-bar{
height: calc(100% - 208px);
.gantt{
height: 100%;
}
&.no-header{
height: calc(100% - 50px);
}
}
.search-bar{
height: 40px;
.legnd {
display: flex;
> div {
align-items: center;
margin-left: 8px;
display: flex;
cursor: pointer;
flex-direction: column;
> div:first-child {
line-height: 20px;
i {
display: inline-block;
width: 11px;
height: 11px;
margin-right: 6px;
&:hover {
opacity: 0.7;
}
}
span {
display: inline-block;
font-size: 10px;
line-height: 20px;
}
}
div:last-child {
font-size: 10px;
width: 100%;
line-height: 20px;
text-align: center;
}
}
}
}
.station-bar{
.load{
text-align: center;
line-height: 50px;
}
>.top{
display: flex;
margin-bottom: 15px;
> div {
// height: 160px;
flex: 1;
position: relative;
border: 1px solid #ccc;
border-radius: 5px;
max-width: 15.6%;
box-shadow: 1px 1px 5px 5px #eaeaea;
box-sizing: border-box;
&:not(:last-child) {
margin-right: 16px;
}
cursor: pointer;
&:hover {
transform: scale(1.05);
transition: 0.2s linear all;
box-shadow: 1px 1px 5px 5px #d8efff;
> div:first-child {
background-color: green;
}
}
&.cur {
box-shadow: 1px 1px 5px 5px #d8efff;
border: 1px solid #bffaff;
> div:first-child {
background-color: green;
}
}
> div:first-child {
position: absolute;
right: 0;
background-color: #ccc;
padding: 6px 10px;
color: #fff;
max-width: 50%;
min-width: 54px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
font-weight: bold;
font-size: 14px;
}
> div:nth-child(2) {
margin-top: 30px;
height: 100px;
background: url("/icons/stand.png") no-repeat center center;
}
> div:last-child {
height: 26px;
line-height: 26px;
text-align: center;
font-size: 12px;
box-shadow: 1px -4px 5px -2px #eaeaea;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&.state0 {
background-color: #92d050;
}
&.state1 {
background-color: #f2f79e;
}
&.state2 {
background-color: #f9df73;
}
&.state3 {
background-color: #f4b2a6;
}
}
}
}
}
}
</style>
<template>
<el-form :inline="true" :model="form" class="demo-form-inline search-bar">
<el-form-item label="">
<span style="cursor:pointer;" @click="headerOpen">
<i v-if="headerShow" class="el-icon-caret-top" title="收缩站位" />
<i v-else class="el-icon-caret-bottom" title="展开" />
</span>
</el-form-item>
<el-form-item label="机型:">
<el-select v-model="form.model" :style="{'width':'90px'}" size="mini" placeholder="机型">
<el-option
v-for="item in modelData"
:key="item.id"
:label="item.defName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="架次:">
<el-select v-model="form.sorties" :style="{'width':'80px'}" size="mini" placeholder="架次">
<el-option
v-for="item in sortiesData"
:key="item.id"
:label="item.defName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="筛选:">
<el-input v-model="form.AOName" size="mini" :style="{'width':'140px'}" placeholder="请输入AO名称" />
</el-form-item>
<el-form-item label="时间:">
<el-date-picker
v-model="form.searchTime"
type="daterange"
:style="{'width':'170px'}"
size="mini"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
/>
</el-form-item>
<el-form-item>
<el-button type="" size="mini" @click="goto">站位计划调整</el-button>
</el-form-item>
<el-form-item
style="width: calc(100% - 850px);
text-align: right;"
>
<div class="legnd">
<div
v-for="item in stateOptions"
:key="item.id"
@click="colorGetGantt(item.value)"
>
<div>
<i class="color" :class="item.value" />
<span :class="{ curtatus: item.value === curColorStatus}">{{
item.label
}}</span>
</div>
<div>{{ item.count || 0 }}</div>
</div>
</div>
</el-form-item>
</el-form>
</template>
<script>
export default {
name: 'TfMomWebSearchBar',
props: {
stateOptions: {
type: Array,
default: () => []
}
},
data() {
return {
headerShow: true,
modelData: [],
sortiesData: [],
curColorStatus: '',
timeoutId: null,
form: {}
}
},
watch: {
'form.model': {
immediate: true,
handler(val) {
if (!val) {
return
}
this.$set(this.form, 'sorties', '')
this.getSortiesList()
}
},
'form.sorties': {
immediate: true,
handler(val) {
const sorties = this.sortiesData.find(r => r.id === val)
this.$set(this.form, 'positionNumber', '')
this.$set(this.form, 'sortiesName', sorties && sorties.defName || '')
this.search()
}
},
'form.AOName': {
immediate: true,
handler(val) {
this.search()
}
},
'form.searchTime': {
immediate: true,
handler() {
this.search()
}
}
},
created() {
this.getModelData()
},
mounted() {
},
methods: {
getSortiesList() {
this.sortiesData = []
const params = { 'searchItems': { 'items': [{ 'fieldName': 'id', 'operator': 'NEQ', 'value': 0 }] }, 'sortItem': [{ 'fieldName': 'modifyTime', 'sortOrder': 'asc' }] }
this.$api.searchApi('AircraftSorties', params).then(res => {
if (res.items && res.items.content) {
this.sortiesData = res.items.content
this.$set(this.form, 'sorties', this.sortiesData[0].id)
}
})
},
getModelData() {
this.modelData = []
const params = { 'searchItems': { 'items': [{ 'fieldName': 'id', 'operator': 'NEQ', 'value': 0 }] }, 'sortItem': [{ 'fieldName': 'modifyTime', 'sortOrder': 'asc' }] }
this.$api.searchApi('AircraftType', params).then(res => {
if (res.items && res.items.content) {
this.modelData = res.items.content
this.$set(this.form, 'model', this.modelData[0].id)
}
})
},
colorGetGantt(state) {
if (this.curColorStatus === state) {
this.curColorStatus = ''
} else {
this.curColorStatus = state
}
this.form.state = this.curColorStatus
this.search()
},
headerOpen() {
this.headerShow = !this.headerShow
this.$emit('showStation', this.headerShow)
},
search() {
this.timeoutId && clearTimeout(this.timeoutId)
this.timeoutId = setTimeout(() => {
this.$emit('search', { ...this.form })
}, 500)
},
goto() {
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="station-bar">
<div v-if="postionList.length" class="top">
<div
v-for="item in postionList"
:key="item.id"
:class="{ cur: item.id === platformId }"
@click="triggerGetGantt(item.id,item.serialNumber)"
>
<div :title="item.serialNumber">
{{ item.serialNumber }}
</div>
<div />
<div :class="item | colorFilter">
{{
"计划总数:" +
item.carryCount +
",完成数:" +
item.completeCount
}}
完成率:
{{ item | proportionFilter }}
</div>
</div>
</div>
<div v-else class="load">
<div v-show="standLoading" class="load">
<i class="el-icon-loading" />
<span>数据加载中···</span>
</div>
<div v-show="!standLoading">
<span>暂无数据</span>
</div>
</div>
</div>
</template>
<script>
import { post } from '@/utils/http'
export default {
name: 'Station',
filters: {
proportionFilter: function(row) {
var num = 0
if (row.completeCount && row.carryCount) {
return (
Math.round((row.completeCount / row.carryCount) * 1000) / 10 + '%'
)
}
return num + '%'
},
colorFilter: function(row) {
var num = 3
if (row.completeCount && row.carryCount) {
var val = row.completeCount / row.carryCount
if (val < 0.5) {
num = 3
} else if (val < 0.8) {
num = 2
} else if (val < 1) {
num = 1
} else {
num = 0
}
}
return 'state' + num
}
},
props: {
sortiesId: {
type: [Number, String],
default: () => ''
},
form: {
type: Object,
default: () => {}
}
},
data() {
return {
postionList: [],
platformId: '',
standLoading: false
}
},
watch: {
sortiesId: {
immediate: true,
handler(val) {
if (!val) {
return
}
this.getStation()
}
}
},
mounted() {
},
methods: {
getStation() {
const params = {
'searchItems': { 'items': [{ 'fieldName': 'aircraftSortiesId', 'operator': 'EQ', 'value': this.sortiesId }] },
'openProps': [{ name: 'aircraftSorties' }],
'sortItem': [{ 'fieldName': 'serialNumber', 'sortOrder': 'asc' }]
}
this.standLoading = true
post('ExtPosition/positionSearch', params).then(res => {
if (res.items) {
this.postionList = res.items
this.triggerGetGantt(this.postionList[0].id, this.postionList[0].serialNumber)
} else {
this.postionList = []
}
this.standLoading = false
}).catch(() => {
this.postionList = []
this.standLoading = false
})
},
triggerGetGantt(id, name) {
this.platformId = id
this.$emit('change', name)
}
}
}
</script>
<style lang="scss" scoped>
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment