| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- <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',
- });
- uni.$emit('refreshPackTaskList');
- uni.$emit('refreshPackTaskDetail');
- uni.navigateBack({
- delta: 1,
- });
- } 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>
|