|
|
@@ -0,0 +1,306 @@
|
|
|
+<template>
|
|
|
+ <z-paging ref="paging" bgColor="#F7F7F7" safe-area-inset-bottom paging-class="paging-btm-shadow" refresher-only @onRefresh="onRefresh" scroll-with-animation>
|
|
|
+ <template #top>
|
|
|
+ <ut-navbar title="批量关联" :fixed="false" border></ut-navbar>
|
|
|
+ <view class="pd-5"></view>
|
|
|
+ </template>
|
|
|
+ <view class="pd-24">
|
|
|
+ <view class="mb-30 p-rtv batch-wapper">
|
|
|
+ <view class="d-flex a-c">
|
|
|
+ <image class="w-50 h-50 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/print-codes/pcxx_icon.png" mode="widthFix" />
|
|
|
+ <view class="f-s-28 c-#333 f-w-5">需关联追溯码的批次信息</view>
|
|
|
+ </view>
|
|
|
+ <view class="pl-50">
|
|
|
+ <view v-if="item" class="border-#8FC1EC b-radius bg-#fff ov-hd">
|
|
|
+ <pack-card :item="item" :dict="{ pt_pack_ref_type }"></pack-card>
|
|
|
+ </view>
|
|
|
+ <view class="pd-30 d-flex j-c">
|
|
|
+ <view class="c-primary f-s-28">
|
|
|
+ <span>待关联数量:</span>
|
|
|
+ <span class="f-s-46 f-w-600">{{ item?.planCount - item?.actualCount || 0 }}</span>
|
|
|
+ <span>{{ item?.unit }}</span>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="d-flex a-c">
|
|
|
+ <image class="w-50 h-50 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/print-codes/glm_icon.png" mode="widthFix" />
|
|
|
+ <view class="f-s-28 c-#333 f-w-5">本批次信息要关联到哪些(提前预制的)追溯码上?</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="pl-50">
|
|
|
+ <template v-for="(row, index) in relations" :key="index">
|
|
|
+ <view :id="`unchecked-row-${index}`" class="p-rtv form-codes-item bg-fff border-#9DD3AB mb-20 b-radius">
|
|
|
+ <view class="d-flex j-sb">
|
|
|
+ <view class="no-num-tag">NO.{{ index + 1 }}</view>
|
|
|
+ </view>
|
|
|
+ <view @click="deleteRow(index)" class="pd-10 close-icon">
|
|
|
+ <up-icon name="close" color="#F74C30" size="34rpx"></up-icon>
|
|
|
+ </view>
|
|
|
+ <view class="pd2-20-30">
|
|
|
+ <view class="f-s-24 c-#999 pd2-4-0">生成批号:{{ row?.item?.batchSn }}</view>
|
|
|
+ <view class="d-flex f-s-24 c-#999 pd2-4-0">
|
|
|
+ <view>码段:</view>
|
|
|
+ <view>
|
|
|
+ <view>{{ row?.item?.traceCodeStart || '-' }} 至 </view>
|
|
|
+ <view>{{ row?.item?.traceCodeEnd || '-' }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="d-flex flex-wrap">
|
|
|
+ <view class="hcol-14 f-s-24 pd2-4-0">
|
|
|
+ <span class="c-#999">生成数量:</span>
|
|
|
+ <span class="c-#999">{{ row?.item?.sumCount || '-' }}个</span>
|
|
|
+ </view>
|
|
|
+ <view class="hcol-16 f-s-24 pd2-4-0">
|
|
|
+ <span class="c-#999">剩余数量:</span>
|
|
|
+ <span class="c-#999">{{ +row?.item?.sumCount - +row?.item?.useCount - +row?.item?.voidCount || '-' }}</span>
|
|
|
+ </view>
|
|
|
+ <view class="hcol-20 f-s-24 pd2-4-0">
|
|
|
+ <span class="c-#999">生成时间:</span>
|
|
|
+ <span class="c-#999">{{ parseTime(row?.item?.createTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</span>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="h-1 bg-#F7F7F7 mg2-0-10"></view>
|
|
|
+ <view class="pd2-20-30">
|
|
|
+ <view class="f-s-28 c-#333 f-w-5 mb-16">请输入要关联的预制码编号:</view>
|
|
|
+ <view class="d-flex a-c j-c mb-24">
|
|
|
+ <up-input placeholder="7位起始编号" maxlength="7" v-model="row.form.startSn" @change="markRowUnchecked(row)"></up-input>
|
|
|
+ <view class="pd2-0-20">至</view>
|
|
|
+ <up-input placeholder="7位结束编号" maxlength="7" v-model="row.form.endSn" @change="markRowUnchecked(row)"></up-input>
|
|
|
+ </view>
|
|
|
+ <view class="d-flex j-c pl-120 pr-120 mb-30">
|
|
|
+ <up-button @click="checkCodesValidItem(row)" :customStyle="formItemBtnCardStyle" type="primary">校验是否可用</up-button>
|
|
|
+ </view>
|
|
|
+ <view v-if="row?.sumnCount">
|
|
|
+ <view class="d-flex a-c">
|
|
|
+ <up-icon class="mr-10" name="checkmark-circle-fill" color="#3FAD5B" size="26rpx"></up-icon>
|
|
|
+ <span class="f-s-24 c-#999">此次共关联{{ row?.sumnCount }}个追溯码,关联明细如下: </span>
|
|
|
+ </view>
|
|
|
+ <view v-for="(col, i) in row?.validCodes" :key="i" class="f-s-24 c-#999 pl-36">
|
|
|
+ <span>{{ i + 1 }}、</span>
|
|
|
+ <span>编号区间为{{ col.startSn.toString().padStart(7, '0') }} - {{ col.endSn.toString().padStart(7, '0') }};</span>
|
|
|
+ <span>共{{ col.count }}个</span>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ <up-button @click="selectCodes" type="primary" plain customStyle="background: #F5F7F5;">
|
|
|
+ <image class="w-36 h-36 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/select_push_icon.png" mode="widthFix" />
|
|
|
+ <span>请选择追溯码</span>
|
|
|
+ </up-button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <template #bottom>
|
|
|
+ <view class="pd3-10-24-20">
|
|
|
+ <view class="f-s-28 c-#333 text-center mb-5">此次共关联{{ totalSumCount }}个追溯码</view>
|
|
|
+ <up-button @click="batchLinkCodes" type="primary">批量关联</up-button>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </z-paging>
|
|
|
+</template>
|
|
|
+<script setup lang="ts">
|
|
|
+import { useClientRequest } from '@/utils/request';
|
|
|
+import { getUrlParams, parseTime, recursiveDecodeURIComponent } from '@/utils/ruoyi';
|
|
|
+import PackCard from '@/plant/models/pack-card.vue';
|
|
|
+import { formItemBtnCardStyle } from '@/assets/styles/uview-plus';
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
+const { pt_pack_ref_type } = toRefs<any>(proxy?.useDict('pt_pack_ref_type'));
|
|
|
+const paging = ref<any>(null);
|
|
|
+const item = ref<any>(null);
|
|
|
+const did = ref('');
|
|
|
+const relations = ref<any[]>([]);
|
|
|
+const callbackName = 'refreshCodesRange';
|
|
|
+// 根据id获取基地详情
|
|
|
+const getDetailById = async (id: string) => {
|
|
|
+ const res = await useClientRequest.get(`/plt-api/app/packTask/${id}`);
|
|
|
+ if (res && res.code === 200) {
|
|
|
+ item.value = res.data || null;
|
|
|
+ }
|
|
|
+};
|
|
|
+const onRefresh = () => {
|
|
|
+ getDetailById(did.value);
|
|
|
+ paging.value?.complete();
|
|
|
+};
|
|
|
+const totalSumCount = computed(() => {
|
|
|
+ return relations.value.reduce((sum, item) => sum + +(item?.sumnCount || 0), 0);
|
|
|
+});
|
|
|
+// 判断节点是否在可视区域内如果在则切换tab createIntersectionObserver
|
|
|
+onLoad((options: any) => {
|
|
|
+ did.value = options?.packId || getUrlParams(recursiveDecodeURIComponent(options?.q))?.packId || '';
|
|
|
+ getDetailById(did.value);
|
|
|
+ uni.$on('refreshBase', () => {
|
|
|
+ onRefresh();
|
|
|
+ });
|
|
|
+ uni.$on(callbackName, onCodeRangeSelected);
|
|
|
+});
|
|
|
+onUnload(() => {
|
|
|
+ uni.$off(callbackName, onCodeRangeSelected);
|
|
|
+});
|
|
|
+const deleteRow = (index: number) => {
|
|
|
+ relations.value.splice(index, 1);
|
|
|
+};
|
|
|
+const markRowUnchecked = (row: any) => {
|
|
|
+ row.hasChecked = false;
|
|
|
+ row.validCodes = [];
|
|
|
+ row.sumnCount = 0;
|
|
|
+};
|
|
|
+// 校验单个码段是否有用
|
|
|
+const checkCodesValidItem = async (row: any) => {
|
|
|
+ if (!row?.form?.startSn || !row?.form?.endSn) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入完整的起始编号和结束编号',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Number(row.form.startSn) > Number(row.form.endSn)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '起始编号不能大于结束编号',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Number(row.form.startSn) < Number(row.item?.startSn)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '起始编号不能小于已有编号',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Number(row.form.endSn) > Number(row.item?.endSn)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '结束编号不能大于已有编号',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const res = await useClientRequest.get(`/plt-api/app/traceCodeLog/checkCodeRange/${row?.form?.id}`, {
|
|
|
+ ...row?.form,
|
|
|
+ });
|
|
|
+ console.log(res);
|
|
|
+ if (!res || res.code !== 200) {
|
|
|
+ row.hasChecked = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const validCodes = res.data;
|
|
|
+ row.validCodes = validCodes.map((item:any) => ({ ...item, logId: row?.form?.id }));
|
|
|
+ row.sumnCount = validCodes.reduce((sum: number, item: any) => sum + item.count, 0);
|
|
|
+ row.hasChecked = true;
|
|
|
+};
|
|
|
+// 校验码段是否有用
|
|
|
+const checkCodesValid = async (data: any) => {
|
|
|
+ if (relations.value.some((relation) => relation?.item?.id === data?.id)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '该追溯码段已选择',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const res = await useClientRequest.get(`/plt-api/app/traceCodeLog/checkCodeRange/${data?.id}`, {
|
|
|
+ ...data,
|
|
|
+ });
|
|
|
+ if (res && res.code === 200) {
|
|
|
+ // return res.data || [];
|
|
|
+ relations.value.push({
|
|
|
+ item: data,
|
|
|
+ form: {
|
|
|
+ id: data?.id,
|
|
|
+ startSn: res.data[0]?.startSn?.toString().padStart(7, '0')
|
|
|
+ },
|
|
|
+ hasChecked: false,
|
|
|
+ validCodes: [],
|
|
|
+ sumnCount: 0,
|
|
|
+ });
|
|
|
+ console.log(relations.value);
|
|
|
+ }
|
|
|
+ // return [];
|
|
|
+};
|
|
|
+const onCodeRangeSelected = (data: any) => {
|
|
|
+ console.log('选中的码段数据:', data);
|
|
|
+ checkCodesValid(data);
|
|
|
+};
|
|
|
+const selectCodes = () => {
|
|
|
+ const selectedIds = relations.value.map((row) => row?.item?.id).filter((id) => id !== null && id !== undefined);
|
|
|
+ uni.$u.route({
|
|
|
+ type: 'navigateTo',
|
|
|
+ url: '/tools/select-code-section/index',
|
|
|
+ params: {
|
|
|
+ // 监听函数字符串
|
|
|
+ callback: callbackName,
|
|
|
+ selectedIds: encodeURIComponent(JSON.stringify(selectedIds)),
|
|
|
+ },
|
|
|
+ });
|
|
|
+};
|
|
|
+const batchLinkCodes = async () => {
|
|
|
+ if (relations.value.length === 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请至少选择一个追溯码段进行关联',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const uncheckedIndex = relations.value.findIndex((row) => !row?.hasChecked);
|
|
|
+ if (uncheckedIndex !== -1) {
|
|
|
+ paging.value?.scrollIntoViewById(`unchecked-row-${uncheckedIndex}`, 30, true);
|
|
|
+ uni.showToast({
|
|
|
+ title: `请先校验第${uncheckedIndex + 1}项`,
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ await uni.showLoading({
|
|
|
+ title: '关联中...',
|
|
|
+ mask: true,
|
|
|
+ });
|
|
|
+ const params = {
|
|
|
+ packId: did.value,
|
|
|
+ relations: relations.value.map((row: any) => row?.validCodes || [])?.flat(),
|
|
|
+ };
|
|
|
+ await useClientRequest.post('/plt-api/app/packTask/batchRelaction', params);
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: '关联成功',
|
|
|
+ icon: 'success',
|
|
|
+ });
|
|
|
+ onRefresh();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('批量关联失败:', error);
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: '关联失败,请重试',
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.batch-wapper {
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 25rpx;
|
|
|
+ top: 50rpx;
|
|
|
+ bottom: 50rpx;
|
|
|
+ width: 1px;
|
|
|
+ background: #37a954;
|
|
|
+ z-index: -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+.no-num-tag {
|
|
|
+ padding: 10rpx 14rpx;
|
|
|
+ font-size: 20rpx;
|
|
|
+ line-height: 1;
|
|
|
+ font-weight: 600;
|
|
|
+ color: $u-primary;
|
|
|
+ background-color: #d9efde;
|
|
|
+ border-radius: 16rpx 0 16rpx 0;
|
|
|
+}
|
|
|
+.close-icon {
|
|
|
+ position: absolute;
|
|
|
+ right: 0rpx;
|
|
|
+ top: 0rpx;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+</style>
|