Selaa lähdekoodia

供应商、服务客户、停车费配置

shasha 1 kuukausi sitten
vanhempi
commit
dc29a39175
17 muutettua tiedostoa jossa 451 lisäystä ja 296 poistoa
  1. 4 0
      snowy-admin-web/src/api/biz/bizServiceCustomerFlowApi.js
  2. 2 12
      snowy-admin-web/src/views/biz/bizservicecustomer/accountForm.vue
  3. 112 84
      snowy-admin-web/src/views/biz/bizservicecustomer/accountIndex.vue
  4. 0 86
      snowy-admin-web/src/views/biz/bizservicecustomer/flowForm.vue
  5. 115 86
      snowy-admin-web/src/views/biz/bizservicecustomer/flowIndex.vue
  6. 23 6
      snowy-admin-web/src/views/biz/bizservicecustomer/index.vue
  7. 2 2
      snowy-admin-web/src/views/biz/bizsupplier/accountIndex.vue
  8. 1 0
      snowy-admin-web/src/views/biz/bizsupplier/index.vue
  9. 2 2
      snowy-admin-web/src/views/biz/bizsupplier/transportIndex.vue
  10. 16 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/controller/BizServiceCustomerFlowController.java
  11. 3 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/entity/BizServiceCustomerAccount.java
  12. 15 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/entity/BizServiceCustomerFlow.java
  13. 5 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/param/BizServiceCustomerFlowAddParam.java
  14. 42 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/param/BizServiceCustomerFlowCancelParam.java
  15. 9 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/BizServiceCustomerFlowService.java
  16. 87 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/impl/BizServiceCustomerFlowServiceImpl.java
  17. 13 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/impl/BizServiceCustomerServiceImpl.java

+ 4 - 0
snowy-admin-web/src/api/biz/bizServiceCustomerFlowApi.js

@@ -24,5 +24,9 @@ export default {
 	// 获取服务客户资金流水详情
 	bizServiceCustomerFlowDetail(data) {
 		return request('detail', data, 'get')
+	},
+	// 取消
+	bizServiceCustomerFlowCancelForm(data) {
+		return request('cancel', data)
 	}
 }

+ 2 - 12
snowy-admin-web/src/views/biz/bizservicecustomer/accountForm.vue

@@ -10,18 +10,6 @@
 			<a-form-item label="账号:" name="loginAccount">
 				<a-input v-model:value="formData.loginAccount" placeholder="请输入账号" allow-clear />
 			</a-form-item>
-			<a-form-item label="充值总余额:" name="rechargeAmount">
-				<a-input v-model:value="formData.rechargeAmount" placeholder="请输入充值总余额" allow-clear />
-			</a-form-item>
-			<a-form-item label="消费总金额:" name="consumptionAmount">
-				<a-input v-model:value="formData.consumptionAmount" placeholder="请输入消费总金额" allow-clear />
-			</a-form-item>
-			<a-form-item label="锁定金额(占用金额):" name="lockAmount">
-				<a-input v-model:value="formData.lockAmount" placeholder="请输入锁定金额(占用金额)" allow-clear />
-			</a-form-item>
-			<a-form-item label="可用余额(账户余额):" name="accountAmount">
-				<a-input v-model:value="formData.accountAmount" placeholder="请输入可用余额(账户余额)" allow-clear />
-			</a-form-item>
 			<a-form-item label="授信额度:" name="creditAmount">
 				<a-input v-model:value="formData.creditAmount" placeholder="请输入授信额度" allow-clear />
 			</a-form-item>
