Browse Source

tracking

master
han\hanst 2 weeks ago
parent
commit
27cafb218f
  1. 1
      src/api/sampleTracking/sampleTracking.js
  2. 4
      src/views/modules/sampleTracking/projectInfoTracking.vue
  3. 2
      src/views/modules/sampleTracking/projectPartTracking.vue
  4. 307
      src/views/modules/sampleTracking/projectProofTracking.vue

1
src/api/sampleTracking/sampleTracking.js

@ -15,5 +15,6 @@ export const oneKeyCreateProofTracking = data => createAPI('/sampleTracking/proo
export const createProofTrackingRecord = data => createAPI('/sampleTracking/proofTracking/createProofRecord', 'POST', data)
export const batchUpdateProofTrackingPlan = data => createAPI('/sampleTracking/proofTracking/batchUpdatePlan', 'POST', data)
export const updateProofTrackingProcess = data => createAPI('/sampleTracking/proofTracking/updateProcess', 'POST', data)
export const updateProofTrackingComments = data => createAPI('/sampleTracking/proofTracking/updateComments', 'POST', data)
export const finishProofTracking = data => createAPI('/sampleTracking/proofTracking/finishProofing', 'POST', data)
export const queryProofTrackingProcessHistory = data => createAPI('/sampleTracking/proofTracking/processHistory', 'POST', data)

4
src/views/modules/sampleTracking/projectInfoTracking.vue

@ -1430,7 +1430,7 @@ export default {
}
},
deletePartModal (row) {
this.$confirm('确定删除该项目物料?', '提示', {
this.$confirm('确定删除该项目物料?将同步删除该物料下的打样追踪记录。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
@ -1450,7 +1450,7 @@ export default {
}).catch(() => {})
},
deleteHandle (row) {
this.$confirm('确定删除该笔数据?', '提示', {
this.$confirm('确定删除该项目?将同步删除该项目下的项目物料及打样追踪记录。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'

2
src/views/modules/sampleTracking/projectPartTracking.vue

@ -1301,7 +1301,7 @@ export default {
})
},
deleteHandle (row) {
this.$confirm('确定删除该笔数据?', '提示', {
this.$confirm('确定删除该项目物料?将同步删除该物料下的打样追踪记录。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'

307
src/views/modules/sampleTracking/projectProofTracking.vue

@ -53,7 +53,7 @@
<el-table-column prop="projectNo" label="项目编码" width="100" show-overflow-tooltip />
<el-table-column prop="projectDesc" label="项目描述" width="120" show-overflow-tooltip />
<el-table-column prop="testPartNo" label="项目物料" width="100" show-overflow-tooltip />
<el-table-column prop="partDesc" label="物料描述" :fixed="batchEditMode ? 'left' : false" width="150" show-overflow-tooltip />
<el-table-column prop="partDesc" label="物料描述" :fixed="'left'" width="150" show-overflow-tooltip />
<!-- <el-table-column prop="customerNo" label="客户编码" width="110" show-overflow-tooltip />
<el-table-column prop="customerDesc" label="客户名称" width="130" show-overflow-tooltip />-->
<el-table-column prop="proofingNo" label="打样单号" width="100" show-overflow-tooltip />
@ -68,7 +68,7 @@
v-for="item in processColumns"
:key="item.code"
:label="item.label"
width="130"
width="120"
align="center"
header-align="center"
>
@ -77,29 +77,77 @@
<el-date-picker
v-if="batchEditMode"
v-model="scope.row[item.actualField]"
:disabled="isProcessComplete(scope.row, item)"
type="date"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
placeholder="实际完成日期"
style="width: 120px"
/>
<el-tooltip
<div
v-else
:content="getProcessTooltip(scope.row, item)"
popper-class="process-date-tooltip"
effect="dark"
placement="top"
class="process-content"
@mouseenter="loadProcessHistory(scope.row, item, false)"
>
<div class="process-content" @mouseenter="loadProcessHistory(scope.row, item)" @click="openProcessDialog(scope.row, item)">
<a class="link-date">{{ formatDate(scope.row[item.actualField]) || '-' }}</a>
</div>
</el-tooltip>
<el-tooltip
effect="dark"
:content="getProcessTooltip(scope.row, item)"
popper-class="process-date-tooltip"
placement="top"
:open-delay="180"
:disabled="!hasProcessHistory(scope.row, item)"
>
<el-date-picker
v-model="scope.row[item.actualField]"
type="date"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
placeholder="请选择"
style="width: 122px"
@change="handleProcessDateChange(scope.row, item, $event)"
/>
</el-tooltip>
<el-button
class="process-complete-btn"
type="success"
size="mini"
plain v-show="!isProcessComplete(scope.row, item)"
:disabled="isProcessComplete(scope.row, item)"
@click.stop="markProcessComplete(scope.row, item)"
></el-button>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="comments" label="Comments" width="160" show-overflow-tooltip />
<el-table-column label="Comments" width="220">
<template slot-scope="scope">
<div class="comments-cell" @dblclick.stop="startCommentsEdit(scope.row)">
<template v-if="isCommentsEditing(scope.row)">
<el-input
v-model="commentsDraft"
v-focus-comments-input="isCommentsEditing(scope.row)"
:ref="'commentsInput_' + scope.row.trackingId"
:id="'commentsInput_' + scope.row.trackingId"
class="comments-edit-input"
size="mini"
clearable
placeholder="请输入,回车也可保存"
@keydown.enter.native.prevent="saveCommentsEdit(scope.row)"
@keyup.esc.native="cancelCommentsEdit"
/>
<el-button
class="comments-save-btn"
type="success"
size="mini"
plain
:loading="commentsSaveLoading"
@click.stop="saveCommentsEdit(scope.row)"
></el-button>
</template>
<span v-else class="comments-text" :title="scope.row.comments || ''">{{ scope.row.comments || '-' }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="150" align="center">
<template slot-scope="scope">
<a @click="openCreateProofDialog(scope.row)">新增打样</a>
@ -666,6 +714,7 @@ import {
oneKeyCreateProofTracking,
queryProofTrackingProcessHistory,
searchProofTracking,
updateProofTrackingComments,
updateProofTrackingProcess
} from '@/api/sampleTracking/sampleTracking'
import { getCustomerNo, saveNewCustomer } from '@/api/eam/eamProject.js'
@ -684,8 +733,46 @@ import {
import { queryCustomerList } from '@/api/customer/customer'
import Chooselist from '@/views/modules/common/Chooselist_eam'
function focusCommentsNativeInput (el, vnode) {
const doFocus = () => {
const componentInput = vnode && vnode.componentInstance && vnode.componentInstance.$refs
? vnode.componentInstance.$refs.input
: null
const inputEl = componentInput || (el && el.querySelector ? el.querySelector('input') : null)
if (!inputEl || typeof inputEl.focus !== 'function') {
return false
}
inputEl.focus()
const textLength = inputEl.value ? String(inputEl.value).length : 0
if (typeof inputEl.setSelectionRange === 'function') {
inputEl.setSelectionRange(textLength, textLength)
}
return true
}
if (doFocus()) {
return
}
setTimeout(doFocus, 0)
setTimeout(doFocus, 50)
setTimeout(doFocus, 100)
}
export default {
name: 'ProjectProofTracking',
directives: {
focusCommentsInput: {
inserted (el, binding, vnode) {
if (binding.value) {
focusCommentsNativeInput(el, vnode)
}
},
componentUpdated (el, binding, vnode) {
if (binding.value && !binding.oldValue) {
focusCommentsNativeInput(el, vnode)
}
}
}
},
components: {
Chooselist
},
@ -780,6 +867,9 @@ export default {
batchEditMode: false,
processHistoryMap: {},
processHistoryRows: [],
commentsEditingTrackingId: null,
commentsDraft: '',
commentsSaveLoading: false,
oneKeyDialogVisible: false,
saveOneKeyLoading: false,
@ -1116,6 +1206,12 @@ export default {
if (data && data.code === 0) {
this.dataList = (data.page && data.page.list) || []
this.totalPage = (data.page && data.page.totalCount) || 0
if (this.commentsEditingTrackingId) {
const hasEditingRow = this.dataList.some(item => item.trackingId === this.commentsEditingTrackingId)
if (!hasEditingRow) {
this.cancelCommentsEdit()
}
}
if (this.dataList.length > 0) {
this.currentRow = this.dataList[0]
}
@ -1142,6 +1238,55 @@ export default {
selectionChange (rows) {
this.selectionRows = rows || []
},
isCommentsEditing (row) {
return !!row && row.trackingId === this.commentsEditingTrackingId
},
startCommentsEdit (row) {
if (!row || !row.trackingId || this.commentsSaveLoading) {
return
}
this.commentsEditingTrackingId = row.trackingId
this.commentsDraft = row.comments || ''
},
cancelCommentsEdit () {
if (this.commentsSaveLoading) {
return
}
this.commentsEditingTrackingId = null
this.commentsDraft = ''
},
saveCommentsEdit (row) {
if (this.commentsSaveLoading) {
return
}
if (!row || !row.trackingId) {
this.$message.warning('跟踪记录ID不能为空')
return
}
const comments = this.commentsDraft == null ? '' : String(this.commentsDraft)
if (comments === (row.comments || '')) {
this.cancelCommentsEdit()
return
}
this.commentsSaveLoading = true
updateProofTrackingComments({
trackingId: row.trackingId,
comments: comments,
updateBy: this.$store.state.user.name
}).then(({ data }) => {
this.commentsSaveLoading = false
if (data && data.code === 0) {
row.comments = comments
this.$message.success('Comments保存成功')
this.cancelCommentsEdit()
} else {
this.$message.error(data.msg || 'Comments保存失败')
}
}).catch(() => {
this.commentsSaveLoading = false
this.$message.error('Comments保存异常')
})
},
rowClick (row) {
this.currentRow = row
},
@ -1403,6 +1548,68 @@ export default {
this.$message.error('批量修改异常')
})
},
handleProcessDateChange (row, processCol, dateVal) {
if (!row || !processCol) {
return
}
const actualDate = this.formatDate(dateVal)
this.updateProcessFromTable(row, processCol, {
status: '已完成',
actualDate: actualDate,
remark: '表格直接选择日期'
}, true)
},
markProcessComplete (row, processCol) {
if (!row || !processCol || this.isProcessComplete(row, processCol)) {
return
}
const today = this.formatDate(new Date())
this.updateProcessFromTable(row, processCol, {
status: '已完成',
actualDate: today,
remark: '表格一键完成'
}, false, '工序已标记为完成')
},
updateProcessFromTable (row, processCol, processData, silentSuccess, successMsg) {
if (!row || !processCol || !row.trackingId) {
this.$message.error('工序参数缺失')
return
}
const status = processData && processData.status ? String(processData.status).trim() : ''
if (!status) {
this.$message.error('工序状态不能为空')
return
}
const actualDate = processData && processData.actualDate ? this.formatDate(processData.actualDate) : ''
const inData = {
trackingId: row.trackingId,
processCode: processCol.code,
processName: processCol.label,
status: status,
actualDate: actualDate || null,
remark: processData && processData.remark ? processData.remark : '',
updateBy: this.$store.state.user.name
}
updateProofTrackingProcess(inData).then(({ data }) => {
if (data && data.code === 0) {
row[processCol.statusField] = status
row[processCol.actualField] = actualDate
const cacheKey = `${row.trackingId}_${processCol.code}`
if (this.processHistoryMap[cacheKey]) {
this.$delete(this.processHistoryMap, cacheKey)
}
if (!silentSuccess) {
this.$message.success(successMsg || '工序更新成功')
}
} else {
this.$message.error(data.msg || '工序更新失败')
this.getDataList()
}
}).catch(() => {
this.$message.error('工序更新异常')
this.getDataList()
})
},
openProcessDialog (row, processCol) {
if (!row || !processCol) {
return
@ -1488,34 +1695,57 @@ export default {
this.$message.error('打样完成异常')
})
},
getProcessCacheKey (row, processCol) {
if (!row || !processCol || !row.trackingId) {
return ''
}
return `${row.trackingId}_${processCol.code}`
},
loadProcessHistory (row, processCol, refreshDialog) {
if (!row || !row.trackingId) {
return
return Promise.resolve([])
}
const cacheKey = `${row.trackingId}_${processCol.code}`
if (this.processHistoryMap[cacheKey] && this.processHistoryMap[cacheKey].length > 0) {
const cacheKey = this.getProcessCacheKey(row, processCol)
if (Object.prototype.hasOwnProperty.call(this.processHistoryMap, cacheKey)) {
const cachedRows = this.processHistoryMap[cacheKey] || []
if (refreshDialog) {
this.processHistoryRows = this.processHistoryMap[cacheKey]
this.processHistoryRows = cachedRows
}
return
return Promise.resolve(cachedRows)
}
queryProofTrackingProcessHistory({
return queryProofTrackingProcessHistory({
trackingId: row.trackingId,
processCode: processCol.code
}).then(({ data }) => {
let rows = []
if (data && data.code === 0) {
const rows = data.rows || []
rows = data.rows || []
// Vue2 key 使 $set tooltip
this.$set(this.processHistoryMap, cacheKey, rows)
if (refreshDialog) {
this.processHistoryRows = rows
}
}
return rows
}).catch(() => {
if (refreshDialog) {
this.processHistoryRows = []
}
this.$set(this.processHistoryMap, cacheKey, [])
return []
})
},
hasProcessHistory (row, processCol) {
if (!row || !processCol || !row.trackingId) {
return false
}
const cacheKey = `${row.trackingId}_${processCol.code}`
const rows = this.processHistoryMap[cacheKey] || []
return rows.length > 0
},
getProcessTooltip (row, processCol) {
if (!row || !processCol) {
return '-'
return ''
}
const cacheKey = row.trackingId ? `${row.trackingId}_${processCol.code}` : ''
const rows = this.processHistoryMap[cacheKey] || []
@ -1539,7 +1769,7 @@ export default {
})
if (dateList.length === 0) {
return '-'
return ''
}
return dateList.join('\n')
},
@ -1670,11 +1900,42 @@ export default {
}
.process-content {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
text-align: center;
line-height: 18px;
}
.process-complete-btn {
padding: 4px 8px;
min-width: 12px;
}
.comments-cell {
display: flex;
align-items: center;
gap: 4px;
min-height: 26px;
}
.comments-edit-input {
flex: 1;
}
.comments-save-btn {
padding: 4px 7px;
min-width: 28px;
}
.comments-text {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.process-date-tooltip {
white-space: pre-line;
}

Loading…
Cancel
Save