From 6be4dc69a73560ab2e08e68d5dbfdf95ae62d5b4 Mon Sep 17 00:00:00 2001 From: zs <zhousong@weben-smart.com> Date: 周三, 14 5月 2025 15:14:37 +0800 Subject: [PATCH] 托盘高级查询 --- HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.tsx | 336 +++++++---- HIAWms/server/src/CMS.Plugin.HIAWms.Application.Contracts/Dtos/WmsContainer/GetWmsContainerInput.cs | 315 +++++++++ HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsContainerAppService.cs | 56 + HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainerQueryDrawer.tsx | 581 +++++++++++++++++++ HIAWms/server/src/CMS.Plugin.HIAWms.EntityFrameworkCore/Repositories/EfCoreWmsContainerRepository.cs | 58 - Weben_CMS专用代码生成器/Code/File/GenerateCodeConfigParamFiles/托盘配置.txt | 14 HIAWms/hiawms_web/src/widgets/WmsContainer/Models/WmsContainerQueryDrawer.ts | 44 + HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.module.scss | 3 HIAWms/server/src/CMS.Plugin.HIAWms.Domain/WmsContainers/IWmsContainerRepository.cs | 6 HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainer.ts | 30 HIAWms/hiawms_web/src/widgets/WmsContainer/Models/Service/WmsContainerQueryDrawer.ts | 35 + HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.tsx | 71 ++ HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.module.scss | 227 +++--- 13 files changed, 1,458 insertions(+), 318 deletions(-) diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainer.ts b/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainer.ts index 97ecbec..65b9471 100644 --- a/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainer.ts +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainer.ts @@ -51,7 +51,11 @@ title: '', isAdd: false, }) - + const dialogConfigForQuery = reactive({ + visible: false, + title: '', + isAdd: false, + }) const dialogSettingConfig = reactive({ visible: false, title: '', @@ -149,6 +153,15 @@ sort.value = params.totalCount + 1 } + //鐐瑰嚮鎸夐挳銆愰珮绾ф煡璇€�� + const onAdvancedQuery = () => { + const params = tableRef.value?.getPaginationParams() + current.value = null + dialogConfigForQuery.visible = true + dialogConfigForQuery.isAdd = true + dialogConfigForQuery.title = '楂樼骇鏌ヨ' + } + const onConfirmWmsContainer = async () => { dialogConfig.visible = false if (dialogConfig.isAdd) { @@ -167,12 +180,13 @@ current.value = row } } - /** - * 瀵煎嚭 - */ - const onExport = () => { - const params = tableRef.value?.getParams() - exportFile('/api/v1/HIAWms/wmsContainer/export', params, 'wmsContainer') + /** + + * 瀵煎嚭 + */ + const onExport = (data = {}) => { + //const params = tableRef.value?.getParams() + exportFile('/api/v1/HIAWms/wmsContainer/export', data, '鎵樼洏绠$悊') } /** @@ -241,6 +255,7 @@ current, search, sort, + dialogConfigForQuery, wmsContainerColumns, paginationParams, headers, @@ -253,6 +268,7 @@ onRowClick, onConfirmWmsContainer, onCheck, + onAdvancedQuery, onAddWmsContainer, } } diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainerQueryDrawer.tsx b/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainerQueryDrawer.tsx new file mode 100644 index 0000000..740cf10 --- /dev/null +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Controllers/WmsContainerQueryDrawer.tsx @@ -0,0 +1,581 @@ +import { + ref, + onMounted, + reactive, + computed, + Ref, + watch, + SetupContext, + h, +} from 'vue' +import { injectModel } from '@/libs/Provider/Provider' +import { WmsContainerDrawer } from '../Models/WmsContainerDrawer' +import { ElMessage } from 'element-plus' +import isEqual from 'lodash/isEqual' +import { ConfirmBox } from '@/components/ConfirmBox/ConfirmBox' +import { cloneDeep } from 'lodash' +// 寮曞叆鍏叡閫夐」閰嶇疆 +import { + FILTER_MODE_OPTIONS_STRING, + FILTER_MODE_OPTIONS_NUM, + FILTER_MODE_OPTIONS_BOOL, +} from '@/components/DyFormForHighQuery/DyFormForHighQueryOptions' +import { BOOLEAN_OPTIONS } from '@/utils/commonOptionConstants' + +export const useWmsContainerQueryDrawer = (props: any, ctx?: any) => { + const wmsContainerDrawer = + injectModel<WmsContainerDrawer>('WmsContainerDrawer') + /** + * 鐢ㄦ潵瀵规瘮鐨勫垵濮嬪寲鏁版嵁 + */ + const initiateData: Ref<Record<string, any>> = ref({}) + const formData = ref<Record<string, any>>({}) + // ref + const formRef = ref() + + const disabled = ref(false) + + const current = computed(() => { + return props.row || null + }) + + const inputNumber = (attrs) => { + return ( + <el-input-number + min="1" + step="1" + precision="0" + {...attrs} + ></el-input-number> + ) + } + + const datePickerRange = (attrs) => { + return ( + <el-date-picker + type="daterange" + value-format="YYYY-MM-DD HH:mm:ss" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + {...attrs} + ></el-date-picker> + ) + } + + const dateTimePickerRange = (attrs) => { + return ( + <el-date-picker + type="datetimerange" + value-format="YYYY-MM-DD HH:mm:ss" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + {...attrs} + ></el-date-picker> + ) + } + + const visible = computed({ + get() { + return props.modelValue + }, + set(val) { + ctx.emit('update:modelValue', val) + }, + }) + /** + * 楂樼骇鏌ヨ鐨刦orm瀛楁 + */ + const formItems = reactive([ + { + label: '鎵樼洏缂栧彿', + prop: 'containerNo', + el: 'input', + //disabled: disabled, + placeholder: '璇疯緭鍏ユ墭鐩樼紪鍙�', + highSelectAttrs: { + prop: 'containerNo_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_STRING, + }, + }, + { + label: '鎵樼洏绫诲瀷', + prop: 'containerType', + el: 'select', + clearable: true, + option: [], + //disabled: disabled, + placeholder: '璇疯緭鍏ユ墭鐩樼被鍨�', + highSelectAttrs: { + prop: 'containerType_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_BOOL, + }, + }, + { + label: '鎵樼洏鐘舵��', + prop: 'containerStatus', + el: 'select', + clearable: true, + option: [], + //disabled: disabled, + placeholder: '璇疯緭鍏ユ墭鐩樼姸鎬�', + highSelectAttrs: { + prop: 'containerStatus_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_BOOL, + }, + }, + { + label: '闀垮害', + prop: 'specLength', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ラ暱搴�', + highSelectAttrs: { + prop: 'specLength_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '瀹藉害', + prop: 'specWidth', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ュ搴�', + highSelectAttrs: { + prop: 'specWidth_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '楂樺害', + prop: 'specHeight', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ラ珮搴�', + highSelectAttrs: { + prop: 'specHeight_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '闄愰暱', + prop: 'limitLength', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ラ檺闀�', + highSelectAttrs: { + prop: 'limitLength_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '闄愬', + prop: 'limitWidth', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ラ檺瀹�', + highSelectAttrs: { + prop: 'limitWidth_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '闄愰珮', + prop: 'limitHeight', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ラ檺楂�', + highSelectAttrs: { + prop: 'limitHeight_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + { + label: '杞介噸涓婇檺', + prop: 'maxWeight', + el: (props: any, { attrs }: SetupContext) => { + return h(inputNumber, { + ...props, + clearable: true, + ...attrs, + }) + }, + width: '100%', + step: 0.01, + precision: 2, + //disabled: disabled, + placeholder: '璇疯緭鍏ヨ浇閲嶄笂闄�', + highSelectAttrs: { + prop: 'maxWeight_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_NUM, + }, + }, + // { + // label: '寮傚父鏁伴噺', + // prop: 'exceptionNumber', + // el: (props: any, { attrs }: SetupContext) => { + // return h(inputNumber, { + // ...props, + // clearable: true, + // ...attrs, + // }) + // }, + // width: '100%', + // step: 1, + // precision: 0, + // //disabled: disabled, + // placeholder: '璇疯緭鍏ュ紓甯告暟閲�', + // highSelectAttrs: { + // prop: 'exceptionNumber_FilterMode', + // el: 'select', + // placeholder: '璇烽�夋嫨', + // options: FILTER_MODE_OPTIONS_NUM, + // }, + // }, + // { + // label: '鐗╂枡鏁伴噺', + // prop: 'materialNumber', + // el: (props: any, { attrs }: SetupContext) => { + // return h(inputNumber, { + // ...props, + // clearable: true, + // ...attrs, + // }) + // }, + // width: '100%', + // step: 1, + // precision: 0, + // //disabled: disabled, + // placeholder: '璇疯緭鍏ョ墿鏂欐暟閲�', + // highSelectAttrs: { + // prop: 'materialNumber_FilterMode', + // el: 'select', + // placeholder: '璇烽�夋嫨', + // options: FILTER_MODE_OPTIONS_NUM, + // }, + // }, + // { + // label: '鍐椾綑瀛楁1 - 棰勭暀鎵╁睍鐢ㄩ��', + // prop: 'redundantField1', + // el: 'input', + // //disabled: disabled, + // placeholder: '璇疯緭鍏ュ啑浣欏瓧娈�1 - 棰勭暀鎵╁睍鐢ㄩ��', + // highSelectAttrs: { + // prop: 'redundantField1_FilterMode', + // el: 'select', + // placeholder: '璇烽�夋嫨', + // options: FILTER_MODE_OPTIONS_STRING, + // }, + // }, + // { + // label: '鍐椾綑瀛楁2 - 棰勭暀鎵╁睍鐢ㄩ��', + // prop: 'redundantField2', + // el: 'input', + // //disabled: disabled, + // placeholder: '璇疯緭鍏ュ啑浣欏瓧娈�2 - 棰勭暀鎵╁睍鐢ㄩ��', + // highSelectAttrs: { + // prop: 'redundantField2_FilterMode', + // el: 'select', + // placeholder: '璇烽�夋嫨', + // options: FILTER_MODE_OPTIONS_STRING, + // }, + // }, + // { + // label: '鍐椾綑瀛楁3 - 棰勭暀鎵╁睍鐢ㄩ��', + // prop: 'redundantField3', + // el: 'input', + // //disabled: disabled, + // placeholder: '璇疯緭鍏ュ啑浣欏瓧娈�3 - 棰勭暀鎵╁睍鐢ㄩ��', + // highSelectAttrs: { + // prop: 'redundantField3_FilterMode', + // el: 'select', + // placeholder: '璇烽�夋嫨', + // options: FILTER_MODE_OPTIONS_STRING, + // }, + // }, + { + label: '澶囨敞', + prop: 'remark', + el: 'input', + //disabled: disabled, + placeholder: '璇疯緭鍏ュ娉�', + highSelectAttrs: { + prop: 'remark_FilterMode', + el: 'select', + placeholder: '璇烽�夋嫨', + options: FILTER_MODE_OPTIONS_STRING, + }, + }, + // { + // label: '', + // prop: 'creationTime', + // el: (props: any, { attrs }: SetupContext) => { + // return h(dateTimePickerRange, { + // ...props, + // clearable: true, + // ...attrs, + // }) + // }, + // width: '100%', + // //disabled: disabled, + // placeholder: '璇疯緭鍏�', + // isDateControl: true, // 鏄惧紡鏍囪涓烘棩鏈熸帶浠� + // }, + // { + // label: '', + // prop: 'lastModificationTime', + // el: (props: any, { attrs }: SetupContext) => { + // return h(dateTimePickerRange, { + // ...props, + // clearable: true, + // ...attrs, + // }) + // }, + // width: '100%', + // //disabled: disabled, + // placeholder: '璇疯緭鍏�', + // isDateControl: true, // 鏄惧紡鏍囪涓烘棩鏈熸帶浠� + // }, + ]) + /** + * 鏍¢獙鏄惁鏈夋暟鎹彉鍖� + */ + const checkIsEqualObject = () => { + const data = { + formData: formData.value, + } + const check = isEqual(initiateData.value, data) + return check + } + const commonGetFormData = () => { + const data = { + containerNo: formData.value.containerNo || '', + containerNo_FilterMode: formData.value.containerNo_FilterMode || '', + containerType: formData.value.containerType || '', + containerType_FilterMode: formData.value.containerType_FilterMode || '', + containerStatus: formData.value.containerStatus || '', + containerStatus_FilterMode: + formData.value.containerStatus_FilterMode || '', + specLength: formData.value.specLength || '', + specLength_FilterMode: formData.value.specLength_FilterMode || '', + specWidth: formData.value.specWidth || '', + specWidth_FilterMode: formData.value.specWidth_FilterMode || '', + specHeight: formData.value.specHeight || '', + specHeight_FilterMode: formData.value.specHeight_FilterMode || '', + limitLength: formData.value.limitLength || '', + limitLength_FilterMode: formData.value.limitLength_FilterMode || '', + limitWidth: formData.value.limitWidth || '', + limitWidth_FilterMode: formData.value.limitWidth_FilterMode || '', + limitHeight: formData.value.limitHeight || '', + limitHeight_FilterMode: formData.value.limitHeight_FilterMode || '', + maxWeight: formData.value.maxWeight || '', + maxWeight_FilterMode: formData.value.maxWeight_FilterMode || '', + exceptionNumber: formData.value.exceptionNumber || '', + exceptionNumber_FilterMode: + formData.value.exceptionNumber_FilterMode || '', + materialNumber: formData.value.materialNumber || '', + materialNumber_FilterMode: formData.value.materialNumber_FilterMode || '', + redundantField1: formData.value.redundantField1 || '', + redundantField1_FilterMode: + formData.value.redundantField1_FilterMode || '', + redundantField2: formData.value.redundantField2 || '', + redundantField2_FilterMode: + formData.value.redundantField2_FilterMode || '', + redundantField3: formData.value.redundantField3 || '', + redundantField3_FilterMode: + formData.value.redundantField3_FilterMode || '', + remark: formData.value.remark || '', + remark_FilterMode: formData.value.remark_FilterMode || '', + creationTime: formData.value.creationTime || '', + lastModificationTime: formData.value.lastModificationTime || '', + } + return data + } + const onClose = (done: () => void) => { + if (visible.value) { + visible.value = false + const data = commonGetFormData() + ctx.emit('close', data) + } + } + /** + * 纭鏌ヨ + */ + const onConfirmQuery = async () => { + const data = commonGetFormData() + ctx.emit('confirmQuery', data) + } + /** + * 閲嶇疆鍏叡select鏌ヨ + */ + const onResetForHighSelect = async () => { + formData.value.containerNo_FilterMode = 1 + formData.value.containerType_FilterMode = 2 + formData.value.containerStatus_FilterMode = 2 + formData.value.specLength_FilterMode = 2 + formData.value.specWidth_FilterMode = 2 + formData.value.specHeight_FilterMode = 2 + formData.value.limitLength_FilterMode = 2 + formData.value.limitWidth_FilterMode = 2 + formData.value.limitHeight_FilterMode = 2 + formData.value.maxWeight_FilterMode = 2 + formData.value.exceptionNumber_FilterMode = 2 + formData.value.materialNumber_FilterMode = 2 + formData.value.redundantField1_FilterMode = 1 + formData.value.redundantField2_FilterMode = 1 + formData.value.redundantField3_FilterMode = 1 + formData.value.remark_FilterMode = 1 + } + /** + * 閲嶇疆鏌ヨ + */ + const onReset = async () => { + formData.value = {} + onResetForHighSelect() //閲嶇疆鍏叡select鏌ヨ + formData.value.containerNo = '' + formData.value.containerType = '' + formData.value.containerStatus = '' + formData.value.specLength = '' + formData.value.specWidth = '' + formData.value.specHeight = '' + formData.value.limitLength = '' + formData.value.limitWidth = '' + formData.value.limitHeight = '' + formData.value.maxWeight = '' + formData.value.exceptionNumber = '' + formData.value.materialNumber = '' + formData.value.redundantField1 = '' + formData.value.redundantField2 = '' + formData.value.redundantField3 = '' + formData.value.remark = '' + formData.value.creationTime = '' + formData.value.lastModificationTime = '' + //鍚戠埗缁勪欢鍙戦�佽嚜瀹氫箟浜嬩欢 + ctx.emit('restQuery') + } + + const updateCheckData = () => { + initiateData.value = { + formData: { + ...formData.value, + }, + } + } + const updateFormItemOptions = (propName: string, enumData: any[]) => { + const item = formItems.find((item) => item.prop === propName) + if (item && enumData) { + item.options = enumData.map((item) => ({ + label: item.description, + value: item.value, + })) + } + } + /** + * 閫氱敤鏌ヨ鏋氫妇 + */ + const commonQueryEnumForFrom = async () => { + const containerTypeEnumEnum = await wmsContainerDrawer.getWmsEnumData({ + EnumName: 'ContainerTypeEnum', + }) + updateFormItemOptions('containerType', containerTypeEnumEnum) + const containerStatusEnumEnum = await wmsContainerDrawer.getWmsEnumData({ + EnumName: 'ContainerStatusEnum', + }) + updateFormItemOptions('containerStatus', containerStatusEnumEnum) + } + commonQueryEnumForFrom() + onResetForHighSelect() //閲嶇疆鍏叡select鏌ヨ + /** + * 寮圭獥鎵撳紑鑾峰彇璇︽儏 + */ + const onOpen = async () => { + disabled.value = false + updateCheckData() + } + + watch(() => current.value, onOpen) + + return { + formItems, + formData, + visible, + formRef, + onOpen, + onClose, + onConfirmQuery, + onReset, + } +} diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/Service/WmsContainerQueryDrawer.ts b/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/Service/WmsContainerQueryDrawer.ts new file mode 100644 index 0000000..eb7a6bf --- /dev/null +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/Service/WmsContainerQueryDrawer.ts @@ -0,0 +1,35 @@ +import { Base } from '@/libs/Base/Base' +const request = Base.request + +/** + * 娣诲姞 + * @returns + */ +export const addWmsContainer = (data: any) => { + return request.post('/api/v1/HIAWms/wmsContainer', data) +} + +/** + * 鑾峰彇璇︽儏 + * @returns + */ +export const getWmsContainer = (id: string) => { + return request.get(`/api/v1/HIAWms/wmsContainer/${id}`) +} + +/** + * 鏇存柊 + * @returns + */ +export const updateWmsContainer = (id: string, data: Record<string, any>) => { + return request.put(`/api/v1/HIAWms/wmsContainer/${id}`, data) +} + +/** + * 鑾峰彇鏋氫妇 + * @returns + */ +export const getWmsEnumData = (data: any) => { + return request.post('/api/v1/WareCmsUtilityApi/WmsEnum', data) +} + diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/WmsContainerQueryDrawer.ts b/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/WmsContainerQueryDrawer.ts new file mode 100644 index 0000000..9e228e8 --- /dev/null +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Models/WmsContainerQueryDrawer.ts @@ -0,0 +1,44 @@ +import { Base } from '@/libs/Base/Base' +import { + addWmsContainer, + getWmsContainer, + updateWmsContainer, + getWmsEnumData, +} from './Service/WmsContainerQueryDrawer' +import { useGlobalState } from '@/libs/Store/Store' + +export class WmsContainerQueryDrawer extends Base<{ [key: string]: any }> { + constructor() { + super({ + data: [], + wmsContainer: {}, + }) + } + + /** + * 娣诲姞 + * @param data + */ + async addWmsContainer(data: Record<string, any>) { + return addWmsContainer(data) + } + /** + * 鏇存柊 + * @param data + */ + async updateWmsContainer(id: string, data: Record<string, any>) { + return updateWmsContainer(id, data) + } + + /** + * 鑾峰彇璇︽儏 + */ + async getWmsContainerDetail(current: any, id?: string) { + return getWmsContainer(id || current?.id) + } + + // 鑾峰彇鏋氫妇鍊� + async getWmsEnumData(data: Record<string, any>) { + return getWmsEnumData(data) + } +} diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.module.scss b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.module.scss new file mode 100644 index 0000000..177adca --- /dev/null +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.module.scss @@ -0,0 +1,3 @@ +.drawer { + width: 800px; +} diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.tsx b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.tsx new file mode 100644 index 0000000..5ba197d --- /dev/null +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer.tsx @@ -0,0 +1,71 @@ +/* + * 鐗╂枡鍩虹淇℃伅鏌ヨ寮瑰嚭妗� +*/ +import { SetupContext, defineComponent } from 'vue' +import BaseQueryDrawer from '@/components/BaseQueryDrawer/BaseQueryDrawer' +import styles from './WmsContainerQueryDrawer.module.scss' +import { useWmsContainerQueryDrawer } from '../../../../Controllers/WmsContainerQueryDrawer.tsx' +import DyFormForHighQuery from '@/components/DyFormForHighQuery/DyFormForHighQuery' + +// @ts-ignore +export default defineComponent<{ + [key: string]: any +}>({ + name: '寮圭獥', + props: { + //鏋氫妇绫诲瀷瀛楀吀 + enumListDict:{ + type: Array as () => Array<{ key: string; value: object }>, // 瀹氫箟鏁扮粍鍏冪礌绫诲瀷 + default: () => [] // 榛樿鍊� + }, + modelValue: { + type: Boolean, + default: false, + }, + title: { + type: String, + default: '', + }, + row: { + type: Object, + }, + sort: { + type: Number, + default: 0, + }, + }, + emits: ['update:modelValue', 'close', 'submit', 'confirmquery1'], + setup(props: Record<string, any>, ctx: SetupContext) { + const { + onClose, + onConfirmQuery, + onOpen, + onReset, + formRef, + visible, + formItems, + formData, + } = useWmsContainerQueryDrawer(props, ctx) + return () => ( + <BaseQueryDrawer + class={styles.drawer} + size="800px" + title={props.title || '楂樼骇鏌ヨ'} + v-model={visible.value} + close-on-click-modal={true} + onReset={onReset} + onConfirmQueryForBase={onConfirmQuery} + onOpen={onOpen} + before-close={onClose} + onClose={onClose} + > + <DyFormForHighQuery + ref={formRef} + formData={formData.value} + labelWidth="106px" + formItemProps={formItems} + ></DyFormForHighQuery> + </BaseQueryDrawer> + ) + }, +}) diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.module.scss b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.module.scss index a3049f6..d460aba 100644 --- a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.module.scss +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.module.scss @@ -1,114 +1,113 @@ -.wmsContainerContent { - width: 100%; - height: 90%; - - .wmsContainerList { - width: 100%; - height: calc(100% - 70px); - } - .headerContent { - display: flex; - justify-content: space-between; - align-items: center; - height: 43px; - } - .header { - margin-bottom: 12px; - display: flex; - justify-content: flex-start; - align-items: center; - } -} - -.tagBox { - width: auto; - min-width: 80px; - height: 24px; - background: #ffffff; - border-radius: 19px 19px 19px 19px; - opacity: 1; - border: 1px dashed #bcc4cc; - width: 50px; - height: 20px; - font-size: 14px; - font-family: PingFang SC, PingFang SC; - font-weight: 400; - color: #5a84ff; - display: flex; - justify-content: center; - align-items: center; - // cursor: pointer; -} - -.group { - display: flex; - justify-content: space-between; - align-items: center; -} - -.groupTable { - width: 100%; -} - -.overBox { - width: 100%; - height: calc(100% - 20px); - overflow: auto; - :global(.cs-collapse-item__header) { - background-color: #f1f1f1; - padding: 0 20px; - height: 35px; - font-size: 16px; - font-family: PingFang SC, PingFang SC; - font-weight: 500; - } - :global(.cs-collapse-item__content) { - padding-bottom: 0px; - } -} -.groupHeader { - width: 100%; - height: 30px; - background: #ccc; -} - -.hideBlock { - display: none; -} - -.queryForm { - padding: 10px; - background: #f5f7fa; - margin-bottom: 0px; - border-radius: 4px; - - .el-form-item { - margin-right: 20px; - margin-bottom: 0; - - // 缁熶竴杈撳叆妗嗗拰閫夋嫨妗嗙殑瀹藉害 - .el-input, .el-select { - width: 200px; // 璁剧疆缁熶竴鐨勫搴� - } - - // 閫夋嫨妗嗗唴閮ㄨ緭鍏ユ鏍峰紡 - .el-select .el-input__wrapper { - height: 32px; // 涓庤緭鍏ユ楂樺害涓�鑷� - padding: 1px 11px; // 涓庤緭鍏ユ鍐呰竟璺濅竴鑷� - } - - // 鏃ユ湡閫夋嫨鍣ㄥ搴� - .el-date-editor { - width: 220px; - } - } -} - -// 濡傛灉闇�瑕佹洿绮剧‘鐨勬帶鍒讹紝鍙互鍗曠嫭璁剧疆 -.formItem { - width: 200px; - - &.el-input, &.el-select { - width: 100%; - } -} \ No newline at end of file +.wmsContainerContent { + width: 100%; + height: 100%; + + .wmsContainerList { + width: 100%; + height: calc(100% - 70px); + } + .headerContent { + display: flex; + justify-content: space-between; + align-items: center; + height: 43px; + } + .header { + margin-bottom: 12px; + display: flex; + justify-content: flex-end; + align-items: center; + } +} + +.tagBox { + width: auto; + min-width: 80px; + height: 24px; + background: #ffffff; + border-radius: 19px 19px 19px 19px; + opacity: 1; + border: 1px dashed #bcc4cc; + width: 50px; + height: 20px; + font-size: 14px; + font-family: PingFang SC, PingFang SC; + font-weight: 400; + color: #5a84ff; + display: flex; + justify-content: center; + align-items: center; + // cursor: pointer; +} + +.group { + display: flex; + justify-content: space-between; + align-items: center; +} + +.groupTable { + width: 100%; +} + +.overBox { + width: 100%; + height: calc(100% - 20px); + overflow: auto; + :global(.cs-collapse-item__header) { + background-color: #f1f1f1; + padding: 0 20px; + height: 35px; + font-size: 16px; + font-family: PingFang SC, PingFang SC; + font-weight: 500; + } + :global(.cs-collapse-item__content) { + padding-bottom: 0px; + } +} +.groupHeader { + width: 100%; + height: 30px; + background: #ccc; +} + +.hideBlock { + display: none; +} +.queryForm { + padding: 10px; + background: #f5f7fa; + margin-bottom: 0px; + border-radius: 4px; + + .el-form-item { + margin-right: 20px; + margin-bottom: 0; + + // 缁熶竴杈撳叆妗嗗拰閫夋嫨妗嗙殑瀹藉害 + .el-input, .el-select { + width: 200px; // 璁剧疆缁熶竴鐨勫搴� + } + + // 閫夋嫨妗嗗唴閮ㄨ緭鍏ユ鏍峰紡 + .el-select .el-input__wrapper { + height: 32px; // 涓庤緭鍏ユ楂樺害涓�鑷� + padding: 1px 11px; // 涓庤緭鍏ユ鍐呰竟璺濅竴鑷� + } + + // 鏃ユ湡閫夋嫨鍣ㄥ搴� + .el-date-editor { + width: 220px; + } + } +} + +// 濡傛灉闇�瑕佹洿绮剧‘鐨勬帶鍒讹紝鍙互鍗曠嫭璁剧疆 +.formItem { + width: 200px; + + &.el-input, &.el-select { + width: 100%; + } +} diff --git a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.tsx b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.tsx index d3fe7d2..4abdbe0 100644 --- a/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.tsx +++ b/HIAWms/hiawms_web/src/widgets/WmsContainer/Views/Pages/WmsContainer/WmsContainer.tsx @@ -5,12 +5,24 @@ import { useWmsContainer } from '../../../Controllers/WmsContainer' import IconButton from '@/components/IconButton/IconButton' import WmsContainerDrawer from '../Dialog/WmsContainerDrawer/WmsContainerDrawer' +import WmsContainerQueryDrawer from '../Dialog/WmsContainerQueryDrawer/WmsContainerQueryDrawer' import Search from '@/components/Search/Search' import { columns } from './Config' import TdButton from '@/components/TdButton/TdButton' import { vPermission } from '@/libs/Permission/Permission' -import { getWmsEnumData } from '@/widgets/HIAWms/Models/Service/WmsMaterialDrawer' -import { ElForm, ElFormItem, ElInput, ElOption, ElSelect } from 'element-plus' +import dayjs from 'dayjs' +import { getWmsEnumData } from '@/widgets/WmsContainer/Models/Service/WmsContainerDrawer' +import { + ElInput, + ElSelect, + ElOption, + ElDatePicker, + ElForm, + ElFormItem, +} from 'element-plus' +import { injectModel } from '@/libs/Provider/Provider' +// 寮曞叆鍏叡閫夐」閰嶇疆 +import { FILTER_MODE_OPTIONS_STRING } from '@/components/DyFormForHighQuery/DyFormForHighQueryOptions' interface RenderTableType { url?: string @@ -32,6 +44,7 @@ dataSource, contextMenu, dialogConfig, + dialogConfigForQuery, tableRef, current, search, @@ -43,25 +56,24 @@ onConfirmWmsContainer, onCheck, onAddWmsContainer, + onAdvancedQuery, onExport, openDetail, onSuccess, onBeforeUpload, } = useWmsContainer(props, ctx) + //瀹氫箟楂樼骇鏌ヨ寮曠敤 + const wmsContainerQueryDrawerRef = ref(null) // 鏂板鐨勬煡璇㈡潯浠� const queryForm = ref({ - containerNo: '', - containerType: '', - containerStatus: '', - filter: '', + searchVal: '', + str_searchFormInputAttrs: [], + searchVal_FilterMode: '', }) - - const queryParams = computed(() => ({ - ...queryForm.value, - containerType: queryForm.value.containerType || '', // 澶勭悊涓嬫媺 - containerStatus: queryForm.value.containerStatus || '', - })) + //瀹氫箟鏁翠綋妯$硦鏌ヨ鐨勫垪鏁扮粍(娉ㄦ剰锛氬繀椤诲ぇ灏忓啓璺熷悗绔殑瀹炰綋绫诲睘鎬у悕涓�鑷达紝鍚﹀垯浼氬鑷村尮閰嶄笉瀵圭殑闂) + const _searchFormInputAttrs = ref(['ContainerNo']) + const searchFormInputAttrs_Placeholder = ref('璇疯緭鍏ユ墭鐩樼紪鍙�') // 鍔ㄦ�佹灇涓鹃�夐」 const enumOptions = reactive({ @@ -72,20 +84,17 @@ // 鑾峰彇鏋氫妇鏁版嵁 const fetchEnumData = async () => { try { - // 鑾峰彇鐗╂枡绫诲瀷鏋氫妇 - const containerTypeData = await getWmsEnumData({ + const containerTypeEnumData = await getWmsEnumData({ EnumName: 'ContainerTypeEnum', }) - enumOptions.containerType = containerTypeData.map((item) => ({ + enumOptions.containerType = containerTypeEnumData.map((item) => ({ label: item.description, value: item.value, })) - - // 鑾峰彇閲囪喘绫诲瀷鏋氫妇 - const containerStatusData = await getWmsEnumData({ + const containerStatusEnumData = await getWmsEnumData({ EnumName: 'ContainerStatusEnum', }) - enumOptions.containerStatus = containerStatusData.map((item) => ({ + enumOptions.containerStatus = containerStatusEnumData.map((item) => ({ label: item.description, value: item.value, })) @@ -94,26 +103,79 @@ } } + // 瀹氫箟鍝嶅簲寮忔煡璇㈡暟鎹� + const _curHighQueryData = ref({ + searchVal: '', + str_searchFormInputAttrs: [], + searchVal_FilterMode: '', + }) // 缁勪欢鎸傝浇鏃惰幏鍙栨灇涓炬暟鎹� onMounted(() => { fetchEnumData() + queryForm.value.searchVal_FilterMode = + FILTER_MODE_OPTIONS_STRING[0]?.value || '' + _curHighQueryData.value.searchVal_FilterMode = + queryForm.value.searchVal_FilterMode + _curHighQueryData.value.str_searchFormInputAttrs = + _searchFormInputAttrs.value }) - // 鏂板鐨勬煡璇㈡柟娉� - const handleQuery = async () => { - console.log('鏌ヨ鏉′欢:', queryParams.value) - // tableRef.value.getTableList() - tableRef.value.getList(queryParams.value) + // 鏂扮増鐨勬煡璇㈡柟娉曪紙涓婚〉闈腑鐨勬寜閽�愭煡璇€�戯級 + const handleQueryForMain = async () => { + _curHighQueryData.value.searchVal = queryForm.value.searchVal + _curHighQueryData.value.searchVal_FilterMode = + queryForm.value.searchVal_FilterMode + _curHighQueryData.value.str_searchFormInputAttrs = + _searchFormInputAttrs.value + tableRef.value.getList(_curHighQueryData.value) } - - // 閲嶇疆鏌ヨ鏉′欢 + // 鏂扮増鐨勬煡璇㈡柟娉曪紙楂樼骇鏌ヨ涓殑鎸夐挳銆愭煡璇€�戯級 + const handleQuery = async (extraParams = {}) => { + let filteredData = commonGetHighQueryForm(extraParams) + commonSaveCurHighQueryData(filteredData) + tableRef.value.getList(filteredData) + } + // 鏂扮増鐨勬煡璇㈤噸缃� const resetQuery = () => { - queryForm.value = { - containerNo: '', - containerType: '', - containerStatus: '', - filter: '', - } + queryForm.value.searchVal = '' + queryForm.value.searchVal_FilterMode = + FILTER_MODE_OPTIONS_STRING[0]?.value || '' + queryForm.value.str_searchFormInputAttrs = _searchFormInputAttrs.value + } + //鏂扮増鐨勫鍑烘柟娉� + const handleExport = () => { + onExport(_curHighQueryData.value) + } + // 鏂扮増鐨勬煡璇㈠脊鍑烘鍏抽棴鏂规硶 + const closeQuery = (extraParams = {}) => { + let filteredData = commonGetHighQueryForm(extraParams) + console.log('closeQuery鏂规硶') + console.log(filteredData) + commonSaveCurHighQueryData(filteredData) + } + //淇濆瓨鏌ヨ鍊� + const commonSaveCurHighQueryData = (filteredData = {}) => { + _curHighQueryData.value = { ..._curHighQueryData.value, ...filteredData } + _curHighQueryData.value.searchVal = queryForm.value.searchVal + _curHighQueryData.value.searchVal_FilterMode = + queryForm.value.searchVal_FilterMode + _curHighQueryData.value.str_searchFormInputAttrs = + _searchFormInputAttrs.value + } + //鑾峰彇楂樼骇鏌ヨ寮瑰嚭妗嗙殑鏌ヨ鍊� + const commonGetHighQueryForm = (extraParams = {}) => { + // 杩囨护鎺� undefined 鐨勫�� + let filteredData = Object.assign( + {}, + ...Object.entries(extraParams).map(([key, value]) => + value !== undefined ? { [key]: value } : {} + ) + ) + //缁勫悎妯$硦鏌ヨ + filteredData.searchVal = queryForm.value.searchVal + filteredData.searchVal_FilterMode = queryForm.value.searchVal_FilterMode + filteredData.str_searchFormInputAttrs = _searchFormInputAttrs.value + return filteredData } /** @@ -129,7 +191,7 @@ params, autoHeight, } = props - console.log(dataSource.value) + return ( <div class={{ @@ -150,8 +212,59 @@ onCheck={onCheck} onRowClick={onRowClick} isHidePagination={isHidePagination} - pageSize={50} + pageSize={20} v-slots={{ + isDisabled: ({ row }: any) => { + return ( + <div> + {row.isDisabled != null + ? row.isDisabled + ? '鏄�' + : '鍚�' + : '-'} + </div> + ) + }, + creationTime: ({ row }: any) => { + return ( + <div> + {row.creationTime != null + ? dayjs(row.creationTime).format('YYYY-MM-DD HH:mm:ss') + : '-'} + </div> + ) + }, + lastModificationTime: ({ row }: any) => { + return ( + <div> + {row.lastModificationTime != null + ? dayjs(row.lastModificationTime).format( + 'YYYY-MM-DD HH:mm:ss' + ) + : '-'} + </div> + ) + }, + isDeleted: ({ row }: any) => { + return ( + <div> + {row.isDeleted != null + ? row.isDeleted + ? '鏄�' + : '鍚�' + : '-'} + </div> + ) + }, + deletionTime: ({ row }: any) => { + return ( + <div> + {row.deletionTime != null + ? dayjs(row.deletionTime).format('YYYY-MM-DD HH:mm:ss') + : '-'} + </div> + ) + }, name: ({ row }: any) => { return row?.name ? ( <TdButton @@ -172,6 +285,7 @@ </div> ) } + return () => { return ( <div class={styles.wmsContainerContent}> @@ -183,87 +297,17 @@ sort={sort.value} onConfirm={onConfirmWmsContainer} /> - - {/* 鏂板鐨勬煡璇㈣〃鍗� */} - <ElForm - inline - model={queryForm.value} - class={styles.queryForm} - label-width="80px" - > - <ElFormItem label="鍏抽敭瀛�"> - <ElInput - v-model={queryForm.value.filter} - placeholder="璇疯緭鍏ュ叧閿瓧鎼滅储" - clearable - class={styles.formItem} - /> - </ElFormItem> - <ElFormItem label="鐗╂枡缂栫爜"> - <ElInput - v-model={queryForm.value.containerNo} - placeholder="璇疯緭鍏ユ墭鐩樼紪鐮�" - clearable - class={styles.formItem} - /> - </ElFormItem> - <ElFormItem label="鐗╂枡绫诲瀷"> - <ElSelect - v-model={queryForm.value.containerType} - placeholder="璇烽�夋嫨鎵樼洏绫诲瀷" - clearable - loading={enumOptions.containerType.length === 0} - class={styles.formItem} - > - {enumOptions.containerType.map((option) => ( - <ElOption - key={option.value} - label={option.label} - value={option.value} - /> - ))} - </ElSelect> - </ElFormItem> - <ElFormItem label="鎵樼洏鐘舵��"> - <ElSelect - v-model={queryForm.value.containerStatus} - placeholder="璇烽�夋嫨鎵樼洏鐘舵��" - clearable - loading={enumOptions.containerStatus.length === 0} - class={styles.formItem} - > - {enumOptions.containerStatus.map((option) => ( - <ElOption - key={option.value} - label={option.label} - value={option.value} - /> - ))} - </ElSelect> - </ElFormItem> - {/* <ElFormItem label="鏃ユ湡鑼冨洿"> - <ElDatePicker - v-model={queryForm.value.dateRange} - type="daterange" - range-separator="鑷�" - start-placeholder="寮�濮嬫棩鏈�" - end-placeholder="缁撴潫鏃ユ湡" - value-format="YYYY-MM-DD" - /> - </ElFormItem> */} - <ElFormItem> - <IconButton type="primary" icon="search" onClick={handleQuery}> - 鏌ヨ - </IconButton> - <IconButton - style="margin-left: 10px;" - icon="refresh" - onClick={resetQuery} - > - 閲嶇疆 - </IconButton> - </ElFormItem> - </ElForm> + {/* 楂樼骇鏌ヨ */} + <WmsContainerQueryDrawer + ref="wmsContainerQueryDrawerRef" + v-model={dialogConfigForQuery.visible} + title={dialogConfigForQuery.title} + row={current.value} + sort={sort.value} + onConfirmQuery={handleQuery} + onRestQuery={resetQuery} + onClose={closeQuery} + /> <div class={styles.headerContent}> <div class={styles.header}> @@ -276,6 +320,7 @@ 娣诲姞 </IconButton> <el-divider direction="vertical" /> + <el-upload v-permission="wmsContainer-import" name="file" @@ -293,20 +338,65 @@ <IconButton v-permission="wmsContainer-output" icon="out" - onClick={onExport} + onClick={handleExport} > 瀵煎嚭 </IconButton> </div> - {/* <Search - placeholder="璇疯緭鍏ュ叧閿瓧" - v-model={search.value} - onConfirm={onSearch} - style={{ marginTop: '-1px' }} - /> */} + <ElFormItem style={{ marginTop: '15px' }}> + <ElFormItem label="鍏抽敭瀛�"> + <el-tooltip + class="box-item" + effect="dark" + content={searchFormInputAttrs_Placeholder.value} + placement="top-start" + > + <ElInput + v-model={queryForm.value.searchVal} + placeholder={searchFormInputAttrs_Placeholder.value} + clearable + class={styles.formItem} + /> + </el-tooltip> + </ElFormItem> + <ElFormItem label="" style="width:100px;"> + <ElSelect + v-model={queryForm.value.searchVal_FilterMode} + placeholder="璇烽�夋嫨" + class={styles.formItem} + > + {FILTER_MODE_OPTIONS_STRING.map((option) => ( + <ElOption + key={option.value} + label={option.label} + value={option.value} + /> + ))} + </ElSelect> + </ElFormItem> + <IconButton + type="primary" + icon="search" + onClick={handleQueryForMain} + > + 鏌ヨ + </IconButton> + {/* <IconButton style="" icon="refresh" onClick={resetQuery}> + 閲嶇疆 + </IconButton> */} + <IconButton + v-permission="wmsContainer-add" + icon="search" + onClick={onAdvancedQuery} + type="primary" + > + 楂樼骇鏌ヨ + </IconButton> + </ElFormItem> </div> + <RenderBaseTable - url="/api/v1/HIAWms/wmsContainer" + url="/api/v1/HIAWms/wmsContainer/page" dataSource={dataSource} isChecked={true} isDrag={true} diff --git a/HIAWms/server/src/CMS.Plugin.HIAWms.Application.Contracts/Dtos/WmsContainer/GetWmsContainerInput.cs b/HIAWms/server/src/CMS.Plugin.HIAWms.Application.Contracts/Dtos/WmsContainer/GetWmsContainerInput.cs index 381554b..4eb1ab8 100644 --- a/HIAWms/server/src/CMS.Plugin.HIAWms.Application.Contracts/Dtos/WmsContainer/GetWmsContainerInput.cs +++ b/HIAWms/server/src/CMS.Plugin.HIAWms.Application.Contracts/Dtos/WmsContainer/GetWmsContainerInput.cs @@ -1,35 +1,292 @@ -using CMS.Plugin.HIAWms.Domain.Shared.Enums; -using Volo.Abp.Application.Dtos; +using CMS.Plugin.HIAWms.Domain.Shared.Enums; +using CmsQueryExtensions.Extension; +using Volo.Abp.Application.Dtos; + +namespace CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsContainer; + +/// <summary> +/// 鎵樼洏绠$悊鏌ヨ鍙傛暟 +/// </summary> +public class GetWmsContainerInput : ExtensiblePagedAndSortedResultRequestDto +{ + + #region 鍏抽敭瀛楁煡璇� + + /// <summary> + /// 鍏抽敭瀛楁ā绯婃煡璇紙娉ㄦ剰鏄皬鍐欙紒锛� + /// </summary> + public string searchVal { get; set; } + + /// <summary> + /// 閫氱敤鏌ヨ閰嶇疆 (1:妯$硦鏌ヨ , 2:绮惧噯鏌ヨ)锛堟敞鎰忔槸灏忓啓锛侊級 + /// </summary> + public SearchFilterModeEnum searchVal_FilterMode { get; set; } = SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// 瀛愭悳绱㈢粍浠朵紶閫掔殑閫氱敤鏌ヨ閰嶇疆鐨勫睘鎬у悕锛堟敞鎰忔槸灏忓啓锛侊級 + /// </summary> + [NoAutoQuery] + public string str_searchFormInputAttrs { get; set; } + /// <summary> + /// 瀛愭悳绱㈢粍浠朵紶閫掔殑閫氱敤鏌ヨ閰嶇疆鐨勫睘鎬у悕锛堟敞鎰忔槸灏忓啓锛侊級 + /// </summary> + public List<string> searchFormInputAttrs + { + get + { + if (!string.IsNullOrEmpty(str_searchFormInputAttrs)) + { + return str_searchFormInputAttrs.Split(',').ToList(); + } + return new List<string>(); + } + } + + #endregion + + /// <summary> + /// 鎵樼洏缂栧彿 + /// </summary> + public string ContainerNo { get; set; } -namespace CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsContainer; + /// <summary> + /// 鎵樼洏缂栧彿-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum ContainerNo_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; -/// <summary> -/// WmsContainer鏌ヨ鍙傛暟瀵硅薄 -/// </summary> -public class GetWmsContainerInput : ExtensiblePagedAndSortedResultRequestDto -{ - /// <summary> - /// Gets or sets the filter. - /// </summary> - public string Filter { get; set; } + /// <summary> + /// 鎵樼洏绫诲瀷 + /// </summary> + public ContainerTypeEnum? ContainerType { get; set; } - /// <summary> - /// Gets or sets the name. - /// </summary> - public string Name { get; set; } + /// <summary> + /// 鎵樼洏绫诲瀷-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum ContainerType_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; - /// <summary> - /// 鎵樼洏缂栧彿 - /// </summary> - public string ContainerNo { get; set; } + /// <summary> + /// 鎵樼洏鐘舵�� + /// </summary> + public ContainerStatusEnum? ContainerStatus { get; set; } - /// <summary> - /// 鎵樼洏绫诲瀷 - /// </summary> - public ContainerTypeEnum ContainerType { get; set; } + /// <summary> + /// 鎵樼洏鐘舵��-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum ContainerStatus_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; - /// <summary> - /// 鎵樼洏鐘舵�� - /// </summary> - public ContainerStatusEnum ContainerStatus { get; set; } -} + /// <summary> + /// 闀垮害 + /// </summary> + public decimal? SpecLength { get; set; } + + /// <summary> + /// 闀垮害-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum SpecLength_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 瀹藉害 + /// </summary> + public decimal? SpecWidth { get; set; } + + /// <summary> + /// 瀹藉害-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum SpecWidth_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 楂樺害 + /// </summary> + public decimal? SpecHeight { get; set; } + + /// <summary> + /// 楂樺害-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum SpecHeight_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 闄愰暱 + /// </summary> + public decimal? LimitLength { get; set; } + + /// <summary> + /// 闄愰暱-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum LimitLength_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 闄愬 + /// </summary> + public decimal? LimitWidth { get; set; } + + /// <summary> + /// 闄愬-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum LimitWidth_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 闄愰珮 + /// </summary> + public decimal? LimitHeight { get; set; } + + /// <summary> + /// 闄愰珮-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum LimitHeight_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 杞介噸涓婇檺 + /// </summary> + public decimal? MaxWeight { get; set; } + + /// <summary> + /// 杞介噸涓婇檺-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum MaxWeight_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 寮傚父鏁伴噺 + /// </summary> + public int? ExceptionNumber { get; set; } + + /// <summary> + /// 寮傚父鏁伴噺-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum ExceptionNumber_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 鐗╂枡鏁伴噺 + /// </summary> + public int? MaterialNumber { get; set; } + + /// <summary> + /// 鐗╂枡鏁伴噺-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum MaterialNumber_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 鍐椾綑瀛楁1 - 棰勭暀鎵╁睍鐢ㄩ�� + /// </summary> + public string RedundantField1 { get; set; } + + /// <summary> + /// 鍐椾綑瀛楁1 - 棰勭暀鎵╁睍鐢ㄩ��-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum RedundantField1_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// 鍐椾綑瀛楁2 - 棰勭暀鎵╁睍鐢ㄩ�� + /// </summary> + public string RedundantField2 { get; set; } + + /// <summary> + /// 鍐椾綑瀛楁2 - 棰勭暀鎵╁睍鐢ㄩ��-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum RedundantField2_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// 鍐椾綑瀛楁3 - 棰勭暀鎵╁睍鐢ㄩ�� + /// </summary> + public string RedundantField3 { get; set; } + + /// <summary> + /// 鍐椾綑瀛楁3 - 棰勭暀鎵╁睍鐢ㄩ��-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum RedundantField3_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// 鎺掑簭 + /// </summary> + public int? Sort { get; set; } + + /// <summary> + /// 鎺掑簭-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum Sort_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// 澶囨敞 + /// </summary> + public string Remark { get; set; } + + /// <summary> + /// 澶囨敞-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum Remark_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// 鏄惁绂佺敤 + /// </summary> + public bool? IsDisabled { get; set; } + + /// <summary> + /// 鏄惁绂佺敤-鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum IsDisabled_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// + /// </summary> + //琛ㄧず鏄� 楂樼骇鏌ヨ鑼冨洿鏌ヨ鐗规�� + [HighSearchRangeAttribute] + public string CreationTime { get; set; } + + + /// <summary> + /// + /// </summary> + public string CreatorId { get; set; } + + /// <summary> + /// -鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum CreatorId_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// + /// </summary> + //琛ㄧず鏄� 楂樼骇鏌ヨ鑼冨洿鏌ヨ鐗规�� + [HighSearchRangeAttribute] + public string LastModificationTime { get; set; } + + + /// <summary> + /// + /// </summary> + public string LastModifierId { get; set; } + + /// <summary> + /// -鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum LastModifierId_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// + /// </summary> + public bool? IsDeleted { get; set; } + + /// <summary> + /// -鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum IsDeleted_FilterMode { get; set; }= SearchFilterModeEnum.绮惧噯鏌ヨ; + + /// <summary> + /// + /// </summary> + public string DeleterId { get; set; } + + /// <summary> + /// -鏌ヨ鍏崇郴杩愮畻绗� + /// </summary> + public SearchFilterModeEnum DeleterId_FilterMode { get; set; }= SearchFilterModeEnum.妯$硦鏌ヨ; + + /// <summary> + /// + /// </summary> + //琛ㄧず鏄� 楂樼骇鏌ヨ鑼冨洿鏌ヨ鐗规�� + [HighSearchRangeAttribute] + public string DeletionTime { get; set; } + + + +} diff --git a/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsContainerAppService.cs b/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsContainerAppService.cs index ea822b8..04a0f69 100644 --- a/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsContainerAppService.cs +++ b/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsContainerAppService.cs @@ -4,6 +4,8 @@ using CMS.Plugin.HIAWms.Domain.Shared.WmsContainers; using CMS.Plugin.HIAWms.Domain.WmsContainers; using CmsQueryExtensions; +using CmsQueryExtensions.Extension; +using System.Linq.Expressions; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Data; @@ -41,12 +43,40 @@ input.Sorting = nameof(WmsContainer.Sort); } - var specification = new WmsContainerSpecification(input.Name); - var container = ObjectMapper.Map < GetWmsContainerInput, WmsContainer>(input); - var count = await _wmscontainerRepository.GetCountAsync(container,input.Filter, specification); - var list = await _wmscontainerRepository.GetListAsync(container,input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter, specification); + #region 鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + + //鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + var whereConditions = DynamicGetQueryParams(input); + + #endregion + + var count = await _wmscontainerRepository.GetCountAsync(whereConditions); + var list = await _wmscontainerRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount); return new PagedResultDto<WmsContainerDto>(count, ObjectMapper.Map<List<WmsContainer>, List<WmsContainerDto>>(list)); + } + + /// <summary> + /// 鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + /// </summary> + /// <param name="input">杈撳叆鍙傛暟</param> + /// <returns></returns> + private FunReturnResultModel<Expression<Func<WmsContainer, bool>>> DynamicGetQueryParams(GetWmsContainerInput input) + { + //鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + var whereConditions = WhereConditionsExtensions.GetWhereConditions<WmsContainer, GetWmsContainerInput>(input); + if (!whereConditions.IsSuccess) + { + throw new Exception("鍔ㄦ�佹瀯閫犳煡璇㈡潯浠跺け璐�:" + whereConditions.ErrMsg); + } + + //涔熷彲鍐嶆鑷畾涔夋瀯寤烘煡璇㈡潯浠� + Expression<Func<WmsContainer, bool>> extendExpression = a => a.IsDeleted == false; + // 浣跨敤 System.Linq.PredicateBuilder 鐨� And + var pres = (System.Linq.Expressions.Expression<Func<WmsContainer, bool>>)(whereConditions.data); + whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression); + + return whereConditions; } /// <inheritdoc /> @@ -299,6 +329,11 @@ } /// <inheritdoc /> + /// <summary> + /// 瀵煎嚭鎵樼洏绠$悊 + /// </summary> + /// <param name="input"></param> + /// <returns></returns> public async Task<(Dictionary<string, object> Sheets, string FileName)> ExportAsync(GetWmsContainerInput input) { Check.NotNull(input, nameof(input)); @@ -308,9 +343,14 @@ input.Sorting = nameof(WmsContainer.Sort); } - var specification = new WmsContainerSpecification(input.Name); - var container = ObjectMapper.Map<GetWmsContainerInput, WmsContainer>(input); - var list = await _wmscontainerRepository.GetListAsync(container,input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter, specification, includeDetails: true); + #region 鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + + //鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + var whereConditions = DynamicGetQueryParams(input); + + #endregion + + var list = await _wmscontainerRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true); var result = ObjectMapper.Map<List<WmsContainer>, List<WmsContainerDto>>(list); var sheets = new Dictionary<string, object> @@ -318,7 +358,7 @@ ["閰嶇疆"] = ExportHelper.ConvertListToExportData(result), }; - var fileName = result.Count > 1 ? "WmsContainer鍒楄〃" : result.Count == 1 ? result.First()?.ContainerNo : "WmsContainer妯$増"; + var fileName = "鎵樼洏绠$悊"; return (sheets, fileName); } diff --git a/HIAWms/server/src/CMS.Plugin.HIAWms.Domain/WmsContainers/IWmsContainerRepository.cs b/HIAWms/server/src/CMS.Plugin.HIAWms.Domain/WmsContainers/IWmsContainerRepository.cs index 50b4374..39f4210 100644 --- a/HIAWms/server/src/CMS.Plugin.HIAWms.Domain/WmsContainers/IWmsContainerRepository.cs +++ b/HIAWms/server/src/CMS.Plugin.HIAWms.Domain/WmsContainers/IWmsContainerRepository.cs @@ -1,3 +1,5 @@ +using CmsQueryExtensions.Extension; +using System.Linq.Expressions; using Volo.Abp.Domain.Repositories; using Volo.Abp.Specifications; @@ -41,7 +43,7 @@ /// <param name="includeDetails">if set to <c>true</c> [include details].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns></returns> - Task<List<WmsContainer>> GetListAsync(WmsContainer? container, string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, string filter = null, Specification<WmsContainer> specification = null, bool includeDetails = false, CancellationToken cancellationToken = default); + Task<List<WmsContainer>> GetListAsync(FunReturnResultModel<Expression<Func<WmsContainer, bool>>> whereConditions, string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, bool includeDetails = false, CancellationToken cancellationToken = default); /// <summary> /// Gets the count asynchronous. @@ -50,5 +52,5 @@ /// <param name="specification">The specification.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns></returns> - Task<long> GetCountAsync(WmsContainer? container, string filter = null, Specification<WmsContainer> specification = null, CancellationToken cancellationToken = default); + Task<long> GetCountAsync(FunReturnResultModel<Expression<Func<WmsContainer, bool>>> whereConditions, CancellationToken cancellationToken = default); } diff --git a/HIAWms/server/src/CMS.Plugin.HIAWms.EntityFrameworkCore/Repositories/EfCoreWmsContainerRepository.cs b/HIAWms/server/src/CMS.Plugin.HIAWms.EntityFrameworkCore/Repositories/EfCoreWmsContainerRepository.cs index f42bc56..971f737 100644 --- a/HIAWms/server/src/CMS.Plugin.HIAWms.EntityFrameworkCore/Repositories/EfCoreWmsContainerRepository.cs +++ b/HIAWms/server/src/CMS.Plugin.HIAWms.EntityFrameworkCore/Repositories/EfCoreWmsContainerRepository.cs @@ -1,6 +1,8 @@ using System.Linq.Dynamic.Core; +using System.Linq.Expressions; using CMS.Plugin.HIAWms.Domain.WmsContainers; using CMS.Plugin.HIAWms.EntityFrameworkCore.Extensions; +using CmsQueryExtensions.Extension; using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -50,52 +52,38 @@ return sort + 1; } - /// <summary> - /// 查询列表 - /// </summary> - /// <param name="container"></param> - /// <param name="sorting"></param> - /// <param name="maxResultCount"></param> - /// <param name="skipCount"></param> - /// <param name="filter"></param> - /// <param name="specification"></param> - /// <param name="includeDetails"></param> - /// <param name="cancellationToken"></param> - /// <returns></returns> - public async Task<List<WmsContainer>> GetListAsync(WmsContainer? container,string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, string filter = null, Specification<WmsContainer> specification = null, bool includeDetails = false, CancellationToken cancellationToken = default) + /// <summary> + /// 获取分页列表托盘管理 + /// </summary> + /// <param name="whereConditions"></param> + /// <param name="sorting"></param> + /// <param name="maxResultCount"></param> + /// <param name="skipCount"></param> + /// <param name="includeDetails"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<List<WmsContainer>> GetListAsync(FunReturnResultModel<Expression<Func<WmsContainer, bool>>> whereConditions, string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, bool includeDetails = false, CancellationToken cancellationToken = default) { - specification ??= new WmsContainerSpecification(); return await (await GetDbSetAsync()) .IncludeDetails(includeDetails) - .Where(specification.ToExpression()) + .WhereIf(whereConditions != null, whereConditions.data) .Where(x => !x.IsDeleted) - .WhereIf(!filter.IsNullOrWhiteSpace(), u => u.ContainerNo.Contains(filter)) - .WhereIf(!string.IsNullOrEmpty(container.ContainerNo),u=>u.ContainerNo.Contains(container.ContainerNo)) - .WhereIf(container.ContainerStatus>0, u=>u.ContainerStatus == u.ContainerStatus) - .WhereIf(container.ContainerType>0, u=>u.ContainerType == u.ContainerType) - .OrderBy(sorting.IsNullOrEmpty() ? nameof(WmsContainer.Sort) : sorting) + .OrderByDescending(x => x.CreationTime) .PageBy(skipCount, maxResultCount) .ToListAsync(GetCancellationToken(cancellationToken)); } - /// <summary> - /// 查询数量 - /// </summary> - /// <param name="container"></param> - /// <param name="filter"></param> - /// <param name="specification"></param> - /// <param name="cancellationToken"></param> - /// <returns></returns> - public async Task<long> GetCountAsync(WmsContainer? container, string filter = null, Specification<WmsContainer> specification = null, CancellationToken cancellationToken = default) + /// <summary> + /// 获取总数托盘管理 + /// </summary> + /// <param name="whereConditions"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<long> GetCountAsync(FunReturnResultModel<Expression<Func<WmsContainer, bool>>> whereConditions, CancellationToken cancellationToken = default) { - specification ??= new WmsContainerSpecification(); return await (await GetQueryableAsync()) - .Where(specification.ToExpression()) + .WhereIf(whereConditions != null, whereConditions.data) .Where(x => !x.IsDeleted) - .WhereIf(!string.IsNullOrEmpty(container.ContainerNo), u => u.ContainerNo.Contains(container.ContainerNo)) - .WhereIf(container.ContainerStatus > 0, u => u.ContainerStatus == u.ContainerStatus) - .WhereIf(container.ContainerType > 0, u => u.ContainerType == u.ContainerType) - .WhereIf(!filter.IsNullOrWhiteSpace(), u => u.ContainerNo.Contains(filter)) .CountAsync(cancellationToken: GetCancellationToken(cancellationToken)); } diff --git "a/Weben_CMS\344\270\223\347\224\250\344\273\243\347\240\201\347\224\237\346\210\220\345\231\250/Code/File/GenerateCodeConfigParamFiles/\346\211\230\347\233\230\351\205\215\347\275\256.txt" "b/Weben_CMS\344\270\223\347\224\250\344\273\243\347\240\201\347\224\237\346\210\220\345\231\250/Code/File/GenerateCodeConfigParamFiles/\346\211\230\347\233\230\351\205\215\347\275\256.txt" new file mode 100644 index 0000000..6782a45 --- /dev/null +++ "b/Weben_CMS\344\270\223\347\224\250\344\273\243\347\240\201\347\224\237\346\210\220\345\231\250/Code/File/GenerateCodeConfigParamFiles/\346\211\230\347\233\230\351\205\215\347\275\256.txt" @@ -0,0 +1,14 @@ +[琛ㄥ悕]:scms_wmscontainers +[瀹炰綋绫诲悕]:WmsContainer +[瀹炰綋绫诲璞″悕]:WmsContainer +[椤甸潰鑿滃崟鍚峕:鎵樼洏绠$悊 +[椤甸潰鑿滃崟瀵硅薄缂╁啓]:wmsContainer +[琛ㄧ殑涓枃娉ㄨВ]:鎵樼洏绠$悊 +[閲嶅鎬ф牎楠屽瓧娈礭:ContainerNo +[鍒犻櫎鎻愮ず瀛楁]:ContainerNo +[妯$硦鏌ヨ瀛楁]:'ContainerNo' +[妯$硦鏌ヨ瀛楁鍚峕:璇疯緭鍏ユ墭鐩樼紪鍙� +[椤圭洰鍛藉悕绌洪棿]:HIAWms +[鏋氫妇绫诲瀷瀛楁闆嗗悎]:ContainerType,ContainerTypeEnum&ContainerStatus,ContainerStatusEnum +[鍓嶇鏍规枃浠跺す鍚嶇О]:web +[鎺掑簭]:CreationTime \ No newline at end of file -- Gitblit v1.9.3