@@ -65,6 +53,8 @@
 	}
 	// 默认要校验的
 	const formRules = {
+		loginAccount: [required('请输入账户')],
+		creditAmount: [required('请输入授信额度')],
 	}
 	// 验证并提交数据
 	const onSubmit = () => {

+ 112 - 84
snowy-admin-web/src/views/biz/bizservicecustomer/accountIndex.vue

@@ -1,56 +1,66 @@
 <template>
-	<a-card :bordered="false">
-		<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"
-		>
-			<template #operator class="table-operator">
-				<a-space>
-					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizServiceCustomerAccountAdd')">
-						<template #icon><plus-outlined /></template>
-						新增
-					</a-button>
-					<xn-batch-button
-						v-if="hasPerm('bizServiceCustomerAccountBatchDelete')"
-						buttonName="批量删除"
-                        icon="DeleteOutlined"
-						:selectedRowKeys="selectedRowKeys"
-						@batchCallBack="deleteBatchBizServiceCustomerAccount"
-					/>
-				</a-space>
-			</template>
-			<template #bodyCell="{ column, record, index }">
-				<template v-if="column.dataIndex === 'serial'">
-					{{ index + 1 }}
-				</template>
-				<template v-if="column.dataIndex === 'action'">
+	<a-drawer :title="title" :width="1150" :open="visible" :destroy-on-close="true" @close="onClose">
+		<a-card :bordered="false" class="mb-2">
+			<s-table
+				ref="tableRef"
+				:columns="columns"
+				:data="loadData"
+				bordered
+				:row-key="(record) => record.id"
+			>
+				<template #operator class="table-operator">
 					<a-space>
-						<a @click="formRef.onOpen(record)" v-if="hasPerm('bizServiceCustomerAccountEdit')">编辑</a>
-						<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerAccountEdit', 'bizServiceCustomerAccountDelete'], 'and')" />
-						<a-popconfirm title="确定要删除吗?" @confirm="deleteBizServiceCustomerAccount(record)">
-							<a-button type="link" danger size="small" v-if="hasPerm('bizServiceCustomerAccountDelete')">删除</a-button>
-						</a-popconfirm>
+						<a-button type="primary" @click="formRef.onOpen(null, serviceCustomerId)" v-if="hasPerm('bizServiceCustomerAccountAdd')">
+							<template #icon><plus-outlined /></template>
+							新增
+						</a-button>
 					</a-space>
 				</template>
-			</template>
-		</s-table>
-	</a-card>
+				<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, serviceCustomerId)" v-if="hasPerm('bizServiceCustomerAccountEdit')">编辑</a>
+
+							<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerAccountEdit', 'bizServiceCustomerAccountDelete'], 'and')" />
+							<a-button type="link" danger size="small" v-if="hasPerm('bizServiceCustomerAccountDelete')" @click="deleteConfig(record)">删除</a-button>
+
+							<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerAccountEdit', 'bizServiceCustomerAccountDelete'], 'or') && hasPerm('bizServiceCustomerFlow')" />
+							<a @click="flowIndexRef.onOpen(record, serviceCustomerId)" v-if="hasPerm('bizServiceCustomerFlow')">流水管理</a>
+						</a-space>
+					</template>
+				</template>
+			</s-table>
+		</a-card>
+	</a-drawer>
+
 	<Form ref="formRef" @successful="tableRef.refresh()" />
+	<FlowIndex ref="flowIndexRef" @onclose="tableRef.refresh()" />
 </template>
 
 <script setup name="bizservicecustomeraccount">
 	import { cloneDeep } from 'lodash-es'
-	import Form from './form.vue'
+	import Form from './accountForm.vue'
+	import FlowIndex from './flowIndex.vue'
 	import bizServiceCustomerAccountApi from '@/api/biz/bizServiceCustomerAccountApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	
+	const submitLoading = ref(false)
+	const toolConfig = { refresh: true, height: false, columnSetting: false, striped: false }
+	// 默认是关闭状态
+	const visible = ref(false)
+	const searchFormState = ref({})
 	const tableRef = ref()
 	const formRef = ref()
