代码提交_对接球机接口

This commit is contained in:
lixiaobang 2026-01-20 17:59:24 +08:00
parent b191114bcc
commit 4b8021094b
11 changed files with 1057 additions and 244 deletions

View File

@ -0,0 +1,41 @@
import request from '@/utils/request'
// 查询球机申请列表
export function listCameraApplication(query) {
return request({
url: '/manage/project/cameraApplication/list',
method: 'get',
params: query
})
}
// 可分配球机列表
export function listAvailableCamera(query) {
return request({
url: '/manage/camera/alloc/availableList',
method: 'get',
params: query
})
}
//确认分配
export function confirmAllocation(data) {
return request({
url: '/manage/camera/alloc/confirm',
method: 'post',
data: data
})
}
//查看分配详情
export function getAllocationDetail(projectId) {
return request({
url: '/manage/camera/alloc/listByProject/' + projectId,
method: 'get'
})
}
//根据cameraId查询球机详情
export function getCameraDetail(cameraId) {
return request({
url: '/manage/camera/ledger/' + cameraId,
method: 'get'
})
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 入库审核列表
export function listInventoryAudit(query) {
return request({
url: '/manage/camera/inbound/auditList',
method: 'get',
params: query
})
}
//确认入库审核通过
export function approveInventoryAudit(data) {
return request({
url: '/manage/camera/inbound/approve',
method: 'post',
data: data
})
}
//确认入库审核驳回
export function rejectInventoryAudit(data) {
return request({
url: '/manage/camera/inbound/reject',
method: 'post',
data: data
})
}

View File

@ -0,0 +1,18 @@
import request from '@/utils/request'
// 查询球机回收记录列表
export function listReturnToInventory(query) {
return request({
url: '/manage/camera/return/list',
method: 'get',
params: query
})
}
//现场回收确认
export function submitReturnToInventory(data) {
return request({
url: '/manage/camera/return/submit',
method: 'post',
data: data
})
}

View File

@ -3,7 +3,7 @@
<el-upload <el-upload
multiple multiple
:disabled="disabled" :disabled="disabled"
:action="uploadImgUrl" :http-request="handleCustomUpload"
list-type="picture-card" list-type="picture-card"
:on-success="handleUploadSuccess" :on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload" :before-upload="handleBeforeUpload"
@ -50,6 +50,7 @@
<script setup> <script setup>
import { getToken } from "@/utils/auth" import { getToken } from "@/utils/auth"
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
import { uploadFile } from '@/api/upload'
const props = defineProps({ const props = defineProps({
modelValue: [String, Object, Array], modelValue: [String, Object, Array],
@ -125,6 +126,24 @@ watch(() => props.modelValue, val => {
} }
},{ deep: true, immediate: true }) },{ deep: true, immediate: true })
//
async function handleCustomUpload(options) {
const { file } = options
try {
const response = await uploadFile(file)
if (response.code === 200) {
//
handleUploadSuccess(response, file)
} else {
//
handleUploadError(new Error(response.msg || '上传失败'), file)
}
} catch (error) {
console.error('上传文件失败:', error)
handleUploadError(error, file)
}
}
// loading // loading
function handleBeforeUpload(file) { function handleBeforeUpload(file) {
let isImg = false let isImg = false
@ -201,9 +220,18 @@ function uploadedSuccessfully() {
} }
// //
function handleUploadError() { function handleUploadError(err, file) {
proxy.$modal.msgError("上传图片失败") number.value--
proxy.$modal.msgError(err?.message || "上传图片失败")
proxy.$modal.closeLoading() proxy.$modal.closeLoading()
//
if (file && proxy.$refs.imageUpload) {
try {
proxy.$refs.imageUpload.handleRemove(file)
} catch (e) {
console.error('移除失败文件时出错:', e)
}
}
} }
// //

View File

@ -78,7 +78,7 @@
</div> </div>
</template> </template>
<script setup name="Index"> <script setup name="Index">
import { ref, onMounted } from "vue"; import { ref, onMounted, onActivated } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { listRiskCardTemplate, publishRiskCardTemplate, obsoleteRiskCardTemplate, exportRiskCardTemplateList } from "@/api/Logistics/riskManagement.js"; import { listRiskCardTemplate, publishRiskCardTemplate, obsoleteRiskCardTemplate, exportRiskCardTemplateList } from "@/api/Logistics/riskManagement.js";
import { ElMessage, ElMessageBox, ElLoading } from "element-plus"; import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
@ -135,6 +135,11 @@ onMounted(() => {
getList(); getList();
}); });
//
onActivated(() => {
getList();
});
// //
const handleQuery = () => { const handleQuery = () => {
pageNum.value = 1; pageNum.value = 1;

View File

@ -12,7 +12,7 @@
<el-input v-model="queryForm.workLocation" placeholder="请输入作业地点"></el-input> <el-input v-model="queryForm.workLocation" placeholder="请输入作业地点"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="分配状态"> <el-form-item label="分配状态">
<el-select v-model="queryForm.allocationStatus" placeholder="请选择分配状态"> <el-select v-model="queryForm.allocStatus" placeholder="请选择分配状态">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option v-for="item in allocationStatusList" :key="item.value" :label="item.label" <el-option v-for="item in allocationStatusList" :key="item.value" :label="item.label"
:value="item.value"></el-option> :value="item.value"></el-option>
@ -20,31 +20,34 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button size="default">重置</el-button> <el-button size="default" @click="handleReset">重置</el-button>
<el-button type="primary" size="default">查询</el-button> <el-button type="primary" size="default" @click="handleQuery">查询</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="card-box"> <div class="card-box">
<el-table :data="tableData"> <el-table :data="tableData" v-loading="loading">
<el-table-column prop="projectName" label="项目名称"></el-table-column> <el-table-column prop="projectName" label="项目名称"></el-table-column>
<el-table-column prop="constructionUnit" label="施工单位"></el-table-column> <el-table-column prop="constructionUnit" label="施工单位"></el-table-column>
<el-table-column prop="workLocation" label="作业地点"></el-table-column> <el-table-column prop="workLocation" label="作业地点"></el-table-column>
<el-table-column prop="workCycle" label="作业周期"></el-table-column> <el-table-column prop="workStart" label="作业周期" width="320">
<template #default="scope">
{{ scope.row.workStart }}{{ scope.row.workEnd }}
</template>
</el-table-column>
<el-table-column prop="riskType" label="风险类型"></el-table-column> <el-table-column prop="riskType" label="风险类型"></el-table-column>
<el-table-column prop="needBallheadNum" label="需分配球机数量"></el-table-column> <el-table-column prop="needCameraCnt" label="需分配球机数量"></el-table-column>
<el-table-column prop="repositoryName" label="所属仓库"></el-table-column>
<el-table-column prop="" label="分配状态"> <el-table-column prop="" label="分配状态">
<template #default="scope"> <template #default="scope">
<el-tag :type="scope.row.allocationStatus === '待分配' ? 'success' : 'danger'"> <el-tag :type="scope.row.allocStatus === '0' ? 'success' : 'danger'">
{{ scope.row.allocationStatus }} {{ scope.row.allocStatus === '0' ? '待分配' : scope.row.allocStatus === '1' ? '已分配' : '' }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="180"> <el-table-column label="操作" width="180">
<template #default="scope"> <template #default="scope">
<el-button size="small" type="text" @click="handleAssignBallhead(scope.row)">分配球机</el-button> <el-button size="small" type="text" @click="handleAssignBallhead(scope.row)">分配球机</el-button>
<el-button size="small" type="primary" link>查看详情</el-button> <el-button size="small" type="primary" link @click="handleViewDetail(scope.row)">查看详情</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -54,86 +57,123 @@
total }} total }}
</span> </span>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]" <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
:total="total" layout="prev, pager, next"></el-pagination> :total="total" layout="prev, pager, next" @size-change="getList" @current-change="getList"></el-pagination>
</div> </div>
</div> </div>
<!-- 分配球机弹窗 --> <!-- 分配球机弹窗 -->
<DialogBox v-if="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" /> <DialogBox v-show="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" :projectInfo="currentProjectInfo" :readonly="isReadonly" />
</div> </div>
</template> </template>
<script setup name="Index"> <script setup name="Index">
import { ref } from "vue"; import { ref, onMounted } from "vue";
import DialogBox from "./components/DialogA.vue" import DialogBox from "./components/DialogA.vue"
import { listCameraApplication } from "@/api/tenement/highRiskProject";
import { ElMessage } from "element-plus";
const dialogShow = ref(false) // const dialogShow = ref(false) //
const currentProjectInfo = ref(null) //
const isReadonly = ref(false) //
// //
const queryForm = ref({ const queryForm = ref({
projectName: "", projectName: "",
constructionUnit: "", constructionUnit: "",
workLocation: "", workLocation: "",
allocationStatus: "" allocStatus: ""
}); });
// //
const allocationStatusList = ref([ const allocationStatusList = ref([
{ {
label: "待分配", label: "待分配",
value: "1" value: "0"
}, },
{ {
label: "已分配", label: "已分配",
value: "2" value: "1"
} }
]); ]);
// //
const tableData = ref([ const tableData = ref([]);
{
id: 1,
projectName: "项目1",
constructionUnit: "施工单位1",
workLocation: "作业地点1",
workCycle: "作业周期1",
riskType: "高空作业",
needBallheadNum: "10",
allocationStatus: "待分配",
repositoryName: "一号仓库",
remark: "备注1"
},
{
id: 2,
projectName: "项目2",
constructionUnit: "施工单位2",
workLocation: "作业地点2",
workCycle: "作业周期2",
riskType: "高空作业",
needBallheadNum: "10",
allocationStatus: "待分配",
repositoryName: "二号仓库",
remark: "备注2"
},
{
id: 3,
projectName: "项目3",
constructionUnit: "施工单位3",
workLocation: "作业地点3",
workCycle: "作业周期3",
riskType: "高空作业",
needBallheadNum: "10",
allocationStatus: "待分配",
repositoryName: "三号仓库",
remark: "备注3"
},
]);
const pageNum = ref(1); // const pageNum = ref(1); //
const pageSize = ref(5); // const pageSize = ref(10); //
const total = ref(20); // const total = ref(0); //
const loading = ref(false); //
//
const getList = async () => {
loading.value = true;
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value
};
//
if (queryForm.value.projectName) {
params.projectName = queryForm.value.projectName;
}
if (queryForm.value.constructionUnit) {
params.constructionUnit = queryForm.value.constructionUnit;
}
if (queryForm.value.workLocation) {
params.workLocation = queryForm.value.workLocation;
}
if (queryForm.value.allocStatus) {
params.allocStatus = queryForm.value.allocStatus;
}
const response = await listCameraApplication(params);
if (response.code === 200) {
tableData.value = response.rows || response.data || [];
total.value = response.total || 0;
} else {
ElMessage.error(response.msg || "获取数据失败");
}
} catch (error) {
console.error("获取列表数据失败:", error);
ElMessage.error("获取数据失败,请稍后重试");
} finally {
loading.value = false;
}
};
//
const handleQuery = () => {
pageNum.value = 1;
getList();
};
//
const handleReset = () => {
queryForm.value = {
projectName: "",
constructionUnit: "",
workLocation: "",
allocStatus: ""
};
pageNum.value = 1;
getList();
};
//
onMounted(() => {
getList();
});
// - // -
const handleAssignBallhead = (row) => { const handleAssignBallhead = (row) => {
currentProjectInfo.value = row
isReadonly.value = false
dialogShow.value = true
}
// -
const handleViewDetail = (row) => {
currentProjectInfo.value = row
isReadonly.value = true
dialogShow.value = true dialogShow.value = true
} }
@ -141,6 +181,7 @@ const handleAssignBallhead = (row) => {
const handleCancel = () => { const handleCancel = () => {
console.log('关闭弹窗') console.log('关闭弹窗')
dialogShow.value = false dialogShow.value = false
isReadonly.value = false
} }

View File

@ -18,29 +18,33 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button size="default">重置</el-button> <el-button size="default" @click="handleReset">重置</el-button>
<el-button type="primary" size="default">查询</el-button> <el-button type="primary" size="default" @click="handleQuery">查询</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="card-box"> <div class="card-box">
<el-table :data="tableData" class="mt-2"> <el-table :data="tableData" v-loading="loading" class="mt-2">
<el-table-column prop="needBallheadNum" label="球机编号"></el-table-column> <el-table-column prop="cameraNo" label="球机编号"></el-table-column>
<el-table-column prop="projectName" label="所属项目"></el-table-column> <el-table-column prop="projectName" label="所属项目"></el-table-column>
<el-table-column prop="returnStatus" label="回收核验结果"></el-table-column> <el-table-column prop="remark" label="回收核验结果"></el-table-column>
<el-table-column prop="returnUserName" label="回收人"></el-table-column> <el-table-column prop="returnBy" label="回收人"></el-table-column>
<el-table-column prop="submitEndTime" label="提交入库时间" format="yyyy-MM-dd HH:mm:ss"></el-table-column> <el-table-column prop="returnTime" label="提交入库时间" format="yyyy-MM-dd HH:mm:ss">
<el-table-column prop="returnStatus" label="回收状态"> <template #default="scope">
{{ formatDate(scope.row.returnTime) }}
</template>
</el-table-column>
<!-- <el-table-column prop="returnStatus" label="回收状态">
<template #default="scope"> <template #default="scope">
<el-tag :type="scope.row.returnStatus === '待回收' ? 'warning' : 'success'"> <el-tag :type="scope.row.returnStatus === '待回收' ? 'warning' : 'success'">
{{ scope.row.returnStatus }} {{ scope.row.returnStatus }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column> -->
<el-table-column label="操作" width="180"> <el-table-column label="操作" width="180">
<template #default="scope"> <template #default="scope">
<el-button size="small" type="primary" link @click="handleAudit(scope.row)">入库审核</el-button> <el-button size="small" type="primary" link @click="handleAudit(scope.row)">入库审核</el-button>
<el-button size="small" type="Info" link>驳回</el-button> <el-button size="small" type="Info" link @click="handleReject(scope.row)">驳回</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -50,17 +54,19 @@
total }} total }}
</span> </span>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]" <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
:total="total" layout="prev, pager, next"></el-pagination> :total="total" layout="prev, pager, next" @size-change="getList" @current-change="getList"></el-pagination>
</div> </div>
</div> </div>
<!-- 入库审核弹窗 --> <!-- 入库审核弹窗 -->
<DialogBox v-if="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" /> <DialogBox v-show="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" :rowData="currentRowData" @refresh="handleRefresh" />
</div> </div>
</template> </template>
<script setup name="Index"> <script setup name="Index">
import { ref } from "vue"; import { ref, onMounted } from "vue";
import DialogBox from "./components/DialogC.vue"; import DialogBox from "./components/DialogC.vue";
import { listInventoryAudit, rejectInventoryAudit } from "@/api/tenement/inventoryAudit";
import { ElMessage, ElMessageBox } from "element-plus";
import { formatDate } from "@/utils";
// //
const queryForm = ref({ const queryForm = ref({
@ -86,47 +92,123 @@ const StatusList = ref([
]); ]);
// //
const tableData = ref([ const tableData = ref([]);
{
id: 1,
needBallheadNum: "1001",
projectName: "项目1",
returnStatus: "待审核",
returnUserName: "用户1",
submitEndTime: "2023-08-01 10:00:00"
},
{
id: 2,
projectName: "项目2",
constructionUnit: "施工单位2",
needBallheadNum: "1002",
submitEndTime: "2023-08-02 10:00:00",
returnStatus: "待回收"
},
{
id: 3,
projectName: "项目3",
constructionUnit: "施工单位3",
needBallheadNum: "1003",
submitEndTime: "2023-08-03 10:00:00",
returnStatus: "已回收待入库"
},
]);
const dialogShow = ref(false); // - const dialogShow = ref(false); // -
const currentRowData = ref(null); //
const pageNum = ref(1); // const pageNum = ref(1); //
const pageSize = ref(5); // const pageSize = ref(5); //
const total = ref(20); // const total = ref(0); //
const loading = ref(false); //
//
const getList = async () => {
loading.value = true;
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value
};
//
if (queryForm.value.dateRange && queryForm.value.dateRange.length === 2) {
params.startTime = queryForm.value.dateRange[0];
params.endTime = queryForm.value.dateRange[1];
}
if (queryForm.value.projectName) {
params.projectName = queryForm.value.projectName;
}
if (queryForm.value.returnStatus !== "") {
params.returnStatus = queryForm.value.returnStatus;
}
const response = await listInventoryAudit(params);
if (response.code === 200) {
tableData.value = response.rows || response.data || [];
total.value = response.total || 0;
} else {
ElMessage.error(response.msg || "获取数据失败");
}
} catch (error) {
console.error("获取列表数据失败:", error);
ElMessage.error("获取数据失败,请稍后重试");
} finally {
loading.value = false;
}
};
//
const handleQuery = () => {
pageNum.value = 1;
getList();
};
//
const handleReset = () => {
queryForm.value = {
dateRange: [],
projectName: "",
returnStatus: ""
};
pageNum.value = 1;
getList();
};
//
onMounted(() => {
getList();
});
// - // -
const handleAudit = (row) => { const handleAudit = (row) => {
currentRowData.value = row; //
dialogShow.value = true dialogShow.value = true
} }
// //
const handleCancel = () => { const handleCancel = () => {
console.log('关闭弹窗') console.log('关闭弹窗')
dialogShow.value = false dialogShow.value = false
currentRowData.value = null; //
}
//
const handleRefresh = () => {
getList()
}
//
const handleReject = async (row) => {
try {
await ElMessageBox.confirm(
`确定要驳回球机编号为"${row.cameraNo}"的入库审核吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
const params = {
id: row.id || row.returnId,
cameraId: row.cameraId || row.id,
cameraNo: row.cameraNo,
returnIds: row.returnId ? [row.returnId] : []
}
const response = await rejectInventoryAudit(params)
if (response.code === 200) {
ElMessage.success('驳回成功')
getList() //
} else {
ElMessage.error(response.msg || '驳回失败')
}
} catch (error) {
if (error !== 'cancel') {
console.error('驳回失败:', error)
ElMessage.error('驳回失败,请稍后重试')
}
}
} }
</script> </script>

View File

@ -9,19 +9,19 @@
<el-input v-model="queryForm.constructionUnit" placeholder="请输入单位名称"></el-input> <el-input v-model="queryForm.constructionUnit" placeholder="请输入单位名称"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="球机编号"> <el-form-item label="球机编号">
<el-input v-model="queryForm.needBallheadNum" placeholder="请输入球机编号"></el-input> <el-input v-model="queryForm.cameraNo" placeholder="请输入球机编号"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="回收状态"> <el-form-item label="回收状态">
<el-select v-model="queryForm.returnStatus" placeholder="请选择回收状态"> <el-select v-model="queryForm.auditStatus" placeholder="请选择回收状态">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option v-for="item in returnStatusList" :key="item.value" :label="item.label" <el-option v-for="item in auditStatusList" :key="item.value" :label="item.label"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button size="default">重置</el-button> <el-button size="default" @click="handleReset">重置</el-button>
<el-button type="primary" size="default">查询</el-button> <el-button type="primary" size="default" @click="handleQuery">查询</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -34,15 +34,19 @@
<el-button type="primary" plain size="default">打印</el-button> <el-button type="primary" plain size="default">打印</el-button>
</div> </div>
</div> </div>
<el-table :data="tableData" class="mt-2"> <el-table :data="tableData" v-loading="loading" class="mt-2">
<el-table-column prop="projectName" label="项目名称"></el-table-column> <el-table-column prop="projectName" label="项目名称"></el-table-column>
<el-table-column prop="constructionUnit" label="施工单位"></el-table-column> <el-table-column prop="constructionUnit" label="施工单位"></el-table-column>
<el-table-column prop="needBallheadNum" label="分配球机编号"></el-table-column> <el-table-column prop="cameraNo" label="分配球机编号"></el-table-column>
<el-table-column prop="submitEndTime" label="提交结束时间"></el-table-column> <el-table-column prop="createTime" label="提交结束时间">
<el-table-column prop="returnStatus" label="回收状态">
<template #default="scope"> <template #default="scope">
<el-tag :type="scope.row.returnStatus === '待回收' ? 'warning' : 'success'"> {{ formatDate(scope.row.createTime) }}
{{ scope.row.returnStatus }} </template>
</el-table-column>
<el-table-column prop="auditStatus" label="回收状态">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.auditStatus)">
{{ getStatusLabel(scope.row.auditStatus) }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
@ -58,85 +62,154 @@
total }} total }}
</span> </span>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]" <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
:total="total" layout="prev, pager, next"></el-pagination> :total="total" layout="prev, pager, next" @size-change="getList" @current-change="getList"></el-pagination>
</div> </div>
</div> </div>
<!-- 球机回收入库弹窗 --> <!-- 球机回收入库弹窗 -->
<DialogBox v-if="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" /> <DialogBox v-show="dialogShow" ref="dialogRef" :show="dialogShow" :CloseDialog="handleCancel" :rowData="currentRowData" @refresh="getList" />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted } from "vue";
import DialogBox from "./components/DialogB.vue" import DialogBox from "./components/DialogB.vue"
import { listReturnToInventory } from "@/api/tenement/returnToInventory";
import { ElMessage } from "element-plus";
import { formatDate } from "@/utils";
// //
const queryForm = ref({ const queryForm = ref({
projectName: "", projectName: "",
constructionUnit: "", constructionUnit: "",
needBallheadNum: "", cameraNo: "",
returnStatus: "" auditStatus: ""
}); });
// //
const returnStatusList = ref([ const auditStatusList = ref([
{ {
label: "待回收", label: "待回收",
value: "-1"
},
{
label: "待审核",
value: "0"
},
{
label: "已通过",
value: "1" value: "1"
}, },
{ {
label: "已回收待入库", label: "已回",
value: "2" value: "2"
} }
]); ]);
// //
const tableData = ref([ const statusMap = {
{ "-1": { label: "待回收", type: "warning" },
id: 1, "0": { label: "待审核", type: "info" },
projectName: "项目1", "1": { label: "已通过", type: "success" },
constructionUnit: "施工单位1", "2": { label: "已驳回", type: "danger" }
needBallheadNum: "1001", };
submitEndTime: "2023-08-01 10:00:00",
returnStatus: "待回收"
},
{
id: 2,
projectName: "项目2",
constructionUnit: "施工单位2",
needBallheadNum: "1002",
submitEndTime: "2023-08-02 10:00:00",
returnStatus: "待回收"
},
{
id: 3,
projectName: "项目3",
constructionUnit: "施工单位3",
needBallheadNum: "1003",
submitEndTime: "2023-08-03 10:00:00",
returnStatus: "已回收待入库"
},
]); //
const getStatusLabel = (status) => {
const statusStr = String(status);
return statusMap[statusStr]?.label || "未知状态";
};
//
const getStatusType = (status) => {
const statusStr = String(status);
return statusMap[statusStr]?.type || "";
};
//
const tableData = ref([]);
const pageNum = ref(1); //
const pageSize = ref(10); //
const total = ref(0); //
const loading = ref(false); //
// //
const dialogShow = ref(false); const dialogShow = ref(false);
//
const currentRowData = ref(null);
const pageNum = ref(1); // //
const pageSize = ref(5); // const getList = async () => {
const total = ref(20); // loading.value = true;
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value
};
//
if (queryForm.value.projectName) {
params.projectName = queryForm.value.projectName;
}
if (queryForm.value.constructionUnit) {
params.constructionUnit = queryForm.value.constructionUnit;
}
if (queryForm.value.cameraNo) {
params.cameraNo = queryForm.value.cameraNo;
}
if (queryForm.value.auditStatus !== "") {
params.auditStatus = queryForm.value.auditStatus;
}
const response = await listReturnToInventory(params);
if (response.code === 200) {
tableData.value = response.rows || response.data || [];
total.value = response.total || 0;
} else {
ElMessage.error(response.msg || "获取数据失败");
}
} catch (error) {
console.error("获取列表数据失败:", error);
ElMessage.error("获取数据失败,请稍后重试");
} finally {
loading.value = false;
}
};
//
const handleQuery = () => {
pageNum.value = 1;
getList();
};
//
const handleReset = () => {
queryForm.value = {
projectName: "",
constructionUnit: "",
cameraNo: "",
auditStatus: ""
};
pageNum.value = 1;
getList();
};
//
onMounted(() => {
getList();
});
// - // -
const handleReturnToInventory = (row) => { const handleReturnToInventory = (row) => {
currentRowData.value = row
dialogShow.value = true dialogShow.value = true
} }
// //
const handleCancel = () => { const handleCancel = () => {
console.log('关闭弹窗')
dialogShow.value = false dialogShow.value = false
currentRowData.value = null
} }
</script> </script>

View File

@ -1,6 +1,6 @@
<!-- 分配球机-弹窗详情 --> <!-- 分配球机-弹窗详情 -->
<template> <template>
<el-dialog title="分配球机" v-model="props.show" @close="handleClose" width="900px"> <el-dialog :title="props.readonly ? '查看详情' : '分配球机'" v-model="props.show" @close="handleClose" width="900px">
<div class="Cneter-box"> <div class="Cneter-box">
<!-- 项目信息 --> <!-- 项目信息 -->
<div class="project-info"> <div class="project-info">
@ -9,13 +9,25 @@
<el-col :span="12"> <el-col :span="12">
<div class="info-item"> <div class="info-item">
<label>项目名称</label> <label>项目名称</label>
<span>地铁10号线扩建工程</span> <span>{{ projectInfo?.projectName || '-' }}</span>
</div>
</el-col>
<el-col :span="12">
<div class="info-item">
<label>施工单位</label>
<span>{{ projectInfo?.constructionUnit || '-' }}</span>
</div>
</el-col>
<el-col :span="12">
<div class="info-item">
<label>作业地点</label>
<span>{{ projectInfo?.workLocation || '-' }}</span>
</div> </div>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<div class="info-item"> <div class="info-item">
<label>需分配球机数量</label> <label>需分配球机数量</label>
<span>3</span> <span>{{ projectInfo?.needCameraCnt || '-' }}</span>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -24,20 +36,22 @@
<!-- 球机选择 --> <!-- 球机选择 -->
<div class="camera-selection"> <div class="camera-selection">
<h3>球机选择</h3> <h3>球机选择</h3>
<el-input placeholder="按球机编号或型号搜索" class="mb-4" style="margin-bottom: 10px;" /> <el-input v-model="searchKeyword" placeholder="按球机编号或型号搜索" class="mb-4" style="margin-bottom: 10px;"
@input="handleSearch" :disabled="props.readonly" />
<el-table :data="cameraList" border height="300px"> <el-table ref="cameraTableRef" :data="cameraList" border height="300px" v-loading="cameraLoading"
<el-table-column type="selection" /> @selection-change="handleSelectionChange">
<el-table-column prop="number" label="球机编号" /> <el-table-column type="selection" :selectable="() => !props.readonly" />
<el-table-column prop="cameraNo" label="球机编号" />
<el-table-column prop="model" label="型号" /> <el-table-column prop="model" label="型号" />
<el-table-column prop="status" label="状态"> <el-table-column prop="status" label="状态">
<template #default="scope"> <template #default="scope">
<el-tag :type="scope.row.status === '闲置' ? 'success' : 'warning'"> <el-tag :type="getStatusType(scope.row.status)">
{{ scope.row.status }} {{ getStatusText(scope.row.status) }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="unit" label="所属单位" /> <el-table-column prop="ownerUnit" label="所属单位" />
</el-table> </el-table>
</div> </div>
@ -48,19 +62,20 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="分配人:"> <el-form-item label="分配人:">
<el-input v-model="form.assigner" placeholder="请输入分配人" /> <el-input v-model="form.assigner" placeholder="请输入分配人" :disabled="props.readonly" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="分配时间:"> <el-form-item label="分配时间:">
<el-date-picker v-model="form.assignTime" type="datetime" placeholder="选择分配时间" <el-date-picker v-model="form.assignTime" type="datetime" placeholder="选择分配时间"
style="width: 100%;" /> style="width: 100%;" :disabled="props.readonly" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="配送地址:"> <el-form-item label="配送地址:">
<el-input v-model="form.deliveryAddress" type="textarea" placeholder="请输入配送地址" :rows="3" /> <el-input v-model="form.deliveryAddress" type="textarea" placeholder="请输入配送地址" :rows="3"
:disabled="props.readonly" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -68,14 +83,16 @@
<!-- 底部按钮 --> <!-- 底部按钮 -->
<template #footer> <template #footer>
<el-button @click="handleClose">取消</el-button> <el-button @click="handleClose">{{ props.readonly ? '关闭' : '取消' }}</el-button>
<el-button type="primary" @click="handleSubmit">确认分配</el-button> <el-button v-if="!props.readonly" type="primary" @click="handleSubmit">确认分配</el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch, defineProps } from 'vue'
import { listAvailableCamera, confirmAllocation, getAllocationDetail, getCameraDetail } from '@/api/tenement/highRiskProject'
import { ElMessage } from 'element-plus'
const props = defineProps({ const props = defineProps({
show: { show: {
@ -85,6 +102,14 @@ const props = defineProps({
CloseDialog: { CloseDialog: {
type: Function, type: Function,
default: () => { } default: () => { }
},
projectInfo: {
type: Object,
default: () => null
},
readonly: {
type: Boolean,
default: false
} }
}) })
@ -92,28 +117,268 @@ const emit = defineEmits(['update:show'])
// //
const form = ref({ const form = ref({
assigner: '张伟', assigner: '',
assignTime: '2024-04-05 14:30', assignTime: '',
deliveryAddress: '北京市朝阳区建国路88号' deliveryAddress: ''
}) })
//
const searchKeyword = ref('')
// //
const cameraList = ref([ const cameraList = ref([])
{ number: 'BG-2024-001', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' }, const cameraLoading = ref(false)
{ number: 'BG-2024-002', model: 'Dahua SD1A404XB-GNR', status: '闲置', unit: '北京设备租赁公司' }, const allCameraList = ref([]) //
{ number: 'BG-2024-003', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' }, const cameraTableRef = ref(null) //
{ number: 'BG-2024-004', model: 'Dahua SD6C425X-GNR', status: '维修中', unit: '北京设备租赁公司' }, const selectedCameras = ref([]) //
{ number: 'BG-2024-005', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' }
]) //
const getCameraList = async () => {
cameraLoading.value = true
try {
const response = await listAvailableCamera({})
if (response.code === 200) {
allCameraList.value = response.rows || response.data || []
cameraList.value = allCameraList.value
} else {
ElMessage.error(response.msg || '获取球机列表失败')
}
} catch (error) {
console.error('获取球机列表失败:', error)
ElMessage.error('获取球机列表失败,请稍后重试')
} finally {
cameraLoading.value = false
}
}
//
const handleSearch = () => {
if (!searchKeyword.value) {
cameraList.value = allCameraList.value
return
}
const keyword = searchKeyword.value.toLowerCase()
cameraList.value = allCameraList.value.filter(item => {
return (item.cameraNo && item.cameraNo.toLowerCase().includes(keyword)) ||
(item.model && item.model.toLowerCase().includes(keyword))
})
}
//
const handleSelectionChange = (selection) => {
selectedCameras.value = selection
//
const needCount = props.projectInfo?.needCameraCnt
if (needCount !== undefined && needCount !== null && !props.readonly) {
const selectedCount = selection.length
if (selectedCount > needCount) {
ElMessage.warning(`已选择${selectedCount}个球机,需分配数量为${needCount}个,请取消多余的选择`)
}
}
}
//
const getStatusText = (status) => {
const statusMap = {
'0': '闲置',
'1': '已分配',
'2': '待回收',
'3': '已入库'
}
return statusMap[status] || status
}
//
const getStatusType = (status) => {
const typeMap = {
'0': 'success',
'1': 'warning',
'2': 'info',
'3': ''
}
return typeMap[status] || ''
}
//
const getDetail = async () => {
if (!props.projectInfo) {
return
}
const projectId = props.projectInfo.id || props.projectInfo.projectId
if (!projectId) {
ElMessage.error('项目ID不存在')
return
}
cameraLoading.value = true
try {
const response = await getAllocationDetail(projectId)
if (response.code === 200) {
const data = response.data || response.rows || []
//
const detailData = Array.isArray(data) ? (data[0] || {}) : data
//
form.value = {
assigner: detailData.allocBy || detailData.assigner || '',
assignTime: detailData.allocTime || detailData.assignTime || '',
deliveryAddress: detailData.allocNote || detailData.deliveryAddress || detailData.deliveryAddr || ''
}
// ID
let allocatedCameraIds = []
if (detailData.cameraIds && Array.isArray(detailData.cameraIds)) {
allocatedCameraIds = detailData.cameraIds
} else if (detailData.cameras && Array.isArray(detailData.cameras)) {
// camerasID
allocatedCameraIds = detailData.cameras.map(cam => cam.id || cam.cameraId || cam.cameraNo).filter(Boolean)
} else if (detailData.cameraId) {
// ID
allocatedCameraIds = [detailData.cameraId]
}
// IDgetCameraDetail
if (allocatedCameraIds.length > 0) {
const cameraDetailList = []
// cameraId
for (const cameraId of allocatedCameraIds) {
try {
const cameraResponse = await getCameraDetail(cameraId)
if (cameraResponse.code === 200) {
const cameraData = cameraResponse.data || cameraResponse
cameraDetailList.push({
id: cameraData.cameraId || cameraData.id || cameraId,
cameraId: cameraData.cameraId || cameraData.id || cameraId,
cameraNo: cameraData.cameraNo || '',
model: cameraData.model || '',
status: cameraData.status || '',
ownerUnit: cameraData.ownerUnit || ''
})
}
} catch (error) {
console.error(`获取球机${cameraId}详情失败:`, error)
}
}
//
cameraList.value = cameraDetailList
allCameraList.value = cameraDetailList
} else {
// ID
cameraList.value = []
allCameraList.value = []
}
} else {
ElMessage.error(response.msg || '获取详情失败')
}
} catch (error) {
console.error('获取详情失败:', error)
ElMessage.error('获取详情失败,请稍后重试')
} finally {
cameraLoading.value = false
}
}
//
watch(() => props.show, (newVal) => {
if (newVal) {
if (props.readonly) {
//
getDetail()
} else {
//
getCameraList()
//
searchKeyword.value = ''
//
form.value = {
assigner: '',
assignTime: '',
deliveryAddress: ''
}
//
selectedCameras.value = []
if (cameraTableRef.value) {
cameraTableRef.value.clearSelection()
}
}
}
})
const handleClose = () => { const handleClose = () => {
props.CloseDialog() props.CloseDialog()
} }
const handleSubmit = () => { const handleSubmit = async () => {
// //
console.log('提交分配信息', form.value) if (selectedCameras.value.length === 0) {
props.CloseDialog() ElMessage.warning('请至少选择一个球机')
return
}
//
const needCount = props.projectInfo?.needCameraCnt
if (needCount !== undefined && needCount !== null) {
const selectedCount = selectedCameras.value.length
if (selectedCount !== needCount) {
ElMessage.warning(`选中的球机数量为${selectedCount}个,需分配球机数量为${needCount}个,数量不一致,请重新选择`)
return
}
}
//
if (!form.value.assigner) {
ElMessage.warning('请输入分配人')
return
}
if (!form.value.assignTime) {
ElMessage.warning('请选择分配时间')
return
}
if (!form.value.deliveryAddress) {
ElMessage.warning('请输入配送地址')
return
}
//
let assignTimeStr = ''
if (form.value.assignTime instanceof Date) {
const year = form.value.assignTime.getFullYear()
const month = String(form.value.assignTime.getMonth() + 1).padStart(2, '0')
const day = String(form.value.assignTime.getDate()).padStart(2, '0')
const hours = String(form.value.assignTime.getHours()).padStart(2, '0')
const minutes = String(form.value.assignTime.getMinutes()).padStart(2, '0')
const seconds = String(form.value.assignTime.getSeconds()).padStart(2, '0')
assignTimeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
} else {
assignTimeStr = form.value.assignTime
}
//
const submitData = {
projectId: props.projectInfo?.id || props.projectInfo?.projectId, // ID
cameraIds: selectedCameras.value.map(camera => camera.id || camera.cameraId), // ID
allocBy: form.value.assigner, //
allocTime: form.value.assignTime, //
allocNote: form.value.deliveryAddress //
}
try {
//
const response = await confirmAllocation(submitData)
if (response.code === 200) {
ElMessage.success('分配成功')
props.CloseDialog()
} else {
ElMessage.error(response.msg || '分配失败')
}
} catch (error) {
console.error('分配失败:', error)
ElMessage.error('分配失败,请稍后重试')
}
} }
</script> </script>

View File

@ -11,31 +11,31 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="球机编号/数量"> <el-form-item label="球机编号">
<el-input v-model="form.cameraIds" disabled /> <el-input v-model="form.cameraNo" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="分配时间"> <el-form-item label="分配时间">
<el-input v-model="form.allocationTime" disabled /> <el-input v-model="form.createTime" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 球机外观完整性 --> <!-- 球机外观完整性 -->
<el-form-item label="球机外观完整性"> <el-form-item label="球机外观完整性">
<el-radio-group v-model="form.appearanceStatus"> <el-radio-group v-model="form.appearanceIntegrity">
<el-radio label="完好">完好</el-radio> <el-radio :label="0">完好</el-radio>
<el-radio label="破损">破损</el-radio> <el-radio :label="1">破损</el-radio>
<el-radio label="丢失">丢失</el-radio> <el-radio :label="2">丢失</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 功能测试结果 --> <!-- 功能测试结果 -->
<el-form-item label="功能测试结果"> <el-form-item label="功能测试结果">
<el-radio-group v-model="form.functionStatus"> <el-radio-group v-model="form.functionalTestResult">
<el-radio label="正常">正常</el-radio> <el-radio :label="0">正常</el-radio>
<el-radio label="异常">异常</el-radio> <el-radio :label="1">异常</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@ -43,32 +43,24 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="回收人"> <el-form-item label="回收人">
<el-input v-model="form.recycler" /> <el-input v-model="form.returnBy" placeholder="请输入回收人" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="回收时间"> <el-form-item label="回收时间">
<el-date-picker v-model="form.recycleTime" type="datetime" style="width: 100%;" /> <el-date-picker v-model="form.returnTime" type="datetime" placeholder="选择回收时间" style="width: 100%;" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 回收照片 --> <!-- 回收照片 -->
<el-form-item label="回收照片"> <el-form-item label="回收照片">
<div class="upload-area"> <ImageUpload v-model="form.returnPhotos" :limit="5" :fileSize="5" />
<p>点击上传或拖拽图片到此处</p>
<p>支持JPG/PNG格式至少上传1张</p>
</div>
<div class="photo-grid">
<div class="photo-item" v-for="(photo, index) in form.photos" :key="index">
<img :src="photo" alt="回收照片" />
</div>
</div>
</el-form-item> </el-form-item>
<!-- 备注 --> <!-- 备注 -->
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="如选择'破损'或'丢失',请在此说明原因" /> <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注信息" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -76,14 +68,17 @@
<!-- 底部按钮 --> <!-- 底部按钮 -->
<template #footer> <template #footer>
<el-button @click="handleClose">返回</el-button> <el-button @click="handleClose">返回</el-button>
<el-button type="primary" @click="handleSubmit">确认回收</el-button> <el-button type="primary" @click="handleSubmit" :loading="submitting">确认回收</el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch } from 'vue'
import ImageUpload from '@/components/ImageUpload/index.vue'
import { submitReturnToInventory } from '@/api/tenement/returnToInventory'
import { ElMessage } from 'element-plus'
import { formatDate } from '@/utils'
const props = defineProps({ const props = defineProps({
show: { show: {
@ -93,35 +88,145 @@ const props = defineProps({
CloseDialog: { CloseDialog: {
type: Function, type: Function,
default: () => { } default: () => { }
},
rowData: {
type: Object,
default: () => null
} }
}) })
const emit = defineEmits(['update:show']) const emit = defineEmits(['update:show', 'refresh'])
//
const submitting = ref(false)
// //
const form = ref({ const form = ref({
assigner: '张伟', projectName: '', //
assignTime: '2024-04-05 14:30', cameraNo: '', //
deliveryAddress: '北京市朝阳区建国路88号' allocationTime: '', //
appearanceIntegrity: '', //
functionalTestResult: '', //
returnBy: '', //
returnTime: '', //
returnPhotos: '', //
remark: '' //
}) })
// //
const cameraList = ref([ watch(() => props.show, (newVal) => {
{ number: 'BG-2024-001', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' }, if (newVal && props.rowData) {
{ number: 'BG-2024-002', model: 'Dahua SD1A404XB-GNR', status: '闲置', unit: '北京设备租赁公司' }, //
{ number: 'BG-2024-003', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' }, form.value = {
{ number: 'BG-2024-004', model: 'Dahua SD6C425X-GNR', status: '维修中', unit: '北京设备租赁公司' }, projectName: props.rowData.projectName || '',
{ number: 'BG-2024-005', model: 'Hikvision DS-2DE4A425IW-DE', status: '闲置', unit: '北京设备租赁公司' } cameraNo: props.rowData.cameraNo || '',
]) allocationTime: formatDate(props.rowData.allocationTime || props.rowData.assignTime || ''),
appearanceIntegrity: props.rowData.appearanceIntegrity !== undefined && props.rowData.appearanceIntegrity !== null ? Number(props.rowData.appearanceIntegrity) : '',
functionalTestResult: props.rowData.functionalTestResult !== undefined && props.rowData.functionalTestResult !== null ? Number(props.rowData.functionalTestResult) : '',
returnBy: props.rowData.returnBy || '',
returnTime: '',
returnPhotos: props.rowData.returnPhotos || props.rowData.photoUrls || '',
remark: props.rowData.remark || ''
}
}
})
const handleClose = () => { const handleClose = () => {
//
form.value = {
projectName: '',
cameraNo: '',
allocationTime: '',
appearanceIntegrity: '',
functionalTestResult: '',
returnBy: '',
returnTime: '',
returnPhotos: '',
remark: ''
}
props.CloseDialog() props.CloseDialog()
} }
const handleSubmit = () => { const handleSubmit = async () => {
// //
console.log('提交分配信息', form.value) if (form.value.appearanceIntegrity === '' || form.value.appearanceIntegrity === null || form.value.appearanceIntegrity === undefined) {
props.CloseDialog() ElMessage.warning('请选择球机外观完整性')
return
}
if (form.value.functionalTestResult === '' || form.value.functionalTestResult === null || form.value.functionalTestResult === undefined) {
ElMessage.warning('请选择功能测试结果')
return
}
if (!form.value.returnBy) {
ElMessage.warning('请输入回收人')
return
}
if (!form.value.returnTime) {
ElMessage.warning('请选择回收时间')
return
}
//
let returnTimeStr = ''
if (form.value.returnTime instanceof Date) {
const year = form.value.returnTime.getFullYear()
const month = String(form.value.returnTime.getMonth() + 1).padStart(2, '0')
const day = String(form.value.returnTime.getDate()).padStart(2, '0')
const hours = String(form.value.returnTime.getHours()).padStart(2, '0')
const minutes = String(form.value.returnTime.getMinutes()).padStart(2, '0')
const seconds = String(form.value.returnTime.getSeconds()).padStart(2, '0')
returnTimeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
} else {
returnTimeStr = form.value.returnTime
}
//
let photoUrls = []
if (form.value.returnPhotos) {
// returnPhotos
if (typeof form.value.returnPhotos === 'string') {
photoUrls = form.value.returnPhotos.split(',').filter(url => url.trim())
} else if (Array.isArray(form.value.returnPhotos)) {
photoUrls = form.value.returnPhotos
}
}
// cameraId
const cameraId = props.rowData?.cameraIds || props.rowData?.id || 0
//
const submitData = {
projectId: props.rowData?.projectId, // ID
id: props.rowData?.id || props.rowData?.returnId, // ID
cameraIds: cameraId.split(',').map(item => item.trim()), // ID
cameraNo: form.value.cameraNo, //
appearanceIntegrity: form.value.appearanceIntegrity, //
functionalTestResult: form.value.functionalTestResult, //
returnBy: form.value.returnBy, //
returnTime: form.value.returnTime, //
photoUrls: photoUrls, //
remark: form.value.remark || '' //
}
submitting.value = true
try {
const response = await submitReturnToInventory(submitData)
if (response.code === 200) {
ElMessage.success('回收确认成功')
emit('refresh') //
handleClose()
} else {
ElMessage.error(response.msg || '回收确认失败')
}
} catch (error) {
console.error('回收确认失败:', error)
ElMessage.error('回收确认失败,请稍后重试')
} finally {
submitting.value = false
}
} }
</script> </script>

View File

@ -7,14 +7,15 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="10"> <el-col :span="10">
<div class="camera-photo"> <div class="camera-photo">
<img src="https://via.placeholder.com/300x200?text=Camera" alt="球机照片" /> <img v-if="form.photoUrl" :src="form.photoUrl" alt="球机照片" />
<div v-else class="no-photo">暂无照片</div>
</div> </div>
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<div class="info-list"> <div class="info-list">
<div class="info-item"> <div class="info-item">
<label>球机编号</label> <label>球机编号</label>
<span>{{ form.cameraId }}</span> <span>{{ form.cameraNo }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<label>所属项目</label> <label>所属项目</label>
@ -22,15 +23,15 @@
</div> </div>
<div class="info-item"> <div class="info-item">
<label>回收人</label> <label>回收人</label>
<span>{{ form.recycler }}</span> <span>{{ form.returnBy }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<label>回收时间</label> <label>回收时间</label>
<span>{{ form.recycleTime }}</span> <span>{{ form.returnTime }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<label>核验结果</label> <label>核验结果</label>
<span>{{ form.inspectionResult }}</span> <span>{{ form.remark }}</span>
</div> </div>
</div> </div>
</el-col> </el-col>
@ -50,14 +51,14 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="入库时间"> <el-form-item label="入库时间">
<el-date-picker v-model="form.storageTime" type="datetime" style="width: 100%;" /> <el-date-picker v-model="form.inboundTime" type="datetime" style="width: 100%;" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form :model="form" label-width="100px"> <el-form :model="form" label-width="100px">
<el-form-item label="入库管理员"> <el-form-item label="入库管理员">
<el-input v-model="form.manager" placeholder="请输入入库管理员" /> <el-input v-model="form.keeper" placeholder="请输入入库管理员" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
@ -68,13 +69,17 @@
<!-- 底部按钮 --> <!-- 底部按钮 -->
<template #footer> <template #footer>
<el-button @click="handleClose">取消</el-button> <el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit">确认入库</el-button> <el-button type="primary" @click="handleSubmit" :loading="submitting">确认入库</el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch } from 'vue'
import { formatDate } from '@/utils'
import { approveInventoryAudit } from '@/api/tenement/inventoryAudit'
import { ElMessage } from 'element-plus'
const props = defineProps({ const props = defineProps({
show: { show: {
type: Boolean, type: Boolean,
@ -83,33 +88,147 @@ const props = defineProps({
CloseDialog: { CloseDialog: {
type: Function, type: Function,
default: () => { } default: () => { }
},
rowData: {
type: Object,
default: () => null
} }
}) })
const emit = defineEmits(['refresh'])
const form = ref({ const form = ref({
cameraId: 'QJ20230401001', cameraNo: '',
projectName: '阳光花园小区改造项目', projectName: '',
recycler: '李建国', returnBy: '',
recycleTime: '2023-04-15 14:30:22', returnTime: '',
inspectionResult: '外观完好,功能正常', remark: '',
warehouse: '1', photoUrl: '', //
storageTime: '2023-04-18 10:30:00', warehouse: '',
manager: '张伟' inboundTime: '',
keeper: ''
}) })
const Frules = ref({ const Frules = ref({
warehouse: [{ required: true, message: '请选择入库仓库', trigger: 'blur' }], warehouse: [{ required: true, message: '请选择入库仓库', trigger: 'blur' }],
}) })
const formRef = ref(null)
const submitting = ref(false)
//
watch(() => props.show, (newVal) => {
if (newVal && props.rowData) {
// URL
let photoUrl = ''
if (props.rowData.returnPhotos) {
if (typeof props.rowData.returnPhotos === 'string') {
const photos = props.rowData.returnPhotos.split(',').filter(url => url.trim())
photoUrl = photos[0] || ''
} else if (Array.isArray(props.rowData.returnPhotos) && props.rowData.returnPhotos.length > 0) {
photoUrl = props.rowData.returnPhotos[0]
}
} else if (props.rowData.photoUrls) {
if (typeof props.rowData.photoUrls === 'string') {
const photos = props.rowData.photoUrls.split(',').filter(url => url.trim())
photoUrl = photos[0] || ''
} else if (Array.isArray(props.rowData.photoUrls) && props.rowData.photoUrls.length > 0) {
photoUrl = props.rowData.photoUrls[0]
}
}
//
form.value = {
cameraNo: props.rowData.cameraNo || '',
projectName: props.rowData.projectName || '',
returnBy: props.rowData.returnBy || '',
returnTime: props.rowData.returnTime ? formatDate(props.rowData.returnTime) : '',
remark: props.rowData.remark || '',
photoUrl: photoUrl,
warehouse: '',
inboundTime: '',
keeper: ''
}
}
})
const handleClose = () => { const handleClose = () => {
//
form.value = {
cameraNo: '',
projectName: '',
returnBy: '',
returnTime: '',
remark: '',
photoUrl: '',
warehouse: '',
inboundTime: '',
keeper: ''
}
props.CloseDialog() props.CloseDialog()
} }
const handleSubmit = () => { const handleSubmit = async () => {
// //
console.log('提交分配信息', form.value) if (!formRef.value) return
props.CloseDialog()
try {
await formRef.value.validate()
} catch (error) {
ElMessage.warning('请完善表单信息')
return
}
//
if (!form.value.warehouse) {
ElMessage.warning('请选择入库仓库')
return
}
//
let inboundTimeStr = ''
if (form.value.inboundTime) {
if (form.value.inboundTime instanceof Date) {
const year = form.value.inboundTime.getFullYear()
const month = String(form.value.inboundTime.getMonth() + 1).padStart(2, '0')
const day = String(form.value.inboundTime.getDate()).padStart(2, '0')
const hours = String(form.value.inboundTime.getHours()).padStart(2, '0')
const minutes = String(form.value.inboundTime.getMinutes()).padStart(2, '0')
const seconds = String(form.value.inboundTime.getSeconds()).padStart(2, '0')
inboundTimeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
} else {
inboundTimeStr = form.value.inboundTime
}
}
//
const submitData = {
id: props.rowData?.id || props.rowData?.returnId, // ID
cameraId: props.rowData?.cameraId || props.rowData?.id, // ID
cameraNo: form.value.cameraNo, //
warehouse: form.value.warehouse, //
inboundTime: form.value.inboundTime, // 使
keeper: form.value.keeper || '', //
returnIds: props.rowData?.returnId ? [props.rowData.returnId] : [] // returnId
}
submitting.value = true
try {
const response = await approveInventoryAudit(submitData)
if (response.code === 200) {
ElMessage.success('确认入库成功')
emit('refresh') //
handleClose()
} else {
ElMessage.error(response.msg || '确认入库失败')
}
} catch (error) {
console.error('确认入库失败:', error)
ElMessage.error('确认入库失败,请稍后重试')
} finally {
submitting.value = false
}
} }
</script> </script>
@ -140,6 +259,16 @@ const handleSubmit = () => {
border-radius: 4px; border-radius: 4px;
} }
.no-photo {
display: flex;
align-items: center;
justify-content: center;
height: 200px;
color: #909399;
background-color: #f5f7fa;
border-radius: 4px;
}
.info-list { .info-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;