no message
parent
9300da4988
commit
63224c8786
|
|
@ -1,18 +1,20 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from "/@/hooks/web/useMessage";
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/agvTask/list',
|
||||
save='/agvTask/add',
|
||||
edit='/agvTask/edit',
|
||||
save = '/agvTask/add',
|
||||
edit = '/agvTask/edit',
|
||||
deleteOne = '/agvTask/delete',
|
||||
deleteBatch = '/agvTask/deleteBatch',
|
||||
importExcel = '/agvTask/importExcel',
|
||||
exportXls = '/agvTask/exportXls',
|
||||
taskReporter = '/api/robot/reporter/task',
|
||||
callBackTask='/tes/apiv2/callBackTask',
|
||||
callBackTask = '/tes/apiv2/callBackTask',
|
||||
cancelTask = '/tes/apiv2/cancelTask',
|
||||
resendTesTask = '/tes/apiv2/resendTesTask',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,11 +39,11 @@ export const list = (params) => defHttp.get({ url: Api.list, params });
|
|||
* @param params
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
|
|
@ -56,12 +58,20 @@ export const batchDelete = (params, handleSuccess) => {
|
|||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
|
|
@ -71,26 +81,53 @@ export const batchDelete = (params, handleSuccess) => {
|
|||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* AGV任务上报
|
||||
* @param params
|
||||
*/
|
||||
export const taskReporter = (params) => {
|
||||
return defHttp.post({url: Api.taskReporter, params}, {
|
||||
joinParamsToUrl: false,
|
||||
isTransformResponse: false
|
||||
});
|
||||
}
|
||||
return defHttp.post(
|
||||
{ url: Api.taskReporter, params },
|
||||
{
|
||||
isTransformResponse: false,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* TES任务上报
|
||||
* @param params
|
||||
*/
|
||||
export const callBackTask = (params) => {
|
||||
return defHttp.post({url: Api.callBackTask, params}, {
|
||||
joinParamsToUrl: false,
|
||||
isTransformResponse: false
|
||||
return defHttp.post(
|
||||
{ url: Api.callBackTask, params },
|
||||
{
|
||||
isTransformResponse: false,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 任务取消
|
||||
* @param params
|
||||
*/
|
||||
export const cancelTask = (params) => {
|
||||
return defHttp.post(
|
||||
{ url: Api.cancelTask, params },
|
||||
{
|
||||
isTransformResponse: false,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 任务重送
|
||||
* @param params
|
||||
*/
|
||||
export const resendTesTask = (params) => {
|
||||
return defHttp.post({ url: Api.resendTesTask, params },{
|
||||
isTransformResponse: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<TesAgvModal ref="registerModal" @success="handleSuccess"></TesAgvModal>
|
||||
<ResendTesAgvModal ref="registerResendModal" @success="handleSuccess"></ResendTesAgvModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -53,9 +54,9 @@
|
|||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns } from './TesAgv.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, callBackTask } from './AgvTask.api';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, callBackTask, cancelTask } from './AgvTask.api';
|
||||
import TesAgvModal from './components/TesAgvModal.vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import ResendTesAgvModal from './components/ResendTesAgvModal.vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDateByPicker } from '/@/utils';
|
||||
|
||||
|
|
@ -65,12 +66,11 @@
|
|||
const queryParam = reactive<any>({
|
||||
agvVendor: 'TES',
|
||||
});
|
||||
const toggleSearchStatus = ref<boolean>(false);
|
||||
const registerModal = ref();
|
||||
const userStore = useUserStore();
|
||||
const registerResendModal = ref();
|
||||
const { createMessage } = useMessage();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: 'TES任务表',
|
||||
api: list,
|
||||
|
|
@ -100,8 +100,7 @@
|
|||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
||||
tableContext;
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const labelCol = reactive({
|
||||
xs: 24,
|
||||
sm: 4,
|
||||
|
|
@ -168,15 +167,45 @@
|
|||
const res = await callBackTask(params);
|
||||
if (res && res.returnCode === 0) {
|
||||
createMessage.success('操作成功');
|
||||
handleSuccess();
|
||||
} else {
|
||||
createMessage.error(res.message || '任务处理失败');
|
||||
createMessage.error(res.returnMsg || '任务处理失败');
|
||||
}
|
||||
} catch (error) {
|
||||
createMessage.error('请求异常: ' + error.message);
|
||||
} finally {
|
||||
handleSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务取消事件
|
||||
*/
|
||||
async function hanndleCancel(record) {
|
||||
const params = {
|
||||
taskID: record.id,
|
||||
};
|
||||
try {
|
||||
const res = await cancelTask(params);
|
||||
if (res && res.returnCode === 0) {
|
||||
createMessage.success('操作成功');
|
||||
} else {
|
||||
createMessage.error(res.returnMsg || '任务处理失败');
|
||||
}
|
||||
} catch (error) {
|
||||
createMessage.error('请求异常: ' + error.message);
|
||||
} finally {
|
||||
handleSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务重发
|
||||
*/
|
||||
function hanndleResend(record) {
|
||||
registerResendModal.value.disableSubmit = false;
|
||||
registerResendModal.value.resend(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
|
|
@ -214,10 +243,26 @@
|
|||
placement: 'topLeft',
|
||||
},
|
||||
auth: 'agvTask:data_agv_task:edit',
|
||||
disabled: record.status === 4 || record.status === 1,
|
||||
disabled: record.status === 4 || record.status === 1 || record.status === 5,
|
||||
},
|
||||
{
|
||||
label: '删除任务',
|
||||
label: '任务取消',
|
||||
popConfirm: {
|
||||
title: '是否确认取消?',
|
||||
confirm: hanndleCancel.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
},
|
||||
auth: 'agvTask:data_agv_task:edit',
|
||||
disabled: record.status != 2,
|
||||
},
|
||||
{
|
||||
label: '任务重送',
|
||||
onClick: hanndleResend.bind(null, record),
|
||||
auth: 'agvTask:data_agv_task:edit',
|
||||
disabled: record.status != 5,
|
||||
},
|
||||
{
|
||||
label: '任务删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除?',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<JFormContainer>
|
||||
<template #detail>
|
||||
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="AgvTaskForm">
|
||||
<a-row>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="容器" v-bind="validateInfos.carrierCode" id="AgvTaskForm-carrierCode" name="carrierCode">
|
||||
<JDictSelectTag
|
||||
v-model:value="formData.carrierCode"
|
||||
placeholder="请选择容器"
|
||||
dictCode="base_stock where iz_active=1 and del_flag=0,stock_code,stock_code"
|
||||
allowClear
|
||||
disabled
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- <a-col :span="24">
|
||||
<a-form-item label="任务类型" v-bind="validateInfos.taskType" id="AgvTaskForm-taskType" name="taskType">
|
||||
<a-input v-model:value="formData.taskType" placeholder="请输入任务类型" allow-clear ></a-input>
|
||||
</a-form-item>
|
||||
</a-col>-->
|
||||
<a-col :span="24">
|
||||
<a-form-item label="业务类型" v-bind="validateInfos.type" id="AgvTaskForm-type" name="type">
|
||||
<JDictSelectTag type="select" v-model:value="formData.type" dictCode="business_type" placeholder="请选择业务类型" disabled />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="任务状态" v-bind="validateInfos.status" id="AgvTaskForm-status" name="status">
|
||||
<JDictSelectTag
|
||||
type="select"
|
||||
v-model:value="formData.status"
|
||||
dictCode="agv_task_status"
|
||||
placeholder="请选择任务状态"
|
||||
:string-to-number="true"
|
||||
disabled
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="优先级" v-bind="validateInfos.priority" id="AgvTaskForm-priority" name="priority">
|
||||
<a-input-number v-model:value="formData.priority" placeholder="请输入优先级" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="目标库位" v-bind="validateInfos.endCode" id="AgvTaskForm-endCode" name="endCode">
|
||||
<JSearchSelect
|
||||
v-model:value="formData.endCode"
|
||||
placeholder="请选择目标库位"
|
||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,point_code"
|
||||
allowClear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
</JFormContainer>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, defineExpose, nextTick } from 'vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getTenantId } from '@/utils/auth';
|
||||
import { cancelTask, resendTesTask } from '../AgvTask.api';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||
import { JSearchSelect, JDictSelectTag } from '@/components/Form';
|
||||
|
||||
const formRef = ref();
|
||||
const useForm = Form.useForm;
|
||||
const emit = defineEmits(['register', 'ok']);
|
||||
//仓库 ID
|
||||
let tenantId = getTenantId();
|
||||
const formData = reactive<Record<string, any>>({
|
||||
id: '',
|
||||
carrierCode: '',
|
||||
carrierType: 'TRAY',
|
||||
taskType: '',
|
||||
type: '',
|
||||
status: 'CREATED',
|
||||
priority: 3,
|
||||
startCode: '',
|
||||
endCode: '',
|
||||
agvVendor: 'TES',
|
||||
tenantId: tenantId,
|
||||
});
|
||||
const { createMessage } = useMessage();
|
||||
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
|
||||
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
|
||||
const confirmLoading = ref<boolean>(false);
|
||||
//表单验证
|
||||
const validatorRules = reactive({
|
||||
carrierCode: [{ required: true, message: '请选择容器!' }],
|
||||
type: [{ required: true, message: '请选择业务类型!' }],
|
||||
priority: [{ required: true, message: '请输入优先级!' }],
|
||||
endCode: [{ required: true, message: '请选择目标库位!' }],
|
||||
status: [{ required: true, message: '请选择任务状态!' }],
|
||||
});
|
||||
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
function edit(record) {
|
||||
nextTick(() => {
|
||||
resetFields();
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if (record.hasOwnProperty(key)) {
|
||||
tmpData[key] = record[key];
|
||||
}
|
||||
});
|
||||
//赋值
|
||||
Object.assign(formData, tmpData);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交数据
|
||||
*/
|
||||
async function submitForm() {
|
||||
try {
|
||||
// 触发表单验证
|
||||
await validate();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
confirmLoading.value = true;
|
||||
try {
|
||||
const res = await resendTesTask(formData);
|
||||
if (res && res.returnCode === 0) {
|
||||
createMessage.success('操作成功');
|
||||
emit('ok');
|
||||
} else {
|
||||
createMessage.error(res.returnMsg || '任务处理失败');
|
||||
}
|
||||
} catch (error) {
|
||||
createMessage.error('请求异常: ' + error.message);
|
||||
} finally {
|
||||
confirmLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
edit,
|
||||
submitForm,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.antd-modal-form {
|
||||
padding: 14px 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:maxHeight="400"
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
@ok="handleOk"
|
||||
:okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭"
|
||||
>
|
||||
<ResendTesAgvForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></ResendTesAgvForm>
|
||||
<template #footer>
|
||||
<a-button @click="handleCancel">取消</a-button>
|
||||
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认 </a-button>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick, defineExpose } from 'vue';
|
||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
||||
import ResendTesAgvForm from '@/views/agvTask/components/ResendTesAgvForm.vue';
|
||||
|
||||
const title = ref<string>('');
|
||||
const visible = ref<boolean>(false);
|
||||
const disableSubmit = ref<boolean>(false);
|
||||
const registerForm = ref();
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
|
||||
/**
|
||||
* 重送
|
||||
*/
|
||||
function resend(record) {
|
||||
title.value = 'TES任务重送';
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
registerForm.value.edit(record);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定按钮点击事件
|
||||
*/
|
||||
function handleOk() {
|
||||
registerForm.value.submitForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* form保存回调事件
|
||||
*/
|
||||
function submitCallback() {
|
||||
handleCancel();
|
||||
emit('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮回调事件
|
||||
*/
|
||||
function handleCancel() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
resend,
|
||||
disableSubmit,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
/**隐藏样式-modal确定按钮 */
|
||||
.jee-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped></style>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="任务状态" v-bind="validateInfos.status" id="AgvTaskForm-status" name="status">
|
||||
<JDictSelectTag type="select" v-model:value="formData.status" dictCode="agv_task_status" placeholder="请选择任务状态" />
|
||||
<JDictSelectTag type="select" v-model:value="formData.status" dictCode="agv_task_status" placeholder="请选择任务状态" :string-to-number="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
|
|
|
|||
|
|
@ -21,11 +21,8 @@
|
|||
import { ref, nextTick, defineExpose } from 'vue';
|
||||
import TesAgvForm from './TesAgvForm.vue';
|
||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const title = ref<string>('');
|
||||
const width = ref<number>(800);
|
||||
const visible = ref<boolean>(false);
|
||||
const disableSubmit = ref<boolean>(false);
|
||||
const registerForm = ref();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
showConveyorLine = '/api/conveyorLine/showConveyorLine',
|
||||
}
|
||||
|
||||
export const showConveyorLine = (conveyorLine) => {
|
||||
return defHttp.get(
|
||||
{
|
||||
url: Api.showConveyorLine,
|
||||
params: { conveyorLine },
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,438 @@
|
|||
<template>
|
||||
<div class="monitor-container">
|
||||
<header class="header">
|
||||
<div class="header-left">
|
||||
<div class="logo-box">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="logo-icon">
|
||||
<rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect>
|
||||
<path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="title-group">
|
||||
<h1 class="system-title">WCS 输送线监控大屏</h1>
|
||||
<div class="system-sub">CONVEYOR LINE MONITORING SYSTEM V4.2</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
<div class="status-group">
|
||||
<span class="status-dot online"></span>
|
||||
<span class="status-text">SYSTEM ONLINE</span>
|
||||
</div>
|
||||
<div class="divider">|</div>
|
||||
<div class="node-info">Node: CN-SH-01</div>
|
||||
<div class="time-display">
|
||||
<span class="time-big">{{ timeOnly }}</span>
|
||||
<span class="date-small">{{ dateOnly }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="dashboard-card">
|
||||
<section class="scan-section">
|
||||
<div class="section-header">
|
||||
<span class="label-cn">当前扫描</span>
|
||||
<span class="label-en">CURRENT SCAN</span>
|
||||
</div>
|
||||
<div class="scan-content">
|
||||
<div class="scan-code">{{ scanData.stockCode }}</div>
|
||||
<button class="pallet-btn">
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none">
|
||||
<path
|
||||
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
||||
></path>
|
||||
</svg>
|
||||
{{ scanData.izAll }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="info-grid">
|
||||
<div class="info-card type-card">
|
||||
<div class="card-label">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M17 1l4 4-4 4"></path>
|
||||
<path d="M3 11V9a4 4 0 0 1 4-4h14"></path>
|
||||
<path d="M7 23l-4-4 4-4"></path>
|
||||
<path d="M21 13v2a4 4 0 0 1-4 4H3"></path>
|
||||
</svg>
|
||||
<span>任务类型 TASK TYPE</span>
|
||||
</div>
|
||||
<div class="card-value value-purple">{{ scanData.taskType }}</div>
|
||||
</div>
|
||||
|
||||
<div class="info-card dest-card">
|
||||
<div class="card-label">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
<path d="M12 21.7C17.3 17 20 13 20 10a8 8 0 1 0-16 0c0 3 2.7 7 8 11.7z"></path>
|
||||
</svg>
|
||||
<span>目的站 DESTINATION</span>
|
||||
</div>
|
||||
<div class="card-value value-pink">{{ scanData.endCode }}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="remark-section">
|
||||
<div class="section-header">
|
||||
<svg class="icon-sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<line x1="12" y1="16" x2="12" y2="12"></line>
|
||||
<line x1="12" y1="8" x2="12.01" y2="8"></line>
|
||||
</svg>
|
||||
<span class="label-mix">特殊描述 / REMARKS</span>
|
||||
</div>
|
||||
<div class="remark-text">{{ scanData.description===''?'无到站任务!!!':scanData.description }}</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { showConveyorLine } from '@/views/conveyorLine/ConveyorLine.api';
|
||||
|
||||
// 模拟数据 (您可以替换为真实 Props 或 API 数据)
|
||||
const scanData = ref({
|
||||
stockCode: '',
|
||||
taskType: '',
|
||||
endCode: '',
|
||||
izAll: '',
|
||||
description: '',
|
||||
});
|
||||
|
||||
// 时间处理
|
||||
const now = ref(dayjs());
|
||||
const updateTime = () => {
|
||||
now.value = dayjs();
|
||||
};
|
||||
|
||||
const timeOnly = computed(() => now.value.format('HH:mm:ss'));
|
||||
const dateOnly = computed(() => {
|
||||
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||
return `${now.value.format('YYYY/MM/DD')} ${weekDays[now.value.day()]}`;
|
||||
});
|
||||
|
||||
let timer;
|
||||
onMounted(() => {
|
||||
timer = setInterval(updateTime, 1000);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
});
|
||||
|
||||
async function queryData() {
|
||||
const conveyorLine = 'CKJBK01';
|
||||
const res = await showConveyorLine(conveyorLine);
|
||||
scanData.value = {
|
||||
stockCode: res.stockCode,
|
||||
taskType: res.taskType,
|
||||
endCode: res.endCode,
|
||||
izAll: res.izAll,
|
||||
description: res.description,
|
||||
};
|
||||
console.log('数据:' , res);
|
||||
}
|
||||
|
||||
// 定时更新查询数据
|
||||
setInterval(() => {
|
||||
console.log('更新数据');
|
||||
queryData();
|
||||
}, 3000);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 引入等宽字体 (可选,如果有本地字体更好) */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@500;700&family=Inter:wght@400;600;800&display=swap');
|
||||
|
||||
/* --- 全局容器 --- */
|
||||
.monitor-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-color: #02050e; /* 极深黑背景 */
|
||||
color: #ffffff;
|
||||
padding: 20px 32px;
|
||||
box-sizing: border-box;
|
||||
font-family:
|
||||
'Inter',
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
Roboto,
|
||||
'Helvetica Neue',
|
||||
Arial,
|
||||
sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* --- 1. Header 样式 --- */
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo-box {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: linear-gradient(135deg, #007bff, #00d4ff);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #fff;
|
||||
}
|
||||
|
||||
.title-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.system-title {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
margin: 0;
|
||||
letter-spacing: 0.5px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.system-sub {
|
||||
font-size: 11px;
|
||||
color: #8b9bb4; /* 稍微偏蓝灰 */
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: #00e676;
|
||||
box-shadow: 0 0 8px #00e676;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
color: #00e676;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.divider {
|
||||
color: #343a40;
|
||||
}
|
||||
|
||||
.node-info {
|
||||
color: #5d6e82;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.time-display {
|
||||
text-align: right;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.time-big {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.date-small {
|
||||
font-size: 12px;
|
||||
color: #8b9bb4;
|
||||
}
|
||||
|
||||
/* --- 2. 主卡片样式 (深蓝框) --- */
|
||||
.dashboard-card {
|
||||
background-color: #101524;
|
||||
background-image: radial-gradient(circle at 100% 0%, rgba(56, 96, 246, 0.12) 0%, transparent 40%);
|
||||
border: 1px solid rgba(47, 54, 77, 0.5);
|
||||
border-radius: 12px;
|
||||
padding: 36px 48px;
|
||||
height: calc(100vh - 110px);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start; /* 内容上对齐 */
|
||||
gap: 30px; /* 模块间距 */
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* 当前扫描 */
|
||||
.section-header {
|
||||
font-size: 14px;
|
||||
color: #495057;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.label-cn {
|
||||
color: #8b9bb4;
|
||||
}
|
||||
|
||||
.scan-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #1f2029;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.scan-code {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: 80px; /* 超大字体 */
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
line-height: 1;
|
||||
text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.pallet-btn {
|
||||
background: rgba(30, 36, 56, 0.6);
|
||||
border: 1px solid #3d5afe;
|
||||
color: #536dfe;
|
||||
padding: 10px 24px;
|
||||
border-radius: 30px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.pallet-btn:hover {
|
||||
background: #3d5afe;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 任务卡片栅格 */
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background-color: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 24px 32px;
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* !* 增加一点微弱的渐变光晕背景 *!
|
||||
.type-card {
|
||||
background: radial-gradient(circle at 100% 0%, rgba(111, 66, 193, 0.1) 0%, transparent 50%), #11111a;
|
||||
}
|
||||
.dest-card {
|
||||
background: radial-gradient(circle at 100% 0%, rgba(232, 62, 140, 0.1) 0%, transparent 50%), #11111a;
|
||||
}*/
|
||||
|
||||
.card-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #6c7a92;
|
||||
font-size: 14px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.card-label .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 40px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* 高亮颜色 */
|
||||
|
||||
.value-purple {
|
||||
color: #00d2ff;
|
||||
text-shadow: 0 0 15px rgba(0, 210, 255, 0.15);
|
||||
}
|
||||
|
||||
.value-pink {
|
||||
color: #c780ff; /* 浅紫 */
|
||||
text-shadow: 0 0 15px rgba(199, 128, 255, 0.15);
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
||||
/* 底部备注 */
|
||||
.remark-section {
|
||||
background-color: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 8px;
|
||||
padding: 24px 32px;
|
||||
flex: 1; /* 占满剩余高度 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.label-mix {
|
||||
font-size: 12px;
|
||||
color: #6c757d;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.icon-sm {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: #6c7a92;
|
||||
}
|
||||
|
||||
.remark-text {
|
||||
font-size: 30px;
|
||||
color: #d1d5db; /* 灰白色,不刺眼 */
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -137,6 +137,10 @@
|
|||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
defSort: {
|
||||
column: 'id',
|
||||
order: 'desc',
|
||||
},
|
||||
showActionColumn: false,
|
||||
beforeFetch: async (params) => {
|
||||
for (let key in fieldPickers) {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { useMessage } from "/@/hooks/web/useMessage";
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/shipping/pick/list',
|
||||
save='/shipping/pick/add',
|
||||
edit='/shipping/pick/edit',
|
||||
save = '/shipping/pick/add',
|
||||
edit = '/shipping/pick/edit',
|
||||
deleteOne = '/shipping/pick/delete',
|
||||
deleteBatch = '/shipping/pick/deleteBatch',
|
||||
importExcel = '/shipping/pick/importExcel',
|
||||
exportXls = '/shipping/pick/exportXls',
|
||||
queryDataById = '/shipping/pick/queryById',
|
||||
pickDetailList = '/shipping/pick/queryPickDetailByMainId',
|
||||
allocatePick = '/shipping/pick/allocatePick',
|
||||
cancelAllocate = '/shipping/pick/cancelAllocate',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
|
|
@ -29,23 +32,26 @@ export const getImportUrl = Api.importExcel;
|
|||
* 查询子表数据
|
||||
* @param params
|
||||
*/
|
||||
export const queryPickDetailListByMainId = (id) => defHttp.get({url: Api.pickDetailList, params:{ id }});
|
||||
export const queryPickDetailListByMainId = (id) =>
|
||||
defHttp.get({
|
||||
url: Api.pickDetailList,
|
||||
params: { id },
|
||||
});
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
|
|
@ -58,24 +64,51 @@ export const batchDelete = (params, handleSuccess) => {
|
|||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据id查询数据
|
||||
* @param params
|
||||
*/
|
||||
export const queryDataById = (id) => defHttp.get({url: Api.queryDataById, params:{ id }});
|
||||
* 根据id查询数据
|
||||
* @param params
|
||||
*/
|
||||
export const queryDataById = (id) => defHttp.get({ url: Api.queryDataById, params: { id } });
|
||||
|
||||
/**
|
||||
* 分配出库单
|
||||
* @param params
|
||||
*/
|
||||
export const allocatePick = (ids,handleSuccess) => {
|
||||
return defHttp.get({ url: Api.allocatePick, params: { ids } }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消分配
|
||||
* @param params
|
||||
*/
|
||||
export const cancelAllocate = (ids,handleSuccess) => {
|
||||
return defHttp.get({ url: Api.cancelAllocate, params: { ids } }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,21 +7,25 @@ export const columns: BasicColumn[] = [
|
|||
title: '系统单号',
|
||||
align: 'center',
|
||||
dataIndex: 'orderNo',
|
||||
width: '130px',
|
||||
},
|
||||
{
|
||||
title: '外部单号',
|
||||
align: 'center',
|
||||
dataIndex: 'thirdOrderNo',
|
||||
width: '130px',
|
||||
},
|
||||
{
|
||||
title: '任务号',
|
||||
align: 'center',
|
||||
dataIndex: 'no',
|
||||
width: '130px',
|
||||
},
|
||||
{
|
||||
title: '订单状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status_dictText',
|
||||
width: '100px',
|
||||
customRender: ({ text }) => {
|
||||
//出库状态:1.已创建;2.部分分配;3.已分配;4.拣货中;5.拣货完成;6.已关闭;7.已取消。
|
||||
const statusColorMap = {
|
||||
|
|
@ -41,38 +45,38 @@ export const columns: BasicColumn[] = [
|
|||
title: '单据类型',
|
||||
align: 'center',
|
||||
dataIndex: 'orderType_dictText',
|
||||
width: '100px',
|
||||
},
|
||||
|
||||
{
|
||||
title: '需求数量',
|
||||
align: 'center',
|
||||
dataIndex: 'orderQty',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
title: '分配数量',
|
||||
align: 'center',
|
||||
dataIndex: 'allocatedQty',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
title: '拣货数量',
|
||||
align: 'center',
|
||||
dataIndex: 'pickedQty',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
title: '外部仓库',
|
||||
align: 'center',
|
||||
dataIndex: 'whCode',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
title: '客户代码',
|
||||
title: '客户',
|
||||
align: 'center',
|
||||
dataIndex: 'customerCode',
|
||||
},
|
||||
{
|
||||
title: '外部仓库',
|
||||
align: 'center',
|
||||
dataIndex: 'whCode',
|
||||
},
|
||||
{
|
||||
title: '订单日期',
|
||||
align: 'center',
|
||||
|
|
@ -108,7 +112,7 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
key: 'unit',
|
||||
type: JVxeTypes.select,
|
||||
dictCode: 'package_unit',
|
||||
width: '130px',
|
||||
width: '80px',
|
||||
placeholder: '请选择${title}',
|
||||
defaultValue: '托',
|
||||
},
|
||||
|
|
@ -116,7 +120,7 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
title: '需求数量',
|
||||
key: 'orderQty',
|
||||
type: JVxeTypes.inputNumber,
|
||||
width: '130px',
|
||||
width: '110px',
|
||||
validateRules: [
|
||||
{
|
||||
required: true, // 必填
|
||||
|
|
@ -128,7 +132,7 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
title: '分配数量',
|
||||
key: 'allocatedQty',
|
||||
type: JVxeTypes.normal,
|
||||
width: '130px',
|
||||
width: '80px',
|
||||
defaultValue: '0',
|
||||
disabled: true,
|
||||
},
|
||||
|
|
@ -136,7 +140,7 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
title: '拣货数量',
|
||||
key: 'pickedQty',
|
||||
type: JVxeTypes.normal,
|
||||
width: '130px',
|
||||
width: '80px',
|
||||
placeholder: '请输入${title}',
|
||||
defaultValue: '0',
|
||||
disabled: true,
|
||||
|
|
@ -145,7 +149,7 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
title: '明细状态',
|
||||
key: 'status',
|
||||
type: JVxeTypes.normal,
|
||||
width: '120px',
|
||||
width: '80px',
|
||||
defaultValue: '1',
|
||||
formatter: ({ cellValue }) => {
|
||||
//入库状态:1.已创建;2.部分收货;3.收货完成;4.已取消。
|
||||
|
|
@ -205,4 +209,10 @@ export const pickDetailColumns: JVxeColumn[] = [
|
|||
placeholder: '请输入${title}',
|
||||
defaultValue: null,
|
||||
},
|
||||
{
|
||||
title: '返回报文',
|
||||
key: 'resMessage',
|
||||
type: JVxeTypes.normal,
|
||||
width: '200px',
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -56,6 +56,25 @@
|
|||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="'shipping:data_pick:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="allocate_loading"
|
||||
v-auth="'shipping:data_pick:allocatePick'"
|
||||
@click="handleAllocatePick"
|
||||
preIcon="ant-design:edit-outlined"
|
||||
>
|
||||
分配
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
danger
|
||||
:loading="cancel_loading"
|
||||
v-auth="'shipping:data_pick:cancelAllocate'"
|
||||
@click="handleCancelAllocate"
|
||||
preIcon="ant-design:edit-outlined"
|
||||
>
|
||||
取消分配
|
||||
</a-button>
|
||||
<a-button type="primary" v-auth="'shipping:data_pick:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出 </a-button>
|
||||
<j-upload-button type="primary" v-auth="'shipping:data_pick:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls"
|
||||
>导入
|
||||
|
|
@ -94,7 +113,7 @@
|
|||
import { useModal } from '/@/components/Modal';
|
||||
import PickModal from './components/PickModal.vue';
|
||||
import { columns } from './Pick.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './Pick.api';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, allocatePick, cancelAllocate } from './Pick.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDateByPicker } from '/@/utils';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
|
|
@ -102,6 +121,8 @@
|
|||
import { JInput, JDictSelectTag } from '@/components/Form';
|
||||
import JRangeDate from '@/components/Form/src/jeecg/components/JRangeDate.vue';
|
||||
|
||||
const allocate_loading = ref(false);
|
||||
const cancel_loading = ref(false);
|
||||
const fieldPickers = reactive({});
|
||||
const formRef = ref();
|
||||
const queryParam = reactive<any>({});
|
||||
|
|
@ -156,7 +177,7 @@
|
|||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys, selectedRows }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
|
|
@ -168,6 +189,67 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配事件
|
||||
*/
|
||||
async function handleAllocatePick() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return createMessage.error('请选择出库单');
|
||||
}
|
||||
|
||||
// 选中的数据中状态有1、2、4 返回true,否则返回false
|
||||
const validStatuses = [1, 2, 4];
|
||||
const allValidStatus = selectedRows.value.every((row: any) => validStatuses.includes(row.status));
|
||||
if (!allValidStatus) {
|
||||
return createMessage.error('【已创建、 部分分配、部分拣货】状态的出库单才允许分配');
|
||||
}
|
||||
if (allocate_loading.value) {
|
||||
return;
|
||||
}
|
||||
// 设置加载状态,防止重复提交
|
||||
allocate_loading.value = true;
|
||||
try {
|
||||
await allocatePick(selectedRowKeys.value, handleSuccess);
|
||||
} catch (e) {
|
||||
console.error('分配失败:', e);
|
||||
handleSuccess()
|
||||
} finally {
|
||||
// 重置加载状态
|
||||
allocate_loading.value = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消分配
|
||||
*/
|
||||
async function handleCancelAllocate() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return createMessage.error('请选择出库单');
|
||||
}
|
||||
|
||||
// 选中的数据中状态有2、3 返回true,否则返回false
|
||||
const validStatuses = [2, 3];
|
||||
const allValidStatus = selectedRows.value.every((row: any) => validStatuses.includes(row.status));
|
||||
if (!allValidStatus) {
|
||||
return createMessage.error('【部分分配、已分配】状态的出库单才允许取消分配');
|
||||
}
|
||||
if (cancel_loading.value) {
|
||||
return;
|
||||
}
|
||||
// 设置加载状态,防止重复提交
|
||||
cancel_loading.value = true;
|
||||
try {
|
||||
await cancelAllocate(selectedRowKeys.value, handleSuccess);
|
||||
} catch (e) {
|
||||
console.error('取消失败:', e);
|
||||
handleSuccess()
|
||||
} finally {
|
||||
// 重置加载状态
|
||||
cancel_loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue