Explorar el Código

企业台账新增产品信息表

heguanxun hace 9 meses
padre
commit
1c0be6f0ec
Se han modificado 17 ficheros con 1415 adiciones y 6 borrados
  1. 34 0
      snowy-admin-web/src/api/biz/qyRecordProductApi.js
  2. 192 0
      snowy-admin-web/src/views/biz/qyrecordproduct/detail.vue
  3. 231 0
      snowy-admin-web/src/views/biz/qyrecordproduct/index.vue
  4. 7 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/param/QyRecordInfoAddParam.java
  5. 6 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/param/QyRecordInfoEditParam.java
  6. 34 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/service/impl/QyRecordInfoServiceImpl.java
  7. 174 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/controller/QyRecordProductController.java
  8. 158 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/entity/QyRecordProduct.java
  9. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/enums/QyRecordProductEnum.java
  10. 25 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/mapper/QyRecordProductMapper.java
  11. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/mapper/mapping/QyRecordProductMapper.xml
  12. 125 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductAddParam.java
  13. 130 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductEditParam.java
  14. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductIdParam.java
  15. 51 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductPageParam.java
  16. 80 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/service/QyRecordProductService.java
  17. 94 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/service/impl/QyRecordProductServiceImpl.java

+ 34 - 0
snowy-admin-web/src/api/biz/qyRecordProductApi.js

