Kaynağa Gözat

客户、提货配置、供应商

shasha 1 ay önce
ebeveyn
işleme
782f85100e

+ 91 - 0
snowy-admin-web/src/views/biz/customer/form.vue

@@ -0,0 +1,91 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑客户' : '增加客户'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-form-item label="客户登录账号:" name="loginAccount">
+				<a-input v-model:value="formData.loginAccount" placeholder="请输入客户登录账号" allow-clear />
+			</a-form-item>
+			<a-form-item label="客户名称:" name="name">
+				<a-input v-model:value="formData.name" placeholder="请输入客户名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="联系人:" name="contact">
+				<a-input v-model:value="formData.contact" placeholder="请输入联系人" allow-clear />
+			</a-form-item>
+			<a-form-item label="手机号:" name="phone">
+				<a-input v-model:value="formData.phone" placeholder="请输入手机号" allow-clear />
+			</a-form-item>
+			<a-form-item label="客户地址:" name="address">
+				<a-input v-model:value="formData.address" placeholder="请输入客户地址" allow-clear />
+			</a-form-item>
+			<a-form-item label="备注:" name="remark">
+				<a-input v-model:value="formData.remark" placeholder="请输入备注" allow-clear />
+			</a-form-item>
+			<a-form-item label="关联用友平台的ID:" name="yongId">
+				<a-input v-model:value="formData.yongId" placeholder="请输入关联用友平台的ID" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="customerForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import customerApi from '@/api/biz/customerApi'
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				customerApi
+					.customerSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 155 - 0
snowy-admin-web/src/views/biz/customer/index.vue

@@ -0,0 +1,155 @@
+<template>
+	<a-card :bordered="false">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="客户登录账号" name="loginAccount">
+						<a-input v-model:value="searchFormState.loginAccount" placeholder="请输入客户登录账号" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="客户名称" name="name">
+						<a-input v-model:value="searchFormState.name" placeholder="请输入客户名称" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="手机号" name="phone">
+						<a-input v-model:value="searchFormState.phone" placeholder="请输入手机号" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+					
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('customerAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+				</a-col>
+			</a-row>
+		</a-form>
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #bodyCell="{ column, record, index }">
+				<template v-if="column.dataIndex === 'serial'">
+					{{ index + 1 }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('customerEdit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteCustomer(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="customer">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import customerApi from '@/api/biz/customerApi'
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const tableRef = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '序号',
+			width: 50,
+			dataIndex: 'serial',
+			align:'center'
+		},
+		{
+			title: '登录账号',
+			dataIndex: 'loginAccount'
+		},
+		{
+			title: '客户名称',
+			dataIndex: 'name'
+		},
+		{
+			title: '联系人',
+			dataIndex: 'contact'
+		},
+		{
+			title: '手机号',
+			dataIndex: 'phone'
+		},
+		{
+			title: '客户地址',
+			dataIndex: 'address'
+		},
+		{
+			title: '备注',
+			dataIndex: 'remark'
+		},
+		{
+			title: '关联用友平台的ID',
+			dataIndex: 'yongId'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['customerEdit', 'customerDelete'])) {
+		columns.push({
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 150
+		})
+	}
+	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) => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		return customerApi.customerPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteCustomer = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		customerApi.customerDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchCustomer = (params) => {
+		customerApi.customerDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 187 - 0
snowy-admin-web/src/views/biz/goodsConf/addForm.vue

@@ -0,0 +1,187 @@
+<template>
+	<xn-form-container
+		:title="'添加提货配置'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-row :gutter="24">
+				<a-col :span="24">
+					<a-form-item label="提货时间段:" name="confStartEndTime">
+						<a-range-picker v-model:value="formData.confStartEndTime" value-format="YYYY-MM-DD HH:mm" show-time style="width: 100%" />
+					</a-form-item>
+				</a-col>
+			</a-row>
+
+			<!-- 批量添加货物 -->
+			<a-form-item label="货物信息" name="goodsJson">
+				<a-row :gutter="24" class="form-row">
+					<a-col :span="12" class="form-row-con"> 货物 </a-col>
+					<a-col :span="8" class="form-row-con"> 最大提货重量(KG) </a-col>
+					<a-col :span="4" class="form-row-con">
+						<a-button type="primary" @click="addDomains()" size="small">
+							<PlusOutlined />
+							增加
+						</a-button>
+					</a-col>
+				</a-row>
+				<div :key="goodsInfo" v-for="(goodsInfo, index) in formData.goodsJson">
+					<a-row :gutter="24">
+						<a-col :span="12">
+							<a-form-item
+								:name="['goodsJson', index, 'goodsId']"
+								:rules="{ required: true, message: '请选择货物' }"
+							>
+								<a-select
+									v-model:value="goodsInfo.goodsId"
+									:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+									:options="goodsList"
+									class="xn-wd"
+									placeholder="请选择货物"
+								/>
+							</a-form-item>
+						</a-col>
+						<a-col :span="8">
+							<a-form-item
+								:name="['goodsJson', index, 'confWeight']"
+								:rules="{ required: true, message: '请输入最大提货重量' }"
+							>
+								<a-input v-model:value="goodsInfo.confWeight" placeholder="请输入重量" allow-clear />
+							</a-form-item>
+						</a-col>
+						<a-col :span="4" class="xn-mt4">
+							<a-button size="small" type="primary" danger ghost @click="delDomains(index)">移除</a-button>
+						</a-col>
+					</a-row>
+				</div>
+			</a-form-item>
+		</a-form>
+
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="goodsConfForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import goodsApi from '@/api/biz/goodsApi'
+	import goodsConfApi from '@/api/biz/goodsConfApi'
+
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const goodsList = ref([])
+
+	//设置表单样式
+	const labelCol = ref({ span: 4})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		formData.value = {
+			confStartEndTime: '',
+			goodsJson: []
+		}
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+
+		// 获取数据库中的所有表
+		goodsApi.getList().then((data) => {
+			goodsList.value = data.map((item) => {
+				return {
+					value: item['id'],
+					label: item['goodsName']+" - "+item['goodsModel']
+				}
+			})
+		}).finally(() => {
+			submitLoading.value = false
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		confStartEndTime: [required('请选择提货时间段')],
+		goodsJson: [required('请选择货物')],
+	}
+
+	// 附属职位信息增行
+	const addDomains = () => {
+		if (formData.value.goodsJson === null) {
+			formData.value.goodsJson = []
+		}
+		formData.value.goodsJson.push({
+			goodsId: undefined,
+			confWeight: undefined
+		})
+	}
+	// 删减行
+	const delDomains = (index) => {
+		formData.value.goodsJson.splice(index, 1)
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				// 因为不切断,我下面转换数据格式,影响上面表单会报错
+				let formDatas = JSON.parse(JSON.stringify(formData.value))
+				// 判断货品信息:至少选择一个
+				if (formDatas.goodsJson && formDatas.goodsJson.length > 0) {
+					formDatas.goodsJson = JSON.stringify(formDatas.goodsJson)
+
+					const formDataParam = cloneDeep(formData.value)
+					submitLoading.value = true
+
+					formDatas.confStartTime = formDataParam.confStartEndTime[0]+":00"
+					formDatas.confEndTime = formDataParam.confStartEndTime[1]+":00"
+					goodsConfApi
+						.goodsConfSubmitForm(formDatas, formDataParam.id)
+						.then(() => {
+							onClose()
+							emit('successful')
+						})
+						.finally(() => {
+							submitLoading.value = false
+						})
+				} else {
+					// 不允许提交  提示信息
+
+				}
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>
+
+<style scoped lang="less">
+	.form-row {
+		background-color: var(--item-hover-bg);
+		margin-left: 0 !important;
+		margin-bottom: 10px;
+	}
+	.form-row-con {
+		padding-bottom: 5px;
+		padding-top: 5px;
+		padding-left: 15px;
+	}
+</style>

+ 102 - 0
snowy-admin-web/src/views/biz/goodsConf/editForm.vue

@@ -0,0 +1,102 @@
+<template>
+	<xn-form-container
+		:title="'编辑提货配置'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-descriptions :column="4" size="middle" bordered class="mb-2" :label-style="labelStyle" :contentStyle="contentStyle">
+			<a-descriptions-item label="货品编码" :span="4">{{ formData.goodsCode }}</a-descriptions-item>
+			<a-descriptions-item label="货品信息" :span="4">{{ formData.goodsName }} ({{ formData.goodsModel }})</a-descriptions-item>
+		</a-descriptions>
+
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-form-item label="提货开始时间:" name="confStartTime">
+				<a-date-picker v-model:value="formData.confStartTime" value-format="YYYY-MM-DD HH:mm" show-time style="width: 100%" />
+			</a-form-item>
+			<a-form-item label="提货结束时间:" name="confEndTime">
+				<a-date-picker v-model:value="formData.confEndTime" value-format="YYYY-MM-DD HH:mm" show-time style="width: 100%" />
+			</a-form-item>
+			<a-form-item label="最大提货重量(KG):" name="confWeight">
+				<a-input v-model:value="formData.confWeight" :min="formData.usedWeight" placeholder="请输入最大提货重量" allow-clear />
+			</a-form-item>
+		</a-form>
+
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="goodsConfForm">
+	import { cloneDeep } from 'lodash-es'
+	import { message } from 'ant-design-vue'
+	import { required } from '@/utils/formRules'
+	import goodsConfApi from '@/api/biz/goodsConfApi'
+
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		confStartTime: [required('请选择提货开始时间')],
+		confEndTime: [required('请选择提货结束时间')],
+		confWeight: [required('请输入最大提货重量')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				// 判断开始和结束时间
+				let confStartTime = new Date(formDataParam.confStartTime+":00")
+				let confEndTime = new Date(formDataParam.confEndTime+":00")
+				if(confStartTime > confEndTime){
+					message.error('结束时间不得小于开始时间!')
+					return
+				}else{
+					goodsConfApi
+					.goodsConfSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+				}
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 206 - 0
snowy-admin-web/src/views/biz/goodsConf/index.vue

@@ -0,0 +1,206 @@
+<template>
+	<a-card :bordered="false">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="货品名称" name="goodsName">
+						<a-input v-model:value="searchFormState.goodsName" placeholder="请输入货品名称" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="9">
+					<a-form-item label="提货开始时间" name="confStartTime">
+						<a-range-picker v-model:value="searchFormState.confStartTime" value-format="YYYY-MM-DD HH:mm" show-time />
+					</a-form-item>
+				</a-col>
+				<a-col :span="9">
+					<a-form-item label="提货结束时间" name="confEndTime">
+						<a-range-picker v-model:value="searchFormState.confEndTime" value-format="YYYY-MM-DD HH:mm" show-time />
+					</a-form-item>
+				</a-col>
+			</a-row>
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="货品编码" name="goodsCode">
+						<a-input v-model:value="searchFormState.goodsCode" placeholder="请输入货品名称" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="9"></a-col>
+				<a-col :span="9">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+
+					<a-button type="primary" @click="addFormRef.onOpen()" v-if="hasPerm('goodsConfAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+				</a-col>
+			</a-row>
+		</a-form>
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #bodyCell="{ column, record, index }">
+				<template v-if="column.dataIndex === 'serial'">
+					{{ index + 1 }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="editFormRef.onOpen(record)" v-if="hasPerm('goodsConfEdit') && Number(record.usedWeight) == 0">编辑</a>
+
+						<a-divider type="vertical" v-if="hasPerm(['goodsConfEdit', 'goodsConfDelete'], 'and')" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteGoodsConf(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('goodsConfDelete')">删除</a-button>
+						</a-popconfirm>
+
+						<a-divider type="vertical" v-if="hasPerm(['goodsConfEdit', 'goodsConfWeight'], 'and')" />
+						<a @click="weightFormRef.onOpen(record)" v-if="hasPerm('goodsConfWeight')">重量</a>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<AddForm ref="addFormRef" @successful="tableRef.refresh()" />
+	<EditForm ref="editFormRef" @successful="tableRef.refresh()" />
+	<WeightForm ref="weightFormRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="goodsConf">
+	import { cloneDeep } from 'lodash-es'
+	import AddForm from './addForm.vue'
+	import EditForm from './editForm.vue'
+	import WeightForm from './weightForm.vue'
+	import goodsConfApi from '@/api/biz/goodsConfApi'
+
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const tableRef = ref()
+	const addFormRef = ref()
+	const editFormRef = ref()
+	const weightFormRef = ref()
+
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '序号',
+			width: 50,
+			dataIndex: 'serial',
+			align:'center'
+		},
+		{
+			title: '货品编码',
+			width: 120,
+			dataIndex: 'goodsCode',
+			align:'center'
+		},
+		{
+			title: '货品名称',
+			dataIndex: 'goodsName',
+			align:'center'
+		},
+		{
+			title: '货品规格',
+			width: 80,
+			dataIndex: 'goodsModel',
+			align:'center'
+		},
+		{
+			title: '提货开始时间',
+			width: 150,
+			dataIndex: 'confStartTime',
+			align:'center'
+		},
+		{
+			title: '提货结束时间',
+			width: 150,
+			dataIndex: 'confEndTime',
+			align:'center'
+		},
+		{
+			title: '可提重量(KG)',
+			width: 110,
+			dataIndex: 'confWeight',
+			align:'center'
+		},
+		{
+			title: '已提重量(KG)',
+			width: 110,
+			dataIndex: 'usedWeight',
+			align:'center'
+		},
+		{
+			title: '剩余重量(KG)',
+			width: 110,
+			dataIndex: 'lastWeight',
+			align:'center'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['goodsConfEdit', 'goodsConfDelete', 'goodsConfWeight'])) {
+		columns.push({
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 200
+		})
+	}
+	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) => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		// confStartTime范围查询条件重载
+		if (searchFormParam.confStartTime) {
+			searchFormParam.startConfStartTime = searchFormParam.confStartTime[0]+":00"
+			searchFormParam.endConfStartTime = searchFormParam.confStartTime[1]+":00"
+			delete searchFormParam.confStartTime
+		}
+		// confEndTime范围查询条件重载
+		if (searchFormParam.confEndTime) {
+			searchFormParam.startConfEndTime = searchFormParam.confEndTime[0]+":00"
+			searchFormParam.endConfEndTime = searchFormParam.confEndTime[1]+":00"
+			delete searchFormParam.confEndTime
+		}
+		return goodsConfApi.goodsConfPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteGoodsConf = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		goodsConfApi.goodsConfDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchGoodsConf = (params) => {
+		goodsConfApi.goodsConfDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 90 - 0
snowy-admin-web/src/views/biz/goodsConf/weightForm.vue

@@ -0,0 +1,90 @@
+<template>
+	<xn-form-container
+		:title="'编辑提货重量'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-descriptions :column="4" size="middle" bordered class="mb-2" :label-style="labelStyle" :contentStyle="contentStyle">
+			<a-descriptions-item label="货品编码" :span="4">{{ formData.goodsCode }}</a-descriptions-item>
+			<a-descriptions-item label="货品信息" :span="4">{{ formData.goodsName }} ( {{ formData.goodsModel }} )</a-descriptions-item>
+			<a-descriptions-item label="提货时间段" :span="4">{{ formData.confStartTime }} ~ {{ formData.confEndTime }}</a-descriptions-item>
+			<a-descriptions-item label="原最大提货重量" :span="4">{{ confWeight }} KG</a-descriptions-item>
+			<a-descriptions-item label="已提货重量" :span="4">{{ formData.usedWeight }} KG</a-descriptions-item>
+			<a-descriptions-item label="剩余提货重量" :span="4">{{ formData.lastWeight }} KG</a-descriptions-item>
+		</a-descriptions>
+
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-form-item label="最大提货重量(KG):" name="confWeight">
+				<a-input-number v-model:value="formData.confWeight" :min="formData.usedWeight" placeholder="请输入最大提货重量" allow-clear />
+			</a-form-item>
+		</a-form>
+
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="goodsConfForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import goodsConfApi from '@/api/biz/goodsConfApi'
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const confWeight = ref("")
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+			confWeight.value = formData.value.confWeight
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		confWeight: [required("请输入最大提货重量")]
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				goodsConfApi
+					.goodsConfSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 92 - 0
snowy-admin-web/src/views/biz/supplier/form.vue

@@ -0,0 +1,92 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑供货商' : '增加供货商'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-form-item label="供货商名称:" name="supplierName">
+				<a-input v-model:value="formData.supplierName" placeholder="请输入供货商名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="供货商地址:" name="supplierAddress">
+				<a-input v-model:value="formData.supplierAddress" placeholder="请输入供货商地址" allow-clear />
+			</a-form-item>
+			<a-form-item label="联系人:" name="supplierContactName">
+				<a-input v-model:value="formData.supplierContactName" placeholder="请输入联系人" allow-clear />
+			</a-form-item>
+			<a-form-item label="手机号:" name="supplierPhone">
+				<a-input v-model:value="formData.supplierPhone" placeholder="请输入手机号" allow-clear />
+			</a-form-item>
+			<a-form-item label="备注:" name="supplierRemark">
+				<a-input v-model:value="formData.supplierRemark" placeholder="请输入备注" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="supplierForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import supplierApi from '@/api/biz/supplierApi'
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		supplierName: [required('请输入供货商名称')],
+		supplierContactName:[required('请输入联系人')],
+		supplierPhone:[required('请输入手机号')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				supplierApi
+					.supplierSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 157 - 0
snowy-admin-web/src/views/biz/supplier/index.vue

@@ -0,0 +1,157 @@
+<template>
+	<a-card :bordered="false">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="供货商名称" name="searchKey">
+						<a-input v-model:value="searchFormState.searchKey" placeholder="请输入供货商名称" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="联系方式" name="searchKey">
+						<a-input v-model:value="searchFormState.searchKey" placeholder="请输入联系方式" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('supplierAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+				</a-col>
+			</a-row>
+		</a-form>
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #bodyCell="{ column, record, index }">
+				<template v-if="column.dataIndex === 'serial'">
+					{{ index + 1 }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('supplierEdit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['supplierEdit', 'supplierDelete'], 'and')" />
+						<a-button type="link" danger size="small" v-if="hasPerm('supplierDelete')" @click="deleteConfig(record)">删除</a-button>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="bizsupplier">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import supplierApi from '@/api/biz/supplierApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const tableRef = ref()
+	const formRef = ref()
+	const submitLoading = ref(false)
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '序号',
+			width: 50,
+			dataIndex: 'serial',
+			align:'center'
+		},
+		{
+			title: '供货商名称',
+			width: 250,
+			dataIndex: 'supplierName',
+			align:'center'
+		},
+		{
+			title: '供货商地址',
+			dataIndex: 'supplierAddress',
+			align:'center'
+		},
+		{
+			title: '联系人',
+			width: 180,
+			dataIndex: 'supplierContactName',
+			align:'center'
+		},
+		{
+			title: '手机号',
+			width: 180,
+			dataIndex: 'supplierPhone',
+			align:'center'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150
+	})
+
+	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) => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		return supplierApi.supplierPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteConfig = (record) => {
+
+		Modal.confirm({
+			title: '确定删除该数据吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params = [
+					{
+						id: record.id
+					}
+				]
+
+				supplierApi
+					.supplierDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+</script>