完善生产异常维修与备件管理功能
This commit is contained in:
@@ -66,7 +66,7 @@
|
||||
</main>
|
||||
|
||||
<aside class="side-column">
|
||||
<section class="panel operator-panel"><h2>提报信息</h2><div><span>提报人</span><strong>{{ currentUser.name || '-' }}</strong></div><div><span>工号</span><strong>{{ currentUser.code || '-' }}</strong></div><div><span>提交时间</span><strong>{{ nowText }}</strong></div></section>
|
||||
<section class="panel operator-panel"><h2>提报信息</h2><div><span>用户编码</span><el-input v-model="userCode" size="small" clearable placeholder="请输入用户编码" @blur="checkUserCode" @keyup.enter="checkUserCode" /></div><div><span>提报人</span><strong>{{ userName || '-' }}</strong></div><div><span>提交时间</span><strong>{{ nowText }}</strong></div><p v-if="userCodeError" class="field-error">{{ userCodeError }}</p></section>
|
||||
<section class="panel"><div class="side-title"><h2>最近异常</h2><span>现场回看</span></div><el-empty v-if="!recentExceptions.length" description="暂无异常记录" :image-size="70" /><div v-for="item in recentExceptions" :key="item.id" class="recent-item"><div><strong>{{ item.order_no || '-' }}</strong><p>{{ item.type_name || '-' }} · {{ [item.reason_name, item.issue_name].filter(Boolean).join(' · ') }}</p></div><el-tag :type="item.status === 2 ? 'success' : item.status === 1 ? 'warning' : 'danger'">{{ item.status_name || '待处理' }}</el-tag></div></section>
|
||||
</aside>
|
||||
</div>
|
||||
@@ -79,10 +79,13 @@ import { ElMessage } from 'element-plus'
|
||||
import type { UploadUserFile } from 'element-plus'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useMemberStore } from '~/stores/member'
|
||||
import { checkExceptionOrder, getExceptionSettings, getExceptionStatistics, getRecentExceptions, submitExceptionRecord, uploadProduceImage, type ProduceExceptionRecord, type ProduceExceptionSetting } from '~/apps/produce/api/exception'
|
||||
import { checkExceptionOrder, checkMemberUser, getExceptionSettings, getExceptionStatistics, getRecentExceptions, submitExceptionRecord, uploadProduceImage, type ProduceExceptionRecord, type ProduceExceptionSetting } from '~/apps/produce/api/exception'
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
const currentUser = computed(() => ({ name: String(memberStore.info?.nickname || memberStore.info?.real_name || memberStore.info?.username || ''), code: String(memberStore.info?.username || memberStore.info?.user_code || '') }))
|
||||
const userCode = ref('')
|
||||
const userName = ref('')
|
||||
const userCodeError = ref('')
|
||||
const form = ref({ orderNo: '', type: '', reason: '', issue: '', remark: '' })
|
||||
const settings = ref<ProduceExceptionSetting[]>([])
|
||||
const recentExceptions = ref<ProduceExceptionRecord[]>([])
|
||||
@@ -109,6 +112,11 @@ const loadData = async () => {
|
||||
if (!form.value.type) selectType(typeOptions.value[0]?.value || '')
|
||||
} catch { /* 请求层已提示错误 */ }
|
||||
}
|
||||
const checkUserCode = async () => {
|
||||
const value = userCode.value.trim()
|
||||
if (!value) { userCodeError.value = '请输入用户编码'; userName.value = ''; return false }
|
||||
try { const result = await checkMemberUser(value); userName.value = result?.nickname || result?.username || ''; userCodeError.value = ''; return true } catch (error: any) { userCodeError.value = error?.message || '用户编码不存在'; userName.value = ''; return false }
|
||||
}
|
||||
const selectType = (value: string) => { form.value.type = value; form.value.reason = activeReasons.value[0]?.value || ''; form.value.issue = activeIssues.value[0]?.value || '' }
|
||||
const selectReason = (value: string) => { form.value.reason = value; form.value.issue = activeIssues.value[0]?.value || '' }
|
||||
const checkOrder = async () => {
|
||||
@@ -122,17 +130,17 @@ const resetForm = () => { form.value = { orderNo: '', type: typeOptions.value[0]
|
||||
const submit = async () => {
|
||||
if (!orderValid.value || !form.value.orderNo.trim()) { await checkOrder(); if (!orderValid.value) return }
|
||||
if (!form.value.type || !form.value.reason || (activeIssues.value.length && !form.value.issue)) { ElMessage.warning('请选择处理类型、异常原因和具体问题'); return }
|
||||
if (!currentUser.value.code) { ElMessage.warning('请先登录后再提报异常'); return }
|
||||
if (!await checkUserCode()) { ElMessage.warning(userCodeError.value); return }
|
||||
submitting.value = true
|
||||
try {
|
||||
const images: string[] = []
|
||||
for (const file of imageFiles.value) if (file.raw) { const url = await uploadProduceImage(file.raw, 'exception'); if (url) images.push(url) }
|
||||
const response = await submitExceptionRecord({ order_no: form.value.orderNo.trim(), user_code: currentUser.value.code, type_id: form.value.type, reason_id: form.value.reason, issue_id: form.value.issue || '', images, remark: form.value.remark.trim() })
|
||||
const response = await submitExceptionRecord({ order_no: form.value.orderNo.trim(), user_code: userCode.value.trim(), type_id: form.value.type, reason_id: form.value.reason, issue_id: form.value.issue || '', images, remark: form.value.remark.trim() })
|
||||
if (response?.code !== 0) { ElMessage.error(response?.msg || '异常提交失败'); return }
|
||||
ElMessage.success('异常已提交'); resetForm(); await loadData()
|
||||
} finally { submitting.value = false }
|
||||
}
|
||||
onMounted(() => { updateNow(); void loadData() })
|
||||
onMounted(() => { updateNow(); userCode.value = currentUser.value.code; userName.value = currentUser.value.name; void loadData() })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -147,4 +155,10 @@ onMounted(() => { updateNow(); void loadData() })
|
||||
.inline-form { display:flex; gap:12px; margin-top:20px; } .inline-form .el-input { flex:1; } .validation { margin-top:10px; font-size:13px; } .validation.success { color:#26b36c; } .validation.error { color:#ef625f; } .option-grid { display:grid; gap:12px; margin-top:18px; } .type-grid { grid-template-columns:repeat(2,1fr); } button { font:inherit; cursor:pointer; } .choice-card,.reason-card { border:1px solid #e6edf5; border-radius:14px; background:#f8fafc; text-align:left; transition:.2s; } .choice-card { padding:16px; } .choice-card strong,.choice-card small { display:block; } .choice-card strong { color:#2b3853; } .choice-card small { margin-top:8px; color:#9aa4b4; } .choice-card.active,.reason-card.active { border-color:#ff9a3c; background:#fff5ed; color:#e97020; } .sub-title { align-items:center; justify-content:space-between; margin-top:26px; } .sub-title span,.side-title span { color:#9aa4b4; font-size:12px; } .reason-grid { grid-template-columns:repeat(3,1fr); } .reason-card { min-height:46px; padding:8px; text-align:center; color:#56647a; } .issue-box { margin-top:18px; padding:16px; border-radius:14px; background:#fffaf5; } .issue-box .sub-title { margin:0 0 12px; } .full-width { width:100%; }
|
||||
:deep(.el-upload--picture-card),:deep(.el-upload-list__item) { width:92px; height:92px; } .upload-plus { font-size:30px; color:#ff9a3c; } .remark-input { margin-top:18px; } .form-actions { display:flex; justify-content:flex-end; gap:12px; } .operator-panel h2 { margin-bottom:18px; } .operator-panel div { display:flex; justify-content:space-between; padding:13px 0; border-bottom:1px solid #eef2f7; font-size:13px; } .operator-panel div:last-child { border-bottom:0; } .operator-panel span { color:#9aa4b4; } .side-title { align-items:center; justify-content:space-between; } .recent-item { display:flex; justify-content:space-between; gap:10px; padding:16px 0; border-bottom:1px solid #eef2f7; } .recent-item:last-child { border-bottom:0; } .recent-item strong { font-size:14px; } .recent-item p { margin:6px 0 0; color:#8a94a6; font-size:12px; }
|
||||
@media (max-width: 900px) { .produce-work-page { padding:16px; } .content-grid { grid-template-columns:1fr; } .side-column { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); } } @media (max-width: 640px) { .page-hero { padding:24px; align-items:flex-start; flex-direction:column; } .hero-user { align-self:stretch; text-align:left; } .summary-grid,.side-column { grid-template-columns:1fr; } .type-grid,.reason-grid { grid-template-columns:1fr; } .inline-form { flex-direction:column; } .form-actions { justify-content:stretch; } .form-actions .el-button { flex:1; } }
|
||||
.operator-panel > div:first-of-type { align-items: center; gap: 16px; }
|
||||
.operator-panel > div:first-of-type > span { flex: 0 0 72px; white-space: nowrap; }
|
||||
.operator-panel > div:first-of-type :deep(.el-input) { flex: 1; min-width: 0; }
|
||||
.operator-panel > div:first-of-type :deep(.el-input__wrapper) { min-height: 40px; padding: 0 13px; border-radius: 9px; box-shadow: 0 0 0 1px #d8e2ef inset; }
|
||||
.operator-panel > div:first-of-type :deep(.el-input__inner) { font-size: 15px; font-weight: 600; }
|
||||
.operator-panel > div:not(:first-of-type) { min-height: 44px; align-items: center; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user