feat: update report detail and verification flow
This commit is contained in:
@@ -518,7 +518,7 @@ export const adminApi = {
|
||||
data,
|
||||
});
|
||||
},
|
||||
saveZhongjianAppraisalReport(data: { id: number; zhongjian_report_no: string; report_files: AdminFileAsset[]; qr_input: string }) {
|
||||
saveZhongjianAppraisalReport(data: Record<string, unknown>) {
|
||||
return request<{ id: number; report: Record<string, any> }>("/api/admin/appraisal-task/zhongjian-report/save", {
|
||||
method: "POST",
|
||||
data,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"name": "安心验作业端",
|
||||
"appid": "__UNI__E0C8390",
|
||||
"description": "安心验仓管与鉴定作业 Android App",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "101",
|
||||
"versionName": "1.0.1",
|
||||
"versionCode": "102",
|
||||
"transformPx": false,
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
|
||||
@@ -24,6 +24,12 @@ const valuationDesc = ref("");
|
||||
const externalRemark = ref("");
|
||||
const internalRemark = ref("");
|
||||
const zhongjianReportNo = ref("");
|
||||
const productName = ref("");
|
||||
const categoryName = ref("");
|
||||
const brandName = ref("");
|
||||
const color = ref("");
|
||||
const sizeSpec = ref("");
|
||||
const serialNo = ref("");
|
||||
const zhongjianFiles = ref<AdminFileAsset[]>([]);
|
||||
const evidenceFiles = ref<AdminFileAsset[]>([]);
|
||||
const activePreviewVideo = ref<AdminFileAsset | null>(null);
|
||||
@@ -86,6 +92,12 @@ function hydrate(detailData: AdminAppraisalTaskDetail) {
|
||||
externalRemark.value = detailData.result_info.external_remark || "";
|
||||
internalRemark.value = detailData.result_info.internal_remark || "";
|
||||
zhongjianReportNo.value = detailData.zhongjian_report?.report_no || "";
|
||||
productName.value = detailData.product_info.product_name || "";
|
||||
categoryName.value = detailData.product_info.category_name || "";
|
||||
brandName.value = detailData.product_info.brand_name || "";
|
||||
color.value = detailData.product_info.color || "";
|
||||
sizeSpec.value = detailData.product_info.size_spec || "";
|
||||
serialNo.value = detailData.product_info.serial_no || "";
|
||||
zhongjianFiles.value = [...(detailData.zhongjian_report?.files || [])];
|
||||
evidenceFiles.value = [...(detailData.result_info.attachments || [])];
|
||||
|
||||
@@ -553,6 +565,14 @@ async function submitZhongjianReport() {
|
||||
showInfoToast("请填写中检报告编号");
|
||||
return;
|
||||
}
|
||||
if (!resultText.value.trim()) {
|
||||
showInfoToast("请填写鉴定结论");
|
||||
return;
|
||||
}
|
||||
if (!productName.value.trim() && !categoryName.value.trim() && !brandName.value.trim()) {
|
||||
showInfoToast("请先完善物品信息");
|
||||
return;
|
||||
}
|
||||
if (!zhongjianFiles.value.length) {
|
||||
showInfoToast("请至少上传 1 个中检报告文件");
|
||||
return;
|
||||
@@ -568,6 +588,19 @@ async function submitZhongjianReport() {
|
||||
await adminApi.saveZhongjianAppraisalReport({
|
||||
id: detail.value.task_info.id,
|
||||
zhongjian_report_no: zhongjianReportNo.value.trim(),
|
||||
product_info: {
|
||||
category_id: detail.value.product_info.category_id,
|
||||
product_name: productName.value.trim(),
|
||||
category_name: categoryName.value.trim(),
|
||||
brand_name: brandName.value.trim(),
|
||||
color: color.value.trim(),
|
||||
size_spec: sizeSpec.value.trim(),
|
||||
serial_no: serialNo.value.trim(),
|
||||
},
|
||||
result_text: resultText.value.trim(),
|
||||
result_desc: resultDesc.value.trim(),
|
||||
attachments: evidenceFiles.value,
|
||||
key_points: templateKeyPointsPayload(),
|
||||
report_files: zhongjianFiles.value,
|
||||
qr_input: qrInput,
|
||||
});
|
||||
@@ -764,6 +797,77 @@ onShow(() => {
|
||||
<view v-else class="card">
|
||||
<view class="card-title">中检报告</view>
|
||||
<view class="stack" style="margin-top: 18rpx">
|
||||
<view class="card-desc">报告展示信息</view>
|
||||
<input v-model="productName" class="field" :disabled="isTaskReadonly" placeholder="产品名称" />
|
||||
<input v-model="categoryName" class="field" :disabled="isTaskReadonly" placeholder="品类" />
|
||||
<input v-model="brandName" class="field" :disabled="isTaskReadonly" placeholder="品牌" />
|
||||
<view class="meta-grid">
|
||||
<input v-model="color" class="field" :disabled="isTaskReadonly" placeholder="颜色" />
|
||||
<input v-model="sizeSpec" class="field" :disabled="isTaskReadonly" placeholder="规格 / 尺寸" />
|
||||
</view>
|
||||
<input v-model="serialNo" class="field" :disabled="isTaskReadonly" placeholder="序列号 / 编码" />
|
||||
<textarea v-model="resultText" class="textarea" :disabled="isTaskReadonly" placeholder="鉴定结论" />
|
||||
<textarea v-model="resultDesc" class="textarea" :disabled="isTaskReadonly" placeholder="结论说明" />
|
||||
|
||||
<view v-if="detail.appraisal_template?.key_points?.length" class="stack">
|
||||
<view class="card-desc">模板项</view>
|
||||
<view v-for="(item, index) in detail.appraisal_template.key_points" :key="`zhongjian-${item.point_code}`" class="stack">
|
||||
<view class="meta-item">
|
||||
<view class="meta-label">{{ item.point_name }}</view>
|
||||
<view class="meta-value">{{ item.point_type }}{{ item.is_required ? " · 必填" : "" }}</view>
|
||||
</view>
|
||||
<input
|
||||
:value="item.point_value"
|
||||
class="field"
|
||||
:disabled="isTaskReadonly"
|
||||
:placeholder="`${item.point_name} 值`"
|
||||
@input="updateTemplatePointFromInput(index, 'point_value', $event)"
|
||||
/>
|
||||
<textarea
|
||||
:value="item.point_remark"
|
||||
class="textarea"
|
||||
:disabled="isTaskReadonly"
|
||||
:placeholder="`${item.point_name} 说明`"
|
||||
@input="updateTemplatePointFromInput(index, 'point_remark', $event)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-desc evidence-title">鉴定图片 / 视频</view>
|
||||
<view v-if="evidenceFiles.length" class="attachment-grid">
|
||||
<view v-for="item in evidenceFiles" :key="`zj-evidence-${item.file_url}`" class="attachment-tile">
|
||||
<view class="attachment-preview" @click="previewAttachment(evidenceFiles, item)">
|
||||
<image v-if="isImageAsset(item)" class="attachment-thumb" :src="item.thumbnail_url || item.file_url" mode="aspectFill" />
|
||||
<template v-else-if="isVideoAsset(item)">
|
||||
<image v-if="item.thumbnail_url" class="attachment-thumb" :src="item.thumbnail_url" mode="aspectFill" />
|
||||
<view v-else class="attachment-video-thumb">
|
||||
<text class="attachment-video-label">视频</text>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else class="attachment-file-thumb">附件</view>
|
||||
<view v-if="isVideoAsset(item)" class="attachment-play" @click.stop="previewAttachment(evidenceFiles, item)">▶</view>
|
||||
</view>
|
||||
<view class="attachment-meta">
|
||||
<view class="attachment-name">{{ item.name || item.file_id }}</view>
|
||||
<view class="attachment-actions">
|
||||
<text class="attachment-type">{{ attachmentTypeLabel(item) }}</text>
|
||||
<text v-if="!isTaskReadonly" class="attachment-remove" @click.stop="removeEvidenceFile(item.file_url)">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!isTaskReadonly" class="upload-actions">
|
||||
<button class="action-button action-button--secondary" :disabled="uploading" @click="chooseEvidenceImage">
|
||||
<text class="action-symbol">+</text>
|
||||
<text>{{ uploading ? "上传中" : "添加鉴定图片" }}</text>
|
||||
</button>
|
||||
<button class="action-button action-button--secondary" :disabled="uploading" @click="chooseEvidenceVideo">
|
||||
<text class="action-symbol">+</text>
|
||||
<text>{{ uploading ? "上传中" : "添加鉴定视频" }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="card-desc">中检报告文件</view>
|
||||
<input v-model="zhongjianReportNo" class="field" :disabled="isTaskReadonly" placeholder="中检报告编号" />
|
||||
<view v-if="zhongjianFiles.length" class="attachment-grid">
|
||||
<view v-for="item in zhongjianFiles" :key="item.file_url" class="attachment-tile">
|
||||
|
||||
Reference in New Issue
Block a user