@@ -0,0 +1,34 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/qyrecordproduct/` + url, ...arg)
+
+/**
+ * 企业台账商品表Api接口管理器
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+export default {
+	// 获取企业台账商品表分页
+	qyRecordProductPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交企业台账商品表表单 edit为true时为编辑,默认为新增
+	qyRecordProductSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除企业台账商品表
+	qyRecordProductDelete(data) {
+		return request('delete', data)
+	},
+	// 导出企业台账商品表
+    qyRecordProductExport(data) {
+        return request('export', data, 'post', {
+            responseType: 'blob'
+        })
+    },
+	// 获取企业台账商品表详情
+	qyRecordProductDetail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 192 - 0
snowy-admin-web/src/views/biz/qyrecordproduct/detail.vue

@@ -0,0 +1,192 @@
+<template>
+    <a-card :bordered="false">
+		<a-page-header
+            :title="formData.id ? '编辑企业台账商品表' : '新增企业台账商品表'"
+			@back="onClose"
+		>
+			<template #extra>
+				<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+				<a-popconfirm title="请确认是否保存?" @confirm="onSubmit" v-if="!isView">
+                    <a-button type="primary" :loading="submitLoading">保存</a-button>
+                </a-popconfirm>
+			</template>
+		</a-page-header>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+            <a-row :gutter="16">
+                <a-col :span="12">
+                    <a-form-item label="预录入台账编号:" name="ylTzCode">
+                        <a-input v-model:value="formData.ylTzCode" :disabled="isView" placeholder="请输入预录入台账编号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="商品序号:" name="productNumber">
+                        <a-input v-model:value="formData.productNumber" :disabled="isView" placeholder="请输入商品序号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="预录入编号:" name="ylCode">
+                        <a-input v-model:value="formData.ylCode" :disabled="isView" placeholder="请输入预录入编号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="企业编号:" name="companyApplyCode">
+                        <a-input v-model:value="formData.companyApplyCode" :disabled="isView" placeholder="请输入企业编号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="企业名称:" name="companyName">
+                        <a-input v-model:value="formData.companyName" :disabled="isView" placeholder="请输入企业名称" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="加工增值核算备案编号:" name="recordNumber">
+                        <a-input v-model:value="formData.recordNumber" :disabled="isView" placeholder="请输入加工增值核算备案编号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="主管关区代码:" name="regionCode">
+                        <a-select v-model:value="formData.regionCode" :disabled="isView" placeholder="请选择主管关区代码" :options="regionCodeOptions" show-search allow-clear option-filter-prop="label"/>
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="商品编号:" name="productCode">
+                        <a-input v-model:value="formData.productCode" :disabled="isView" placeholder="请输入商品编号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="商品名称:" name="productName">
+                        <a-input v-model:value="formData.productName" :disabled="isView" placeholder="请输入商品名称" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="版本号:" name="version">
+                        <a-input v-model:value="formData.version" :disabled="isView" placeholder="请输入版本号" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="HS编码:" name="hsCode">
+                        <a-input v-model:value="formData.hsCode" :disabled="isView" placeholder="请输入HS编码" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="人民币单价:" name="unitPrice">
+                        <a-input v-model:value="formData.unitPrice" :disabled="isView" placeholder="请输入人民币单价" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="商品数量:" name="quantity">
+                        <a-input v-model:value="formData.quantity" :disabled="isView" placeholder="请输入商品数量" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="计量单位:" name="measurementUnit">
+                        <a-input v-model:value="formData.measurementUnit" :disabled="isView" placeholder="请输入计量单位" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="成品内销人民币价格:" name="domesticSalePrice">
+                        <a-input v-model:value="formData.domesticSalePrice" :disabled="isView" placeholder="请输入成品内销人民币价格" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="境外进口料件总价(RMB):" name="importTotal">
+                        <a-input v-model:value="formData.importTotal" :disabled="isView" placeholder="请输入境外进口料件总价(RMB)" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="国内采购料件总价(RMB):" name="domesticTotal">
+                        <a-input v-model:value="formData.domesticTotal" :disabled="isView" placeholder="请输入国内采购料件总价(RMB)" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="自主核算产品收益占比:" name="selfRatio">
+                        <a-input v-model:value="formData.selfRatio" :disabled="isView" placeholder="请输入自主核算产品收益占比" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="企业自主核算加工增值率:" name="selfRate">
+                        <a-input v-model:value="formData.selfRate" :disabled="isView" placeholder="请输入企业自主核算加工增值率" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="备注:" name="remark">
+                        <a-input v-model:value="formData.remark" :disabled="isView" placeholder="请输入备注" allow-clear />
+                    </a-form-item>
+                </a-col>
+            </a-row>
+        </a-form>
+	</a-card>
+</template>
+
+<script setup name="qyRecordProductDetail">
+	import tool from '@/utils/tool'
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import qyRecordProductApi from '@/api/biz/qyRecordProductApi'
+	// 抽屉状态
+    const { proxy } = getCurrentInstance()
+	const emit = defineEmits({ successful: null, onClose: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const isView = ref(false)
+	const regionCodeOptions = ref([])
+
+	// 打开抽屉
+	const onOpen = (record, view = false) => {
+	    isView.value = view
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+		regionCodeOptions.value = tool.dictList('zgqdm')
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		isView.value = true
+		emit('onClose')
+	}
+	// 默认要校验的
+	const formRules = {
+		regionCode: [required('请输入主管关区代码')],
+		productCode: [required('请输入商品编号')],
+		productName: [required('请输入商品名称')],
+		version: [required('请输入版本号')],
+		hsCode: [required('请输入HS编码')],
+		unitPrice: [required('请输入人民币单价')],
+		quantity: [required('请输入商品数量')],
+		measurementUnit: [required('请输入计量单位')],
+		domesticSalePrice: [required('请输入成品内销人民币价格')],
+		importTotal: [required('请输入境外进口料件总价(RMB)')],
+		domesticTotal: [required('请输入国内采购料件总价(RMB)')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				qyRecordProductApi
+					.qyRecordProductSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>
+
+<style lang="less" scoped>
+</style>

+ 231 - 0
snowy-admin-web/src/views/biz/qyrecordproduct/index.vue

@@ -0,0 +1,231 @@
+<template>
+	<a-card :bordered="false" v-if="indexShow">
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+			v-model:filterParam="filterParam"
+			:scroll="{ x: 2000 }"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="onDetail()" v-if="hasPerm('qyRecordProductAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete
+						v-if="hasPerm('qyRecordProductDelete')"
+						:selectedRowKeys="selectedRowKeys"
+						@batchDelete="deleteBatchQyRecordProduct"
+					/>
+					<a-button @click="onExport" v-if="hasPerm('qyRecordProductBatchExport')">
+                        <template #icon><export-outlined /></template>
+                        批量导出
+                    </a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'regionCode'">
+					{{ $TOOL.dictTypeData('zgqdm', record.regionCode) }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+					    <a @click="onDetail(record, true)" v-if="hasPerm('qyRecordProductView')">查看</a>
+						<a @click="onDetail(record)" v-if="hasPerm('qyRecordProductEdit')">编辑</a>
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteQyRecordProduct(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('qyRecordProductDelete')">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Detail v-else ref="detailRef" @onClose="indexShow = true" @successful="onSearch()" />
+</template>
+
+<script setup name="qyrecordproduct">
+	import { cloneDeep } from 'lodash-es'
+	import Detail from './detail.vue'
+	import qyRecordProductApi from '@/api/biz/qyRecordProductApi'
+	import downloadUtil from "@/utils/downloadUtil";
+    const { proxy } = getCurrentInstance()
+	const tableRef = ref()
+	const filterParam = ref({})
+	const detailRef = ref()
+	const indexShow = ref(true)
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '商品序号',
+			dataIndex: 'productNumber',
+		},
+		{
+			title: '预录入编号',
+			dataIndex: 'ylCode',
+		},
+		{
+			title: '企业编号',
+			dataIndex: 'companyApplyCode',
+		},
+		{
+			title: '企业名称',
+			dataIndex: 'companyName',
+		},
+		{
+			title: '加工增值核算备案编号',
+			dataIndex: 'recordNumber',
+		},
+		{
+			title: '主管关区代码',
+			dataIndex: 'regionCode',
+		},
+		{
+			title: '商品编号',
+			dataIndex: 'productCode',
+		},
+		{
+			title: '商品名称',
+			dataIndex: 'productName',
+		},
+		{
+			title: '版本号',
+			dataIndex: 'version',
+		},
+		{
+			title: 'HS编码',
+			dataIndex: 'hsCode',
+		},
+		{
+			title: '人民币单价',
+			dataIndex: 'unitPrice',
+		},
+		{
+			title: '商品数量',
+			dataIndex: 'quantity',
+		},
+		{
+			title: '计量单位',
+			dataIndex: 'measurementUnit',
+		},
+		{
+			title: '成品内销人民币价格',
+			dataIndex: 'domesticSalePrice',
+		},
+		{
+			title: '境外进口料件总价(RMB)',
+			dataIndex: 'importTotal',
+		},
+		{
+			title: '国内采购料件总价(RMB)',
+			dataIndex: 'domesticTotal',
+		},
+		{
+			title: '自主核算产品收益占比',
+			dataIndex: 'selfRatio',
+		},
+		{
+			title: '企业自主核算加工增值率',
+			dataIndex: 'selfRate',
+		},
+		{
+			title: '备注',
+			dataIndex: 'remark',
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['qyRecordProductEdit', 'qyRecordProductDelete'])) {
+		columns.push({
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 200,
+			fixed: 'right',
+		})
+	}
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+        tableRef.value.clearSelected()
+        return qyRecordProductApi.qyRecordProductPage(parameter).then((data) => {
+            return data
+        })
+    }
+    // 搜索同时备份参数
+    const onSearch = (parameter) => {
+        searchFormStateReal.value = cloneDeep(Object.assign(searchFormState.value, filterParam.value))
+        nextTick(() => {
+            tableRef.value.refresh(parameter)
+        })
+    }
+    // 重置
+    const reset = () => {
+        searchFormRef.value.resetFields()
+        onSearch(true)
+    }
+	// 删除
+	const deleteQyRecordProduct = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		qyRecordProductApi.qyRecordProductDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchQyRecordProduct = (params) => {
+		qyRecordProductApi.qyRecordProductDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+	// 批量导出
+    const onExport = () => {
+        const params = {
+            ...filterParam.value
+        }
+        if (selectedRowKeys.value.length > 0) {
+            params.ids = selectedRowKeys.value
+        } else {
+            Object.entries(searchFormStateReal.value).forEach(([key, value]) => {
+                console.log(key)
+                if (proxy.$util.isValue(value)) {
+                    params[key] = value
+                }
+            })
+        }
+        qyRecordProductApi.qyRecordProductExport(params).then((res) => {
+            downloadUtil.resultDownload(res)
+            tableRef.value.clearSelected()
+        })
+    }
+	// 切换至表单
+    const onDetail = (record = null, view) => {
+    	indexShow.value = false
+    	nextTick(() => {
+            detailRef.value.onOpen(record, view)
+    	})
+    }
+</script>
+
+<style lang="less" scoped>
+</style>

+ 7 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/param/QyRecordInfoAddParam.java

@@ -19,6 +19,7 @@ import lombok.Setter;
 import jakarta.validation.constraints.NotBlank;
 import vip.xiaonuo.biz.modular.qyrecardbody.param.QyRecardBodyAddParam;
 import vip.xiaonuo.biz.modular.qyrecordattachment.param.QyRecordAttachmentAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
 
 import java.util.List;
 
@@ -98,10 +99,14 @@ public class QyRecordInfoAddParam {
     private String status;
 
     /** 企业备案信息主体*/
-    @Schema(description = "审核状态", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "料件信息", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<QyRecardBodyAddParam> qyRecardBodyAddParams;
 
     /** 企业备案信息附件*/
-    @Schema(description = "审核状态", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "附件信息", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<QyRecordAttachmentAddParam> qyRecordAttachmentAddParams;
+
+    /** 企业备案商品附件*/
+    @Schema(description = "商品信息", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<QyRecordProductAddParam> qyRecordProductAddParams;
 }

+ 6 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/param/QyRecordInfoEditParam.java

@@ -22,6 +22,8 @@ import vip.xiaonuo.biz.modular.qyrecardbody.param.QyRecardBodyAddParam;
 import vip.xiaonuo.biz.modular.qyrecardbody.param.QyRecardBodyEditParam;
 import vip.xiaonuo.biz.modular.qyrecordattachment.param.QyRecordAttachmentAddParam;
 import vip.xiaonuo.biz.modular.qyrecordattachment.param.QyRecordAttachmentEditParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductEditParam;
 
 import java.math.BigDecimal;
 import java.util.Date;
@@ -111,4 +113,8 @@ public class QyRecordInfoEditParam {
     /** 企业备案信息附件*/
     @Schema(description = "审核状态", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<QyRecordAttachmentEditParam> qyRecordAttachmentEditParams;
+
+    /** 企业备案商品附件*/
+    @Schema(description = "商品信息", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<QyRecordProductEditParam> qyRecordProductAddParams;
 }

+ 34 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordinfo/service/impl/QyRecordInfoServiceImpl.java

@@ -37,6 +37,10 @@ import vip.xiaonuo.biz.modular.qyrecordattachment.param.QyRecordAttachmentIdPara
 import vip.xiaonuo.biz.modular.qyrecordattachment.service.QyRecordAttachmentService;
 import vip.xiaonuo.biz.modular.qyrecordinfochecklist.entity.QyRecordInfoCheckList;
 import vip.xiaonuo.biz.modular.qyrecordinfochecklist.service.QyRecordInfoCheckListService;
+import vip.xiaonuo.biz.modular.qyrecordproduct.entity.QyRecordProduct;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductEditParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.service.QyRecordProductService;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
@@ -64,7 +68,8 @@ public class QyRecordInfoServiceImpl extends ServiceImpl<QyRecordInfoMapper, QyR
 
     @Resource
     private QyRecordAttachmentService qyRecordAttachmentService;
-
+    @Resource
+    private QyRecordProductService qyRecordProductService;
     @Resource
     private QyRecardBodyService qyRecardBodyService;
 
@@ -102,6 +107,7 @@ public class QyRecordInfoServiceImpl extends ServiceImpl<QyRecordInfoMapper, QyR
         QyRecordInfo qyRecordInfo = BeanUtil.toBean(qyRecordInfoAddParam, QyRecordInfo.class);
         this.save(qyRecordInfo);
         List<QyRecardBodyAddParam> qyRecardBodyAddParams = qyRecordInfoAddParam.getQyRecardBodyAddParams();
+        //1、料件信息
         if(CollectionUtil.isNotEmpty(qyRecardBodyAddParams)){
             qyRecardBodyAddParams.stream().forEach(qyRecardBodyAddParam -> {
                 qyRecardBodyAddParam.setQyRecordInfoId(qyRecordInfo.getId());
@@ -110,6 +116,16 @@ public class QyRecordInfoServiceImpl extends ServiceImpl<QyRecordInfoMapper, QyR
                 qyRecardBodyService.save(qyRecardBody);
             });
         }
+        //2、商品信息
+        List<QyRecordProductAddParam> qyRecordProductAddParams = qyRecordInfoAddParam.getQyRecordProductAddParams();
+        if(CollectionUtil.isNotEmpty(qyRecordProductAddParams)){
+            qyRecordProductAddParams.stream().forEach(item -> {
+                item.setQyRecordInfoId(qyRecordInfo.getId());
+                QyRecordProduct qyRecordProduct = BeanUtil.toBean(item, QyRecordProduct.class);
+                qyRecordProductService.save(qyRecordProduct);
+            });
+        }
+        //3、附件信息
         List<QyRecordAttachmentAddParam> qyRecordAttachmentAddParams = qyRecordInfoAddParam.getQyRecordAttachmentAddParams();
         if(CollectionUtil.isNotEmpty(qyRecordAttachmentAddParams)){
             qyRecordAttachmentAddParams.stream().forEach(qyRecordAttachmentAddParam -> {
@@ -165,6 +181,7 @@ public class QyRecordInfoServiceImpl extends ServiceImpl<QyRecordInfoMapper, QyR
         this.updateById(qyRecordInfo);
         qyRecardBodyService.remove(new LambdaQueryWrapper<QyRecardBody>().eq(QyRecardBody::getQyRecordInfoId, qyRecordInfo.getId()));
         qyRecordAttachmentService.remove(new LambdaQueryWrapper<QyRecordAttachment>().eq(QyRecordAttachment::getQyRecordInfoId, qyRecordInfo.getId()));
+        qyRecordProductService.remove(new LambdaQueryWrapper<QyRecordProduct>().eq(QyRecordProduct::getQyRecordInfoId, qyRecordInfo.getId()));
 
         List<QyRecardBodyEditParam> bodyAddParams = qyRecordInfoEditParam.getQyRecardBodyEditParams();
         if (CollectionUtil.isNotEmpty(bodyAddParams)){
@@ -176,13 +193,26 @@ public class QyRecordInfoServiceImpl extends ServiceImpl<QyRecordInfoMapper, QyR
                 qyRecardBodyService.save(qyRecardBody);
             });
         }
+
+        List<QyRecordProductEditParam> productEditParams = qyRecordInfoEditParam.getQyRecordProductAddParams();
+        if (CollectionUtil.isNotEmpty(productEditParams)){
+            productEditParams.stream().forEach(item -> {
+                item.setQyRecordInfoId(qyRecordInfo.getId());
+                QyRecardBody qyRecardBody = BeanUtil.toBean(item, QyRecardBody.class);
+                qyRecardBody.setQyRecordInfoId(qyRecordInfo.getId());
+                qyRecardBody.setId(null);
+                qyRecardBodyService.save(qyRecardBody);
+            });
+        }
+
+        //商品信息
         List<QyRecordAttachmentEditParam> attachmentEditParams = qyRecordInfoEditParam.getQyRecordAttachmentEditParams();
         if(CollectionUtil.isNotEmpty(attachmentEditParams)){
             attachmentEditParams.stream().forEach(qyRecordAttachmentAddParam -> {
                 qyRecordAttachmentAddParam.setQyRecordInfoId(qyRecordInfo.getId());
-                QyRecordAttachment qyRecordAttachment = BeanUtil.toBean(qyRecordAttachmentAddParam, QyRecordAttachment.class);
-                qyRecordAttachment.setId(null);
-                qyRecordAttachmentService.save(qyRecordAttachment);
+                QyRecordProduct product = BeanUtil.toBean(qyRecordAttachmentAddParam, QyRecordProduct.class);
+                product.setId(null);
+                qyRecordProductService.save(product);
             });
         }
         if ("2".equals(qyRecordInfo.getStatus())){

+ 174 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/controller/QyRecordProductController.java

@@ -0,0 +1,174 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.URLUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.biz.modular.qyrecordproduct.entity.QyRecordProduct;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductEditParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductIdParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductPageParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.service.QyRecordProductService;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+import java.io.IOException;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import java.net.URLEncoder;
+import java.util.HashMap;
+
+/**
+ * 企业台账商品表控制器
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ */
+@Tag(name = "企业台账商品表控制器")
+@RestController
+@Validated
+public class QyRecordProductController {
+
+    @Resource
+    private QyRecordProductService qyRecordProductService;
+
+    /**
+     * 获取企业台账商品表分页
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "获取企业台账商品表分页")
+    @SaCheckPermission("/biz/qyrecordproduct/page")
+    @GetMapping("/biz/qyrecordproduct/page")
+    public CommonResult<Page<QyRecordProduct>> page(QyRecordProductPageParam qyRecordProductPageParam) {
+        return CommonResult.data(qyRecordProductService.page(qyRecordProductPageParam));
+    }
+
+    /**
+     * 添加企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "添加企业台账商品表")
+    @CommonLog("添加企业台账商品表")
+    @SaCheckPermission("/biz/qyrecordproduct/add")
+    @PostMapping("/biz/qyrecordproduct/add")
+    public CommonResult<String> add(@RequestBody @Valid QyRecordProductAddParam qyRecordProductAddParam) {
+        qyRecordProductService.add(qyRecordProductAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "编辑企业台账商品表")
+    @CommonLog("编辑企业台账商品表")
+    @SaCheckPermission("/biz/qyrecordproduct/edit")
+    @PostMapping("/biz/qyrecordproduct/edit")
+    public CommonResult<String> edit(@RequestBody @Valid QyRecordProductEditParam qyRecordProductEditParam) {
+        qyRecordProductService.edit(qyRecordProductEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 导出企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "导出企业台账商品表")
+    @CommonLog("导出企业台账商品表")
+    @SaCheckPermission("/biz/qyrecordproduct/export")
+    @PostMapping("/biz/qyrecordproduct/export")
+    public void export(@RequestBody @Valid QyRecordProductPageParam qyRecordProductPageParam, HttpServletResponse response) {
+        Page<QyRecordProduct> page =  qyRecordProductService.page(qyRecordProductPageParam);
+        List<QyRecordProduct> records = page.getRecords();
+        exportExcel(response,QyRecordProduct.class,records,"企业台账商品表");
+    }
+
+
+    /**
+     * 导出表格数据
+     * @param cl       表格字段实体类
+     * @param data     查询数据
+     * @param sheetName  表格名称
+     */
+    public void exportExcel(HttpServletResponse response, Class cl, List data, String sheetName){
+       HashMap<String, String> map = new HashMap<>();
+       try {
+           response.setHeader("Content-disposition", "attachment;filename=" + URLUtil.encode(sheetName) + ".xlsx");
+           response.setHeader("Access-Control-Allow-Origin", "*");
+           response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+           response.setContentType("application/octet-stream;charset=UTF-8");
+           EasyExcel.write(response.getOutputStream(), cl).autoCloseStream(Boolean.FALSE).sheet(sheetName).doWrite(data);
+       } catch (IOException e) {
+           response.reset();
+           response.setContentType("application/json");
+           response.setCharacterEncoding("utf-8");
+           map.put("status", "failure");
+           map.put("message", "下载文件失败" + e.getMessage());
+           try {
+               response.getWriter().println(JSON.toJSONString(map));
+           } catch (IOException ex) {
+               ex.printStackTrace();
+           }
+       }
+    }
+
+    /**
+     * 删除企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "删除企业台账商品表")
+    @CommonLog("删除企业台账商品表")
+    @SaCheckPermission("/biz/qyrecordproduct/delete")
+    @PostMapping("/biz/qyrecordproduct/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<QyRecordProductIdParam> qyRecordProductIdParamList) {
+        qyRecordProductService.delete(qyRecordProductIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取企业台账商品表详情
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    @Operation(summary = "获取企业台账商品表详情")
+    @SaCheckPermission("/biz/qyrecordproduct/detail")
+    @GetMapping("/biz/qyrecordproduct/detail")
+    public CommonResult<QyRecordProduct> detail(@Valid QyRecordProductIdParam qyRecordProductIdParam) {
+        return CommonResult.data(qyRecordProductService.detail(qyRecordProductIdParam));
+    }
+}

+ 158 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/entity/QyRecordProduct.java

@@ -0,0 +1,158 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.entity;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 企业台账商品表实体
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+@Setter
+@TableName("qy_record_product")
+public class QyRecordProduct {
+
+    /** ID */
+    @TableId
+    @Schema(description = "ID")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 0,value = "ID")
+    private String id;
+
+    /** 企业备案信息id */
+    @Schema(description = "企业备案信息id")
+    private String qyRecordInfoId;
+
+    /** 商品序号 */
+    @Schema(description = "商品序号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 2,value = "商品序号")
+    private String productNumber;
+
+    /** 预录入编号 */
+    @Schema(description = "预录入编号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 3,value = "预录入编号")
+    private String ylCode;
+
+    /** 企业编号 */
+    @Schema(description = "企业编号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 4,value = "企业编号")
+    private String companyApplyCode;
+
+    /** 企业名称 */
+    @Schema(description = "企业名称")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 5,value = "企业名称")
+    private String companyName;
+
+    /** 加工增值核算备案编号 */
+    @Schema(description = "加工增值核算备案编号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 6,value = "加工增值核算备案编号")
+    private String recordNumber;
+
+    /** 主管关区代码 */
+    @Schema(description = "主管关区代码")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 7,value = "主管关区代码")
+    private String regionCode;
+
+    /** 商品编号 */
+    @Schema(description = "商品编号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 8,value = "商品编号")
+    private String productCode;
+
+    /** 商品名称 */
+    @Schema(description = "商品名称")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 9,value = "商品名称")
+    private String productName;
+
+    /** 版本号 */
+    @Schema(description = "版本号")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 10,value = "版本号")
+    private String version;
+
+    /** HS编码 */
+    @Schema(description = "HS编码")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 11,value = "HS编码")
+    private String hsCode;
+
+    /** 人民币单价 */
+    @Schema(description = "人民币单价")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 12,value = "人民币单价")
+    private String unitPrice;
+
+    /** 商品数量 */
+    @Schema(description = "商品数量")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 13,value = "商品数量")
+    private String quantity;
+
+    /** 计量单位 */
+    @Schema(description = "计量单位")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 14,value = "计量单位")
+    private String measurementUnit;
+
+    /** 成品内销人民币价格 */
+    @Schema(description = "成品内销人民币价格")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 15,value = "成品内销人民币价格")
+    private String domesticSalePrice;
+
+    /** 境外进口料件总价(RMB) */
+    @Schema(description = "境外进口料件总价(RMB)")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 16,value = "境外进口料件总价(RMB)")
+    private String importTotal;
+
+    /** 国内采购料件总价(RMB) */
+    @Schema(description = "国内采购料件总价(RMB)")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 17,value = "国内采购料件总价(RMB)")
+    private String domesticTotal;
+
+    /** 自主核算产品收益占比 */
+    @Schema(description = "自主核算产品收益占比")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 18,value = "自主核算产品收益占比")
+    private String selfRatio;
+
+    /** 企业自主核算加工增值率 */
+    @Schema(description = "企业自主核算加工增值率")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 19,value = "企业自主核算加工增值率")
+    private String selfRate;
+
+    /** 备注 */
+    @Schema(description = "备注")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 20,value = "备注")
+    private String remark;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/enums/QyRecordProductEnum.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.enums;
+
+import lombok.Getter;
+
+/**
+ * 企业台账商品表枚举
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+public enum QyRecordProductEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    QyRecordProductEnum(String value) {
+        this.value = value;
+    }
+}

+ 25 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/mapper/QyRecordProductMapper.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.biz.modular.qyrecordproduct.entity.QyRecordProduct;
+
+/**
+ * 企业台账商品表Mapper接口
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+public interface QyRecordProductMapper extends BaseMapper<QyRecordProduct> {
+}

+ 5 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/mapper/mapping/QyRecordProductMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="vip.xiaonuo.biz.modular.qyrecordproduct.mapper.QyRecordProductMapper">
+
+</mapper>

+ 125 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductAddParam.java

@@ -0,0 +1,125 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 企业台账商品表添加参数
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+@Setter
+public class QyRecordProductAddParam {
+
+    /** 预录入台账编号 */
+    @Schema(description = "预录入台账编号")
+    private String ylTzCode;
+
+    /** 企业备案信息id */
+    @Schema(description = "企业备案信息id")
+    private String qyRecordInfoId;
+
+    /** 预录入编号 */
+    @Schema(description = "预录入编号")
+    private String ylCode;
+
+    /** 企业编号 */
+    @Schema(description = "企业编号")
+    private String companyApplyCode;
+
+    /** 企业名称 */
+    @Schema(description = "企业名称")
+    private String companyName;
+
+    /** 加工增值核算备案编号 */
+    @Schema(description = "加工增值核算备案编号")
+    private String recordNumber;
+
+    /** 主管关区代码 */
+    @Schema(description = "主管关区代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "regionCode不能为空")
+    private String regionCode;
+
+    /** 商品编号 */
+    @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "productCode不能为空")
+    private String productCode;
+
+    /** 商品名称 */
+    @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "productName不能为空")
+    private String productName;
+
+    /** 版本号 */
+    @Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "version不能为空")
+    private String version;
+
+    /** HS编码 */
+    @Schema(description = "HS编码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "hsCode不能为空")
+    private String hsCode;
+
+    /** 人民币单价 */
+    @Schema(description = "人民币单价", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "unitPrice不能为空")
+    private String unitPrice;
+
+    /** 商品数量 */
+    @Schema(description = "商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "quantity不能为空")
+    private String quantity;
+
+    /** 计量单位 */
+    @Schema(description = "计量单位", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "measurementUnit不能为空")
+    private String measurementUnit;
+
+    /** 成品内销人民币价格 */
+    @Schema(description = "成品内销人民币价格", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "domesticSalePrice不能为空")
+    private String domesticSalePrice;
+
+    /** 境外进口料件总价(RMB) */
+    @Schema(description = "境外进口料件总价(RMB)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "importTotal不能为空")
+    private String importTotal;
+
+    /** 国内采购料件总价(RMB) */
+    @Schema(description = "国内采购料件总价(RMB)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "domesticTotal不能为空")
+    private String domesticTotal;
+
+    /** 自主核算产品收益占比 */
+    @Schema(description = "自主核算产品收益占比")
+    private String selfRatio;
+
+    /** 企业自主核算加工增值率 */
+    @Schema(description = "企业自主核算加工增值率")
+    private String selfRate;
+
+    /** 备注 */
+    @Schema(description = "备注")
+    private String remark;
+
+}

+ 130 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductEditParam.java

@@ -0,0 +1,130 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 企业台账商品表编辑参数
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+@Setter
+public class QyRecordProductEditParam {
+
+    /** ID */
+    @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 企业备案信息id */
+    @Schema(description = "企业备案信息id")
+    private String qyRecordInfoId;
+
+    /** 商品序号 */
+    @Schema(description = "商品序号")
+    private String productNumber;
+
+    /** 预录入编号 */
+    @Schema(description = "预录入编号")
+    private String ylCode;
+
+    /** 企业编号 */
+    @Schema(description = "企业编号")
+    private String companyApplyCode;
+
+    /** 企业名称 */
+    @Schema(description = "企业名称")
+    private String companyName;
+
+    /** 加工增值核算备案编号 */
+    @Schema(description = "加工增值核算备案编号")
+    private String recordNumber;
+
+    /** 主管关区代码 */
+    @Schema(description = "主管关区代码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "regionCode不能为空")
+    private String regionCode;
+
+    /** 商品编号 */
+    @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "productCode不能为空")
+    private String productCode;
+
+    /** 商品名称 */
+    @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "productName不能为空")
+    private String productName;
+
+    /** 版本号 */
+    @Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "version不能为空")
+    private String version;
+
+    /** HS编码 */
+    @Schema(description = "HS编码", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "hsCode不能为空")
+    private String hsCode;
+
+    /** 人民币单价 */
+    @Schema(description = "人民币单价", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "unitPrice不能为空")
+    private String unitPrice;
+
+    /** 商品数量 */
+    @Schema(description = "商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "quantity不能为空")
+    private String quantity;
+
+    /** 计量单位 */
+    @Schema(description = "计量单位", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "measurementUnit不能为空")
+    private String measurementUnit;
+
+    /** 成品内销人民币价格 */
+    @Schema(description = "成品内销人民币价格", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "domesticSalePrice不能为空")
+    private String domesticSalePrice;
+
+    /** 境外进口料件总价(RMB) */
+    @Schema(description = "境外进口料件总价(RMB)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "importTotal不能为空")
+    private String importTotal;
+
+    /** 国内采购料件总价(RMB) */
+    @Schema(description = "国内采购料件总价(RMB)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "domesticTotal不能为空")
+    private String domesticTotal;
+
+    /** 自主核算产品收益占比 */
+    @Schema(description = "自主核算产品收益占比")
+    private String selfRatio;
+
+    /** 企业自主核算加工增值率 */
+    @Schema(description = "企业自主核算加工增值率")
+    private String selfRate;
+
+    /** 备注 */
+    @Schema(description = "备注")
+    private String remark;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductIdParam.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 企业台账商品表Id参数
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+@Setter
+public class QyRecordProductIdParam {
+
+    /** ID */
+    @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 51 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/param/QyRecordProductPageParam.java

@@ -0,0 +1,51 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 企业台账商品表查询参数
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Getter
+@Setter
+public class QyRecordProductPageParam {
+
+    /** 当前页 */
+    @Schema(description = "当前页码")
+    private Integer current;
+
+    /** 每页条数 */
+    @Schema(description = "每页条数")
+    private Integer size;
+
+    /** 排序字段 */
+    @Schema(description = "排序字段,字段驼峰名称,如:userName")
+    private String sortField;
+
+    /** 排序方式 */
+    @Schema(description = "排序方式,升序:ASCEND;降序:DESCEND")
+    private String sortOrder;
+
+    /** 关键词 */
+    @Schema(description = "关键词")
+    private String searchKey;
+
+}

+ 80 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/service/QyRecordProductService.java

@@ -0,0 +1,80 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.qyrecordproduct.entity.QyRecordProduct;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductEditParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductIdParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductPageParam;
+
+import java.util.List;
+
+/**
+ * 企业台账商品表Service接口
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+public interface QyRecordProductService extends IService<QyRecordProduct> {
+
+    /**
+     * 获取企业台账商品表分页
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    Page<QyRecordProduct> page(QyRecordProductPageParam qyRecordProductPageParam);
+
+    /**
+     * 添加企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    void add(QyRecordProductAddParam qyRecordProductAddParam);
+
+    /**
+     * 编辑企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    void edit(QyRecordProductEditParam qyRecordProductEditParam);
+
+    /**
+     * 删除企业台账商品表
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    void delete(List<QyRecordProductIdParam> qyRecordProductIdParamList);
+
+    /**
+     * 获取企业台账商品表详情
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     */
+    QyRecordProduct detail(QyRecordProductIdParam qyRecordProductIdParam);
+
+    /**
+     * 获取企业台账商品表详情
+     *
+     * @author hgx
+     * @date  2024/07/12 16:02
+     **/
+    QyRecordProduct queryEntity(String id);
+}

+ 94 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/qyrecordproduct/service/impl/QyRecordProductServiceImpl.java

@@ -0,0 +1,94 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.qyrecordproduct.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.biz.modular.qyrecordproduct.entity.QyRecordProduct;
+import vip.xiaonuo.biz.modular.qyrecordproduct.mapper.QyRecordProductMapper;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductAddParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductEditParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductIdParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.param.QyRecordProductPageParam;
+import vip.xiaonuo.biz.modular.qyrecordproduct.service.QyRecordProductService;
+
+import java.util.List;
+
+/**
+ * 企业台账商品表Service接口实现类
+ *
+ * @author hgx
+ * @date  2024/07/12 16:02
+ **/
+@Service
+public class QyRecordProductServiceImpl extends ServiceImpl<QyRecordProductMapper, QyRecordProduct> implements QyRecordProductService {
+
+    @Override
+    public Page<QyRecordProduct> page(QyRecordProductPageParam qyRecordProductPageParam) {
+        QueryWrapper<QyRecordProduct> queryWrapper = new QueryWrapper<QyRecordProduct>().checkSqlInjection();
+        if(ObjectUtil.isAllNotEmpty(qyRecordProductPageParam.getSortField(), qyRecordProductPageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(qyRecordProductPageParam.getSortOrder());
+            queryWrapper.orderBy(true, qyRecordProductPageParam.getSortOrder().equalsIgnoreCase(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(qyRecordProductPageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(QyRecordProduct::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(QyRecordProductAddParam qyRecordProductAddParam) {
+        QyRecordProduct qyRecordProduct = BeanUtil.toBean(qyRecordProductAddParam, QyRecordProduct.class);
+        this.save(qyRecordProduct);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(QyRecordProductEditParam qyRecordProductEditParam) {
+        QyRecordProduct qyRecordProduct = this.queryEntity(qyRecordProductEditParam.getId());
+        BeanUtil.copyProperties(qyRecordProductEditParam, qyRecordProduct);
+        this.updateById(qyRecordProduct);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<QyRecordProductIdParam> qyRecordProductIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(qyRecordProductIdParamList, QyRecordProductIdParam::getId));
+    }
+
+    @Override
+    public QyRecordProduct detail(QyRecordProductIdParam qyRecordProductIdParam) {
+        return this.queryEntity(qyRecordProductIdParam.getId());
+    }
+
+    @Override
+    public QyRecordProduct queryEntity(String id) {
+        QyRecordProduct qyRecordProduct = this.getById(id);
+        if(ObjectUtil.isEmpty(qyRecordProduct)) {
+            throw new CommonException("企业台账商品表不存在,id值为:{}", id);
+        }
+        return qyRecordProduct;
+    }
+}