-	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const flowIndexRef = ref()
+	const recordData = ref()
+	const title = ref()
+	const serviceCustomerId = ref()
+
 	const columns = [
 		{
 			title: '序号',
@@ -60,79 +70,97 @@
 		},
 		{
 			title: '账号',
-			dataIndex: 'loginAccount'
+			width: 150,
+			dataIndex: 'loginAccount',
+			align:'center'
 		},
 		{
 			title: '充值总余额',
-			dataIndex: 'rechargeAmount'
+			width: 150,
+			dataIndex: 'rechargeAmount',
+			align:'center'
 		},
 		{
 			title: '消费总金额',
-			dataIndex: 'consumptionAmount'
+			width: 150,
+			dataIndex: 'consumptionAmount',
+			align:'center'
 		},
 		{
-			title: '锁定金额(占用金额)',
-			dataIndex: 'lockAmount'
+			title: '锁定金额',
+			width: 150,
+			dataIndex: 'lockAmount',
+			align:'center'
 		},
 		{
-			title: '可用余额(账户余额)',
-			dataIndex: 'accountAmount'
+			title: '可用余额',
+			width: 150,
+			dataIndex: 'accountAmount',
+			align:'center'
 		},
 		{
 			title: '授信额度',
-			dataIndex: 'creditAmount'
+			width: 150,
+			dataIndex: 'creditAmount',
+			align:'center'
 		},
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizServiceCustomerAccountEdit', 'bizServiceCustomerAccountDelete'])) {
+	if (hasPerm(['bizServiceCustomerAccountEdit', 'bizServiceCustomerAccountDelete', 'bizServiceCustomerFlow'], 'or')) {
 		columns.push({
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 260
 		})
 	}
-	const selectedRowKeys = ref([])
-	// 列表选择配置
-	const options = {
-		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
-		alert: {
-			show: true,
-			clear: () => {
-				selectedRowKeys.value = ref([])
-			}
-		},
-		rowSelection: {
-			onChange: (selectedRowKey, selectedRows) => {
-				selectedRowKeys.value = selectedRowKey
-			}
+	// 打开抽屉
+	const onOpen = (record) => {
+		recordData.value = record
+		title.value = "【" + record.name + "】-账户管理"
+		searchFormState.value = {
+			serviceCustomerId: record.id
 		}
+		serviceCustomerId.value = record.id
+		visible.value = true
 	}
 	const loadData = (parameter) => {
-		return bizServiceCustomerAccountApi.bizServiceCustomerAccountPage(parameter).then((data) => {
+		return bizServiceCustomerAccountApi.bizServiceCustomerAccountPage(Object.assign(parameter, searchFormState.value)).then((data) => {
 			return data
 		})
 	}
-	// 重置
-	const reset = () => {
-		searchFormRef.value.resetFields()
-		tableRef.value.refresh(true)
+	// 关闭抽屉
+	const onClose = () => {
+		visible.value = false
 	}
 	// 删除
-	const deleteBizServiceCustomerAccount = (record) => {
-		let params = [
-			{
-				id: record.id
-			}
-		]
-		bizServiceCustomerAccountApi.bizServiceCustomerAccountDelete(params).then(() => {
-			tableRef.value.refresh(true)
-		})
-	}
-	// 批量删除
-	const deleteBatchBizServiceCustomerAccount = (params) => {
-		bizServiceCustomerAccountApi.bizServiceCustomerAccountDelete(params).then(() => {
-			tableRef.value.clearRefreshSelected()
+	const deleteConfig = (record) => {
+		Modal.confirm({
+			title: '确定删除该数据吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params = [
+					{
+						id: record.id
+					}
+				]
+
+				bizServiceCustomerAccountApi
+					.bizServiceCustomerAccountDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
 		})
 	}
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
 </script>

+ 0 - 86
snowy-admin-web/src/views/biz/bizservicecustomer/flowForm.vue

@@ -1,86 +0,0 @@
-<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="操作类型  1:充值   2:消费:" name="operateType">
-				<a-input v-model:value="formData.operateType" placeholder="请输入操作类型  1:充值   2:消费" allow-clear />
-			</a-form-item>
-			<a-form-item label="操作前账户余额(充值或消费前账户余额):" name="operateAmountBegin">
-				<a-input v-model:value="formData.operateAmountBegin" placeholder="请输入操作前账户余额(充值或消费前账户余额)" allow-clear />
-			</a-form-item>
-			<a-form-item label="操作金额(充值或消费金额):" name="operateAmount">
-				<a-input v-model:value="formData.operateAmount" placeholder="请输入操作金额(充值或消费金额)" allow-clear />
-			</a-form-item>
-			<a-form-item label="操作后账户余额(充值或消费后账户余额):" name="operateAmountAfter">
-				<a-input v-model:value="formData.operateAmountAfter" 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="bizServiceCustomerFlowForm">
-	import { cloneDeep } from 'lodash-es'
-	import { required } from '@/utils/formRules'
-	import bizServiceCustomerFlowApi from '@/api/biz/bizServiceCustomerFlowApi'
-	// 抽屉状态
-	const open = ref(false)
-	const emit = defineEmits({ successful: null })
-	const formRef = ref()
-	// 表单数据
-	const formData = ref({})
-	const submitLoading = ref(false)
-
-	//设置表单样式
-	const labelCol = ref({ span: 4})
-	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 = {
-	}
-	// 验证并提交数据
-	const onSubmit = () => {
-		formRef.value
-			.validate()
-			.then(() => {
-				submitLoading.value = true
-				const formDataParam = cloneDeep(formData.value)
-				bizServiceCustomerFlowApi
-					.bizServiceCustomerFlowSubmitForm(formDataParam, formDataParam.id)
-					.then(() => {
-						onClose()
-						emit('successful')
-					})
-					.finally(() => {
-						submitLoading.value = false
-					})
-			})
-			.catch(() => {})
-	}
-	// 抛出函数
-	defineExpose({
-		onOpen
-	})
-</script>

+ 115 - 86
snowy-admin-web/src/views/biz/bizservicecustomer/flowIndex.vue

@@ -1,56 +1,68 @@
 <template>
-	<a-card :bordered="false">
-		<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"
-		>
-			<template #operator class="table-operator">
-				<a-space>
-					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizServiceCustomerFlowAdd')">
-						<template #icon><plus-outlined /></template>
-						新增
-					</a-button>
-					<xn-batch-button
-						v-if="hasPerm('bizServiceCustomerFlowBatchDelete')"
-						buttonName="批量删除"
-                        icon="DeleteOutlined"
-						:selectedRowKeys="selectedRowKeys"
-						@batchCallBack="deleteBatchBizServiceCustomerFlow"
-					/>
-				</a-space>
-			</template>
-			<template #bodyCell="{ column, record, index }">
-				<template v-if="column.dataIndex === 'serial'">
-					{{ index + 1 }}
-				</template>
-				<template v-if="column.dataIndex === 'action'">
+	<a-drawer :title="title" :width="850" :open="visible" :destroy-on-close="true" @close="onClose">
+		<a-card :bordered="false">
+			<s-table
+				ref="tableRef"
+				:columns="columns"
+				:data="loadData"
+				bordered
+				:row-key="(record) => record.id"
+			>
+				<template #operator class="table-operator">
 					<a-space>
-						<a @click="formRef.onOpen(record)" v-if="hasPerm('bizServiceCustomerFlowEdit')">编辑</a>
-						<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerFlowEdit', 'bizServiceCustomerFlowDelete'], 'and')" />
-						<a-popconfirm title="确定要删除吗?" @confirm="deleteBizServiceCustomerFlow(record)">
-							<a-button type="link" danger size="small" v-if="hasPerm('bizServiceCustomerFlowDelete')">删除</a-button>
-						</a-popconfirm>
+						<a-button type="primary" @click="rechargeFormRef.onOpen(null, serviceCustomerId, scAccountId)" v-if="hasPerm('bizServiceCustomerFlowRecharge')">
+							<template #icon><plus-outlined /></template>
+							充值
+						</a-button>
+						<a-button type="primary" @click="consumeFormRef.onOpen(null, serviceCustomerId, scAccountId)" v-if="hasPerm('bizServiceCustomerFlowConsume')">
+							<template #icon><minus-outlined /></template>
+							扣费
+						</a-button>
 					</a-space>
 				</template>
-			</template>
-		</s-table>
-	</a-card>
-	<Form ref="formRef" @successful="tableRef.refresh()" />
+				<template #bodyCell="{ column, record, index }">
+					<template v-if="column.dataIndex === 'serial'">
+						{{ index + 1 }}
+					</template>
+					<template v-if="column.dataIndex === 'action'">
+						<a-space>
+							<a @click="cancelRef.onOpen(record, serviceCustomerId, scAccountId)" v-if="hasPerm('bizServiceCustomerFlowCancel')">取消</a>
+						</a-space>
+					</template>
+				</template>
+			</s-table>
+		</a-card>
+	</a-drawer>
+
+	<RechargeForm ref="rechargeFormRef" @successful="tableRef.refresh()" />
+	<ConsumeForm ref="consumeFormRef" @successful="tableRef.refresh()" />
+	<CancelForm ref="cancelRef" @successful="tableRef.refresh()" />
 </template>
 
-<script setup name="bizservicecustomerflow">
+<script setup name="bizservicecustomeraccount">
 	import { cloneDeep } from 'lodash-es'
-	import Form from './flowForm.vue'
+	import RechargeForm from './flowRechargeForm.vue'
+	import ConsumeForm from './flowConsumeForm.vue'
+	import CancelForm from './flowCancelForm.vue'	
 	import bizServiceCustomerFlowApi from '@/api/biz/bizServiceCustomerFlowApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	
+	const submitLoading = ref(false)
+	const toolConfig = { refresh: true, height: false, columnSetting: false, striped: false }
+	// 默认是关闭状态
+	const visible = ref(false)
+	const searchFormState = ref({})
 	const tableRef = ref()
-	const formRef = ref()
-	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const rechargeFormRef = ref()
+	const consumeFormRef = ref()
+	const cancelRef = ref()
+	const recordData = ref()
+	const title = ref()
+	const serviceCustomerId = ref()
+	const scAccountId = ref()
+	
 	const columns = [
 		{
 			title: '序号',
@@ -59,77 +71,94 @@
 			align:'center'
 		},
 		{
-			title: '操作类型  1:充值   2:消费',
-			dataIndex: 'operateType'
+			title: '操作类型',
+			width: 100,
+			dataIndex: 'operateType',
+			align:'center'
 		},
 		{
-			title: '操作前账户余额',
-			dataIndex: 'operateAmountBegin'
+			title: '操作前余额',
+			width: 150,
+			dataIndex: 'operateAmountBegin',
+			align:'center'
 		},
 		{
 			title: '操作金额',
-			dataIndex: 'operateAmount'
+			width: 150,
+			dataIndex: 'operateAmount',
+			align:'center'
 		},
 		{
-			title: '操作后账户余额',
-			dataIndex: 'operateAmountAfter'
+			title: '操作后余额',
+			width: 150,
+			dataIndex: 'operateAmountAfter',
+			align:'center'
 		},
 		{
 			title: '操作时间',
+			width: 180,
 			dataIndex: 'createTime',
 			align: 'center'
 		},
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizServiceCustomerFlowEdit', 'bizServiceCustomerFlowDelete'])) {
+	if (hasPerm(['bizServiceCustomerFlowCancel'])) {
 		columns.push({
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 100
 		})
 	}
-	const selectedRowKeys = ref([])
-	// 列表选择配置
-	const options = {
-		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
-		alert: {
-			show: true,
-			clear: () => {
-				selectedRowKeys.value = ref([])
-			}
-		},
-		rowSelection: {
-			onChange: (selectedRowKey, selectedRows) => {
-				selectedRowKeys.value = selectedRowKey
-			}
+	// 打开抽屉
+	const onOpen = (record, scId) => {
+		recordData.value = record
+		title.value = "【" + record.loginAccount + "】-账户流水管理"
+		searchFormState.value = {
+			serviceCustomerId: scId,
+			scAccountId: record.id
 		}
+		serviceCustomerId.value = scId
+		scAccountId.value = record.id
+		visible.value = true
 	}
 	const loadData = (parameter) => {
-		return bizServiceCustomerFlowApi.bizServiceCustomerFlowPage(parameter).then((data) => {
+		return bizServiceCustomerFlowApi.bizServiceCustomerFlowPage(Object.assign(parameter, searchFormState.value)).then((data) => {
 			return data
 		})
 	}
-	// 重置
-	const reset = () => {
-		searchFormRef.value.resetFields()
-		tableRef.value.refresh(true)
+	// 关闭抽屉
+	const onClose = () => {
+		visible.value = false
 	}
 	// 删除
-	const deleteBizServiceCustomerFlow = (record) => {
-		let params = [
-			{
-				id: record.id
-			}
-		]
-		bizServiceCustomerFlowApi.bizServiceCustomerFlowDelete(params).then(() => {
-			tableRef.value.refresh(true)
-		})
-	}
-	// 批量删除
-	const deleteBatchBizServiceCustomerFlow = (params) => {
-		bizServiceCustomerFlowApi.bizServiceCustomerFlowDelete(params).then(() => {
-			tableRef.value.clearRefreshSelected()
+	const deleteConfig = (record) => {
+		Modal.confirm({
+			title: '确定删除该数据吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params = [
+					{
+						id: record.id
+					}
+				]
+
+				bizServiceCustomerFlowApi
+					.bizServiceCustomerFlowDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
 		})
 	}
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
 </script>

+ 23 - 6
snowy-admin-web/src/views/biz/bizservicecustomer/index.vue

@@ -36,23 +36,32 @@
 						<a @click="formRef.onOpen(record)" v-if="hasPerm('bizServiceCustomerEdit')">编辑</a>
 						<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerEdit', 'bizServiceCustomerDelete'], 'and')" />
 						<a-button type="link" danger size="small" v-if="hasPerm('bizServiceCustomerDelete')" @click="deleteConfig(record)">删除</a-button>
+					
+						<a-divider type="vertical" v-if="hasPerm(['bizServiceCustomerEdit', 'bizServiceCustomerDelete'], 'or') && hasPerm('bizServiceCustomerAccount')" />
+						<a @click="accountIndexRef.onOpen(record)" v-if="hasPerm('bizServiceCustomerAccount')">账户管理</a>
 					</a-space>
 				</template>
 			</template>
 		</s-table>
 	</a-card>
 	<Form ref="formRef" @successful="tableRef.refresh()" />
+	<AccountIndex ref="accountIndexRef" @successful="tableRef.refresh()" />
 </template>
 
 <script setup name="bizservicecustomer">
 	import { cloneDeep } from 'lodash-es'
 	import Form from './form.vue'
+	import AccountIndex from './accountIndex.vue'
 	import bizServiceCustomerApi from '@/api/biz/bizServiceCustomerApi'
+	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 accountIndexRef = ref()
 	const submitLoading = ref(false)
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
 	const columns = [
@@ -64,33 +73,41 @@
 		},
 		{
 			title: '客户名称',
-			dataIndex: 'name'
+			width: 180,
+			dataIndex: 'name',
+			align: 'center'
 		},
 		{
 			title: '联系人',
-			dataIndex: 'contact'
+			width: 180,
+			dataIndex: 'contact',
+			align: 'center'
 		},
 		{
 			title: '手机号',
-			dataIndex: 'phone'
+			width: 180,
+			dataIndex: 'phone',
+			align: 'center'
 		},
 		{
 			title: '客户地址',
-			dataIndex: 'address'
+			dataIndex: 'address',
+			align: 'center'
 		},
 		{
 			title: '创建时间',
+			width: 180,
 			dataIndex: 'createTime',
 			align: 'center'
 		},
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizServiceCustomerEdit', 'bizServiceCustomerDelete'])) {
+	if (hasPerm(['bizServiceCustomerEdit', 'bizServiceCustomerDelete', 'bizServiceCustomerAccount'], 'or')) {
 		columns.push({
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 260
 		})
 	}
 

+ 2 - 2
snowy-admin-web/src/views/biz/bizsupplier/accountIndex.vue

@@ -113,8 +113,8 @@
 					}
 				]
 
-				bizLoadTimeApi
-					.bizLoadTimeDelete(params)
+				bizSupplierAccountApi
+					.bizSupplierAccountDelete(params)
 					.then(() => {
 						tableRef.value.refresh(true)
 					})

+ 1 - 0
snowy-admin-web/src/views/biz/bizsupplier/index.vue

@@ -108,6 +108,7 @@
 		},
 		{
 			title: '创建时间',
+			width: 180,
 			dataIndex: 'createTime',
 			align: 'center'
 		},

+ 2 - 2
snowy-admin-web/src/views/biz/bizsupplier/transportIndex.vue

@@ -121,8 +121,8 @@
 					}
 				]
 
-				bizLoadTimeApi
-					.bizLoadTimeDelete(params)
+				bizSupplierTransportApi
+					.bizSupplierTransportDelete(params)
 					.then(() => {
 						tableRef.value.refresh(true)
 					})

+ 16 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/controller/BizServiceCustomerFlowController.java

@@ -21,13 +21,10 @@ 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.biz.modular.bizservicecustomer.param.*;
 import vip.xiaonuo.common.annotation.CommonLog;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.biz.modular.bizservicecustomer.entity.BizServiceCustomerFlow;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowAddParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowEditParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowIdParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowPageParam;
 import vip.xiaonuo.biz.modular.bizservicecustomer.service.BizServiceCustomerFlowService;
 
 import jakarta.annotation.Resource;
@@ -76,6 +73,21 @@ public class BizServiceCustomerFlowController {
         return CommonResult.ok();
     }
 
+    /**
+     * 取消服务客户资金流水
+     *
+     * @author sandy
+     * @date  2025/06/03 17:40
+     */
+    @Operation(summary = "取消服务客户资金流水")
+    @CommonLog("取消服务客户资金流水")
+    @SaCheckPermission("/biz/bizservicecustomerflow/cancel")
+    @PostMapping("/biz/bizservicecustomerflow/cancel")
+    public CommonResult<String> cancel(@RequestBody @Valid BizServiceCustomerFlowCancelParam bizServiceCustomerFlowCancelParam) {
+        bizServiceCustomerFlowService.cancel(bizServiceCustomerFlowCancelParam);
+        return CommonResult.ok();
+    }
+
     /**
      * 编辑服务客户资金流水
      *

+ 3 - 3
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/entity/BizServiceCustomerAccount.java

@@ -36,9 +36,9 @@ public class BizServiceCustomerAccount extends CommonEntity {
     @Schema(description = "主键ID")
     private String id;
 
-    /** 客户id */
-    @Schema(description = "客户id")
-    private String customerId;
+    /** 服务客户id */
+    @Schema(description = "服务客户id")
+    private String serviceCustomerId;
 
     /** 账号 */
     @Schema(description = "账号")

+ 15 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/entity/BizServiceCustomerFlow.java

@@ -38,10 +38,14 @@ public class BizServiceCustomerFlow extends CommonEntity {
 
     /** 服务客户id */
     @Schema(description = "服务客户id")
-    private String customerAccountId;
+    private String serviceCustomerId;
+
+    /** 服务客户账户id */
+    @Schema(description = "服务客户账户id")
+    private String scAccountId;
 
     /** 操作类型  1:充值   2:消费 */
-    @Schema(description = "操作类型  1:充值   2:消费")
+    @Schema(description = "操作类型")
     private String operateType;
 
     /** 操作前账户余额(充值或消费前账户余额) */
@@ -55,4 +59,13 @@ public class BizServiceCustomerFlow extends CommonEntity {
     /** 操作后账户余额(充值或消费后账户余额) */
     @Schema(description = "操作后账户余额(充值或消费后账户余额)")
     private BigDecimal operateAmountAfter;
+
+    /** 操作状态   0正常    1取消 */
+    @Schema(description = "操作类型")
+    private String operateStatus;
+
+    /** 取消说明 */
+    @Schema(description = "取消说明")
+    private String operateExplain;
+
 }

+ 5 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/param/BizServiceCustomerFlowAddParam.java

@@ -30,7 +30,11 @@ public class BizServiceCustomerFlowAddParam {
 
     /** 服务客户id */
     @Schema(description = "服务客户id")
-    private String customerAccountId;
+    private String serviceCustomerId;
+
+    /** 服务客户账户id */
+    @Schema(description = "服务客户账户id")
+    private String scAccountId;
 
     /** 操作类型  1:充值   2:消费 */
     @Schema(description = "操作类型  1:充值   2:消费")

+ 42 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/param/BizServiceCustomerFlowCancelParam.java

@@ -0,0 +1,42 @@
+/*
+ * 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.bizservicecustomer.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 服务客户资金流水编辑参数
+ *
+ * @author fanzherong
+ * @date  2025/05/29 14:40
+ **/
+@Getter
+@Setter
+public class BizServiceCustomerFlowCancelParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 取消说明 */
+    @Schema(description = "取消说明")
+    private String operateExplain;
+
+
+}

+ 9 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/BizServiceCustomerFlowService.java

@@ -15,10 +15,7 @@ package vip.xiaonuo.biz.modular.bizservicecustomer.service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import vip.xiaonuo.biz.modular.bizservicecustomer.entity.BizServiceCustomerFlow;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowAddParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowEditParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowIdParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowPageParam;
+import vip.xiaonuo.biz.modular.bizservicecustomer.param.*;
 
 import java.util.List;
 
@@ -46,6 +43,14 @@ public interface BizServiceCustomerFlowService extends IService<BizServiceCustom
      */
     void add(BizServiceCustomerFlowAddParam bizServiceCustomerFlowAddParam);
 
+    /**
+     * 添加服务客户资金流水
+     *
+     * @author fanzherong
+     * @date  2025/05/29 14:40
+     */
+    void cancel(BizServiceCustomerFlowCancelParam bizServiceCustomerFlowCancelParam);
+
     /**
      * 编辑服务客户资金流水
      *

+ 87 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/impl/BizServiceCustomerFlowServiceImpl.java

@@ -19,19 +19,22 @@ 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 io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.bizservicecustomer.entity.BizServiceCustomerAccount;
+import vip.xiaonuo.biz.modular.bizservicecustomer.param.*;
+import vip.xiaonuo.biz.modular.bizservicecustomer.service.BizServiceCustomerAccountService;
+import vip.xiaonuo.biz.modular.goods.service.BizGoodsService;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.biz.modular.bizservicecustomer.entity.BizServiceCustomerFlow;
 import vip.xiaonuo.biz.modular.bizservicecustomer.mapper.BizServiceCustomerFlowMapper;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowAddParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowEditParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowIdParam;
-import vip.xiaonuo.biz.modular.bizservicecustomer.param.BizServiceCustomerFlowPageParam;
 import vip.xiaonuo.biz.modular.bizservicecustomer.service.BizServiceCustomerFlowService;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -43,6 +46,10 @@ import java.util.List;
 @Service
 public class BizServiceCustomerFlowServiceImpl extends ServiceImpl<BizServiceCustomerFlowMapper, BizServiceCustomerFlow> implements BizServiceCustomerFlowService {
 
+    @Resource
+    private BizServiceCustomerAccountService accountService;
+
+
     @Override
     public Page<BizServiceCustomerFlow> page(BizServiceCustomerFlowPageParam bizServiceCustomerFlowPageParam) {
         QueryWrapper<BizServiceCustomerFlow> queryWrapper = new QueryWrapper<BizServiceCustomerFlow>().checkSqlInjection();
@@ -60,7 +67,83 @@ public class BizServiceCustomerFlowServiceImpl extends ServiceImpl<BizServiceCus
     @Override
     public void add(BizServiceCustomerFlowAddParam bizServiceCustomerFlowAddParam) {
         BizServiceCustomerFlow bizServiceCustomerFlow = BeanUtil.toBean(bizServiceCustomerFlowAddParam, BizServiceCustomerFlow.class);
+        // 计算 获取当前账户的余额
+        BizServiceCustomerAccount account = accountService.getById(bizServiceCustomerFlow.getScAccountId());
+        /** 可用余额(账户余额) */
+        BigDecimal accountAmount = BigDecimal.ZERO;
+        /** 充值总余额 */
+        BigDecimal rechargeAmount = BigDecimal.ZERO;
+        /** 消费总金额 */
+        BigDecimal consumptionAmount = BigDecimal.ZERO;
+
+        if(null != account){
+            accountAmount = account.getAccountAmount();
+            rechargeAmount = account.getRechargeAmount();
+            consumptionAmount = account.getConsumptionAmount();
+        }else{
+            throw new CommonException("服务客户账户不存在!");
+        }
+        bizServiceCustomerFlow.setOperateAmountBegin(accountAmount);
+        if("1".equals(bizServiceCustomerFlow.getOperateType())){
+            // 充值
+            rechargeAmount = rechargeAmount.add(bizServiceCustomerFlow.getOperateAmount());
+            accountAmount = accountAmount.add(bizServiceCustomerFlow.getOperateAmount());
+        }else{
+            consumptionAmount = consumptionAmount.add(bizServiceCustomerFlow.getOperateAmount());
+            accountAmount = accountAmount.subtract(bizServiceCustomerFlow.getOperateAmount());
+        }
+        bizServiceCustomerFlow.setOperateAmountAfter(accountAmount);
         this.save(bizServiceCustomerFlow);
+
+        // 更新账户信息
+        account.setAccountAmount(accountAmount);
+        account.setRechargeAmount(rechargeAmount);
+        account.setConsumptionAmount(consumptionAmount);
+        accountService.updateById(account);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void cancel(BizServiceCustomerFlowCancelParam bizServiceCustomerFlowCancelParam) {
+        BizServiceCustomerFlow bizServiceCustomerFlow = this.queryEntity(bizServiceCustomerFlowCancelParam.getId());
+        // 计算 获取当前账户的余额
+        BizServiceCustomerAccount account = accountService.getById(bizServiceCustomerFlow.getScAccountId());
+        /** 可用余额(账户余额) */
+        BigDecimal accountAmount = BigDecimal.ZERO;
+        /** 充值总余额 */
+        BigDecimal rechargeAmount = BigDecimal.ZERO;
+        /** 消费总金额 */
+        BigDecimal consumptionAmount = BigDecimal.ZERO;
+
+        if(null != account){
+            accountAmount = account.getAccountAmount();
+            rechargeAmount = account.getRechargeAmount();
+            consumptionAmount = account.getConsumptionAmount();
+        }else{
+            throw new CommonException("服务客户账户不存在!");
+        }
+        if("1".equals(bizServiceCustomerFlow.getOperateType())){
+            // 充值
+            rechargeAmount = rechargeAmount.subtract(bizServiceCustomerFlow.getOperateAmount());
+            accountAmount = accountAmount.subtract(bizServiceCustomerFlow.getOperateAmount());
+        }else{
+            consumptionAmount = consumptionAmount.subtract(bizServiceCustomerFlow.getOperateAmount());
+            accountAmount = accountAmount.add(bizServiceCustomerFlow.getOperateAmount());
+        }
+        // 判断
+        if(accountAmount.compareTo(BigDecimal.ZERO) < 0){
+            throw new CommonException("服务客户账户余额不支持取消本次充值!");
+        }
+        // 更新账户信息
+        account.setAccountAmount(accountAmount);
+        account.setRechargeAmount(rechargeAmount);
+        account.setConsumptionAmount(consumptionAmount);
+        accountService.updateById(account);
+
+        // 更新流水数据为取消状态
+        bizServiceCustomerFlow.setOperateStatus("1");
+        bizServiceCustomerFlow.setOperateExplain(bizServiceCustomerFlowCancelParam.getOperateExplain());
+        this.updateById(bizServiceCustomerFlow);
     }
 
     @Transactional(rollbackFor = Exception.class)

+ 13 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizservicecustomer/service/impl/BizServiceCustomerServiceImpl.java

@@ -15,6 +15,7 @@ package vip.xiaonuo.biz.modular.bizservicecustomer.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.PhoneUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -59,6 +60,12 @@ public class BizServiceCustomerServiceImpl extends ServiceImpl<BizServiceCustome
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void add(BizServiceCustomerAddParam bizServiceCustomerAddParam) {
+        //校验手机号格式
+        if(ObjectUtil.isNotEmpty(bizServiceCustomerAddParam.getPhone())){
+            if(!PhoneUtil.isMobile(bizServiceCustomerAddParam.getPhone())) {
+                throw new CommonException("手机号码:{}格式错误", bizServiceCustomerAddParam.getPhone());
+            }
+        }
         BizServiceCustomer bizServiceCustomer = BeanUtil.toBean(bizServiceCustomerAddParam, BizServiceCustomer.class);
         this.save(bizServiceCustomer);
     }
@@ -66,6 +73,12 @@ public class BizServiceCustomerServiceImpl extends ServiceImpl<BizServiceCustome
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void edit(BizServiceCustomerEditParam bizServiceCustomerEditParam) {
+        //校验手机号格式
+        if(ObjectUtil.isNotEmpty(bizServiceCustomerEditParam.getPhone())){
+            if(!PhoneUtil.isMobile(bizServiceCustomerEditParam.getPhone())) {
+                throw new CommonException("手机号码:{}格式错误", bizServiceCustomerEditParam.getPhone());
+            }
+        }
         BizServiceCustomer bizServiceCustomer = this.queryEntity(bizServiceCustomerEditParam.getId());
         BeanUtil.copyProperties(bizServiceCustomerEditParam, bizServiceCustomer);
         this.updateById(bizServiceCustomer);