diff --git a/src/api/backend/api/index.ts b/src/api/backend/api/index.ts index 3bc796a..df7de94 100644 --- a/src/api/backend/api/index.ts +++ b/src/api/backend/api/index.ts @@ -28,7 +28,8 @@ import * as businessTodo from './businessTodo'; import * as contract from './contract'; import * as materialsInventory from './materialsInventory'; import * as company from './company'; - +import * as product from './product'; +import * as materialsInOut from './materialsInOut'; export default { auth, account, @@ -56,4 +57,6 @@ export default { contract, materialsInventory, company, + product, + materialsInOut, }; diff --git a/src/api/backend/api/materialsInOut.ts b/src/api/backend/api/materialsInOut.ts new file mode 100644 index 0000000..fcee606 --- /dev/null +++ b/src/api/backend/api/materialsInOut.ts @@ -0,0 +1,110 @@ +import { request, type RequestOptions } from '@/utils/request'; + +/** 获取原材料出入库记录列表 GET /api/materials-in-out */ +export async function materialsInOutList( + params: API.MaterialsInOutListParams, + options?: RequestOptions, +) { + return request<{ + items?: API.MaterialsInOutEntity[]; + meta?: { + itemCount?: number; + totalItems?: number; + itemsPerPage?: number; + totalPages?: number; + currentPage?: number; + }; + }>('/api/materials-in-out', { + method: 'GET', + params: { + // page has a default value: 1 + page: '1', + // pageSize has a default value: 10 + pageSize: '10', + + ...params, + }, + ...(options || {}), + }); +} + +/** 新增原材料出入库记录 POST /api/materials-in-out */ +export async function materialsInOutCreate( + body: API.MaterialsInOutDto, + options?: RequestOptions, +) { + return request('/api/materials-in-out', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + data: body, + ...(options || { successMsg: '创建成功' }), + }); +} + +/** 获取原材料出入库记录信息 GET /api/materials-in-out/${param0} */ +export async function materialsInOutInfo( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.MaterialsInOutInfoParams, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/contract/${param0}`, { + method: 'GET', + params: { ...queryParams }, + ...(options || {}), + }); +} + +/** 解除原材料出入库记录和附件关联 PUT /api/materials-in-out/unlink-attachments/${param0} */ +export async function unlinkAttachments( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.MaterialsInOutUpdateParams, + body: API.MaterialsInOutDto, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/materials-in-out/unlink-attachments/${param0}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + params: { ...queryParams }, + data: body, + ...options, + }); +} + +/** 更新原材料出入库记录 PUT /api/materials-in-out/${param0} */ +export async function MaterialsInOutUpdate( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.MaterialsInOutUpdateParams, + body: API.MaterialsInOutUpdateDto, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/materials-in-out/${param0}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + params: { ...queryParams }, + data: body, + ...(options || { successMsg: '更新成功' }), + }); +} + +/** 删除原材料出入库记录 DELETE /api/materials-in-out/${param0} */ +export async function materialsInOutDelete( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.MaterialsInOutDeleteParams, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/materials-in-out/${param0}`, { + method: 'DELETE', + params: { ...queryParams }, + ...(options || { successMsg: '删除成功' }), + }); +} diff --git a/src/api/backend/api/product.ts b/src/api/backend/api/product.ts new file mode 100644 index 0000000..2cb23f8 --- /dev/null +++ b/src/api/backend/api/product.ts @@ -0,0 +1,104 @@ +import { request, type RequestOptions } from '@/utils/request'; + +/** 获取产品列表 GET /api/product */ +export async function productList(params: API.ProductParams, options?: RequestOptions) { + return request<{ + items?: API.ProductEntity[]; + meta?: { + itemCount?: number; + totalItems?: number; + itemsPerPage?: number; + totalPages?: number; + currentPage?: number; + }; + }>('/api/product', { + method: 'GET', + params: { + // page has a default value: 1 + page: '1', + // pageSize has a default value: 10 + pageSize: '10', + + ...params, + }, + ...(options || {}), + }); +} + +/** 新增产品 POST /api/product */ +export async function productCreate(body: API.ProductDto, options?: RequestOptions) { + return request('/api/product', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + data: body, + ...(options || { successMsg: '创建成功' }), + }); +} + +/** 获取产品信息 GET /api/product/${param0} */ +export async function productInfo( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.ProductInfoParams, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/product/${param0}`, { + method: 'GET', + params: { ...queryParams }, + ...(options || {}), + }); +} + +/** 解除产品和附件关联 PUT /api/product/unlink-attachments/${param0} */ +export async function unlinkAttachments( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.ProductUpdateParams, + body: API.ProductUpdateDto, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/product/unlink-attachments/${param0}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + params: { ...queryParams }, + data: body, + ...options, + }); +} + +/** 更新产品 PUT /api/product/${param0} */ +export async function productUpdate( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.ProductUpdateParams, + body: API.ProductUpdateDto, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/product/${param0}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + params: { ...queryParams }, + data: body, + ...(options || { successMsg: '更新成功' }), + }); +} + +/** 删除产品 DELETE /api/product/${param0} */ +export async function productDelete( + // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) + params: API.ProductDeleteParams, + options?: RequestOptions, +) { + const { id: param0, ...queryParams } = params; + return request(`/api/product/${param0}`, { + method: 'DELETE', + params: { ...queryParams }, + ...(options || { successMsg: '删除成功' }), + }); +} diff --git a/src/api/backend/api/typings.d.ts b/src/api/backend/api/typings.d.ts index 75ea030..2762b15 100644 --- a/src/api/backend/api/typings.d.ts +++ b/src/api/backend/api/typings.d.ts @@ -1356,7 +1356,7 @@ declare namespace API { type ContractInfoParams = { id: number; }; - + // Materials Inventory type MaterialsInventoryUpdateParams = { id: number; }; @@ -1513,6 +1513,7 @@ declare namespace API { type MaterialsInventoryDeleteParams = { id: number; }; + // Company type CompanyEntity = { /** 公司名称 */ name: string; @@ -1551,5 +1552,152 @@ declare namespace API { type CompanyDeleteParams = { id: number; }; + // Product + type ProductEntity = { + /** 产品名称 */ + name: string; + /** 是否删除 */ + isDelete: string; + /** 附件 */ + files?: StorageInfo[]; + id: number; + createdAt: string; + updatedAt: string; + }; + type ProductDto = { + /** 产品名称 */ + name: string; + fileIds?: number[]; + }; + type ProductUpdateParams = { + id: number; + }; + type ProductParams = { + page?: number; + pageSize?: number; + field?: string; + order?: 'ASC' | 'DESC'; + _t?: number; + }; + type ProductInfoParams = { + id: number; + }; + type ProductUpdateDto = { + /** 产品名称 */ + name?: string; + /** 附件 */ + fileIds?: number[]; + }; + type ProductDeleteParams = { + id: number; + }; + // Materials In out history + type MaterialsInOutUpdateParams = { + id: number; + }; + + type MaterialsInOutInfoParams = { + id: number; + }; + + type MaterialsInOutListParams = { + page?: number; + pageSize?: number; + field?: string; + order?: 'ASC' | 'DESC'; + _t?: number; + }; + + type MaterialsInOutEntity = { + /** 公司名称 */ + companyName: string; + /** 产品名称 */ + product: number; + /** 出库或入库 */ + inOrOut: number; + /** 单位(字典) */ + unit: number; + /** 时间 */ + time: Date; + /** 数量 */ + quantity: number; + /** 单价 */ + unitPrice: number; + /** 金额 */ + amount: number; + /** 经办人 */ + agent: string; + /** 领料单号 */ + issuanceNumber?: number; + /** 项目 */ + project: string; + /** 备注 */ + remark: string; + /** 附件 */ + files: StorageInfo[]; + id: number; + createdAt: string; + updatedAt: string; + }; + + type MaterialsInOutDto = { + /** 公司名称 */ + companyName: string; + /** 产品名称 */ + product: number; + /** 出库或入库 */ + inOrOut: number; + /** 单位(字典) */ + unit: number; + /** 时间 */ + time: Date; + /** 数量 */ + quantity: number; + /** 单价 */ + unitPrice: number; + /** 金额 */ + amount: number; + /** 经办人 */ + agent: string; + /** 领料单号 */ + issuanceNumber?: number; + /** 项目 */ + project: string; + /** 备注 */ + remark: string; + /** 附件 */ + files: StorageInfo[]; + }; + type MaterialsInOutUpdateDto = { + /** 公司名称 */ + companyName: string; + /** 产品名称 */ + product: number; + /** 出库或入库 */ + inOrOut: number; + /** 单位(字典) */ + unit: number; + /** 时间 */ + time: Date; + /** 数量 */ + quantity: number; + /** 单价 */ + unitPrice: number; + /** 金额 */ + amount: number; + /** 经办人 */ + agent: string; + /** 领料单号 */ + issuanceNumber?: number; + /** 项目 */ + project: string; + /** 备注 */ + remark: string; + /** 附件 */ + fileIds: number[]; + }; + type MaterialsInOutDeleteParams = { + id: number; + }; } diff --git a/src/enums/materialsInventoryEnum.ts b/src/enums/materialsInventoryEnum.ts new file mode 100644 index 0000000..ee2fcb0 --- /dev/null +++ b/src/enums/materialsInventoryEnum.ts @@ -0,0 +1,4 @@ +export enum MaterialsInOutEnum { + In = 0, // 入库 + Out = 1, // 出库 +} diff --git a/src/permission/permCode.ts b/src/permission/permCode.ts index d324ccb..ed65976 100644 --- a/src/permission/permCode.ts +++ b/src/permission/permCode.ts @@ -84,7 +84,12 @@ const permissions = [ "app:company:read", "app:company:create", "app:company:update", - "app:company:delete" + "app:company:delete", + "app:product:list", + "app:product:read", + "app:product:create", + "app:product:update", + "app:product:delete" ] as const; export type PermissionType = (typeof permissions)[number]; diff --git a/src/views/company/columns.tsx b/src/views/meterials-inventory/company/columns.tsx similarity index 100% rename from src/views/company/columns.tsx rename to src/views/meterials-inventory/company/columns.tsx diff --git a/src/views/company/formSchemas.ts b/src/views/meterials-inventory/company/formSchemas.ts similarity index 100% rename from src/views/company/formSchemas.ts rename to src/views/meterials-inventory/company/formSchemas.ts diff --git a/src/views/company/index.vue b/src/views/meterials-inventory/company/index.vue similarity index 100% rename from src/views/company/index.vue rename to src/views/meterials-inventory/company/index.vue diff --git a/src/views/meterials-inventory/in-out/columns.tsx b/src/views/meterials-inventory/in-out/columns.tsx new file mode 100644 index 0000000..a93c61f --- /dev/null +++ b/src/views/meterials-inventory/in-out/columns.tsx @@ -0,0 +1,131 @@ +import type { TableColumn } from '@/components/core/dynamic-table'; +import { ContractStatusEnum } from '@/enums/contractEnum'; +import { DictEnum } from '@/enums/dictEnum'; +import { MaterialsInOutEnum } from '@/enums/materialsInventoryEnum'; +import { useDictStore } from '@/store/modules/dict'; +import { formatToDate } from '@/utils/dateUtil'; +import { Tag } from 'ant-design-vue'; + +export type TableListItem = API.MaterialsInOutEntity; +export type TableColumnItem = TableColumn; +const dictStore = useDictStore(); +export const baseColumns: TableColumnItem[] = [ + { + title: '产品名称', + width: 180, + dataIndex: 'product', + }, + { + title: '单位', + width: 60, + hideInSearch: true, + dataIndex: 'unit', + formItemProps: { + component: 'Select', + componentProps: { + options: dictStore + .getDictItemsByCode(DictEnum.Unit) + .map(({ label, id }) => ({ value: id, label })), + }, + }, + customRender: ({ record }) => { + return dictStore.getDictItemsByCode(DictEnum.Unit)?.length + ? dictStore.getDictItemsByCode(DictEnum.Unit).find((item) => item.id === record.unit) + ?.label || '' + : ''; + }, + }, + + { + title: '入库/出库', + width: 80, + dataIndex: 'inOrOut', + fixed: 'right', + formItemProps: { + component: 'Select', + componentProps: { + options: Object.values(MaterialsInOutEnum) + .filter((value) => typeof value === 'number') + .map((item) => formatStatus(item as MaterialsInOutEnum)), + }, + }, + customRender: ({ record }) => { + const { color, label } = formatStatus(record.inOrOut); + return {label}; + }, + }, + { + title: '时间', + width: 120, + align: 'center', + dataIndex: 'time', + customRender: ({ record }) => { + return formatToDate(record.time); + }, + }, + { + title: '数量', + hideInSearch: true, + width: 80, + dataIndex: 'quantity', + }, + { + title: '单价', + hideInSearch: true, + width: 80, + dataIndex: 'unitPrice', + }, + { + title: '金额', + width: 80, + align: 'center', + dataIndex: 'amount', + }, + { + title: '经办人', + width: 80, + dataIndex: 'agent', + }, + { + title: '领料单号', + width: 80, + dataIndex: 'issuanceNumber', + }, + { + title: '项目', + width: 80, + dataIndex: 'project', + }, + { + title: '备注', + width: 80, + dataIndex: 'remark', + }, +]; + +export function formatStatus(status: MaterialsInOutEnum): { + color: string; + label: string; + value: number; +} { + switch (status) { + case MaterialsInOutEnum.In: + return { + color: 'green', + label: '入库', + value: MaterialsInOutEnum.In, + }; + case MaterialsInOutEnum.Out: + return { + color: 'red', + label: '出库', + value: MaterialsInOutEnum.Out, + }; + default: + return { + color: 'green', + label: '入库', + value: MaterialsInOutEnum.In, + }; + } +} diff --git a/src/views/meterials-inventory/in-out/formSchemas.ts b/src/views/meterials-inventory/in-out/formSchemas.ts new file mode 100644 index 0000000..ac2997e --- /dev/null +++ b/src/views/meterials-inventory/in-out/formSchemas.ts @@ -0,0 +1,115 @@ +import type { FormSchema } from '@/components/core/schema-form/'; +import { ContractStatusEnum } from '@/enums/contractEnum'; +import { formatStatus } from './columns'; + +export const contractSchemas = ( + contractTypes: API.DictItemEntity[], +): FormSchema[] => [ + // { + // field: 'contractNumber', + // component: 'Input', + // label: '合同编号', + // rules: [{ required: true, type: 'string' }], + // colProps: { + // span: 12, + // }, + // }, + // { + // field: 'title', + // component: 'Input', + // label: '合同标题', + // rules: [{ required: true, type: 'string' }], + // colProps: { + // span: 12, + // }, + // }, + + // { + // field: 'partyA', + // component: 'Input', + // label: '甲方', + // rules: [{ required: true, type: 'string' }], + // colProps: { + // span: 12, + // }, + // }, + // { + // field: 'partyB', + // component: 'Input', + // label: '乙方', + // rules: [{ required: true, type: 'string' }], + // colProps: { + // span: 12, + // }, + // }, + + // { + // field: 'signingDate', + // label: '签订时间', + // component: 'DatePicker', + // // defaultValue: new Date(), + // colProps: { span: 12 }, + // componentProps: {}, + // }, + // { + // field: 'deliveryDeadline', + // label: '交付期限', + // component: 'DatePicker', + // // defaultValue: new Date(), + // colProps: { span: 12 }, + // }, + // { + // field: 'type', + // label: '合同类型', + // component: 'Select', + // required: true, + // colProps: { + // span: 12, + // }, + // componentProps: { + // options: contractTypes.map(({ label, id }) => ({ value: id, label })), + // }, + // }, + // { + // field: 'status', + // label: '审核结果', + // component: 'Select', + // required:true, + // defaultValue: 0, + // colProps: { + // span: 12, + // }, + // componentProps: { + // allowClear: false, + // options: Object.values(ContractStatusEnum) + // .filter((value) => typeof value === 'number') + // .map((item) => formatStatus(item as ContractStatusEnum)), + // }, + // }, + // { + // field: 'remark', + // component: 'InputTextArea', + // label: '备注', + // }, + // { + // field: 'menuIds', + // component: 'Tree', + // label: '菜单权限', + // componentProps: { + // checkable: true, + // vModelKey: 'checkedKeys', + // fieldNames: { + // title: 'name', + // key: 'id', + // }, + // style: { + // height: '350px', + // paddingTop: '5px', + // overflow: 'auto', + // borderRadius: '6px', + // border: '1px solid #dcdfe6', + // resize: 'vertical', + // }, + // }, + // }, +]; diff --git a/src/views/meterials-inventory/in-out/index.vue b/src/views/meterials-inventory/in-out/index.vue new file mode 100644 index 0000000..0508e19 --- /dev/null +++ b/src/views/meterials-inventory/in-out/index.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/src/views/meterials-inventory/columns.tsx b/src/views/meterials-inventory/inventory-check/columns.tsx similarity index 100% rename from src/views/meterials-inventory/columns.tsx rename to src/views/meterials-inventory/inventory-check/columns.tsx diff --git a/src/views/meterials-inventory/formSchemas.ts b/src/views/meterials-inventory/inventory-check/formSchemas.ts similarity index 100% rename from src/views/meterials-inventory/formSchemas.ts rename to src/views/meterials-inventory/inventory-check/formSchemas.ts diff --git a/src/views/meterials-inventory/index.vue b/src/views/meterials-inventory/inventory-check/index.vue similarity index 98% rename from src/views/meterials-inventory/index.vue rename to src/views/meterials-inventory/inventory-check/index.vue index 7c982ab..366f966 100644 --- a/src/views/meterials-inventory/index.vue +++ b/src/views/meterials-inventory/inventory-check/index.vue @@ -60,9 +60,9 @@ }, { title: '操作', - maxWidth: 80, - width: 80, - minWidth: 80, + maxWidth: 150, + width: 150, + minWidth: 150, dataIndex: 'ACTION', hideInSearch: true, fixed: 'right', diff --git a/src/views/meterials-inventory/product/columns.tsx b/src/views/meterials-inventory/product/columns.tsx new file mode 100644 index 0000000..830642d --- /dev/null +++ b/src/views/meterials-inventory/product/columns.tsx @@ -0,0 +1,10 @@ +import type { TableColumn } from '@/components/core/dynamic-table'; + +export type TableListItem = API.ProductEntity; +export type TableColumnItem = TableColumn; +export const baseColumns: TableColumnItem[] = [ + { + title: '产品名称', + dataIndex: 'name', + }, +]; diff --git a/src/views/meterials-inventory/product/formSchemas.ts b/src/views/meterials-inventory/product/formSchemas.ts new file mode 100644 index 0000000..62d7f35 --- /dev/null +++ b/src/views/meterials-inventory/product/formSchemas.ts @@ -0,0 +1,12 @@ +import type { FormSchema } from '@/components/core/schema-form/'; +export const formSchemas: FormSchema[] = [ + { + field: 'name', + component: 'Input', + label: '产品名称', + rules: [{ required: true, type: 'string' }], + colProps: { + span: 12, + }, + }, +]; diff --git a/src/views/meterials-inventory/product/index.vue b/src/views/meterials-inventory/product/index.vue new file mode 100644 index 0000000..05be11b --- /dev/null +++ b/src/views/meterials-inventory/product/index.vue @@ -0,0 +1,201 @@ + + + + +