Merge branch 'main' of http://27.223.88.102:33000/chenx/qhmes
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||
"@vant/area-data": "^1.5.2",
|
||||
"@vue/shared": "^3.5.22",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.12.2",
|
||||
|
||||
@@ -48,9 +48,12 @@ export function ensureWebSocketConnected(): void {
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
if (result?.status?.value === 'OPEN' && connectedUrl === url) {
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】已连接/连接中则复用,避免重复建连-----------
|
||||
const status = result?.status?.value;
|
||||
if (connectedUrl === url && (status === 'OPEN' || status === 'CONNECTING')) {
|
||||
return;
|
||||
}
|
||||
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】已连接/连接中则复用,避免重复建连-----------
|
||||
connectWebSocket(url);
|
||||
}
|
||||
|
||||
@@ -59,20 +62,34 @@ export function ensureWebSocketConnected(): void {
|
||||
* @param url
|
||||
*/
|
||||
export function connectWebSocket(url: string) {
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】单例连接:关闭旧实例后再建,防止多路 autoReconnect 互踢-----------
|
||||
const status = result?.status?.value;
|
||||
if (connectedUrl === url && (status === 'OPEN' || status === 'CONNECTING')) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
result?.close?.();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
connectedUrl = url;
|
||||
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】单例连接:关闭旧实例后再建,防止多路 autoReconnect 互踢-----------
|
||||
// 代码逻辑说明: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
const token = (getToken() || '') as string;
|
||||
result = useWebSocket(url, {
|
||||
// 自动重连 (遇到错误最多重复连接10次)
|
||||
autoReconnect: {
|
||||
retries : 10,
|
||||
delay : 5000
|
||||
retries: 10,
|
||||
delay: 5000,
|
||||
},
|
||||
// 心跳检测
|
||||
// 心跳检测:服务端同连接直接回 ping;pongTimeout 需大于网络抖动
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【WebSocket】稳定心跳参数,避免 pong 超时频繁断线-----------
|
||||
heartbeat: {
|
||||
message: "ping",
|
||||
interval: 55000
|
||||
message: 'ping',
|
||||
interval: 30000,
|
||||
pongTimeout: 20000,
|
||||
},
|
||||
//update-end---author:jiangxh ---date:20260729 for:【WebSocket】稳定心跳参数,避免 pong 超时频繁断线-----------
|
||||
protocols: [token],
|
||||
// 代码逻辑说明: [issues/6662] 演示系统socket总断,换一个写法
|
||||
onConnected: function (ws) {
|
||||
@@ -81,7 +98,11 @@ export function connectWebSocket(url: string) {
|
||||
//update-begin---author:xsl ---date:20260528 for:【IM聊天】WS 重连后通知监听方重新拉取消息-----------
|
||||
if (wsConnectionCount > 1) {
|
||||
reconnectListeners.forEach((cb) => {
|
||||
try { cb(); } catch (err) { console.error(err); }
|
||||
try {
|
||||
cb();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
//update-end---author:xsl ---date:20260528 for:【IM聊天】WS 重连后通知监听方重新拉取消息-----------
|
||||
@@ -112,54 +133,8 @@ export function connectWebSocket(url: string) {
|
||||
}
|
||||
},
|
||||
});
|
||||
// if (result) {
|
||||
// result.open = onOpen;
|
||||
// result.close = onClose;
|
||||
|
||||
// const ws = unref(result.ws);
|
||||
// if(ws!=null){
|
||||
// ws.onerror = onError;
|
||||
// ws.onmessage = onMessage;
|
||||
// ws.onopen = onOpen;
|
||||
// ws.onclose = onClose;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
function onOpen() {
|
||||
console.log('[WebSocket] 连接成功');
|
||||
}
|
||||
|
||||
function onClose(e) {
|
||||
console.log('[WebSocket] 连接断开:', e);
|
||||
}
|
||||
|
||||
function onError(e) {
|
||||
console.log('[WebSocket] 连接发生错误: ', e);
|
||||
}
|
||||
|
||||
function onMessage(e) {
|
||||
console.debug('[WebSocket] -----接收消息-------', e.data);
|
||||
try {
|
||||
// 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
if(e==='ping'){
|
||||
return;
|
||||
}
|
||||
const data = JSON.parse(e.data);
|
||||
for (const callback of listeners.keys()) {
|
||||
try {
|
||||
callback(data);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[WebSocket] data解析失败:', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加 WebSocket 消息监听
|
||||
* @param callback
|
||||
|
||||
@@ -293,7 +293,9 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
|
||||
// authenticationScheme: 'Bearer',
|
||||
authenticationScheme: '',
|
||||
//接口超时设置
|
||||
timeout: 10 * 1000,
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【HTTP】远程库场景默认超时10s过短,调整为60s-----------
|
||||
timeout: 60 * 1000,
|
||||
//update-end---author:jiangxh ---date:20260729 for:【HTTP】远程库场景默认超时10s过短,调整为60s-----------
|
||||
// 基础接口地址
|
||||
// baseURL: globSetting.apiUrl,
|
||||
headers: { 'Content-Type': ContentTypeEnum.JSON },
|
||||
|
||||
@@ -10,6 +10,8 @@ enum Api {
|
||||
importExcel = '/mes/material/material/importExcel',
|
||||
exportXls = '/mes/material/material/exportXls',
|
||||
queryById = '/mes/material/material/queryById',
|
||||
checkMaterialCode = '/mes/material/material/checkMaterialCode',
|
||||
checkMaterialName = '/mes/material/material/checkMaterialName',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
@@ -17,6 +19,12 @@ export const getImportUrl = Api.importExcel;
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params }, { successMessageMode: 'none' });
|
||||
|
||||
export const checkMaterialCode = (params: { materialCode: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkMaterialCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const checkMaterialName = (params: { materialName: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkMaterialName, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const deleteOne = (params, handleSuccess) =>
|
||||
defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => handleSuccess());
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { loadTreeData } from '/@/api/common/api';
|
||||
import { checkMaterialName } from './MesMaterial.api';
|
||||
|
||||
function useStatusText(v: unknown) {
|
||||
if (v === 1) return '使用中';
|
||||
@@ -32,6 +33,7 @@ const glueCategoryProps = {
|
||||
placeholder: '请选择胶料类别',
|
||||
};
|
||||
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【胶料】列表/表单去掉胶料编码展示-----------
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: '胶料名称', align: 'center', width: 160, dataIndex: 'materialName' },
|
||||
{ title: '胶料类别', align: 'center', width: 140, dataIndex: 'categoryId_dictText' },
|
||||
@@ -92,7 +94,32 @@ export const searchFormSchema: FormSchema[] = [
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{ label: '', field: 'id', component: 'Input', show: false },
|
||||
{ label: '胶料名称', field: 'materialName', component: 'Input', required: true },
|
||||
//update-begin---author:jiangxh ---date:20260730 for:【胶料】编号隐藏,保存由后端按名称回填-----------
|
||||
// 列表/表单均不展示;新增编辑保存后后端将 materialCode = materialName
|
||||
{ label: '', field: 'materialCode', component: 'Input', show: false },
|
||||
//update-end---author:jiangxh ---date:20260730 for:【胶料】编号隐藏,保存由后端按名称回填-----------
|
||||
{
|
||||
label: '胶料名称',
|
||||
field: 'materialName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
dynamicRules: ({ model }) => [
|
||||
{ required: true, message: '请输入胶料名称' },
|
||||
{
|
||||
validator: async (_rule, value) => {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
if (!v) return Promise.resolve();
|
||||
try {
|
||||
await checkMaterialName({ materialName: v, dataId: model?.id });
|
||||
return Promise.resolve();
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '胶料名称不能重复');
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '胶料类别',
|
||||
field: 'categoryId',
|
||||
@@ -141,3 +168,4 @@ export const formSchema: FormSchema[] = [
|
||||
componentProps: { options: specialRubberOptions },
|
||||
},
|
||||
];
|
||||
//update-end---author:jiangxh ---date:20260729 for:【胶料】列表/表单去掉胶料编码展示-----------
|
||||
|
||||
@@ -29,6 +29,7 @@ import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import MesMaterialModal from './modules/MesMaterialModal.vue';
|
||||
import { columns, searchFormSchema } from './MesMaterial.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './MesMaterial.api';
|
||||
import { applyJeecgLikeQuery, RUBBER_MATERIAL_LIKE_FIELDS } from './materialQuery.util';
|
||||
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
@@ -39,6 +40,7 @@ const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
canResize: true,
|
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true },
|
||||
actionColumn: { width: 120 },
|
||||
beforeFetch: (params) => applyJeecgLikeQuery(params, RUBBER_MATERIAL_LIKE_FIELDS),
|
||||
},
|
||||
exportConfig: { name: '胶料信息', url: getExportUrl },
|
||||
importConfig: { url: getImportUrl, success: handleSuccess },
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Modal } from 'ant-design-vue';
|
||||
enum Api {
|
||||
list = '/mes/material/mixerMaterial/list',
|
||||
queryById = '/mes/material/mixerMaterial/queryById',
|
||||
checkMaterialCode = '/mes/material/mixerMaterial/checkMaterialCode',
|
||||
checkMaterialName = '/mes/material/mixerMaterial/checkMaterialName',
|
||||
save = '/mes/material/mixerMaterial/add',
|
||||
edit = '/mes/material/mixerMaterial/edit',
|
||||
deleteOne = '/mes/material/mixerMaterial/delete',
|
||||
@@ -17,6 +19,12 @@ export const getImportUrl = Api.importExcel;
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
|
||||
export const checkMaterialCode = (params: { materialCode: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkMaterialCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const checkMaterialName = (params: { materialName: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkMaterialName, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const deleteOne = (params, handleSuccess) =>
|
||||
defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => handleSuccess());
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { loadTreeData } from '/@/api/common/api';
|
||||
import { checkMaterialCode, checkMaterialName } from './MesMixerMaterial.api';
|
||||
|
||||
function feedManageStatusText(v: unknown) {
|
||||
if (v === 1) return '在投管';
|
||||
@@ -93,8 +94,50 @@ const useStatusOptions = [
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{ label: '', field: 'id', component: 'Input', show: false },
|
||||
{ label: '物料编码', field: 'materialCode', component: 'Input', required: true },
|
||||
{ label: '物料名称', field: 'materialName', component: 'Input', required: true },
|
||||
{
|
||||
label: '物料编码',
|
||||
field: 'materialCode',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
dynamicRules: ({ model }) => [
|
||||
{ required: true, message: '请输入物料编码' },
|
||||
{
|
||||
validator: async (_rule, value) => {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
if (!v) return Promise.resolve();
|
||||
try {
|
||||
await checkMaterialCode({ materialCode: v, dataId: model?.id });
|
||||
return Promise.resolve();
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '物料编码不能重复');
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '物料名称',
|
||||
field: 'materialName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
dynamicRules: ({ model }) => [
|
||||
{ required: true, message: '请输入物料名称' },
|
||||
{
|
||||
validator: async (_rule, value) => {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
if (!v) return Promise.resolve();
|
||||
try {
|
||||
await checkMaterialName({ materialName: v, dataId: model?.id });
|
||||
return Promise.resolve();
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '物料名称不能重复');
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
{ label: 'ERP编号', field: 'erpCode', component: 'Input' },
|
||||
{
|
||||
label: '物料大类',
|
||||
@@ -127,7 +170,9 @@ export const formSchema: FormSchema[] = [
|
||||
componentProps: { options: useStatusOptions },
|
||||
},
|
||||
{ label: '比重', field: 'specificGravity', component: 'InputNumber', componentProps: { min: 0, step: 0.001, precision: 6 } },
|
||||
{ label: '保质期(天)', field: 'shelfLifeDays', component: 'InputNumber', componentProps: { min: 0, precision: 0 } },
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天-----------
|
||||
{ label: '保质期(天)', field: 'shelfLifeDays', component: 'InputNumber', defaultValue: 365, componentProps: { min: 0, precision: 0 } },
|
||||
//update-end---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天-----------
|
||||
{ label: '最短烘胶时间(分钟)', field: 'minBakeMinutes', component: 'InputNumber', componentProps: { min: 0, precision: 0 } },
|
||||
{
|
||||
label: '总安全库存KG',
|
||||
|
||||
@@ -77,6 +77,7 @@ import MesMixerMaterialModal from './modules/MesMixerMaterialModal.vue';
|
||||
import MesMixerMaterialSysCategoryModal from './modules/MesMixerMaterialSysCategoryModal.vue';
|
||||
import { columns, searchFormSchema } from './MesMixerMaterial.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './MesMixerMaterial.api';
|
||||
import { applyJeecgLikeQuery, MIXER_MATERIAL_LIKE_FIELDS } from './materialQuery.util';
|
||||
import { loadTreeData as loadCategoryTreeRoot } from '/@/views/system/category/category.api';
|
||||
import type { KeyType } from '/@/components/Tree/src/types/tree';
|
||||
import { deleteMaterialSysCategory, fetchMaterialCategoryRoot } from './MesMixerMaterialSysCategory.api';
|
||||
@@ -119,7 +120,10 @@ const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
canResize: true,
|
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true },
|
||||
actionColumn: { width: 120 },
|
||||
beforeFetch: (params) => Object.assign(params, queryParam),
|
||||
beforeFetch: (params) => {
|
||||
Object.assign(params, queryParam);
|
||||
return applyJeecgLikeQuery(params, MIXER_MATERIAL_LIKE_FIELDS);
|
||||
},
|
||||
},
|
||||
exportConfig: { name: '密炼物料信息', url: getExportUrl, params: queryParam },
|
||||
importConfig: { url: getImportUrl, success: handleSuccess },
|
||||
|
||||
52
jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts
Normal file
52
jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Jeecg QueryGenerator 模糊查询工具:
|
||||
* - 普通字段:值两侧加 * 转为 LIKE
|
||||
* - 关键字多字段 OR:走 superQueryParams
|
||||
*/
|
||||
|
||||
/** 给指定字符串查询字段追加 *value*(已含 * 则不重复处理) */
|
||||
export function applyJeecgLikeQuery(params: Recordable, fields: string[]): Recordable {
|
||||
if (!params || !fields?.length) {
|
||||
return params;
|
||||
}
|
||||
for (const field of fields) {
|
||||
const raw = params[field];
|
||||
if (raw == null || raw === '') {
|
||||
continue;
|
||||
}
|
||||
const text = String(raw).trim();
|
||||
if (!text || text.includes('*')) {
|
||||
continue;
|
||||
}
|
||||
params[field] = `*${text}*`;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/** 构造多字段 OR 模糊高级查询参数 */
|
||||
export function buildOrLikeSuperQuery(fields: string[], keyword: string): {
|
||||
superQueryMatchType: string;
|
||||
superQueryParams: string;
|
||||
} | null {
|
||||
const kw = keyword?.trim();
|
||||
if (!kw || !fields?.length) {
|
||||
return null;
|
||||
}
|
||||
const conditions = fields.map((field) => ({
|
||||
field,
|
||||
rule: 'like',
|
||||
val: kw,
|
||||
}));
|
||||
return {
|
||||
superQueryMatchType: 'or',
|
||||
superQueryParams: encodeURI(JSON.stringify(conditions)),
|
||||
};
|
||||
}
|
||||
|
||||
/** 密炼物料文本查询字段 */
|
||||
export const MIXER_MATERIAL_LIKE_FIELDS = ['materialCode', 'materialName', 'erpCode', 'materialDesc', 'aliasName'];
|
||||
|
||||
/** 胶料文本查询字段(已去掉胶料编码) */
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字查询去掉编码-----------
|
||||
export const RUBBER_MATERIAL_LIKE_FIELDS = ['materialName', 'erpCode', 'aliasName', 'shortName'];
|
||||
//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字查询去掉编码-----------
|
||||
@@ -10,6 +10,7 @@
|
||||
import { BasicTable, useTable } from '/@/components/Table';
|
||||
import { list as materialList, queryById as queryMaterialById } from '../MesMaterial.api';
|
||||
import { columns as materialColumns, searchFormSchema as materialSearch } from '../MesMaterial.data';
|
||||
import { applyJeecgLikeQuery, RUBBER_MATERIAL_LIKE_FIELDS } from '../materialQuery.util';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const emit = defineEmits(['register', 'select']);
|
||||
@@ -21,7 +22,9 @@
|
||||
|
||||
const [registerTable, { reload, getSelectRowKeys, getSelectRows, setSelectedRowKeys, clearSelectedRowKeys }] = useTable({
|
||||
api: materialList,
|
||||
columns: materialColumns.slice(0, 6),
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】配合示方选胶料不展示胶料编码-----------
|
||||
columns: materialColumns.filter((col) => col.dataIndex !== 'materialCode').slice(0, 6),
|
||||
//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】配合示方选胶料不展示胶料编码-----------
|
||||
rowKey: 'id',
|
||||
useSearchForm: true,
|
||||
formConfig: {
|
||||
@@ -32,12 +35,15 @@
|
||||
canResize: false,
|
||||
showIndexColumn: false,
|
||||
immediate: true,
|
||||
beforeFetch: (params) => ({
|
||||
...params,
|
||||
enableFlag: params.enableFlag ?? 1,
|
||||
onlySales: onlySales.value ? 1 : undefined,
|
||||
excludeProductionFB1: excludeProductionFB1.value ? 1 : undefined,
|
||||
}),
|
||||
beforeFetch: (params) => {
|
||||
const next = {
|
||||
...params,
|
||||
enableFlag: params.enableFlag ?? 1,
|
||||
onlySales: onlySales.value ? 1 : undefined,
|
||||
excludeProductionFB1: excludeProductionFB1.value ? 1 : undefined,
|
||||
};
|
||||
return applyJeecgLikeQuery(next, RUBBER_MATERIAL_LIKE_FIELDS);
|
||||
},
|
||||
rowSelection: {
|
||||
type: 'radio',
|
||||
columnWidth: 48,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { BasicTable, useTable } from '/@/components/Table';
|
||||
import { list as mixerList, queryById as queryMixerById } from '../MesMixerMaterial.api';
|
||||
import { columns as mixerColumns, searchFormSchema as mixerSearch } from '../MesMixerMaterial.data';
|
||||
import { applyJeecgLikeQuery, MIXER_MATERIAL_LIKE_FIELDS } from '../materialQuery.util';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A53】通用密炼物料选料弹窗种类改读配置表-----------
|
||||
import {
|
||||
@@ -40,6 +41,7 @@
|
||||
canResize: false,
|
||||
showIndexColumn: false,
|
||||
immediate: true,
|
||||
beforeFetch: (params) => applyJeecgLikeQuery(params, MIXER_MATERIAL_LIKE_FIELDS),
|
||||
rowSelection: {
|
||||
type: 'radio',
|
||||
columnWidth: 48,
|
||||
|
||||
@@ -3,12 +3,35 @@ import { FormSchema } from '/@/components/Form';
|
||||
export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
{ label: 'id', field: 'id', component: 'Input', show: false },
|
||||
{ label: 'tenantId', field: 'tenantId', component: 'InputNumber', show: false },
|
||||
{
|
||||
label: '访问模式',
|
||||
field: 'accessMode',
|
||||
component: 'Select',
|
||||
defaultValue: 'DESKTOP_AGENT',
|
||||
required: true,
|
||||
helpMessage: '桌面代理:由厂区桌面端直连设备库;直连:MES 服务器 JDBC(仅调试)',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '桌面代理(推荐)', value: 'DESKTOP_AGENT' },
|
||||
{ label: '服务端直连', value: 'DIRECT' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '绑定桌面代理 ID',
|
||||
field: 'agentDeviceId',
|
||||
component: 'Input',
|
||||
helpMessage: '与桌面端「设备 ID」一致;留空则自动选用当前在线代理',
|
||||
componentProps: { placeholder: '例如工控机计算机名' },
|
||||
ifShow: ({ values }) => values.accessMode !== 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '服务器地址',
|
||||
field: 'serverHost',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: { placeholder: 'IP 或域名,例如 192.168.1.10 或 xxx.vicp.fun' },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '端口',
|
||||
@@ -17,6 +40,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
defaultValue: 1433,
|
||||
required: true,
|
||||
componentProps: { min: 1, max: 65535, style: { width: '100%' } },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '数据库名',
|
||||
@@ -24,6 +48,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
component: 'Input',
|
||||
defaultValue: 'MES_ShareDB',
|
||||
required: true,
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '用户名',
|
||||
@@ -31,12 +56,14 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: { placeholder: '例如 sa' },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'dbPassword',
|
||||
component: 'InputPassword',
|
||||
componentProps: { placeholder: '编辑时留空表示不修改密码' },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '读取开关',
|
||||
@@ -68,7 +95,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
label: '启用连接',
|
||||
field: 'status',
|
||||
component: 'Switch',
|
||||
helpMessage: '开启后立即连接中间库并热刷新数据源,无需重启后端',
|
||||
helpMessage: '开启后立即生效(桌面代理模式无需 MES 直连 SQL Server)',
|
||||
componentProps: {
|
||||
checkedChildren: '启用',
|
||||
checkedValue: 1,
|
||||
@@ -83,6 +110,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
component: 'InputNumber',
|
||||
defaultValue: 120,
|
||||
componentProps: { min: 10, max: 600, style: { width: '100%' } },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '连接超时(毫秒)',
|
||||
@@ -90,6 +118,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [
|
||||
component: 'InputNumber',
|
||||
defaultValue: 120000,
|
||||
componentProps: { min: 5000, max: 600000, style: { width: '100%' } },
|
||||
ifShow: ({ values }) => values.accessMode === 'DIRECT',
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
|
||||
@@ -33,15 +33,15 @@
|
||||
const values = await getMcsDbConfig({ tenantId });
|
||||
setModalProps({ confirmLoading: false });
|
||||
if (values) {
|
||||
await setFieldsValue({ ...values, dbPassword: '' });
|
||||
await setFieldsValue({ ...values, dbPassword: '', accessMode: values.accessMode || 'DESKTOP_AGENT' });
|
||||
} else {
|
||||
await setFieldsValue({ tenantId, readEnabled: 1, writeEnabled: 1, status: 0, serverPort: 1433, dbName: 'MES_ShareDB' });
|
||||
await setFieldsValue({ tenantId, readEnabled: 1, writeEnabled: 1, status: 0, serverPort: 1433, dbName: 'MES_ShareDB', accessMode: 'DESKTOP_AGENT' });
|
||||
}
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
const values = await validate();
|
||||
if (!values.id && !values.dbPassword) {
|
||||
if (!values.id && values.accessMode === 'DIRECT' && !values.dbPassword) {
|
||||
createMessage.warning('请输入数据库密码');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<div style="font-size: 16px"> 1.配置说明</div>
|
||||
</template>
|
||||
<div class="base-desc">
|
||||
在此配置 SQL Server 中间库(MES_ShareDB)连接信息。<strong>保存后立即生效,无需重启后端</strong>,也无需修改 application.yml。
|
||||
读取开关控制 MCS→MES 方向数据查询;写入开关控制 MES→MCS 方向数据写入。
|
||||
推荐使用<strong>桌面代理</strong>模式:厂区桌面端直连设备 SQL Server,MES 通过 STOMP 命令读写。
|
||||
也可切换为服务端直连(仅调试)。读取/写入开关仍控制 MCS↔MES 方向。
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
@@ -22,18 +22,32 @@
|
||||
</template>
|
||||
<a-alert v-if="connStatus" type="info" show-icon style="margin-bottom: 12px" message="当前运行状态" :description="connStatus" />
|
||||
<div class="flex-flow">
|
||||
<div class="base-title">访问模式</div>
|
||||
<div class="base-message" style="display: flex; align-items: center; height: 50px">
|
||||
<a-tag :color="runtimeStatus.agentMode ? 'blue' : 'default'">{{ runtimeStatus.agentMode ? '桌面代理' : '服务端直连' }}</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-flow">
|
||||
<div class="base-title">桌面代理</div>
|
||||
<div class="base-message" style="display: flex; align-items: center; height: 50px; gap: 8px">
|
||||
<a-tag :color="runtimeStatus.agentOnline ? 'green' : 'orange'">{{ runtimeStatus.agentOnline ? '在线' : '离线' }}</a-tag>
|
||||
<a-tag :color="runtimeStatus.agentDbConnected ? 'green' : 'default'">{{ runtimeStatus.agentDbConnected ? '库已连通' : '库未连通' }}</a-tag>
|
||||
<span v-if="runtimeStatus.agentHostName || configData.agentDeviceId">{{ runtimeStatus.agentHostName || configData.agentDeviceId }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-flow" v-if="!runtimeStatus.agentMode">
|
||||
<div class="base-title">服务器</div>
|
||||
<div class="base-message">
|
||||
<a-input :value="displayHost" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-flow">
|
||||
<div class="flex-flow" v-if="!runtimeStatus.agentMode">
|
||||
<div class="base-title">数据库</div>
|
||||
<div class="base-message">
|
||||
<a-input :value="configData.dbName || '-'" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-flow">
|
||||
<div class="flex-flow" v-if="!runtimeStatus.agentMode">
|
||||
<div class="base-title">用户名</div>
|
||||
<div class="base-message">
|
||||
<a-input :value="configData.dbUsername || '-'" readonly />
|
||||
@@ -52,14 +66,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-flow">
|
||||
<div class="base-title">连接状态</div>
|
||||
<div class="base-title">配置状态</div>
|
||||
<div class="base-message" style="display: flex; align-items: center; height: 50px">
|
||||
<a-tag :color="runtimeStatus.dbConfigActive ? 'green' : 'orange'">{{ runtimeStatus.dbConfigActive ? '已启用数据库配置' : '使用 yml 默认配置' }}</a-tag>
|
||||
<a-tag :color="runtimeStatus.dbConfigActive ? 'green' : 'orange'">{{ runtimeStatus.dbConfigActive ? '已启用' : '未启用/回退 yml' }}</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 20px; width: 100%; text-align: right">
|
||||
<a-button type="primary" @click="editClick">编辑配置</a-button>
|
||||
<a-button @click="testClick" style="margin-left: 10px">连接测试</a-button>
|
||||
<a-button @click="testClick" style="margin-left: 10px">{{ runtimeStatus.agentMode ? '请求桌面探测' : '连接测试' }}</a-button>
|
||||
<a-button v-if="configData.id" @click="deleteClick" danger style="margin-left: 10px">删除配置</a-button>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
@@ -97,9 +111,12 @@
|
||||
const connStatus = computed(() => {
|
||||
const s = runtimeStatus.value;
|
||||
if (!configData.value.id) {
|
||||
return '尚未保存数据库配置,当前使用 application.yml 中的 sqlserver_mcs 默认连接。';
|
||||
return '尚未保存配置。推荐使用桌面代理模式:桌面端连接设备库后,MES 即可读写。';
|
||||
}
|
||||
return `读取:${s.readEnabled ? '开' : '关'} | 写入:${s.writeEnabled ? '开' : '关'} | 连接:${s.dbConfigActive ? '已启用数据库配置' : '使用 yml 默认配置'}`;
|
||||
const mode = s.agentMode ? '桌面代理' : '服务端直连';
|
||||
const agent = s.agentOnline ? '代理在线' : '代理离线';
|
||||
const db = s.agentDbConnected ? '库连通' : '库未连通';
|
||||
return `模式:${mode} | ${agent} | ${db} | 读取:${s.readEnabled ? '开' : '关'} | 写入:${s.writeEnabled ? '开' : '关'}${s.agentDbMessage ? ' | ' + s.agentDbMessage : ''}`;
|
||||
});
|
||||
|
||||
async function reload() {
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
|
||||
export const baseColumns: BasicColumn[] = [
|
||||
{ title: '日期', align: 'center', dataIndex: 'statDate', width: 140 },
|
||||
{ title: '原材料名称', align: 'center', dataIndex: 'rawMaterialName', width: 260, ellipsis: true },
|
||||
{ title: '需求重量(KG)', align: 'center', dataIndex: 'demandWeight', width: 180 },
|
||||
];
|
||||
|
||||
export const machineColumns: BasicColumn[] = [{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, ...baseColumns];
|
||||
export const machineColumns: BasicColumn[] = [
|
||||
baseColumns[0],
|
||||
{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 },
|
||||
...baseColumns.slice(1),
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
export const baseSearchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '日期',
|
||||
field: 'statDate',
|
||||
@@ -18,6 +23,12 @@ export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } },
|
||||
];
|
||||
|
||||
export const machineSearchFormSchema: FormSchema[] = [
|
||||
baseSearchFormSchema[0],
|
||||
{ label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } },
|
||||
...baseSearchFormSchema.slice(1),
|
||||
];
|
||||
|
||||
export const superQuerySchema = {
|
||||
machineName: { title: '机台', order: 0, view: 'text' },
|
||||
statDate: { title: '日期', order: 1, view: 'date' },
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
import {
|
||||
baseColumns,
|
||||
machineColumns,
|
||||
searchFormSchema,
|
||||
baseSearchFormSchema,
|
||||
machineSearchFormSchema,
|
||||
superQuerySchema,
|
||||
} from './MesXslAutoSmallMaterialDemandPlan.data';
|
||||
import { list, getExportUrl } from './MesXslAutoSmallMaterialDemandPlan.api';
|
||||
@@ -40,7 +41,7 @@
|
||||
columns: baseColumns,
|
||||
canResize: true,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
schemas: baseSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
},
|
||||
@@ -57,20 +58,33 @@
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, setColumns }] = tableContext;
|
||||
const [registerTable, { reload, setColumns, setProps }] = tableContext;
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
onMounted(() => {
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
});
|
||||
|
||||
function applyColumns() {
|
||||
setColumns(groupByMachine.value ? machineColumns : baseColumns);
|
||||
}
|
||||
|
||||
function applySearchSchemas() {
|
||||
setProps({
|
||||
formConfig: {
|
||||
schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function onGroupByMachineChange() {
|
||||
queryParam.groupByMachine = groupByMachine.value ? 1 : 0;
|
||||
if (!groupByMachine.value) {
|
||||
delete queryParam.machineName;
|
||||
}
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { checkEquipmentCode, checkEquipmentName } from './MesXslEquipmentLedger.
|
||||
const colHalf = { span: 12 };
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: '系统编号', align: 'center', dataIndex: 'ledgerNo', width: 100 },
|
||||
{ title: '系统编号', align: 'center', dataIndex: 'ledgerNo', width: 100, defaultHidden: true },
|
||||
{ title: '设备编号', align: 'center', dataIndex: 'equipmentCode', width: 130 },
|
||||
{ title: '设备名称', align: 'center', dataIndex: 'equipmentName', width: 160 },
|
||||
{ title: '工序', align: 'center', dataIndex: 'processOperationName', width: 120 },
|
||||
@@ -12,6 +12,8 @@ export const columns: BasicColumn[] = [
|
||||
{ title: '设备类型', align: 'center', dataIndex: 'equipmentTypeName', width: 110 },
|
||||
{ title: '设备厂家', align: 'center', dataIndex: 'manufacturerName', width: 120 },
|
||||
{ title: '所属工厂', align: 'center', dataIndex: 'factoryName', width: 120 },
|
||||
{ title: '设备描述', align: 'left', dataIndex: 'equipmentDesc', width: 200, ellipsis: true },
|
||||
{ title: '受控PDA', align: 'center', dataIndex: 'controlledPda', width: 120 },
|
||||
{ title: '设备状态', align: 'center', dataIndex: 'equipmentStatus_dictText', width: 90 },
|
||||
{ title: '是否启用', align: 'center', dataIndex: 'enabledFlag_dictText', width: 90 },
|
||||
{ title: '设备型号', align: 'center', dataIndex: 'equipmentModel', width: 110, defaultHidden: true },
|
||||
@@ -85,14 +87,6 @@ export const formSchema: FormSchema[] = [
|
||||
{ label: '', field: 'equipmentCategoryId', component: 'Input', show: false, dynamicRules: () => [{ required: true, message: '请选择设备类别' }] },
|
||||
{ label: '', field: 'equipmentTypeId', component: 'Input', show: false, dynamicRules: () => [{ required: true, message: '请选择设备类型' }] },
|
||||
{ label: '', field: 'factoryId', component: 'Input', show: false },
|
||||
{
|
||||
label: '所属工序',
|
||||
field: 'processOperationName',
|
||||
component: 'Input',
|
||||
slot: 'processOperationPicker',
|
||||
colProps: colHalf,
|
||||
dynamicRules: () => [{ required: true, message: '请选择所属工序' }],
|
||||
},
|
||||
{
|
||||
label: '系统编号',
|
||||
field: 'ledgerNo',
|
||||
@@ -100,6 +94,30 @@ export const formSchema: FormSchema[] = [
|
||||
colProps: colHalf,
|
||||
componentProps: { readonly: true, placeholder: '保存时从001起自动生成' },
|
||||
},
|
||||
{
|
||||
label: '设备类型',
|
||||
field: 'equipmentTypeName',
|
||||
component: 'Input',
|
||||
slot: 'equipmentTypePicker',
|
||||
colProps: colHalf,
|
||||
dynamicRules: () => [{ required: true, message: '请选择设备类型' }],
|
||||
},
|
||||
{
|
||||
label: '所属工序',
|
||||
field: 'processOperationName',
|
||||
component: 'Input',
|
||||
colProps: colHalf,
|
||||
componentProps: { readonly: true, placeholder: '选择设备类型后自动带出' },
|
||||
dynamicRules: () => [{ required: true, message: '请先选择设备类型' }],
|
||||
},
|
||||
{
|
||||
label: '设备类别',
|
||||
field: 'equipmentCategoryName',
|
||||
component: 'Input',
|
||||
colProps: colHalf,
|
||||
componentProps: { readonly: true, placeholder: '选择设备类型后自动带出' },
|
||||
dynamicRules: () => [{ required: true, message: '请先选择设备类型' }],
|
||||
},
|
||||
{
|
||||
label: '设备编号',
|
||||
field: 'equipmentCode',
|
||||
@@ -153,22 +171,6 @@ export const formSchema: FormSchema[] = [
|
||||
slot: 'manufacturerPicker',
|
||||
colProps: colHalf,
|
||||
},
|
||||
{
|
||||
label: '设备类别',
|
||||
field: 'equipmentCategoryName',
|
||||
component: 'Input',
|
||||
slot: 'equipmentCategoryPicker',
|
||||
colProps: colHalf,
|
||||
dynamicRules: () => [{ required: true, message: '请选择设备类别' }],
|
||||
},
|
||||
{
|
||||
label: '设备类型',
|
||||
field: 'equipmentTypeName',
|
||||
component: 'Input',
|
||||
slot: 'equipmentTypePicker',
|
||||
colProps: colHalf,
|
||||
dynamicRules: () => [{ required: true, message: '请选择设备类型' }],
|
||||
},
|
||||
{
|
||||
label: '所属工厂',
|
||||
field: 'factoryName',
|
||||
|
||||
@@ -10,13 +10,6 @@
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #processOperationPicker="{ model, field }">
|
||||
<a-input-group compact style="display: flex; width: 100%">
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择工序" style="flex: 1" />
|
||||
<a-button type="primary" :disabled="isDetail" @click="openProcessSelect">选择</a-button>
|
||||
<a-button v-if="model.processOperationId && !isDetail" @click="clearProcess(model)">清除</a-button>
|
||||
</a-input-group>
|
||||
</template>
|
||||
<template #manufacturerPicker="{ model, field }">
|
||||
<a-input-group compact style="display: flex; width: 100%">
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择设备厂家" style="flex: 1" />
|
||||
@@ -24,13 +17,6 @@
|
||||
<a-button v-if="model.manufacturerId && !isDetail" @click="clearManufacturer(model)">清除</a-button>
|
||||
</a-input-group>
|
||||
</template>
|
||||
<template #equipmentCategoryPicker="{ model, field }">
|
||||
<a-input-group compact style="display: flex; width: 100%">
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择设备类别" style="flex: 1" />
|
||||
<a-button type="primary" :disabled="isDetail" @click="openCategorySelect">选择</a-button>
|
||||
<a-button v-if="model.equipmentCategoryId && !isDetail" @click="clearCategory(model)">清除</a-button>
|
||||
</a-input-group>
|
||||
</template>
|
||||
<template #equipmentTypePicker="{ model, field }">
|
||||
<a-input-group compact style="display: flex; width: 100%">
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择设备类型" style="flex: 1" />
|
||||
@@ -46,13 +32,11 @@
|
||||
</a-input-group>
|
||||
</template>
|
||||
</BasicForm>
|
||||
<MesXslProcessOperationSelectModal @register="registerProcessModal" @select="onProcessSelect" />
|
||||
<MesXslManufacturerSelectModal
|
||||
@register="registerManufacturerModal"
|
||||
:modal-title="manufacturerModalTitle"
|
||||
@select="onManufacturerSelect"
|
||||
/>
|
||||
<MesXslEquipmentCategorySelectModal @register="registerCategoryModal" @select="onCategorySelect" />
|
||||
<MesXslEquipmentTypeSelectModal @register="registerTypeModal" @select="onTypeSelect" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
@@ -61,14 +45,14 @@
|
||||
import { computed, ref, unref, onMounted } from 'vue';
|
||||
import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { formSchema } from '../MesXslEquipmentLedger.data';
|
||||
import { fetchNextLedgerNo, saveOrUpdate } from '../MesXslEquipmentLedger.api';
|
||||
import MesXslProcessOperationSelectModal from '/@/views/xslmes/mesXslEquipmentCategory/components/MesXslProcessOperationSelectModal.vue';
|
||||
import MesXslManufacturerSelectModal from './MesXslManufacturerSelectModal.vue';
|
||||
import MesXslEquipmentCategorySelectModal from '/@/views/xslmes/mesXslEquipmentType/components/MesXslEquipmentCategorySelectModal.vue';
|
||||
import MesXslEquipmentTypeSelectModal from './MesXslEquipmentTypeSelectModal.vue';
|
||||
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const { createMessage } = useMessage();
|
||||
const isUpdate = ref(true);
|
||||
const isDetail = ref(false);
|
||||
|
||||
@@ -89,9 +73,7 @@
|
||||
manufacturerPickTarget.value === 'factory' ? '选择所属工厂' : '选择设备厂家',
|
||||
);
|
||||
|
||||
const [registerProcessModal, { openModal: openProcessModal }] = useModal();
|
||||
const [registerManufacturerModal, { openModal: openManufacturerModal }] = useModal();
|
||||
const [registerCategoryModal, { openModal: openCategoryModal }] = useModal();
|
||||
const [registerTypeModal, { openModal: openTypeModal }] = useModal();
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate, setProps, getFieldsValue }] = useForm({
|
||||
@@ -127,11 +109,6 @@
|
||||
!unref(isUpdate) ? '新增设备台账' : unref(isDetail) ? '设备台账详情' : '编辑设备台账',
|
||||
);
|
||||
|
||||
function openProcessSelect() {
|
||||
const v = getFieldsValue();
|
||||
openProcessModal(true, { processOperationId: v?.processOperationId });
|
||||
}
|
||||
|
||||
function openManufacturerSelect(target: 'manufacturer' | 'factory') {
|
||||
manufacturerPickTarget.value = target;
|
||||
const v = getFieldsValue();
|
||||
@@ -140,23 +117,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
function openCategorySelect() {
|
||||
const v = getFieldsValue();
|
||||
openCategoryModal(true, { equipmentCategoryId: v?.equipmentCategoryId });
|
||||
}
|
||||
|
||||
function openTypeSelect() {
|
||||
const v = getFieldsValue();
|
||||
openTypeModal(true, { equipmentTypeId: v?.equipmentTypeId });
|
||||
}
|
||||
|
||||
function onProcessSelect(payload: Recordable) {
|
||||
setFieldsValue({
|
||||
processOperationId: payload.processOperationId,
|
||||
processOperationName: payload.processOperationName,
|
||||
});
|
||||
}
|
||||
|
||||
function onManufacturerSelect(payload: Recordable) {
|
||||
if (manufacturerPickTarget.value === 'factory') {
|
||||
setFieldsValue({
|
||||
@@ -171,27 +136,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onCategorySelect(payload: Recordable) {
|
||||
setFieldsValue({
|
||||
equipmentCategoryId: payload.equipmentCategoryId,
|
||||
equipmentCategoryName: payload.equipmentCategoryName,
|
||||
});
|
||||
}
|
||||
|
||||
function onTypeSelect(payload: Recordable) {
|
||||
setFieldsValue({
|
||||
equipmentTypeId: payload.equipmentTypeId,
|
||||
equipmentTypeName: payload.equipmentTypeName,
|
||||
equipmentCategoryId: payload.equipmentCategoryId || getFieldsValue()?.equipmentCategoryId,
|
||||
equipmentCategoryName: payload.equipmentCategoryName || getFieldsValue()?.equipmentCategoryName,
|
||||
equipmentTypeId: payload.equipmentTypeId || '',
|
||||
equipmentTypeName: payload.equipmentTypeName || '',
|
||||
equipmentCategoryId: payload.equipmentCategoryId || '',
|
||||
equipmentCategoryName: payload.equipmentCategoryName || '',
|
||||
processOperationId: payload.processOperationId || '',
|
||||
processOperationName: payload.processOperationName || '',
|
||||
});
|
||||
}
|
||||
|
||||
function clearProcess(model: Recordable) {
|
||||
model.processOperationId = '';
|
||||
model.processOperationName = '';
|
||||
}
|
||||
|
||||
function clearManufacturer(model: Recordable) {
|
||||
model.manufacturerId = '';
|
||||
model.manufacturerName = '';
|
||||
@@ -202,26 +157,38 @@
|
||||
model.factoryName = '';
|
||||
}
|
||||
|
||||
function clearCategory(model: Recordable) {
|
||||
model.equipmentCategoryId = '';
|
||||
model.equipmentCategoryName = '';
|
||||
}
|
||||
|
||||
function clearType(model: Recordable) {
|
||||
model.equipmentTypeId = '';
|
||||
model.equipmentTypeName = '';
|
||||
model.equipmentCategoryId = '';
|
||||
model.equipmentCategoryName = '';
|
||||
model.processOperationId = '';
|
||||
model.processOperationName = '';
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
// validate 结果可能不含隐藏字段最新值,与 getFieldsValue 合并
|
||||
const values = { ...(getFieldsValue() || {}), ...(await validate()) };
|
||||
if (!values.equipmentTypeId) {
|
||||
createMessage.warning('请选择设备类型');
|
||||
return;
|
||||
}
|
||||
if (!values.processOperationId) {
|
||||
createMessage.warning('所选设备类型未绑定工序,请先维护设备类型');
|
||||
return;
|
||||
}
|
||||
if (!values.equipmentCategoryId) {
|
||||
createMessage.warning('所选设备类型未绑定设备类别,请先维护设备类型');
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
closeModal();
|
||||
emit('success');
|
||||
} catch (e) {
|
||||
// 表单校验失败时 ant-design 会标红;此处避免未捕获异常导致“点保存无反应”
|
||||
console.warn('[设备台账] 保存校验未通过', e);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
equipmentTypeName: '',
|
||||
equipmentCategoryId: '',
|
||||
equipmentCategoryName: '',
|
||||
processOperationId: '',
|
||||
processOperationName: '',
|
||||
});
|
||||
closeModal();
|
||||
return;
|
||||
@@ -88,6 +90,8 @@
|
||||
equipmentTypeName: row.typeName || '',
|
||||
equipmentCategoryId: row.equipmentCategoryId || '',
|
||||
equipmentCategoryName: row.equipmentCategoryName || '',
|
||||
processOperationId: row.processOperationId || '',
|
||||
processOperationName: row.processOperationName || '',
|
||||
});
|
||||
closeModal();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,10 @@ export const batchDelete = (params, handleSuccess) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const saveOrUpdate = (params, isUpdate) => defHttp.post({ url: isUpdate ? Api.edit : Api.save, params });
|
||||
export const saveOrUpdate = (params, isUpdate) =>
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】保存延长超时,避免远程库慢导致误报超时-----------
|
||||
defHttp.post({ url: isUpdate ? Api.edit : Api.save, params, timeout: 120 * 1000 });
|
||||
//update-end---author:jiangxh ---date:20260729 for:【配合示方】保存延长超时,避免远程库慢导致误报超时-----------
|
||||
|
||||
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方-----------
|
||||
export const buildMixingGeneratePreview = (params) =>
|
||||
|
||||
@@ -111,7 +111,7 @@ export function applyWeightPercentToLines(lines: Recordable[]): void {
|
||||
row.weightPercent = null;
|
||||
return;
|
||||
}
|
||||
row.weightPercent = Number(((phr / totalPhr) * 100).toFixed(1));
|
||||
row.weightPercent = Number(((phr / totalPhr) * 100).toFixed(3));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -429,9 +429,25 @@ export function createEmptyLineRows(count = DEFAULT_LINE_ROW_COUNT): Recordable[
|
||||
return Array.from({ length: count }, () => ({ id: buildUUID() }));
|
||||
}
|
||||
|
||||
/** 明细数值保留三位小数 */
|
||||
export function roundFormulaLineDecimal3(value: unknown): number | null {
|
||||
if (value == null || value === '') {
|
||||
return null;
|
||||
}
|
||||
const n = Number(value);
|
||||
return Number.isFinite(n) ? Number(n.toFixed(3)) : null;
|
||||
}
|
||||
|
||||
/** 确保每行有唯一 id(JVxeTable rowKey 依赖 id,否则单元格无法渲染) */
|
||||
export function normalizeLineRows(rows: Recordable[]): Recordable[] {
|
||||
return (rows || []).map((r) => ({ ...r, id: r?.id || buildUUID() }));
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数-----------
|
||||
return (rows || []).map((r) => ({
|
||||
...r,
|
||||
id: r?.id || buildUUID(),
|
||||
weightPercent: roundFormulaLineDecimal3(r?.weightPercent),
|
||||
volume: roundFormulaLineDecimal3(r?.volume),
|
||||
}));
|
||||
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数-----------
|
||||
}
|
||||
|
||||
function sectionTitle(label: string, field: string): FormSchema {
|
||||
@@ -931,6 +947,7 @@ export function buildLineJVxeColumns(mixingStages?: number | null, tableDisabled
|
||||
type: JVxeTypes.inputNumber,
|
||||
minWidth: 90,
|
||||
align: 'center',
|
||||
props: { precision: 3 },
|
||||
},
|
||||
{
|
||||
title: '体积',
|
||||
@@ -939,6 +956,7 @@ export function buildLineJVxeColumns(mixingStages?: number | null, tableDisabled
|
||||
minWidth: 90,
|
||||
align: 'center',
|
||||
placeholder: '自动计算',
|
||||
props: { precision: 3 },
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
//update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】打开预览即匹配胶料,失败则关闭弹窗-----------
|
||||
const preview = await buildMixingGeneratePreview({ formulaSpecId: formulaSpecId.value });
|
||||
rubberName.value = preview?.rubberName || '';
|
||||
mixingStages.value = preview?.mixingStages || 0;
|
||||
@@ -106,9 +107,13 @@
|
||||
if (!tableRows.value.length) {
|
||||
createMessage.warning('无可生成的混炼段,请检查混合段数');
|
||||
}
|
||||
} catch (_e) {
|
||||
// 预览阶段胶料匹配失败等错误由全局提示,关闭弹窗避免空表继续操作
|
||||
closeModal();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
//update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】打开预览即匹配胶料,失败则关闭弹窗-----------
|
||||
});
|
||||
|
||||
function formatMachineNames(machines: Recordable[] = []) {
|
||||
|
||||
@@ -441,6 +441,7 @@
|
||||
createEmptyLineRows,
|
||||
getActiveStageCount,
|
||||
normalizeLineRows,
|
||||
roundFormulaLineDecimal3,
|
||||
stageTotalNumberProps,
|
||||
SUMMARY_FOOTER_FIELD_KEYS,
|
||||
SUMMARY_METRICS_FIELD_KEYS,
|
||||
@@ -1464,7 +1465,7 @@
|
||||
const material = (raw as Recordable)?.id != null ? raw : (raw as Recordable)?.result;
|
||||
const sg = Number(material?.specificGravity);
|
||||
if (sg > 0) {
|
||||
row.volume = Number((Number(row.phr) / sg).toFixed(6));
|
||||
row.volume = Number((Number(row.phr) / sg).toFixed(3));
|
||||
} else {
|
||||
row.volume = null;
|
||||
}
|
||||
@@ -1505,6 +1506,10 @@
|
||||
.filter((r) => r && (r.mixerMaterialId || r.phr != null))
|
||||
.map((r, index) => ({
|
||||
...stripFormulaLineDisplayFields(r),
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积提交保留三位小数-----------
|
||||
weightPercent: roundFormulaLineDecimal3(r.weightPercent),
|
||||
volume: roundFormulaLineDecimal3(r.volume),
|
||||
//update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积提交保留三位小数-----------
|
||||
sortNo: index,
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
|
||||
export const baseColumns: BasicColumn[] = [
|
||||
{ title: '日期', align: 'center', dataIndex: 'statDate', width: 140 },
|
||||
{ title: '原材料名称', align: 'center', dataIndex: 'rawMaterialName', width: 260, ellipsis: true },
|
||||
{ title: '需求重量(KG)', align: 'center', dataIndex: 'demandWeight', width: 180 },
|
||||
];
|
||||
|
||||
export const machineColumns: BasicColumn[] = [{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, ...baseColumns];
|
||||
export const machineColumns: BasicColumn[] = [
|
||||
baseColumns[0],
|
||||
{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 },
|
||||
...baseColumns.slice(1),
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
export const baseSearchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '日期',
|
||||
field: 'statDate',
|
||||
@@ -18,6 +23,12 @@ export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } },
|
||||
];
|
||||
|
||||
export const machineSearchFormSchema: FormSchema[] = [
|
||||
baseSearchFormSchema[0],
|
||||
{ label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } },
|
||||
...baseSearchFormSchema.slice(1),
|
||||
];
|
||||
|
||||
export const superQuerySchema = {
|
||||
machineName: { title: '机台', order: 0, view: 'text' },
|
||||
statDate: { title: '日期', order: 1, view: 'date' },
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
import {
|
||||
baseColumns,
|
||||
machineColumns,
|
||||
searchFormSchema,
|
||||
baseSearchFormSchema,
|
||||
machineSearchFormSchema,
|
||||
superQuerySchema,
|
||||
} from './MesXslManualSmallMaterialDemandPlan.data';
|
||||
import { list, getExportUrl } from './MesXslManualSmallMaterialDemandPlan.api';
|
||||
@@ -40,7 +41,7 @@
|
||||
columns: baseColumns,
|
||||
canResize: true,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
schemas: baseSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
},
|
||||
@@ -57,20 +58,33 @@
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, setColumns }] = tableContext;
|
||||
const [registerTable, { reload, setColumns, setProps }] = tableContext;
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
onMounted(() => {
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
});
|
||||
|
||||
function applyColumns() {
|
||||
setColumns(groupByMachine.value ? machineColumns : baseColumns);
|
||||
}
|
||||
|
||||
function applySearchSchemas() {
|
||||
setProps({
|
||||
formConfig: {
|
||||
schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function onGroupByMachineChange() {
|
||||
queryParam.groupByMachine = groupByMachine.value ? 1 : 0;
|
||||
if (!groupByMachine.value) {
|
||||
delete queryParam.machineName;
|
||||
}
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/xslmes/mesXslMillAction/list',
|
||||
queryById = '/xslmes/mesXslMillAction/queryById',
|
||||
exportXls = '/xslmes/mesXslMillAction/exportXls',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
@@ -0,0 +1,33 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: 'GUID', align: 'center', dataIndex: 'guid', width: 280 },
|
||||
{ title: '动作地址', align: 'center', dataIndex: 'actAddr', width: 100 },
|
||||
{ title: '动作名称', align: 'center', dataIndex: 'actName', width: 140 },
|
||||
{ title: '动作名称(英)', align: 'center', dataIndex: 'actNameEn', width: 140 },
|
||||
{ title: '动作备注', align: 'center', dataIndex: 'actMemo', width: 120 },
|
||||
{ title: '关联地址', align: 'center', dataIndex: 'actRepaddr', width: 100 },
|
||||
{ title: '写入时间', align: 'center', dataIndex: 'writeTime', width: 170 },
|
||||
{ title: '读写标识', align: 'center', dataIndex: 'rwFlag', width: 90 },
|
||||
{ title: '更新时间', align: 'center', dataIndex: 'updateTime', width: 170 },
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '动作名称', field: 'actName', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '动作地址', field: 'actAddr', component: 'InputNumber', colProps: { span: 6 } },
|
||||
{ label: 'GUID', field: 'guid', component: 'Input', colProps: { span: 6 } },
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{ label: '', field: 'id', component: 'Input', show: false },
|
||||
{ label: 'GUID', field: 'guid', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } },
|
||||
{ label: '动作地址', field: 'actAddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '关联地址', field: 'actRepaddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作名称', field: 'actName', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作名称(英)', field: 'actNameEn', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作备注', field: 'actMemo', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } },
|
||||
{ label: '写入时间', field: 'writeTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '读取时间', field: 'readTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '读写标识', field: 'rwFlag', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '更新时间', field: 'updateTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
];
|
||||
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div class="mes-xsl-mill-action-page">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="'xslmes:mcsSyncConfig:setting'" preIcon="ant-design:sync-outlined" @click="openCollect"> 采集操作 </a-button>
|
||||
<a-button type="link" v-auth="'xslmes:mes_xsl_mill_action:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<MesXslMillActionModal @register="registerModal" />
|
||||
<CollectModal @register="registerCollectModal" @success="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="xslmes-mesXslMillAction" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import MesXslMillActionModal from './components/MesXslMillActionModal.vue';
|
||||
import CollectModal from '/@/views/xslmesMcs/mcsSyncConfig/components/CollectModal.vue';
|
||||
import { columns, searchFormSchema } from './MesXslMillAction.data';
|
||||
import { list, getExportUrl } from './MesXslMillAction.api';
|
||||
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerCollectModal, { openModal: openCollectModal }] = useModal();
|
||||
|
||||
const { tableContext, onExportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '开炼机动作接收',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: true,
|
||||
formConfig: { labelWidth: 100, schemas: searchFormSchema, autoSubmitOnEnter: true },
|
||||
actionColumn: { width: 80, fixed: 'right' },
|
||||
},
|
||||
exportConfig: { name: '开炼机动作接收', url: getExportUrl },
|
||||
});
|
||||
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
|
||||
function openCollect() {
|
||||
openCollectModal(true, { bizType: 'MILL_ACT' });
|
||||
}
|
||||
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, { record, isUpdate: true, showFooter: false });
|
||||
}
|
||||
|
||||
function getTableAction(record) {
|
||||
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/* 空数据时 BasicTable canResize 不计算高度,用视口高度把表格区域铺满 */
|
||||
.mes-xsl-mill-action-page {
|
||||
min-height: calc(100vh - 120px);
|
||||
|
||||
:deep(.jeecg-basic-table-form-container) {
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
:deep(.ant-table-wrapper),
|
||||
:deep(.ant-spin-nested-loading),
|
||||
:deep(.ant-spin-container),
|
||||
:deep(.ant-table),
|
||||
:deep(.ant-table-container) {
|
||||
min-height: calc(100vh - 280px);
|
||||
}
|
||||
|
||||
:deep(.ant-table-body) {
|
||||
min-height: calc(100vh - 360px) !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-tbody > tr.ant-table-placeholder > td) {
|
||||
height: calc(100vh - 360px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose title="开炼机动作接收" :width="900">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../MesXslMillAction.data';
|
||||
|
||||
defineEmits(['register']);
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, setProps }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showOkBtn: false, showCancelBtn: true, cancelText: '关闭' });
|
||||
if (data?.record) {
|
||||
await setFieldsValue({ ...data.record });
|
||||
}
|
||||
setProps({ disabled: true });
|
||||
});
|
||||
</script>
|
||||
@@ -14,10 +14,10 @@ enum Api {
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
export const checkConditionName = (params: { conditionName: string; dataId?: string }) =>
|
||||
export const checkConditionName = (params: { conditionName: string; equipmentId?: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkConditionName, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const checkConditionCode = (params: { conditionCode: string; dataId?: string }) =>
|
||||
export const checkConditionCode = (params: { conditionCode: string; equipmentId?: string; dataId?: string }) =>
|
||||
defHttp.get({ url: Api.checkConditionCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' });
|
||||
|
||||
export const deleteOne = (params, handleSuccess) =>
|
||||
|
||||
@@ -42,11 +42,13 @@ export const formSchema: FormSchema[] = [
|
||||
validator: async (_rule, value) => {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
if (!v) return Promise.resolve();
|
||||
// 未选设备时不做跨设备校验,保存时仍会强制校验
|
||||
if (!model?.equipmentId) return Promise.resolve();
|
||||
try {
|
||||
await checkConditionName({ conditionName: v, dataId: model?.id });
|
||||
await checkConditionName({ conditionName: v, equipmentId: model.equipmentId, dataId: model?.id });
|
||||
return Promise.resolve();
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '条件名称不能重复');
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '同一设备下条件名称不能重复');
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
@@ -64,11 +66,12 @@ export const formSchema: FormSchema[] = [
|
||||
validator: async (_rule, value) => {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
if (!v) return Promise.resolve();
|
||||
if (!model?.equipmentId) return Promise.resolve();
|
||||
try {
|
||||
await checkConditionCode({ conditionCode: v, dataId: model?.id });
|
||||
await checkConditionCode({ conditionCode: v, equipmentId: model.equipmentId, dataId: model?.id });
|
||||
return Promise.resolve();
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '条件代码不能重复');
|
||||
return Promise.reject(e?.response?.data?.message || e?.message || '同一设备下条件代码不能重复');
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
|
||||
@@ -79,11 +79,11 @@ export const mainSchema: FormSchema[] = [
|
||||
rules: [{ required: true, message: '请选择发行编号' }],
|
||||
},
|
||||
//update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】混炼示方基本信息字段优化-----------
|
||||
{ label: '换算系数', field: 'convertFactor', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 2, style: { width: '100%' } } },
|
||||
{ label: '填充体积', field: 'fillVolume', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } },
|
||||
{ label: '换算系数', field: 'convertFactor', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } },
|
||||
{ label: '填充体积', field: 'fillVolume', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 2, style: { width: '100%' } } },
|
||||
{ label: '回收炭黑(秒)', field: 'recycleCarbonSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } },
|
||||
{ label: '母胶比重', field: 'motherRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } },
|
||||
{ label: '终炼胶比重', field: 'finalRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } },
|
||||
{ label: '母胶比重', field: 'motherRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } },
|
||||
{ label: '终炼胶比重', field: 'finalRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } },
|
||||
{ label: '适用工厂', field: 'applyFactory', component: 'Input', colProps: { span: 8 } },
|
||||
{ label: '段数', field: 'stageCount', component: 'Input', colProps: { span: 8 }, componentProps: { placeholder: '如 2/3' } },
|
||||
{ label: '纯混炼时间(秒)', field: 'pureMixSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } },
|
||||
@@ -319,7 +319,13 @@ const MIXING_MATERIAL_WEIGHT_SCALE = 6;
|
||||
|
||||
//update-begin---author:cursor ---date:20260526 for:【XSLMES-20260526-A60】换算系数/配方参数数值展示优化-----------
|
||||
/** 换算系数展示小数位 */
|
||||
export const MIXING_CONVERT_FACTOR_SCALE = 2;
|
||||
export const MIXING_CONVERT_FACTOR_SCALE = 3;
|
||||
|
||||
/** 母胶比重展示小数位 */
|
||||
export const MIXING_MOTHER_RUBBER_SG_SCALE = 3;
|
||||
|
||||
/** 填充体积展示小数位 */
|
||||
export const MIXING_FILL_VOLUME_SCALE = 2;
|
||||
|
||||
/** 配方参数设定允许的小数精度 */
|
||||
export const MIXING_RECIPE_PARAM_DECIMAL_SCALE = 6;
|
||||
@@ -333,7 +339,7 @@ export const MIXING_RECIPE_PARAM_DECIMAL_FIELDS = [
|
||||
'maxFeedTemp',
|
||||
] as const;
|
||||
|
||||
/** 换算系数展示:固定保留两位小数 */
|
||||
/** 换算系数展示:固定保留三位小数 */
|
||||
export function formatMixingConvertFactorDisplay(value: unknown): string {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '';
|
||||
@@ -536,7 +542,7 @@ export function calcMixingFillVolume(totalWeight: unknown, specificGravity: unkn
|
||||
return null;
|
||||
}
|
||||
const materialVolume = weight / sg;
|
||||
return Number(((materialVolume / volume) * 100).toFixed(6));
|
||||
return Number(((materialVolume / volume) * 100).toFixed(MIXING_FILL_VOLUME_SCALE));
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A46】填充体积按单重/比重/机台有效体积自动计算-----------
|
||||
|
||||
@@ -1311,8 +1317,9 @@ export function applyMixingMaterialFromSelection(row: Recordable, material: Reco
|
||||
//update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】选料弹窗新增胶料页签(查询胶料信息)-----------
|
||||
/** 选料弹窗「胶料」页签表格列(数据源为胶料信息 mes_material) */
|
||||
export const mixingRubberPickerTableColumns: BasicColumn[] = [
|
||||
{ title: '胶料编码', align: 'center', width: 140, dataIndex: 'materialCode' },
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签去掉胶料编码-----------
|
||||
{ title: '胶料名称', align: 'center', width: 180, dataIndex: 'materialName' },
|
||||
//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签去掉胶料编码-----------
|
||||
//update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签补齐自动/人工称量列-----------
|
||||
{ title: '自动/人工称量', align: 'center', width: 132, dataIndex: 'pickerWeighMode' },
|
||||
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签补齐自动/人工称量列-----------
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<a-input
|
||||
v-model:value="keyword"
|
||||
allow-clear
|
||||
placeholder="关键字(编码/名称/描述)"
|
||||
:placeholder="keywordPlaceholder"
|
||||
style="width: 280px"
|
||||
@pressEnter="reloadTable"
|
||||
/>
|
||||
@@ -105,6 +105,11 @@
|
||||
import { list as rubberList, queryById as queryRubberById } from '/@/views/mes/material/MesMaterial.api';
|
||||
import { loadTreeData } from '/@/api/common/api';
|
||||
//update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签查询胶料信息(mes_material)------------->
|
||||
import {
|
||||
buildOrLikeSuperQuery,
|
||||
MIXER_MATERIAL_LIKE_FIELDS,
|
||||
RUBBER_MATERIAL_LIKE_FIELDS,
|
||||
} from '/@/views/mes/material/materialQuery.util';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||
import MesXslMixingMaterialCategorySetting from './MesXslMixingMaterialCategorySetting.vue';
|
||||
@@ -133,6 +138,11 @@
|
||||
const RUBBER_TREE_ALL = 'ALL';
|
||||
const RUBBER_CATEGORY_PCODE = 'XSLMES_RUBBER';
|
||||
const pickerType = ref<'mixer' | 'rubber'>('mixer');
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签关键字提示去掉编码-----------
|
||||
const keywordPlaceholder = computed(() =>
|
||||
pickerType.value === 'rubber' ? '关键字(名称/别名/ERP)' : '关键字(编码/名称/描述)',
|
||||
);
|
||||
//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签关键字提示去掉编码-----------
|
||||
const rubberTreeLoading = ref(false);
|
||||
const rubberCategoryTree = ref<Recordable[]>([]);
|
||||
/** 胶料类别 id -> { code, title },用于按种类配置编码匹配 */
|
||||
@@ -256,14 +266,20 @@
|
||||
const kw = keyword.value?.trim();
|
||||
if (pickerType.value === 'rubber') {
|
||||
const rubberParams = { ...params, ...selectedRubberCategoryFilter.value };
|
||||
if (kw) {
|
||||
rubberParams.materialName = `*${kw}*`;
|
||||
//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字按名称/ERP/别名模糊查询-----------
|
||||
// 关键字按名称/ERP/别名模糊 OR 查询(不含编码)
|
||||
const orQuery = buildOrLikeSuperQuery(RUBBER_MATERIAL_LIKE_FIELDS, kw || '');
|
||||
//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字按名称/ERP/别名模糊查询-----------
|
||||
if (orQuery) {
|
||||
Object.assign(rubberParams, orQuery);
|
||||
}
|
||||
return rubberParams;
|
||||
}
|
||||
const next = { ...params, ...selectedCategoryFilter.value };
|
||||
if (kw) {
|
||||
next.materialName = `*${kw}*`;
|
||||
// 关键字按编码/名称/描述/ERP/别名模糊 OR 查询
|
||||
const orQuery = buildOrLikeSuperQuery(MIXER_MATERIAL_LIKE_FIELDS, kw || '');
|
||||
if (orQuery) {
|
||||
Object.assign(next, orQuery);
|
||||
}
|
||||
return next;
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<a-input-number
|
||||
v-model:value="sheetForm.convertFactor"
|
||||
:disabled="!showFooter"
|
||||
:precision="2"
|
||||
:precision="3"
|
||||
:formatter="formatConvertFactorInput"
|
||||
:parser="parseConvertFactorInput"
|
||||
:bordered="false"
|
||||
@@ -78,7 +78,7 @@
|
||||
</td>
|
||||
<th class="formTitle" colspan="1">填充体积</th>
|
||||
<td class="formValue" colspan="1">
|
||||
<a-input-number v-model:value="sheetForm.fillVolume" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" />
|
||||
<a-input-number v-model:value="sheetForm.fillVolume" :disabled="!showFooter" :precision="2" :bordered="false" class="form-input" style="width: 100%" />
|
||||
</td>
|
||||
<th class="formTitle" colspan="1">回收炭黑(秒)</th>
|
||||
<td class="formValue">
|
||||
@@ -99,7 +99,7 @@
|
||||
</td>
|
||||
<th class="formTitle" colspan="1">母胶比重</th>
|
||||
<td class="formValue">
|
||||
<a-input-number v-model:value="sheetForm.motherRubberSg" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
|
||||
<a-input-number v-model:value="sheetForm.motherRubberSg" :disabled="!showFooter" :precision="3" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
|
||||
</td>
|
||||
<th class="formTitle">段数</th>
|
||||
<td class="formValue" colspan="2">
|
||||
@@ -123,7 +123,7 @@
|
||||
<tr>
|
||||
<th class="formTitle" colspan="1">终炼胶比重</th>
|
||||
<td class="formValue">
|
||||
<a-input-number v-model:value="sheetForm.finalRubberSg" :disabled="!showFooter" :precision="6" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
|
||||
<a-input-number v-model:value="sheetForm.finalRubberSg" :disabled="!showFooter" :precision="3" :bordered="false" class="form-input" style="width: 100%" @update:value="recalcFillVolume" />
|
||||
</td>
|
||||
<th class="formTitle" colspan="1">适用工厂</th>
|
||||
<td class="formValue" colspan="2">
|
||||
|
||||
@@ -10,16 +10,23 @@ export const baseColumns: BasicColumn[] = [
|
||||
];
|
||||
|
||||
export const machineColumns: BasicColumn[] = [
|
||||
baseColumns[0],
|
||||
{ title: '机台', align: 'center', dataIndex: 'machineName', width: 160 },
|
||||
...baseColumns,
|
||||
...baseColumns.slice(1),
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
export const baseSearchFormSchema: FormSchema[] = [
|
||||
{ label: '计划日期', field: 'planDate', component: 'DatePicker', colProps: { span: 6 } },
|
||||
{ label: 'ERP编号', field: 'erpCode', component: 'JInput', colProps: { span: 6 } },
|
||||
{ label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } },
|
||||
];
|
||||
|
||||
export const machineSearchFormSchema: FormSchema[] = [
|
||||
baseSearchFormSchema[0],
|
||||
{ label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } },
|
||||
...baseSearchFormSchema.slice(1),
|
||||
];
|
||||
|
||||
export const superQuerySchema = {
|
||||
planDate: { title: '计划日期', order: 0, view: 'date' },
|
||||
machineName: { title: '机台', order: 1, view: 'text' },
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
import {
|
||||
baseColumns,
|
||||
machineColumns,
|
||||
searchFormSchema,
|
||||
baseSearchFormSchema,
|
||||
machineSearchFormSchema,
|
||||
superQuerySchema,
|
||||
} from './MesXslRawMaterialDemandPlan.data';
|
||||
import { list, getExportUrl } from './MesXslRawMaterialDemandPlan.api';
|
||||
@@ -40,7 +41,7 @@
|
||||
columns: baseColumns,
|
||||
canResize: true,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
schemas: baseSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
},
|
||||
@@ -57,20 +58,33 @@
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, setColumns }] = tableContext;
|
||||
const [registerTable, { reload, setColumns, setProps }] = tableContext;
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
onMounted(() => {
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
});
|
||||
|
||||
function applyColumns() {
|
||||
setColumns(groupByMachine.value ? machineColumns : baseColumns);
|
||||
}
|
||||
|
||||
function applySearchSchemas() {
|
||||
setProps({
|
||||
formConfig: {
|
||||
schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function onGroupByMachineChange() {
|
||||
queryParam.groupByMachine = groupByMachine.value ? 1 : 0;
|
||||
if (!groupByMachine.value) {
|
||||
delete queryParam.machineName;
|
||||
}
|
||||
applyColumns();
|
||||
applySearchSchemas();
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/xslmes/mcs/mcsToMesActMill/list',
|
||||
queryById = '/xslmes/mcs/mcsToMesActMill/queryById',
|
||||
exportXls = '/xslmes/mcs/mcsToMesActMill/exportXls',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
@@ -0,0 +1,29 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: 'GUID', align: 'center', dataIndex: 'guid', width: 280 },
|
||||
{ title: '动作地址', align: 'center', dataIndex: 'actAddr', width: 100 },
|
||||
{ title: '动作名称', align: 'center', dataIndex: 'actName', width: 140 },
|
||||
{ title: '动作名称(英)', align: 'center', dataIndex: 'actNameEn', width: 140 },
|
||||
{ title: '动作备注', align: 'center', dataIndex: 'actMemo', width: 120 },
|
||||
{ title: '关联地址', align: 'center', dataIndex: 'actRepaddr', width: 100 },
|
||||
{ title: '写入时间', align: 'center', dataIndex: 'writeTime', width: 170 },
|
||||
{ title: '读写标识', align: 'center', dataIndex: 'rwFlag', width: 90 },
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '动作名称', field: 'actName', component: 'JInput', colProps: { span: 6 } },
|
||||
{ label: '动作地址', field: 'actAddr', component: 'InputNumber', colProps: { span: 6 } },
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{ label: 'GUID', field: 'guid', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } },
|
||||
{ label: '动作地址', field: 'actAddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '关联地址', field: 'actRepaddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作名称', field: 'actName', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作名称(英)', field: 'actNameEn', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '动作备注', field: 'actMemo', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } },
|
||||
{ label: '写入时间', field: 'writeTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '读取时间', field: 'readTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
{ label: '读写标识', field: 'rwFlag', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } },
|
||||
];
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose title="开炼机动作(中间库)" :width="900">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../McsToMesActMill.data';
|
||||
|
||||
defineEmits(['register']);
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, setProps }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showOkBtn: false, showCancelBtn: true, cancelText: '关闭' });
|
||||
if (data?.record) {
|
||||
await setFieldsValue({ ...data.record });
|
||||
}
|
||||
setProps({ disabled: true });
|
||||
});
|
||||
</script>
|
||||
71
jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/index.vue
Normal file
71
jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/index.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="'xslmes:mcsSyncConfig:setting'" preIcon="ant-design:sync-outlined" @click="openCollect"> 采集操作 </a-button>
|
||||
<a-button type="link" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<McsToMesActMillModal @register="registerModal" />
|
||||
<CollectModal @register="registerCollectModal" @success="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="xslmes-mcs-mcsToMesActMill" setup>
|
||||
import { reactive } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import McsToMesActMillModal from './components/McsToMesActMillModal.vue';
|
||||
import CollectModal from '../mcsSyncConfig/components/CollectModal.vue';
|
||||
import { columns, searchFormSchema } from './McsToMesActMill.data';
|
||||
import { list, getExportUrl } from './McsToMesActMill.api';
|
||||
|
||||
const queryParam = reactive<any>({});
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerCollectModal, { openModal: openCollectModal }] = useModal();
|
||||
|
||||
const { tableContext, onExportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '开炼机动作(中间库)',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: true,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToTime: [['writeTime', ['writeTime_begin', 'writeTime_end'], 'YYYY-MM-DD HH:mm:ss']],
|
||||
},
|
||||
actionColumn: { width: 80, fixed: 'right' },
|
||||
beforeFetch: (params) => Object.assign(params, queryParam),
|
||||
},
|
||||
exportConfig: { name: '开炼机动作(中间库)', url: getExportUrl, params: queryParam },
|
||||
});
|
||||
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
const superQueryConfig = reactive({});
|
||||
|
||||
function openCollect() {
|
||||
openCollectModal(true, { bizType: 'MILL_ACT' });
|
||||
}
|
||||
|
||||
function handleSuperQuery(params) {
|
||||
Object.keys(params).map((k) => {
|
||||
queryParam[k] = params[k];
|
||||
});
|
||||
reload();
|
||||
}
|
||||
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, { record, isUpdate: true, showFooter: false });
|
||||
}
|
||||
|
||||
function getTableAction(record) {
|
||||
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user