fix(mes): 修复迁移 review 第三批 finding(B019-B023)+ schema/风格清理
修复 MES migration review 的 1 个 P1 + 多个 P2/P3 finding,覆盖 web-antd 和 web-ele 两端。 - MES-B019 (P1, R020): OQC 从待检任务预填时,checkQuantity 缺省取 outQuantity,避免必填的检测数量为空被校验拦截。 - MES-B020 (P2, R012): 清理 pro/card、stocktaking/task 残留的 TODO @AI 临时注释,taskId 补正式业务尾注释。 - MES-B021 (P2, R017): 自动编码分段"循环方式"列改 slot + DictTag,仅 cycleFlag 为真才渲染(非循环行留空,对齐源 v-if 行为)。 - MES-B022 (P3, R035): 盘点结果选中盘点清单行后,物料/批次/仓储位置字段 按 lineId 禁用,避免改成与清单不一致的值。 - MES-B023 (P3, R038): 抽出 QcIndicatorResultSpecificationInput 组件, schema 仅保留单个 resultSpecification 字段,组件内按 resultType 切 RadioGroup(FILE)/Select(DICT),消除重复 fieldName 的双 FormField/重复 key。 附带代码风格对齐: - pro/card、stocktaking/task 的 getTitle 改为「特殊态 if 提前 return + create/update 三元收尾」,对齐 oqc/returnvendor 等主流模块写法。 验证: - pnpm exec eslint <本批改动文件>(antd + ele)通过 - pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc 过滤 qc/indicator、qc/oqc、md/autocode、wm/stocktaking/task、pro/card 无报错 Ref: project_duibiao/mes/review_vben/INDEX.md (MES-R012/R017/R020/R035/R038)pull/351/MERGE
parent
26d07e2e28
commit
0fe9607302
|
|
@ -448,10 +448,7 @@ export function usePartGridColumns(): VxeTableGridOptions<MesMdAutoCodePartApi.A
|
||||||
title: '循环方式',
|
title: '循环方式',
|
||||||
width: 120,
|
width: 120,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
cellRender: {
|
slots: { default: 'cycleMethod' },
|
||||||
name: 'CellDict',
|
|
||||||
props: { type: DICT_TYPE.MES_MD_AUTO_CODE_CYCLE_METHOD },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'remark',
|
field: 'remark',
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import type { MesMdAutoCodePartApi } from '#/api/mes/md/autocode/part';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
|
@ -13,6 +14,7 @@ import {
|
||||||
deleteAutoCodePart,
|
deleteAutoCodePart,
|
||||||
getAutoCodePartListByRuleId,
|
getAutoCodePartListByRuleId,
|
||||||
} from '#/api/mes/md/autocode/part';
|
} from '#/api/mes/md/autocode/part';
|
||||||
|
import { DictTag } from '#/components/dict-tag';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { usePartGridColumns } from '../data';
|
import { usePartGridColumns } from '../data';
|
||||||
|
|
@ -107,6 +109,13 @@ watch(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Grid class="w-full" table-title="规则组成">
|
<Grid class="w-full" table-title="规则组成">
|
||||||
|
<template #cycleMethod="{ row }">
|
||||||
|
<DictTag
|
||||||
|
v-if="row.cycleFlag"
|
||||||
|
:type="DICT_TYPE.MES_MD_AUTO_CODE_CYCLE_METHOD"
|
||||||
|
:value="row.cycleMethod"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|
|
||||||
|
|
@ -41,22 +41,16 @@ const canSubmit = computed(() => // 编辑态草稿可提交
|
||||||
formType.value === 'update' &&
|
formType.value === 'update' &&
|
||||||
formData.value?.status === MesProCardStatusEnum.PREPARE,
|
formData.value?.status === MesProCardStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
// TODO @AI:标题方法的代码风格;
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['流转卡']);
|
||||||
return $t('ui.actionTitle.view', ['流转卡']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '完成流转卡';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['流转卡']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['流转卡']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '完成流转卡';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['流转卡'])
|
||||||
|
: $t('ui.actionTitle.create', ['流转卡']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
@ -125,7 +119,6 @@ async function handleFinish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
// TODO @AI:检查下 onConfirm 方法的风格,是不是缺了一个 // 关闭并提示??看看其他模块,是不是也有这个情况?
|
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
if (!isEditable.value) {
|
if (!isEditable.value) {
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
export { default as QcIndicatorResultSpecificationInput } from './result-specification-input.vue';
|
||||||
export { default as QcIndicatorSelectDialog } from './select-dialog.vue';
|
export { default as QcIndicatorSelectDialog } from './select-dialog.vue';
|
||||||
export { default as QcIndicatorSelect } from './select.vue';
|
export { default as QcIndicatorSelect } from './select.vue';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { MesQcResultValueType } from '@vben/constants';
|
||||||
|
|
||||||
|
import { RadioGroup, Select } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { getSimpleDictTypeList } from '#/api/system/dict/type';
|
||||||
|
|
||||||
|
defineOptions({ name: 'QcIndicatorResultSpecificationInput' });
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
modelValue?: string;
|
||||||
|
resultType?: number;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
modelValue: undefined,
|
||||||
|
resultType: undefined,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value?: string];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const fileOptions = [
|
||||||
|
{ label: '图片/照片', value: 'IMG' },
|
||||||
|
{ label: '文件', value: 'FILE' },
|
||||||
|
];
|
||||||
|
const dictTypeOptions = ref<{ name?: string; type?: string }[]>([]);
|
||||||
|
|
||||||
|
const innerValue = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value?: string) => emit('update:modelValue', value),
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 加载字典类型选项(仅字典类型结果值需要) */
|
||||||
|
async function loadDictTypeOptions() {
|
||||||
|
if (dictTypeOptions.value.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dictTypeOptions.value = await getSimpleDictTypeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.resultType,
|
||||||
|
(value) => {
|
||||||
|
if (value === MesQcResultValueType.DICT) {
|
||||||
|
void loadDictTypeOptions();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<RadioGroup
|
||||||
|
v-if="resultType === MesQcResultValueType.FILE"
|
||||||
|
v-model:value="innerValue"
|
||||||
|
:options="fileOptions"
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
v-else-if="resultType === MesQcResultValueType.DICT"
|
||||||
|
v-model:value="innerValue"
|
||||||
|
:field-names="{ label: 'name', value: 'type' }"
|
||||||
|
:filter-option="
|
||||||
|
(input: string, option: any) =>
|
||||||
|
(option.name as string).toLowerCase().includes(input.toLowerCase())
|
||||||
|
"
|
||||||
|
:options="dictTypeOptions"
|
||||||
|
allow-clear
|
||||||
|
class="w-full"
|
||||||
|
placeholder="请选择字典类型"
|
||||||
|
show-search
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
@ -2,7 +2,7 @@ import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { MesQcIndicatorApi } from '#/api/mes/qc/indicator';
|
import type { MesQcIndicatorApi } from '#/api/mes/qc/indicator';
|
||||||
|
|
||||||
import { h } from 'vue';
|
import { h, markRaw } from 'vue';
|
||||||
|
|
||||||
import { DICT_TYPE, MesAutoCodeRuleCode, MesQcResultValueType } from '@vben/constants';
|
import { DICT_TYPE, MesAutoCodeRuleCode, MesQcResultValueType } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
@ -10,7 +10,8 @@ import { getDictOptions } from '@vben/hooks';
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
|
|
||||||
import { generateAutoCode } from '#/api/mes/md/autocode/record';
|
import { generateAutoCode } from '#/api/mes/md/autocode/record';
|
||||||
import { getSimpleDictTypeList } from '#/api/system/dict/type';
|
|
||||||
|
import { QcIndicatorResultSpecificationInput } from './components';
|
||||||
|
|
||||||
/** 新增/修改的表单 */
|
/** 新增/修改的表单 */
|
||||||
export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
||||||
|
|
@ -93,37 +94,17 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'resultSpecification',
|
fieldName: 'resultSpecification',
|
||||||
label: '文件类型',
|
label: '结果值属性',
|
||||||
component: 'RadioGroup',
|
component: markRaw(QcIndicatorResultSpecificationInput),
|
||||||
componentProps: {
|
// 按结果值类型在组件内部切换文件类型 RadioGroup / 字典类型 ApiSelect
|
||||||
options: [
|
|
||||||
{ label: '图片/照片', value: 'IMG' },
|
|
||||||
{ label: '文件', value: 'FILE' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['resultType'],
|
triggerFields: ['resultType'],
|
||||||
show: (values) => values.resultType === MesQcResultValueType.FILE,
|
if: (values) =>
|
||||||
},
|
values.resultType === MesQcResultValueType.FILE ||
|
||||||
rules: 'required',
|
values.resultType === MesQcResultValueType.DICT,
|
||||||
},
|
componentProps: (values) => ({
|
||||||
{
|
resultType: values.resultType,
|
||||||
fieldName: 'resultSpecification',
|
}),
|
||||||
label: '字典类型',
|
|
||||||
component: 'ApiSelect',
|
|
||||||
componentProps: {
|
|
||||||
allowClear: true,
|
|
||||||
api: getSimpleDictTypeList,
|
|
||||||
filterOption: (input: string, option: any) =>
|
|
||||||
(option.label as string).toLowerCase().includes(input.toLowerCase()),
|
|
||||||
labelField: 'name',
|
|
||||||
placeholder: '请选择字典类型',
|
|
||||||
showSearch: true,
|
|
||||||
valueField: 'type',
|
|
||||||
},
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: ['resultType'],
|
|
||||||
show: (values) => values.resultType === MesQcResultValueType.DICT,
|
|
||||||
},
|
},
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -171,10 +171,15 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
} else if (data?.prefill) {
|
} else if (data?.prefill) {
|
||||||
// 预填模式:来自待检任务
|
// 预填模式:来自待检任务。源项目靠 watcher 自动把 outQuantity 同步到
|
||||||
formData.value = { ...data.prefill };
|
// checkQuantity,这里显式补齐,避免必填的检测数量为空
|
||||||
|
const prefill = {
|
||||||
|
...data.prefill,
|
||||||
|
checkQuantity: data.prefill.checkQuantity ?? data.prefill.outQuantity,
|
||||||
|
};
|
||||||
|
formData.value = { ...prefill };
|
||||||
// 设置到 values
|
// 设置到 values
|
||||||
await formApi.setValues(data.prefill);
|
await formApi.setValues(prefill);
|
||||||
}
|
}
|
||||||
originalSnapshot.value = JSON.stringify(await formApi.getValues());
|
originalSnapshot.value = JSON.stringify(await formApi.getValues());
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,11 @@ export function useResultFormSchema(
|
||||||
placeholder: '请选择物料',
|
placeholder: '请选择物料',
|
||||||
},
|
},
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
|
// 选中盘点清单后,物料由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'batchCode',
|
fieldName: 'batchCode',
|
||||||
|
|
@ -509,6 +514,11 @@ export function useResultFormSchema(
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '请输入批次编码',
|
placeholder: '请输入批次编码',
|
||||||
},
|
},
|
||||||
|
// 选中盘点清单后,批次由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'takingQuantity',
|
fieldName: 'takingQuantity',
|
||||||
|
|
@ -535,6 +545,11 @@ export function useResultFormSchema(
|
||||||
placeholder: '请选择仓库',
|
placeholder: '请选择仓库',
|
||||||
},
|
},
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
|
// 选中盘点清单后,仓库由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'locationId',
|
fieldName: 'locationId',
|
||||||
|
|
@ -542,8 +557,10 @@ export function useResultFormSchema(
|
||||||
component: markRaw(WmWarehouseLocationSelect),
|
component: markRaw(WmWarehouseLocationSelect),
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['warehouseId'],
|
triggerFields: ['warehouseId', 'lineId'],
|
||||||
show: (values) => !!values.warehouseId,
|
show: (values) => !!values.warehouseId,
|
||||||
|
// 选中盘点清单后,库区由清单带出且禁止改动
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
componentProps: (values) => ({
|
componentProps: (values) => ({
|
||||||
onChange: () => formApi?.setFieldValue('areaId', undefined),
|
onChange: () => formApi?.setFieldValue('areaId', undefined),
|
||||||
placeholder: '请选择库区',
|
placeholder: '请选择库区',
|
||||||
|
|
@ -557,8 +574,10 @@ export function useResultFormSchema(
|
||||||
component: markRaw(WmWarehouseAreaSelect),
|
component: markRaw(WmWarehouseAreaSelect),
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['locationId'],
|
triggerFields: ['locationId', 'lineId'],
|
||||||
show: (values) => !!values.locationId,
|
show: (values) => !!values.locationId,
|
||||||
|
// 选中盘点清单后,库位由清单带出且禁止改动
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
componentProps: (values) => ({
|
componentProps: (values) => ({
|
||||||
locationId: values.locationId,
|
locationId: values.locationId,
|
||||||
placeholder: '请选择库位',
|
placeholder: '请选择库位',
|
||||||
|
|
|
||||||
|
|
@ -49,25 +49,19 @@ const showResultTab = computed(
|
||||||
(!!formData.value?.status &&
|
(!!formData.value?.status &&
|
||||||
formData.value.status !== MesWmStockTakingTaskStatusEnum.PREPARE),
|
formData.value.status !== MesWmStockTakingTaskStatusEnum.PREPARE),
|
||||||
);
|
);
|
||||||
// TODO @AI:这里的代码风格,标题的代码风格;
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['盘点任务']);
|
||||||
return $t('ui.actionTitle.view', ['盘点任务']);
|
|
||||||
}
|
|
||||||
case 'execute': {
|
|
||||||
return '执行盘点';
|
|
||||||
}
|
|
||||||
case 'submit': {
|
|
||||||
return '提交盘点任务';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['盘点任务']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['盘点任务']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'execute') {
|
||||||
|
return '执行盘点';
|
||||||
|
}
|
||||||
|
if (formType.value === 'submit') {
|
||||||
|
return '提交盘点任务';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['盘点任务'])
|
||||||
|
: $t('ui.actionTitle.create', ['盘点任务']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
@ -125,7 +119,6 @@ async function handleExecute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
// TODO @AI:注释风格,代码的;
|
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
if (!isEditable.value) {
|
if (!isEditable.value) {
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { useResultFormSchema } from '../data';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formData = ref<MesWmStockTakingResultApi.StockTakingResult>();
|
const formData = ref<MesWmStockTakingResultApi.StockTakingResult>();
|
||||||
const taskId = ref<number>(); // TODO @AI:尾注释;
|
const taskId = ref<number>(); // 所属盘点任务编号
|
||||||
const isExecute = ref(false); // 是否执行盘点模式(可选择盘点清单回填)
|
const isExecute = ref(false); // 是否执行盘点模式(可选择盘点清单回填)
|
||||||
const getTitle = computed(() =>
|
const getTitle = computed(() =>
|
||||||
formData.value?.id
|
formData.value?.id
|
||||||
|
|
|
||||||
|
|
@ -448,10 +448,7 @@ export function usePartGridColumns(): VxeTableGridOptions<MesMdAutoCodePartApi.A
|
||||||
title: '循环方式',
|
title: '循环方式',
|
||||||
width: 120,
|
width: 120,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
cellRender: {
|
slots: { default: 'cycleMethod' },
|
||||||
name: 'CellDict',
|
|
||||||
props: { type: DICT_TYPE.MES_MD_AUTO_CODE_CYCLE_METHOD },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'remark',
|
field: 'remark',
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import type { MesMdAutoCodePartApi } from '#/api/mes/md/autocode/part';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
|
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
|
@ -13,6 +14,7 @@ import {
|
||||||
deleteAutoCodePart,
|
deleteAutoCodePart,
|
||||||
getAutoCodePartListByRuleId,
|
getAutoCodePartListByRuleId,
|
||||||
} from '#/api/mes/md/autocode/part';
|
} from '#/api/mes/md/autocode/part';
|
||||||
|
import { DictTag } from '#/components/dict-tag';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { usePartGridColumns } from '../data';
|
import { usePartGridColumns } from '../data';
|
||||||
|
|
@ -107,6 +109,13 @@ watch(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Grid class="w-full" table-title="规则组成">
|
<Grid class="w-full" table-title="规则组成">
|
||||||
|
<template #cycleMethod="{ row }">
|
||||||
|
<DictTag
|
||||||
|
v-if="row.cycleFlag"
|
||||||
|
:type="DICT_TYPE.MES_MD_AUTO_CODE_CYCLE_METHOD"
|
||||||
|
:value="row.cycleMethod"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|
|
||||||
|
|
@ -42,20 +42,15 @@ const canSubmit = computed(() => // 编辑态草稿可提交
|
||||||
formData.value?.status === MesProCardStatusEnum.PREPARE,
|
formData.value?.status === MesProCardStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['流转卡']);
|
||||||
return $t('ui.actionTitle.view', ['流转卡']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '完成流转卡';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['流转卡']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['流转卡']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '完成流转卡';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['流转卡'])
|
||||||
|
: $t('ui.actionTitle.create', ['流转卡']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
export { default as QcIndicatorResultSpecificationInput } from './result-specification-input.vue';
|
||||||
export { default as QcIndicatorSelectDialog } from './select-dialog.vue';
|
export { default as QcIndicatorSelectDialog } from './select-dialog.vue';
|
||||||
export { default as QcIndicatorSelect } from './select.vue';
|
export { default as QcIndicatorSelect } from './select.vue';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { MesQcResultValueType } from '@vben/constants';
|
||||||
|
|
||||||
|
import { ElOption, ElRadioButton, ElRadioGroup, ElSelect } from 'element-plus';
|
||||||
|
|
||||||
|
import { getSimpleDictTypeList } from '#/api/system/dict/type';
|
||||||
|
|
||||||
|
defineOptions({ name: 'QcIndicatorResultSpecificationInput' });
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
modelValue?: string;
|
||||||
|
resultType?: number;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
modelValue: undefined,
|
||||||
|
resultType: undefined,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value?: string];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const fileOptions = [
|
||||||
|
{ label: '图片/照片', value: 'IMG' },
|
||||||
|
{ label: '文件', value: 'FILE' },
|
||||||
|
];
|
||||||
|
const dictTypeOptions = ref<{ name?: string; type?: string }[]>([]);
|
||||||
|
|
||||||
|
const innerValue = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value?: string) => emit('update:modelValue', value),
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 加载字典类型选项(仅字典类型结果值需要) */
|
||||||
|
async function loadDictTypeOptions() {
|
||||||
|
if (dictTypeOptions.value.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dictTypeOptions.value = await getSimpleDictTypeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.resultType,
|
||||||
|
(value) => {
|
||||||
|
if (value === MesQcResultValueType.DICT) {
|
||||||
|
void loadDictTypeOptions();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElRadioGroup
|
||||||
|
v-if="resultType === MesQcResultValueType.FILE"
|
||||||
|
v-model="innerValue"
|
||||||
|
>
|
||||||
|
<ElRadioButton
|
||||||
|
v-for="option in fileOptions"
|
||||||
|
:key="option.value"
|
||||||
|
:value="option.value"
|
||||||
|
>
|
||||||
|
{{ option.label }}
|
||||||
|
</ElRadioButton>
|
||||||
|
</ElRadioGroup>
|
||||||
|
<ElSelect
|
||||||
|
v-else-if="resultType === MesQcResultValueType.DICT"
|
||||||
|
v-model="innerValue"
|
||||||
|
class="!w-full"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
placeholder="请选择字典类型"
|
||||||
|
>
|
||||||
|
<ElOption
|
||||||
|
v-for="item in dictTypeOptions"
|
||||||
|
:key="item.type"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.type!"
|
||||||
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</template>
|
||||||
|
|
@ -2,7 +2,7 @@ import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { MesQcIndicatorApi } from '#/api/mes/qc/indicator';
|
import type { MesQcIndicatorApi } from '#/api/mes/qc/indicator';
|
||||||
|
|
||||||
import { h } from 'vue';
|
import { h, markRaw } from 'vue';
|
||||||
|
|
||||||
import { DICT_TYPE, MesAutoCodeRuleCode, MesQcResultValueType } from '@vben/constants';
|
import { DICT_TYPE, MesAutoCodeRuleCode, MesQcResultValueType } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
@ -10,7 +10,8 @@ import { getDictOptions } from '@vben/hooks';
|
||||||
import { ElButton } from 'element-plus';
|
import { ElButton } from 'element-plus';
|
||||||
|
|
||||||
import { generateAutoCode } from '#/api/mes/md/autocode/record';
|
import { generateAutoCode } from '#/api/mes/md/autocode/record';
|
||||||
import { getSimpleDictTypeList } from '#/api/system/dict/type';
|
|
||||||
|
import { QcIndicatorResultSpecificationInput } from './components';
|
||||||
|
|
||||||
/** 新增/修改的表单 */
|
/** 新增/修改的表单 */
|
||||||
export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
||||||
|
|
@ -92,37 +93,17 @@ export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'resultSpecification',
|
fieldName: 'resultSpecification',
|
||||||
label: '文件类型',
|
label: '结果值属性',
|
||||||
component: 'RadioGroup',
|
component: markRaw(QcIndicatorResultSpecificationInput),
|
||||||
componentProps: {
|
// 按结果值类型在组件内部切换文件类型 RadioGroup / 字典类型 Select
|
||||||
options: [
|
|
||||||
{ label: '图片/照片', value: 'IMG' },
|
|
||||||
{ label: '文件', value: 'FILE' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['resultType'],
|
triggerFields: ['resultType'],
|
||||||
show: (values) => values.resultType === MesQcResultValueType.FILE,
|
if: (values) =>
|
||||||
},
|
values.resultType === MesQcResultValueType.FILE ||
|
||||||
rules: 'required',
|
values.resultType === MesQcResultValueType.DICT,
|
||||||
},
|
componentProps: (values) => ({
|
||||||
{
|
resultType: values.resultType,
|
||||||
fieldName: 'resultSpecification',
|
}),
|
||||||
label: '字典类型',
|
|
||||||
component: 'ApiSelect',
|
|
||||||
componentProps: {
|
|
||||||
api: getSimpleDictTypeList,
|
|
||||||
clearable: true,
|
|
||||||
filterMethod: (input: string, option: any) =>
|
|
||||||
(option.label as string).toLowerCase().includes(input.toLowerCase()),
|
|
||||||
filterable: true,
|
|
||||||
labelField: 'name',
|
|
||||||
placeholder: '请选择字典类型',
|
|
||||||
valueField: 'type',
|
|
||||||
},
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: ['resultType'],
|
|
||||||
show: (values) => values.resultType === MesQcResultValueType.DICT,
|
|
||||||
},
|
},
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -178,10 +178,15 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
} else if (data?.prefill) {
|
} else if (data?.prefill) {
|
||||||
// 预填模式:来自待检任务
|
// 预填模式:来自待检任务。源项目靠 watcher 自动把 outQuantity 同步到
|
||||||
formData.value = { ...data.prefill };
|
// checkQuantity,这里显式补齐,避免必填的检测数量为空
|
||||||
|
const prefill = {
|
||||||
|
...data.prefill,
|
||||||
|
checkQuantity: data.prefill.checkQuantity ?? data.prefill.outQuantity,
|
||||||
|
};
|
||||||
|
formData.value = { ...prefill };
|
||||||
// 设置到 values
|
// 设置到 values
|
||||||
await formApi.setValues(data.prefill);
|
await formApi.setValues(prefill);
|
||||||
}
|
}
|
||||||
originalSnapshot.value = JSON.stringify(await formApi.getValues());
|
originalSnapshot.value = JSON.stringify(await formApi.getValues());
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,11 @@ export function useResultFormSchema(
|
||||||
placeholder: '请选择物料',
|
placeholder: '请选择物料',
|
||||||
},
|
},
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
|
// 选中盘点清单后,物料由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'batchCode',
|
fieldName: 'batchCode',
|
||||||
|
|
@ -510,6 +515,11 @@ export function useResultFormSchema(
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '请输入批次编码',
|
placeholder: '请输入批次编码',
|
||||||
},
|
},
|
||||||
|
// 选中盘点清单后,批次由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'takingQuantity',
|
fieldName: 'takingQuantity',
|
||||||
|
|
@ -537,6 +547,11 @@ export function useResultFormSchema(
|
||||||
placeholder: '请选择仓库',
|
placeholder: '请选择仓库',
|
||||||
},
|
},
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
|
// 选中盘点清单后,仓库由清单带出且禁止改动
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: ['lineId'],
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldName: 'locationId',
|
fieldName: 'locationId',
|
||||||
|
|
@ -544,8 +559,10 @@ export function useResultFormSchema(
|
||||||
component: markRaw(WmWarehouseLocationSelect),
|
component: markRaw(WmWarehouseLocationSelect),
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['warehouseId'],
|
triggerFields: ['warehouseId', 'lineId'],
|
||||||
show: (values) => !!values.warehouseId,
|
show: (values) => !!values.warehouseId,
|
||||||
|
// 选中盘点清单后,库区由清单带出且禁止改动
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
componentProps: (values) => ({
|
componentProps: (values) => ({
|
||||||
onChange: () => formApi?.setFieldValue('areaId', undefined),
|
onChange: () => formApi?.setFieldValue('areaId', undefined),
|
||||||
placeholder: '请选择库区',
|
placeholder: '请选择库区',
|
||||||
|
|
@ -559,8 +576,10 @@ export function useResultFormSchema(
|
||||||
component: markRaw(WmWarehouseAreaSelect),
|
component: markRaw(WmWarehouseAreaSelect),
|
||||||
rules: 'selectRequired',
|
rules: 'selectRequired',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['locationId'],
|
triggerFields: ['locationId', 'lineId'],
|
||||||
show: (values) => !!values.locationId,
|
show: (values) => !!values.locationId,
|
||||||
|
// 选中盘点清单后,库位由清单带出且禁止改动
|
||||||
|
disabled: (values) => values.lineId != null,
|
||||||
componentProps: (values) => ({
|
componentProps: (values) => ({
|
||||||
locationId: values.locationId,
|
locationId: values.locationId,
|
||||||
placeholder: '请选择库位',
|
placeholder: '请选择库位',
|
||||||
|
|
|
||||||
|
|
@ -50,23 +50,18 @@ const showResultTab = computed(
|
||||||
formData.value.status !== MesWmStockTakingTaskStatusEnum.PREPARE),
|
formData.value.status !== MesWmStockTakingTaskStatusEnum.PREPARE),
|
||||||
);
|
);
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['盘点任务']);
|
||||||
return $t('ui.actionTitle.view', ['盘点任务']);
|
|
||||||
}
|
|
||||||
case 'execute': {
|
|
||||||
return '执行盘点';
|
|
||||||
}
|
|
||||||
case 'submit': {
|
|
||||||
return '提交盘点任务';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['盘点任务']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['盘点任务']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'execute') {
|
||||||
|
return '执行盘点';
|
||||||
|
}
|
||||||
|
if (formType.value === 'submit') {
|
||||||
|
return '提交盘点任务';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['盘点任务'])
|
||||||
|
: $t('ui.actionTitle.create', ['盘点任务']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue