fanzherong_v 2 ヶ月 前
コミット
e927a94477
61 ファイル変更1623 行追加90 行削除
  1. 2 1
      snowy-admin-web/index.html
  2. BIN
      snowy-admin-web/public/img/login_background2.png
  3. BIN
      snowy-admin-web/public/img/tanglogo1.png
  4. 28 0
      snowy-admin-web/src/api/biz/bizDisableRecordApi.js
  5. 15 1
      snowy-admin-web/src/api/biz/bizUserApi.js
  6. 2 2
      snowy-admin-web/src/components/XnRoleSelector/index.vue
  7. 2 2
      snowy-admin-web/src/views/auth/login/login.less
  8. 1 1
      snowy-admin-web/src/views/auth/login/login.vue
  9. 3 3
      snowy-admin-web/src/views/biz/consumptionrecord/index.vue
  10. 4 11
      snowy-admin-web/src/views/biz/couponrecord/index.vue
  11. 96 0
      snowy-admin-web/src/views/biz/member/addUser.vue
  12. 5 5
      snowy-admin-web/src/views/biz/member/consumption.vue
  13. 104 0
      snowy-admin-web/src/views/biz/member/disable.vue
  14. 8 8
      snowy-admin-web/src/views/biz/member/form.vue
  15. 140 0
      snowy-admin-web/src/views/biz/member/impExp.vue
  16. 29 6
      snowy-admin-web/src/views/biz/member/index.vue
  17. 3 3
      snowy-admin-web/src/views/biz/org/index.vue
  18. 1 1
      snowy-admin-web/src/views/biz/rebaterecord/index.vue
  19. 27 1
      snowy-admin-web/src/views/biz/rechargeplanconfig/form.vue
  20. 36 4
      snowy-admin-web/src/views/biz/rechargeplanconfig/index.vue
  21. 5 5
      snowy-admin-web/src/views/biz/rechargerecord/form.vue
  22. 2 2
      snowy-admin-web/src/views/biz/rechargerecord/index.vue
  23. 2 2
      snowy-admin-web/src/views/biz/statisty/total.vue
  24. 43 1
      snowy-admin-web/src/views/biz/warn/index.vue
  25. 3 3
      snowy-admin-web/src/views/sys/org/index.vue
  26. 2 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/consumptionrecord/mapper/mapping/ConsumptionRecordMapper.xml
  27. 12 6
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/consumptionrecord/service/impl/ConsumptionRecordServiceImpl.java
  28. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/entity/BizCouponRecord.java
  29. 6 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/mapper/BizCouponRecordMapper.java
  30. 32 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/mapper/mapping/BizCouponRecordMapper.xml
  31. 2 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/param/BizCouponRecordPageParam.java
  32. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/service/BizCouponRecordService.java
  33. 19 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/service/impl/BizCouponRecordServiceImpl.java
  34. 123 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/controller/BizDisableRecordController.java
  35. 64 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/entity/BizDisableRecord.java
  36. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/enums/BizDisableRecordEnum.java
  37. 30 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/mapper/BizDisableRecordMapper.java
  38. 17 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/mapper/mapping/BizDisableRecordMapper.xml
  39. 50 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordAddParam.java
  40. 55 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordEditParam.java
  41. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordIdParam.java
  42. 53 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordPageParam.java
  43. 80 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/service/BizDisableRecordService.java
  44. 99 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/service/impl/BizDisableRecordServiceImpl.java
  45. 11 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/controller/BizRechargePlanConfigController.java
  46. 6 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/entity/BizRechargePlanConfig.java
  47. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/mapper/BizRechargePlanConfigMapper.java
  48. 17 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/mapper/mapping/BizRechargePlanConfigMapper.xml
  49. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigAddParam.java
  50. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigEditParam.java
  51. 2 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigPageParam.java
  52. 7 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/service/impl/BizRechargePlanConfigServiceImpl.java
  53. 4 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargerecord/mapper/mapping/BizRechargeRecordMapper.xml
  54. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargerecord/service/impl/BizRechargeRecordServiceImpl.java
  55. 36 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/controller/BizUserController.java
  56. 13 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/param/BizUserAddParam.java
  57. 20 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/param/BizUserImport.java
  58. 11 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/service/BizUserService.java
  59. 197 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/service/impl/BizUserServiceImpl.java
  60. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/wx/WxPayNotifyController.java
  61. BIN
      snowy-plugin/snowy-plugin-biz/src/main/resources/user.xlsx

+ 2 - 1
snowy-admin-web/index.html

@@ -4,7 +4,8 @@
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
-  <link rel="icon" href="/favicon.ico">
+<!--  <link rel="icon" href="/favicon.ico">-->
+	<link rel="icon" href="/img/tanglogo1.png">
   <title>Snowy</title>
   <style>
     .dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1677FF;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}

BIN
snowy-admin-web/public/img/login_background2.png


BIN
snowy-admin-web/public/img/tanglogo1.png


+ 28 - 0
snowy-admin-web/src/api/biz/bizDisableRecordApi.js

@@ -0,0 +1,28 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/disablerecord/` + url, ...arg)
+
+/**
+ * 清除记录Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+export default {
+	// 获取清除记录分页
+	bizDisableRecordPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交清除记录表单 edit为true时为编辑,默认为新增
+	bizDisableRecordSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除清除记录
+	bizDisableRecordDelete(data) {
+		return request('delete', data)
+	},
+	// 获取清除记录详情
+	bizDisableRecordDetail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 15 - 1
snowy-admin-web/src/api/biz/bizUserApi.js

@@ -42,6 +42,10 @@ export default {
 	userDisableUser(data) {
 		return request('disableUser', data)
 	},
+	// 禁用人员
+	userDisableCustomer(data) {
+		return request('disableCustomer', data)
+	},
 	// 启用人员
 	userEnableUser(data) {
 		return request('enableUser', data)
@@ -85,5 +89,15 @@ export default {
 		return request('exportUserInfo', data, 'get', {
 			responseType: 'blob'
 		})
-	}
+	},
+	// 下载导入模板
+	downloadImportTemplate(data) {
+		return request('down', data, 'get', {
+			responseType: 'blob'
+		})
+	},
+	// 导入
+	itemImport(data) {
+		return request('import', data)
+	},
 }

+ 2 - 2
snowy-admin-web/src/components/XnRoleSelector/index.vue

@@ -1,9 +1,9 @@
 <template>
 	<!-- 这是引入后展示的样式 -->
 	<div v-if="props.show">
-		<a-tag v-for="data in dataArray" closable @close="deleteObj(data)" :key="data.id" class="mb-1">{{
+<!--		<a-tag v-for="data in dataArray" closable @close="deleteObj(data)" :key="data.id" class="mb-1">{{
 			data.name
-		}}</a-tag>
+		}}</a-tag>-->
 		<a-button
 			type="primary"
 			size="small"

+ 2 - 2
snowy-admin-web/src/views/auth/login/login.less

@@ -19,8 +19,8 @@
 	height: 100%;
 	overflow: hidden;
 	background-size: cover;
-	background-position: center;
-	background-image: url(/img/login_background.png);
+	background-position: left center;
+	background-image: url(/img/login_background2.png);
 	position: relative;
 }
 @keyframes myfirst {

+ 1 - 1
snowy-admin-web/src/views/auth/login/login.vue

@@ -8,7 +8,7 @@
 					target="_blank"
 					@click="handleLink"
 				>
-					<img :alt="sysBaseConfig.SNOWY_SYS_NAME" src="/img/logo.png" />
+<!--					<img :alt="sysBaseConfig.SNOWY_SYS_NAME" src="/img/logo.png" />-->
 				</a>
 			</div>
 		</div>

+ 3 - 3
snowy-admin-web/src/views/biz/consumptionrecord/index.vue

@@ -147,17 +147,17 @@
 			align: 'center',
 		},
 		{
-			title: '原账户余额',
+			title: '原账户糕点',
 			dataIndex: 'accountBalance',
 			align: 'center',
 		},
 		{
-			title: '原代金券余额',
+			title: '原账户积分',
 			dataIndex: 'voucherBalance',
 			align: 'center',
 		},
 		{
-			title: '消费金额',
+			title: '消费糕点或积分',
 			dataIndex: 'consumptionMoney',
 			align: 'center',
 		},

+ 4 - 11
snowy-admin-web/src/views/biz/couponrecord/index.vue

@@ -3,8 +3,8 @@
 		<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="couponNo">
-						<a-input v-model:value="searchFormState.couponNo" placeholder="优惠券编码查询" />
+					<a-form-item label="蛋糕券编码" name="couponNo">
+						<a-input v-model:value="searchFormState.couponNo" placeholder="蛋糕券编码查询" />
 					</a-form-item>
 				</a-col>
 				<a-col :span="6">
@@ -33,13 +33,6 @@
 						<template #icon><plus-outlined /></template>
 						新增
 					</a-button>
-					<xn-batch-button
-						v-if="hasPerm('bizCouponRecordBatchDelete')"
-						buttonName="批量删除"
-                        icon="DeleteOutlined"
-						:selectedRowKeys="selectedRowKeys"
-						@batchCallBack="deleteBatchBizCouponRecord"
-					/>
 				</a-space>
 			</template>
 			<template #bodyCell="{ column, record , index }">
@@ -93,13 +86,13 @@
 			width: 50
 		},
 		{
-			title: '优惠券编码',
+			title: '蛋糕券编码',
 			dataIndex: 'couponNo',
 			align: 'center',
 			width: 200
 		},
 		{
-			title: '优惠券生成时间',
+			title: '蛋糕券生成时间',
 			dataIndex: 'time',
 			align: 'center',
 			width: 150

+ 96 - 0
snowy-admin-web/src/views/biz/member/addUser.vue

@@ -0,0 +1,96 @@
+<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" :label-col="labelCol" :wrapper-col="wrapperCol">
+			<a-form-item label="姓名:" name="name">
+				<a-input v-model:value="formData.name" placeholder="请输入姓名" allow-clear />
+			</a-form-item>
+			<a-form-item label="手机号:" name="phone">
+				<a-input v-model:value="formData.phone" placeholder="请输入手机号" allow-clear @blur="onBlur"/>
+			</a-form-item>
+			<a-form-item label="糕点:" name="accountBalance">
+				<a-input-number v-model:value="formData.accountBalance" placeholder="请输入糕点" allow-clear :min="0" :max="99999999" style="width:100%"/>
+			</a-form-item>
+			<a-form-item label="积分:" name="voucherBalance">
+				<a-input-number v-model:value="formData.voucherBalance" placeholder="请输入积分" allow-clear :min="0" :max="99999999" style="width:100%"/>
+			</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="consumptionRecordForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizUserApi from '@/api/biz/bizUserApi'
+	// 抽屉状态
+	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: 18 })
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+
+	const onBlur = () => {
+		console.log(formData.value.phone)
+		formData.value.account = formData.value.phone
+		formData.value.orgId = '1543842934270394368'
+		formData.value.userType = '3'
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		name: [required('请输入姓名')],
+		phone: [required('请输入手机号')],
+		/*accountBalance: [required('请输入糕点')],
+		voucherBalance: [required('请输入积分')],*/
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizUserApi
+					.submitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 5 - 5
snowy-admin-web/src/views/biz/member/consumption.vue

@@ -10,14 +10,14 @@
 			<a-form-item label="会员姓名:" name="name">
 				<a-input v-model:value="formData.name" placeholder="请输入会员姓名" disabled allow-clear />
 			</a-form-item>
-			<a-form-item label="账户余额:" name="accountBalance">
+			<a-form-item label="糕点:" name="accountBalance">
 				<a-input v-model:value="formData.accountBalance" placeholder="请输入账户余额" disabled allow-clear />
 			</a-form-item>
-			<a-form-item label="代金券余额:" name="voucherBalance">
+			<a-form-item label="积分:" name="voucherBalance">
 				<a-input v-model:value="formData.voucherBalance" placeholder="请输入代金券余额" disabled allow-clear />
 			</a-form-item>
-			<a-form-item label="消费金额:" name="consumptionMoney">
-				<a-input-number v-model:value="formData.consumptionMoney" placeholder="请输入消费金额" allow-clear :min="0.1" :max="formData.accountBalance+formData.voucherBalance" style="width:100%"/>
+			<a-form-item label="消费糕点或积分:" name="consumptionMoney">
+				<a-input-number v-model:value="formData.consumptionMoney" placeholder="请输入消费糕点或积分" allow-clear :min="0.1" :max="formData.accountBalance+formData.voucherBalance" style="width:100%"/>
 			</a-form-item>
 			<a-form-item label="手机号:" name="phoneNumber">
 				<a-input v-model:value="formData.phoneNumber" placeholder="请输入手机号" disabled allow-clear style="width:100%"/>
@@ -85,7 +85,7 @@
 	// 默认要校验的
 	const formRules = {
 		name: [required('请输入消费者姓名')],
-		consumptionMoney: [required('请输入消费金额')],
+		consumptionMoney: [required('请输入消费糕点或积分')],
 		accountBalance:  [required('请输入账户余额')],
 		voucherBalance:  [required('请输入代金券余额')],
 		phoneNumber:  [required('请输入手机号')],

+ 104 - 0
snowy-admin-web/src/views/biz/member/disable.vue

@@ -0,0 +1,104 @@
+<template>
+	<xn-form-container
+		title="详情"
+		:width="1000"
+		:visible="visible"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+
+		<a-form ref="formRef" :model="formData" layout="vertical">
+			<s-table
+				ref="tableRef"
+				:columns="columns"
+				:data="loadData"
+				:alert="false"
+				:showPagination="true"
+				bordered
+				:row-key="(record) => record.id"
+			>
+				<template #bodyCell="{ column, record }">
+					<template v-if="column.dataIndex === 'couponCode'">
+
+					</template>
+				</template>
+			</s-table>
+
+		</a-form>
+	</xn-form-container>
+</template>
+
+<script setup name="messageDetail">
+	import bizDisableRecordApi from '@/api/biz/bizDisableRecordApi'
+	import {cloneDeep} from "lodash-es";
+	const receiveInfoList = ref([])
+	const emit = defineEmits({ successful: null })
+
+	// 默认是关闭状态
+	const visible = ref(false)
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const tableRef = ref()
+	const columns = [
+		{
+			title: '姓名',
+			dataIndex: 'userName',
+			align: 'center',
+		},
+		{
+			title: '手机号',
+			dataIndex: 'phone',
+			align: 'center',
+		},
+		{
+			title: '冻结糕点',
+			dataIndex: 'accountBalance',
+			align: 'center',
+		},
+		{
+			title: '冻结积分',
+			dataIndex: 'voucherBalance',
+			align: 'center',
+		},
+		{
+			title: '冻结蛋糕券',
+			dataIndex: 'couponCode',
+			align: 'center',
+			ellipsis: true,
+			width:200
+		},
+		{
+			title: '冻结时间',
+			dataIndex: 'createTime',
+			align: 'center',
+		},
+	]
+	// 打开抽屉
+	const onOpen = (record) => {
+		visible.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+
+	const loadData = () => {
+		let param = {
+			userId: formData.value.id,
+		}
+		return bizDisableRecordApi.bizDisableRecordPage(param).then((res) => {
+			return res
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		receiveInfoList.value = []
+		visible.value = false
+		emit('successful')
+	}
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
+</script>

+ 8 - 8
snowy-admin-web/src/views/biz/member/form.vue

@@ -10,10 +10,10 @@
 			<a-form-item label="会员姓名:" name="name">
 				<a-input v-model:value="formData.name" placeholder="请输入会员姓名" disabled allow-clear />
 			</a-form-item>
-			<a-form-item label="账户余额:" name="accountBalance">
+			<a-form-item label="糕点:" name="accountBalance">
 				<a-input v-model:value="formData.accountBalance" placeholder="请输入账户余额" disabled allow-clear />
 			</a-form-item>
-			<a-form-item label="代金券余额:" name="voucherBalance">
+			<a-form-item label="积分:" name="voucherBalance">
 				<a-input v-model:value="formData.voucherBalance" placeholder="请输入代金券余额" disabled allow-clear />
 			</a-form-item>
 			<a-form-item label="调整操作:" name="consumptionOperate">
@@ -42,15 +42,15 @@
 			<a-form-item label="调整方式:" name="consumptionType">
 				<a-radio-group button-style="solid" v-model:value="formData.consumptionType">
 					<a-radio-button value="1">
-						代金券
+						积分
 					</a-radio-button>
 					<a-radio-button value="2">
-						余额
+						糕点
 					</a-radio-button>
 				</a-radio-group>
 			</a-form-item>
-			<a-form-item label="调整金额:" name="consumptionMoney">
-				<a-input-number v-model:value="formData.consumptionMoney" placeholder="请输入调整金额" allow-clear :min="0.1" :max="99999999" style="width:100%"/>
+			<a-form-item label="调整糕点或积分:" name="consumptionMoney">
+				<a-input-number v-model:value="formData.consumptionMoney" placeholder="请输入调整糕点或积分" allow-clear :min="0.1" :max="99999999" style="width:100%"/>
 			</a-form-item>
 			<a-form-item label="说明:" name="consumptionRemark">
 				<a-input v-model:value="formData.consumptionRemark" placeholder="请输入说明" allow-clear />
@@ -130,7 +130,7 @@
 		name: [required('请输入消费者姓名')],
 		consumptionOperate:  [required('请选择调整操作')],
 		consumptionType: [required('请选择调整方式')],
-		consumptionMoney: [required('请输入调整金额')],
+		consumptionMoney: [required('请输入调整糕点或积分')],
 		consumptionRemark: [required('请输入说明')],
 		accountBalance:  [required('请输入账户余额')],
 		voucherBalance:  [required('请输入代金券余额')],
@@ -140,7 +140,7 @@
 	//title: '确定要为'+formData.value.name+(formData.value.consumptionOperate=='1'?'赠送':'扣减')+(formData.value.consumptionType=='1'?'代金券':'余额')+formData.value.consumptionMoney+'元吗?',
 	const onSubmit = () => {
 		Modal.confirm({
-			title: '确定要为'+formData.value.name+(formData.value.consumptionOperate=='1'?'赠送':'扣减')+(formData.value.consumptionType=='1'?'代金券':'余额')+formData.value.consumptionMoney+'元吗?',
+			title: '确定要为'+formData.value.name+(formData.value.consumptionOperate=='1'?'赠送':'扣减')+formData.value.consumptionMoney+(formData.value.consumptionType=='1'?'积分':'糕点')+'吗?',
 			icon: createVNode(ExclamationCircleOutlined),
 			content: '',
 			onOk() {

+ 140 - 0
snowy-admin-web/src/views/biz/member/impExp.vue

@@ -0,0 +1,140 @@
+<template>
+	<xn-form-container :destroy-on-close="true" :visible="visible" :width="700" title="导入" @close="onClose">
+		<span
+			>导入数据格式严格按照系统模板进行数据录入,请点击
+			<a-button size="small" type="primary" @click="downloadImportUserTemplate">下载模板</a-button>
+		</span>
+		<a-divider dashed />
+		<div>
+			<a-spin :spinning="impUploadLoading">
+				<a-upload-dragger :accept="uploadAccept" :custom-request="customRequestLocal" :show-upload-list="false">
+					<p class="ant-upload-drag-icon">
+						<inbox-outlined></inbox-outlined>
+					</p>
+					<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
+					<p class="ant-upload-hint">仅支持xls、xlsx格式文件</p>
+				</a-upload-dragger>
+			</a-spin>
+		</div>
+		 <a-alert v-if="impAlertStatus" :show-icon="false" banner class="mt-3" closable type="info" @close="onImpClose">
+			<template #description>
+				<p>导入总数:{{ impResultData.totalCount }} 条</p>
+				<p>导入成功:{{ impResultData.successCount }} 条</p>
+				<div v-if="impResultData.errorCount > 0">
+					<p><span style="color: red">失败条数:</span>{{ impResultData.errorCount }} 条</p>
+					<a-table :columns="impErrorColumns" :dataSource="impResultErrorDataSource" size="small" />
+				</div>
+			</template>
+		</a-alert>
+	</xn-form-container>
+</template>
+
+<script name="itemImpExp" setup>
+	import { message } from 'ant-design-vue'
+	import downloadUtil from '@/utils/downloadUtil'
+	import bizUserApi from '@/api/biz/bizUserApi'
+
+	const impUploadLoading = ref(false)
+	const impAlertStatus = ref(false)
+	const impResultData = ref({})
+	const impResultErrorDataSource = ref([])
+	const impAccept = [
+		{
+			extension: '.xls',
+			mimeType: 'application/vnd.ms-excel'
+		},
+		{
+			extension: '.xlsx',
+			mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+		}
+	]
+	// 指定能选择的文件类型
+	const uploadAccept = String(
+		impAccept.map((item) => {
+			return item.mimeType
+		})
+	)
+	// 导入
+	const customRequestLocal = (data) => {
+		impUploadLoading.value = true
+		const fileData = new FormData()
+		// 校验上传文件扩展名和文件类型是否为.xls、.xlsx
+		const extension = '.'.concat(data.file.name.split('.').slice(-1).toString().toLowerCase())
+		const mimeType = data.file.type
+		// 提取允许的扩展名
+		const extensionArr = impAccept.map((item) => item.extension)
+		// 提取允许的MIMEType
+		const mimeTypeArr = impAccept.map((item) => item.mimeType)
+		if (!extensionArr.includes(extension) || !mimeTypeArr.includes(mimeType)) {
+			message.warning('上传文件类型仅支持xls、xlsx格式文件!')
+			impUploadLoading.value = false
+			return false
+		}
+		fileData.append('file', data.file)
+		return bizUserApi
+			.itemImport(fileData)
+			.then((res) => {
+				impAlertStatus.value = true
+				impResultData.value = res
+				impResultErrorDataSource.value = res.errorDetail
+				emit('successful')
+			})
+			.finally(() => {
+				impUploadLoading.value = false
+			})
+	}
+	// 关闭导入提示
+	const onImpClose = () => {
+		console.log("关闭导入提示")
+		impAlertStatus.value = false
+	}
+	const impErrorColumns = [
+		{
+			title: '索引',
+			dataIndex: 'index',
+			width: '80px'
+		},
+		{
+			title: '原因',
+			dataIndex: 'msg'
+		}
+	]
+	// 定义emit事件
+	//const emit = defineEmits({ successful: null })
+	const emit = defineEmits(['itemImportBack'])
+	// 默认是关闭状态
+	let visible = ref(false)
+	const submitLoading = ref(false)
+
+	// 打开抽屉
+	const onOpen = () => {
+		visible.value = true
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		console.log("close")
+		visible.value = false
+		if (impAlertStatus.value === true) {
+			console.log("111")
+		}
+		emit('successful')
+		// 关闭导入的提示
+		onImpClose()
+	}
+	// 下载用户导入模板
+	const downloadImportUserTemplate = () => {
+		impUploadLoading.value = true
+		bizUserApi
+			.downloadImportTemplate()
+			.then((res) => {
+				downloadUtil.resultDownload(res)
+			})
+			.finally(() => {
+				impUploadLoading.value = false
+			})
+	}
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
+</script>

+ 29 - 6
snowy-admin-web/src/views/biz/member/index.vue

@@ -35,6 +35,18 @@
 	</a-card>
 	<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-button type="primary" @click="addUserRef.onOpen()" v-if="hasPerm('customerAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<a-button @click="ImpExpRef.onOpen()" style="margin-left:10px" v-if="hasPerm('customerImport')">
+						<template #icon><ImportOutlined /></template>
+						导入
+					</a-button>
+				</a-space>
+			</template>
 			<template #bodyCell="{ column, record, index }">
 				<template v-if="column.dataIndex === 'serial'">
 					{{ index + 1 }}
@@ -49,7 +61,7 @@
 						:loading="loading"
 						:checked="record.userStatus === 'ENABLE'"
 						@change="editStatus(record)"
-						v-if="hasPerm('bizUserUpdataStatus') && record.disableFlag == '1'"
+						v-if="hasPerm('bizUserUpdataStatus')"
 					/>
 					<a-tag v-else :color="record.userStatus === 'ENABLE' ? 'blue' : 'pink'">{{
 							$TOOL.dictTypeData('COMMON_STATUS', record.userStatus)
@@ -60,21 +72,32 @@
 					<a @click="formRef.onOpen(record)" v-if="hasPerm('bizUserEdit') && record.userStatus == 'ENABLE'">余额调整</a>
 					<a-divider type="vertical" v-if="hasPerm('bizUserConsumption') && record.userStatus == 'ENABLE'"/>
 					<a @click="consumptionRef.onOpen(record)" v-if="hasPerm('bizUserConsumption') && record.userStatus == 'ENABLE'">消费结算</a>
+<!--					<a-divider type="vertical" v-if="hasPerm('disableRecord') && record.userStatus == 'DISABLED'"/>-->
+					<a @click="disableRef.onOpen(record)" v-if="hasPerm('disableRecord') && record.userStatus == 'DISABLED'">冻结记录</a>
 				</template>
 			</template>
 		</s-table>
 	</a-card>
 	<Form ref="formRef" @successful="tableRef.refresh()" />
 	<Consumption ref="consumptionRef" @successful="tableRef.refresh()" />
+	<AddUserRef ref="addUserRef" @successful="tableRef.refresh()" />
+	<ImpExp ref="ImpExpRef" @successful="tableRef.refresh()" />
+	<DisableRef ref="disableRef" @successful="tableRef.refresh()" />
 </template>
 <script setup name="bizUser">
 	import tool from '@/utils/tool'
 	import bizUserApi from '@/api/biz/bizUserApi'
 	import Form from "./form.vue";
 	import Consumption from './consumption.vue'
+	import AddUserRef from './addUser.vue'
+	import ImpExp from './impExp.vue'
+	import DisableRef from './disable.vue'
 
 	const consumptionRef = ref()
 	const loading = ref(false)
+	const addUserRef = ref()
+	const ImpExpRef = ref()
+	const disableRef = ref()
 
 	const columns = [
 		{
@@ -96,12 +119,12 @@
 			width: 120,
 			align: 'center',
 		},
-		{
+		/*{
 			title: '性别',
 			dataIndex: 'gender',
 			align: 'center',
 			width: 80
-		},
+		},*/
 		{
 			title: '手机',
 			dataIndex: 'phone',
@@ -110,13 +133,13 @@
 			ellipsis: true
 		},
 		{
-			title: '账户余额',
+			title: '糕点',
 			dataIndex: 'accountBalance',
 			width: 80,
 			align: 'center',
 		},
 		{
-			title: '代金券余额',
+			title: '积分',
 			dataIndex: 'voucherBalance',
 			width: 80,
 			align: 'center',
@@ -158,7 +181,7 @@
 		loading.value = true
 		if (record.userStatus === 'ENABLE') {
 			bizUserApi
-				.userDisableUser(record)
+				.userDisableCustomer(record)
 				.then(() => {
 					tableRef.value.refresh()
 				})

+ 3 - 3
snowy-admin-web/src/views/biz/org/index.vue

@@ -128,12 +128,12 @@
 		{
 			title: '门店编码',
 			dataIndex: 'code',
-			width:150
+			width:120
 		},
 		{
 			title: '门店地址',
 			dataIndex: 'address',
-			width:200
+			width:180
 		},
 		{
 			title: '分类',
@@ -151,7 +151,7 @@
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 180
 		})
 	}
 	const selectedRowKeys = ref([])

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

@@ -80,7 +80,7 @@
 			align: 'center',
 		},
 		{
-			title: '返利金额(元)',
+			title: '返利积分(个)',
 			dataIndex: 'rebateAmout',
 			align: 'center',
 		},

+ 27 - 1
snowy-admin-web/src/views/biz/rechargeplanconfig/form.vue

@@ -7,6 +7,24 @@
 		@close="onClose"
 	>
 		<a-form ref="formRef" :model="formData" :rules="formRules" :label-col="{span: 5}">
+			<a-form-item label="充值门店" name="orgId">
+				<a-tree-select
+					v-model:value="formData.orgId"
+					style="width: 100%"
+					:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+					placeholder="请选择充值门店"
+					allow-clear
+					tree-default-expand-all
+					:tree-data="treeData"
+					:field-names="{
+									children: 'children',
+									label: 'name',
+									value: 'id'
+								}"
+					selectable="false"
+					tree-line
+				/>
+			</a-form-item>
 			<a-form-item label="充值金额及以上:" name="rechargeAmount">
 				<a-input-number v-model:value="formData.rechargeAmount" style="width: 100%" :min="0" :max="99999999"
 								:precision="2" placeholder="请输入充值金额及以上" allow-clear/>
@@ -39,6 +57,7 @@
 import {cloneDeep} from 'lodash-es'
 import {required} from '@/utils/formRules'
 import bizRechargePlanConfigApi from '@/api/biz/bizRechargePlanConfigApi'
+import bizOrgApi from '@/api/biz/bizOrgApi'
 // 抽屉状态
 const open = ref(false)
 const emit = defineEmits({successful: null})
@@ -46,6 +65,7 @@ const formRef = ref()
 // 表单数据
 const formData = ref({})
 const submitLoading = ref(false)
+const treeData = ref([])
 
 // 打开抽屉
 const onOpen = (record) => {
@@ -61,13 +81,19 @@ const onClose = () => {
 	formData.value = {}
 	open.value = false
 }
+
+// 获取机构树并加入顶级
+bizOrgApi.orgTreeSelector().then((res) => {
+	treeData.value = res
+})
 // 默认要校验的
 const formRules = {
 	rechargeAmount: [required('请输入充值金额及以上')],
 	couponAmount: [required('请输入优惠券金额')],
 	couponNum: [required('请输入优惠券数量')],
 	accountBalance: [required('请输入账户到账金额')],
-	rebateRatio: [required('请输入返点比例(代金券)')]
+	rebateRatio: [required('请输入返点比例(代金券)')],
+	orgId: [required('请选择充值门店')],
 }
 // 验证并提交数据
 const onSubmit = () => {

+ 36 - 4
snowy-admin-web/src/views/biz/rechargeplanconfig/index.vue

@@ -2,6 +2,26 @@
 	<a-card :bordered="false" class="xn-mb10">
 		<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
 			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="门店" name="orgId">
+						<a-tree-select
+							v-model:value="searchFormState.orgId"
+							style="width: 100%"
+							:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+							placeholder="请选择门店"
+							allow-clear
+							tree-default-expand-all
+							:tree-data="treeData"
+							:field-names="{
+									children: 'children',
+									label: 'name',
+									value: 'id'
+								}"
+							selectable="false"
+							tree-line
+						/>
+					</a-form-item>
+				</a-col>
 				<a-col :span="6">
 					<a-form-item name="status" label="状态">
 						<a-select v-model:value="searchFormState.status" placeholder="请选择">
@@ -92,6 +112,7 @@
 <script setup name="rechargeplanconfig">
 	import Form from './form.vue'
 	import bizRechargePlanConfigApi from '@/api/biz/bizRechargePlanConfigApi'
+	import bizOrgApi from '@/api/biz/bizOrgApi'
 	import tool from '@/utils/tool'
 	import { ref } from 'vue'
 	const searchFormRef = ref()
@@ -100,6 +121,7 @@
 	const formRef = ref()
 	const loading = ref(false)
 	const statusData = tool.dictList('COMMON_STATUS')
+	const treeData = ref([])
 	const columns = [
 		{
 			title: '序号',
@@ -107,28 +129,33 @@
 			width: 80,
 			align: 'center',
 		},
+		{
+			title: '门店',
+			dataIndex: 'orgName',
+			align: 'center',
+		},
 		{
 			title: '充值金额及以上(元)',
 			dataIndex: 'rechargeAmount',
 			align: 'center',
 		},
 		{
-			title: '优惠券金额(元)',
+			title: '蛋糕券金额(元)',
 			dataIndex: 'couponAmount',
 			align: 'center',
 		},
 		{
-			title: '优惠券数量',
+			title: '蛋糕券数量',
 			dataIndex: 'couponNum',
 			align: 'center',
 		},
 		{
-			title: '账户增加金额(元)',
+			title: '账户增加糕点(个)',
 			dataIndex: 'accountBalance',
 			align: 'center',
 		},
 		{
-			title: '返点比例(代金券)',
+			title: '返点比例(积分)',
 			dataIndex: 'rebateRatio',
 			align: 'center',
 		},
@@ -159,6 +186,11 @@
 		searchFormRef.value.resetFields()
 		tableRef.value.refresh(true)
 	}
+
+	// 获取机构树并加入顶级
+	bizOrgApi.orgTreeSelector().then((res) => {
+		treeData.value = res
+	})
 	// 删除
 	const deleteBizRechargePlanConfig = (record) => {
 		let params = [

+ 5 - 5
snowy-admin-web/src/views/biz/rechargerecord/form.vue

@@ -3,11 +3,11 @@
 		<a-form ref="formRef" :model="formData">
 			<a-descriptions :column="2" bordered>
 				<a-descriptions-item label="姓名">{{ formData.name }}</a-descriptions-item>
-				<a-descriptions-item label="充值金额">{{ formData.rechargeAmount }}</a-descriptions-item>
-				<a-descriptions-item label="充值金额">{{ formData.rechargeAmount }}</a-descriptions-item>
+				<a-descriptions-item label="手机号">{{ formData.phone }}</a-descriptions-item>
+				<a-descriptions-item label="充值金额">{{ formData.rechargeAmount + '元' }}</a-descriptions-item>
 				<a-descriptions-item label="充值时间">{{ formData.rechargeTime }}</a-descriptions-item>
-				<a-descriptions-item label="原账户余额">{{ formData.oldAccountBalance + '元' }}</a-descriptions-item>
-				<a-descriptions-item label="新账户余额">{{ formData.newAccountBalance + '元' }}</a-descriptions-item>
+				<a-descriptions-item label="原账户糕点">{{ formData.oldAccountBalance + '个' }}</a-descriptions-item>
+				<a-descriptions-item label="新账户糕点">{{ formData.newAccountBalance + '个' }}</a-descriptions-item>
 				<a-descriptions-item label="返利金额" v-if="formData.rebateAmount != null">{{
 					formData.rebateAmount
 				}}</a-descriptions-item>
@@ -15,7 +15,7 @@
 					formData.couponNum
 				}}</a-descriptions-item>
 				<a-descriptions-item label="订单号">{{ formData.orderNo }}</a-descriptions-item>
-				<a-descriptions-item label="是否支付">{{ formData.isPay }}</a-descriptions-item>
+				<a-descriptions-item label="是否支付">{{ formData.isPay == true?'已支付':'待支付' }}</a-descriptions-item>
 				<a-descriptions-item label="充值方案说明:" v-if="formData.rechargePlanId != null">{{
 					formData.rechargePlanDescribe
 				}}</a-descriptions-item>

+ 2 - 2
snowy-admin-web/src/views/biz/rechargerecord/index.vue

@@ -76,12 +76,12 @@
 			align: 'center',
 		},
 		{
-			title: '原账户余额(元)',
+			title: '原账户糕点(个)',
 			dataIndex: 'oldAccountBalance',
 			align: 'center',
 		},
 		{
-			title: '新账户余额(元)',
+			title: '新账户糕点(个)',
 			dataIndex: 'newAccountBalance',
 			align: 'center',
 		},

+ 2 - 2
snowy-admin-web/src/views/biz/statisty/total.vue

@@ -446,11 +446,11 @@
 				},
 			]
 		},
-		{
+		/*{
 			title: '注册会员数',
 			dataIndex: 'userCount',
 			align: 'center'
-		},
+		},*/
 
 	]
 

+ 43 - 1
snowy-admin-web/src/views/biz/warn/index.vue

@@ -58,6 +58,18 @@
 				<template v-if="column.dataIndex === 'serial'">
 					{{ index + 1 }}
 				</template>
+				<template v-if="column.dataIndex === 'userStatus'">
+					<a-switch
+						:loading="loading"
+						:checked="record.userStatus === 'ENABLE'"
+						@change="editStatus(record)"
+						v-if="hasPerm('bizUserUpdataStatus')"
+					/>
+					<a-tag v-else :color="record.userStatus === 'ENABLE' ? 'blue' : 'pink'">{{
+							$TOOL.dictTypeData('COMMON_STATUS', record.userStatus)
+						}}</a-tag>
+					<!--					<span v-else>{{ $TOOL.dictTypeData('COMMON_STATUS', record.userStatus) }}</span>-->
+				</template>
 			</template>
 		</s-table>
 	</a-card>
@@ -71,6 +83,7 @@
 	import bizOrgApi from '@/api/biz/bizOrgApi'
 	import DetailForm from './detail.vue'
 	import Consumption from "@/views/biz/member/consumption.vue";
+	import bizUserApi from '@/api/biz/bizUserApi'
 
 	const tableRef = ref()
 	const formRef = ref()
@@ -83,7 +96,7 @@
 	const toggleAdvanced = () => {
 		advanced.value = !advanced.value
 	}
-
+	const loading = ref(false)
 	const consumptionOperateList = tool.dictList('consumption_operate')
 	const treeData = ref([])
 
@@ -115,6 +128,11 @@
 			dataIndex: 'count',
 			align: 'center',
 		},
+		{
+			title: '状态',
+			dataIndex: 'userStatus',
+			align: 'center',
+		},
 
 		{
 			title: '操作',
@@ -187,4 +205,28 @@
 			tableRef.value.clearRefreshSelected()
 		})
 	}
+
+	// 修改状态
+	const editStatus = (record) => {
+		loading.value = true
+		if (record.userStatus === 'ENABLE') {
+			bizUserApi
+				.userDisableUser(record)
+				.then(() => {
+					tableRef.value.refresh()
+				})
+				.finally(() => {
+					loading.value = false
+				})
+		} else {
+			bizUserApi
+				.userEnableUser(record)
+				.then(() => {
+					tableRef.value.refresh()
+				})
+				.finally(() => {
+					loading.value = false
+				})
+		}
+	}
 </script>

+ 3 - 3
snowy-admin-web/src/views/sys/org/index.vue

@@ -123,12 +123,12 @@
 		{
 			title: '门店编码',
 			dataIndex: 'code',
-			width:150
+			width:120
 		},
 		{
 			title: '门店地址',
 			dataIndex: 'address',
-			width:200
+			width:180
 		},
 		{
 			title: '分类',
@@ -144,7 +144,7 @@
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 180
 		}
 	]
 	const selectedRowKeys = ref([])

+ 2 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/consumptionrecord/mapper/mapping/ConsumptionRecordMapper.xml

@@ -155,10 +155,11 @@
 
     <select id="getWarnPageList" resultType="vip.xiaonuo.biz.modular.user.result.BizMemberUserResult">
         SELECT
-            a.userId,
+            a.userId id,
             su.NAME name,
             su.PHONE phone,
             su.ACCOUNT account,
+            su.USER_STATUS,
             a.count
         FROM
             (

+ 12 - 6
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/consumptionrecord/service/impl/ConsumptionRecordServiceImpl.java

@@ -117,13 +117,13 @@ public class ConsumptionRecordServiceImpl extends ServiceImpl<ConsumptionRecordM
             if(StringUtils.equals(consumptionRecord.getConsumptionOperate(),"3") || StringUtils.equals(consumptionRecord.getConsumptionOperate(),"4")){
                 //消费结算,设置下说明
                 if(StringUtils.equals(consumptionRecord.getConsumptionType(),"1")){
-                    consumptionRecord.setConsumptionRemark("代金券消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"元");
+                    consumptionRecord.setConsumptionRemark("积分消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"个");
                 }
                 if(StringUtils.equals(consumptionRecord.getConsumptionType(),"2")){
-                    consumptionRecord.setConsumptionRemark("账户余额消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"元");
+                    consumptionRecord.setConsumptionRemark("糕点消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"个");
                 }
                 if(StringUtils.equals(consumptionRecord.getConsumptionType(),"3")){
-                    consumptionRecord.setConsumptionRemark("代金券消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"元"+",账户余额消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"元");
+                    consumptionRecord.setConsumptionRemark("积分消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"个"+",糕点消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"个");
                 }
             }
         }
@@ -164,14 +164,14 @@ public class ConsumptionRecordServiceImpl extends ServiceImpl<ConsumptionRecordM
             if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"1")){
                 //选择代金券,用户原有代金券金额-本次扣减金额
                 if(consumptionRecord.getConsumptionMoney().compareTo(bizUser.getVoucherBalance()) > 0){
-                    throw new CommonException("会员当前代金券余额不足,不可扣减!");
+                    throw new CommonException("会员当前账户积分不足,不可扣减!");
                 }
                 bizUser.setVoucherBalance(bizUser.getVoucherBalance().subtract(consumptionRecordAddParam.getConsumptionMoney()));
                 consumptionRecord.setVoucherMoney(consumptionRecordAddParam.getConsumptionMoney());
             }else if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"2")){
                 //选择账户余额,用户原有余额-本次扣减余额
                 if(consumptionRecord.getConsumptionMoney().compareTo(bizUser.getAccountBalance()) > 0){
-                    throw new CommonException("会员当前账户余额不足,不可扣减!");
+                    throw new CommonException("会员当前账户糕点不足,不可扣减!");
                 }
                 bizUser.setAccountBalance(bizUser.getAccountBalance().subtract(consumptionRecordAddParam.getConsumptionMoney()));
                 consumptionRecord.setAccountMoney(consumptionRecordAddParam.getConsumptionMoney());
@@ -200,7 +200,7 @@ public class ConsumptionRecordServiceImpl extends ServiceImpl<ConsumptionRecordM
                 BigDecimal subtract = consumptionRecordAddParam.getConsumptionMoney().subtract(bizUser.getVoucherBalance());
                 //如果差额大于账户余额,表示账户余额不足
                 if(subtract.compareTo(bizUser.getAccountBalance()) > 0){
-                    throw new CommonException("账户余额不足,请先充值!");
+                    throw new CommonException("账户糕点不足,请先充值!");
                 }
                 //记录消费信息
                 consumptionRecord.setVoucherMoney(bizUser.getVoucherBalance());
@@ -267,6 +267,12 @@ public class ConsumptionRecordServiceImpl extends ServiceImpl<ConsumptionRecordM
                 throw new CommonException("手机号码:{}格式错误", consumptionRecordAddParam.getPhoneNumber());
             }
         }
+        if(ObjectUtil.isNotEmpty(consumptionRecordAddParam.getUserId())){
+            BizUser bizUser = bizUserService.getById(consumptionRecordAddParam.getUserId());
+            if(StringUtils.equals(bizUser.getUserStatus(),"DISABLED")){
+                throw new CommonException("用户账号冻结,不可消费!");
+            }
+        }
     }
 
     @Transactional(rollbackFor = Exception.class)

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/entity/BizCouponRecord.java

@@ -93,4 +93,7 @@ public class BizCouponRecord extends CommonEntity {
     @TableField(exist = false)
     private String phone;
 
+    /**清除状态  1:已清除  0:未清除*/
+    private Integer destroyStatus;
+
 }

+ 6 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/mapper/BizCouponRecordMapper.java

@@ -18,6 +18,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord;
 
+import java.util.List;
+
 /**
  * 优惠券记录Mapper接口
  *
@@ -26,4 +28,8 @@ import vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord;
  **/
 public interface BizCouponRecordMapper extends BaseMapper<BizCouponRecord> {
     Page<BizCouponRecord> getPageList(@Param("page") Page<BizCouponRecord> page, @Param("ew") QueryWrapper<BizCouponRecord> ew);
+
+    BizCouponRecord getCouponNoList(@Param("ew") QueryWrapper<BizCouponRecord> ew);
+
+    List<BizCouponRecord> getList(@Param("ew") QueryWrapper<BizCouponRecord> ew);
 }

+ 32 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/mapper/mapping/BizCouponRecordMapper.xml

@@ -25,4 +25,36 @@
         left join SYS_ORG so on so.id = bcr.org_id
         ${ew.customSqlSegment}
     </select>
+    <select id="getCouponNoList" resultType="vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord">
+        SELECT
+            brr.user_id,
+            GROUP_CONCAT(bcr.coupon_no ORDER BY brr.user_id ASC SEPARATOR ', ') AS coupon_no
+        FROM
+            biz_coupon_record bcr
+            LEFT JOIN biz_recharge_record brr ON bcr.recharge_record_id = brr.id
+            ${ew.customSqlSegment}
+    </select>
+    <select id="getList" resultType="vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord">
+        select
+            bcr.id,
+            bcr.coupon_no,
+            bcr.time,
+            bcr.coupon_status,
+            bcr.start_time,
+            bcr.end_time,
+            bcr.destroy_user,
+            bcr.destroy_time,
+            bcr.org_id,
+            su.name userName,
+            su.phone,
+            u.name destroyUserName,
+            so.name destroyOrgName,
+            brr.coupon_amount
+        from biz_coupon_record bcr
+                 left join biz_recharge_record brr on bcr.recharge_record_id = brr.id
+                 left join SYS_USER su on su.id = brr.user_id
+                 left join SYS_USER u on u.id = bcr.destroy_user
+                 left join SYS_ORG so on so.id = bcr.org_id
+            ${ew.customSqlSegment}
+    </select>
 </mapper>

+ 2 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/param/BizCouponRecordPageParam.java

@@ -61,4 +61,6 @@ public class BizCouponRecordPageParam {
 
     private String orgId;
 
+    private String userId;
+
 }

+ 4 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/service/BizCouponRecordService.java

@@ -85,6 +85,10 @@ public interface BizCouponRecordService extends IService<BizCouponRecord> {
      */
     BizCouponRecord queryByCode(BizCouponRecordPageParam bizCouponRecordPageParam);
 
+    BizCouponRecord getCouponNoList(BizCouponRecordPageParam bizCouponRecordPageParam);
+
+    List<BizCouponRecord> getList(BizCouponRecordPageParam bizCouponRecordPageParam);
+
     /**优惠券核销*/
     void destroy(BizCouponRecordEditParam bizCouponRecordEditParam);
 }

+ 19 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/couponrecord/service/impl/BizCouponRecordServiceImpl.java

@@ -123,6 +123,25 @@ public class BizCouponRecordServiceImpl extends ServiceImpl<BizCouponRecordMappe
         return bizCouponRecord;
     }
 
+    @Override
+    public BizCouponRecord getCouponNoList(BizCouponRecordPageParam bizCouponRecordPageParam) {
+        QueryWrapper<BizCouponRecord> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("brr.user_id",bizCouponRecordPageParam.getUserId());
+        queryWrapper.groupBy("brr.user_id");
+        BizCouponRecord couponNoList = this.getBaseMapper().getCouponNoList(queryWrapper);
+        return couponNoList;
+    }
+
+    @Override
+    public List<BizCouponRecord> getList(BizCouponRecordPageParam bizCouponRecordPageParam) {
+        QueryWrapper<BizCouponRecord> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("brr.user_id",bizCouponRecordPageParam.getUserId());
+        queryWrapper.eq("bcr.coupon_status","0");
+        queryWrapper.eq("bcr.delete_flag","NOT_DELETE");
+        List<BizCouponRecord> list = this.getBaseMapper().getList(queryWrapper);
+        return list;
+    }
+
     /***/
     @Override
     public void destroy(BizCouponRecordEditParam bizCouponRecordEditParam) {

+ 123 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/controller/BizDisableRecordController.java

@@ -0,0 +1,123 @@
+/*
+ * 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.disablerecord.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+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.disablerecord.entity.BizDisableRecord;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordAddParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordEditParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordIdParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordPageParam;
+import vip.xiaonuo.biz.modular.disablerecord.service.BizDisableRecordService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 清除记录控制器
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ */
+@Tag(name = "清除记录控制器")
+@RestController
+@Validated
+public class BizDisableRecordController {
+
+    @Resource
+    private BizDisableRecordService bizDisableRecordService;
+
+    /**
+     * 获取清除记录分页
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    @Operation(summary = "获取清除记录分页")
+    @SaCheckPermission("/biz/disablerecord/page")
+    @GetMapping("/biz/disablerecord/page")
+    public CommonResult<Page<BizDisableRecord>> page(BizDisableRecordPageParam bizDisableRecordPageParam) {
+        return CommonResult.data(bizDisableRecordService.page(bizDisableRecordPageParam));
+    }
+
+    /**
+     * 添加清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    @Operation(summary = "添加清除记录")
+    @CommonLog("添加清除记录")
+    @SaCheckPermission("/biz/disablerecord/add")
+    @PostMapping("/biz/disablerecord/add")
+    public CommonResult<String> add(@RequestBody @Valid BizDisableRecordAddParam bizDisableRecordAddParam) {
+        bizDisableRecordService.add(bizDisableRecordAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    @Operation(summary = "编辑清除记录")
+    @CommonLog("编辑清除记录")
+    @SaCheckPermission("/biz/disablerecord/edit")
+    @PostMapping("/biz/disablerecord/edit")
+    public CommonResult<String> edit(@RequestBody @Valid BizDisableRecordEditParam bizDisableRecordEditParam) {
+        bizDisableRecordService.edit(bizDisableRecordEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    @Operation(summary = "删除清除记录")
+    @CommonLog("删除清除记录")
+    @SaCheckPermission("/biz/disablerecord/delete")
+    @PostMapping("/biz/disablerecord/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizDisableRecordIdParam> bizDisableRecordIdParamList) {
+        bizDisableRecordService.delete(bizDisableRecordIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取清除记录详情
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    @Operation(summary = "获取清除记录详情")
+    @SaCheckPermission("/biz/disablerecord/detail")
+    @GetMapping("/biz/disablerecord/detail")
+    public CommonResult<BizDisableRecord> detail(@Valid BizDisableRecordIdParam bizDisableRecordIdParam) {
+        return CommonResult.data(bizDisableRecordService.detail(bizDisableRecordIdParam));
+    }
+}

+ 64 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/entity/BizDisableRecord.java

@@ -0,0 +1,64 @@
+/*
+ * 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.disablerecord.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import vip.xiaonuo.common.pojo.CommonEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 清除记录实体
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+@Setter
+@TableName("biz_disable_record")
+public class BizDisableRecord extends CommonEntity {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 用户ID */
+    @Schema(description = "用户ID")
+    private String userId;
+
+    /** 账户余额清除金额 */
+    @Schema(description = "账户余额清除金额")
+    private BigDecimal accountBalance;
+
+    /** 代金券清除金额 */
+    @Schema(description = "代金券清除金额")
+    private BigDecimal voucherBalance;
+
+    /** 清除蛋糕券编码 */
+    @Schema(description = "清除蛋糕券编码")
+    private String couponCode;
+
+    /**用户名*/
+    @TableField(exist = false)
+    private String userName;
+
+    /**手机号*/
+    @TableField(exist = false)
+    private String phone;
+
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/enums/BizDisableRecordEnum.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.disablerecord.enums;
+
+import lombok.Getter;
+
+/**
+ * 清除记录枚举
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+public enum BizDisableRecordEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    BizDisableRecordEnum(String value) {
+        this.value = value;
+    }
+}

+ 30 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/mapper/BizDisableRecordMapper.java

@@ -0,0 +1,30 @@
+/*
+ * 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.disablerecord.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import vip.xiaonuo.biz.modular.consumptionrecord.entity.ConsumptionRecord;
+import vip.xiaonuo.biz.modular.disablerecord.entity.BizDisableRecord;
+
+/**
+ * 清除记录Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+public interface BizDisableRecordMapper extends BaseMapper<BizDisableRecord> {
+    Page<BizDisableRecord> getPageList(@Param("page") Page<BizDisableRecord> page, @Param("ew") QueryWrapper<BizDisableRecord> ew);
+}

+ 17 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/mapper/mapping/BizDisableRecordMapper.xml

@@ -0,0 +1,17 @@
+<?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.disablerecord.mapper.BizDisableRecordMapper">
+
+    <select id="getPageList" resultType="vip.xiaonuo.biz.modular.disablerecord.entity.BizDisableRecord">
+        select
+            su.name userName,
+            su.phone,
+            bdr.account_balance,
+            bdr.voucher_balance,
+            bdr.coupon_code,
+            bdr.create_time
+        from biz_disable_record bdr
+        left join SYS_USER su on bdr.user_id = su.ID
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 50 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordAddParam.java

@@ -0,0 +1,50 @@
+/*
+ * 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.disablerecord.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 fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+@Setter
+public class BizDisableRecordAddParam {
+
+    /** 用户ID */
+    @Schema(description = "用户ID")
+    private String userId;
+
+    /** 账户余额清除金额 */
+    @Schema(description = "账户余额清除金额")
+    private BigDecimal accountBalance;
+
+    /** 代金券清除金额 */
+    @Schema(description = "代金券清除金额")
+    private BigDecimal voucherBalance;
+
+    /** 清除蛋糕券编码 */
+    @Schema(description = "清除蛋糕券编码")
+    private String couponCode;
+
+}

+ 55 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordEditParam.java

@@ -0,0 +1,55 @@
+/*
+ * 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.disablerecord.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 fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+@Setter
+public class BizDisableRecordEditParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 用户ID */
+    @Schema(description = "用户ID")
+    private String userId;
+
+    /** 账户余额清除金额 */
+    @Schema(description = "账户余额清除金额")
+    private BigDecimal accountBalance;
+
+    /** 代金券清除金额 */
+    @Schema(description = "代金券清除金额")
+    private BigDecimal voucherBalance;
+
+    /** 清除蛋糕券编码 */
+    @Schema(description = "清除蛋糕券编码")
+    private String couponCode;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordIdParam.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.disablerecord.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 清除记录Id参数
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+@Setter
+public class BizDisableRecordIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 53 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/param/BizDisableRecordPageParam.java

@@ -0,0 +1,53 @@
+/*
+ * 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.disablerecord.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 清除记录查询参数
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Getter
+@Setter
+public class BizDisableRecordPageParam {
+
+    /** 当前页 */
+    @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;
+
+    private String userId;
+
+}

+ 80 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/service/BizDisableRecordService.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.disablerecord.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.disablerecord.entity.BizDisableRecord;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordAddParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordEditParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordIdParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordPageParam;
+
+import java.util.List;
+
+/**
+ * 清除记录Service接口
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+public interface BizDisableRecordService extends IService<BizDisableRecord> {
+
+    /**
+     * 获取清除记录分页
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    Page<BizDisableRecord> page(BizDisableRecordPageParam bizDisableRecordPageParam);
+
+    /**
+     * 添加清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    void add(BizDisableRecordAddParam bizDisableRecordAddParam);
+
+    /**
+     * 编辑清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    void edit(BizDisableRecordEditParam bizDisableRecordEditParam);
+
+    /**
+     * 删除清除记录
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    void delete(List<BizDisableRecordIdParam> bizDisableRecordIdParamList);
+
+    /**
+     * 获取清除记录详情
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     */
+    BizDisableRecord detail(BizDisableRecordIdParam bizDisableRecordIdParam);
+
+    /**
+     * 获取清除记录详情
+     *
+     * @author fanzherong
+     * @date  2025/02/14 11:33
+     **/
+    BizDisableRecord queryEntity(String id);
+}

+ 99 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/disablerecord/service/impl/BizDisableRecordServiceImpl.java

@@ -0,0 +1,99 @@
+/*
+ * 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.disablerecord.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.disablerecord.entity.BizDisableRecord;
+import vip.xiaonuo.biz.modular.disablerecord.mapper.BizDisableRecordMapper;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordAddParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordEditParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordIdParam;
+import vip.xiaonuo.biz.modular.disablerecord.param.BizDisableRecordPageParam;
+import vip.xiaonuo.biz.modular.disablerecord.service.BizDisableRecordService;
+import vip.xiaonuo.common.util.CommonCryptogramUtil;
+
+import java.util.List;
+
+/**
+ * 清除记录Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/02/14 11:33
+ **/
+@Service
+public class BizDisableRecordServiceImpl extends ServiceImpl<BizDisableRecordMapper, BizDisableRecord> implements BizDisableRecordService {
+
+    @Override
+    public Page<BizDisableRecord> page(BizDisableRecordPageParam bizDisableRecordPageParam) {
+        QueryWrapper<BizDisableRecord> queryWrapper = new QueryWrapper<BizDisableRecord>().checkSqlInjection();
+        if(ObjectUtil.isNotEmpty(bizDisableRecordPageParam.getUserId())){
+            queryWrapper.eq("bdr.user_id",bizDisableRecordPageParam.getUserId());
+        }
+        queryWrapper.eq("bdr.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("bdr.create_time");
+        Page<BizDisableRecord> pageList = this.getBaseMapper().getPageList(CommonPageRequest.defaultPage(), queryWrapper);
+        for(BizDisableRecord bizDisableRecord : pageList.getRecords()){
+            if(ObjectUtil.isNotEmpty(bizDisableRecord.getPhone())){
+                bizDisableRecord.setPhone(CommonCryptogramUtil.doSm4CbcDecrypt(bizDisableRecord.getPhone()));
+            }
+        }
+        return pageList;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizDisableRecordAddParam bizDisableRecordAddParam) {
+        BizDisableRecord bizDisableRecord = BeanUtil.toBean(bizDisableRecordAddParam, BizDisableRecord.class);
+        this.save(bizDisableRecord);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BizDisableRecordEditParam bizDisableRecordEditParam) {
+        BizDisableRecord bizDisableRecord = this.queryEntity(bizDisableRecordEditParam.getId());
+        BeanUtil.copyProperties(bizDisableRecordEditParam, bizDisableRecord);
+        this.updateById(bizDisableRecord);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizDisableRecordIdParam> bizDisableRecordIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizDisableRecordIdParamList, BizDisableRecordIdParam::getId));
+    }
+
+    @Override
+    public BizDisableRecord detail(BizDisableRecordIdParam bizDisableRecordIdParam) {
+        return this.queryEntity(bizDisableRecordIdParam.getId());
+    }
+
+    @Override
+    public BizDisableRecord queryEntity(String id) {
+        BizDisableRecord bizDisableRecord = this.getById(id);
+        if(ObjectUtil.isEmpty(bizDisableRecord)) {
+            throw new CommonException("清除记录不存在,id值为:{}", id);
+        }
+        return bizDisableRecord;
+    }
+}

+ 11 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/controller/BizRechargePlanConfigController.java

@@ -13,8 +13,11 @@
 package vip.xiaonuo.biz.modular.rechargeplanconfig.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qcloud.cos.internal.crypto.QCLOUDKMS;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
 import org.springframework.validation.annotation.Validated;
@@ -166,10 +169,14 @@ public class BizRechargePlanConfigController {
      */
     @Operation(summary = "获取充值方案配置分页")
     @GetMapping("/biz/rechargeplanconfig/list")
-    public CommonResult<List<BizRechargePlanConfig>> list() {
-        List<BizRechargePlanConfig> planConfigs = bizRechargePlanConfigService.list(new LambdaQueryWrapper<BizRechargePlanConfig>()
-                .eq(BizRechargePlanConfig::getStatus, "ENABLE")
-                .orderByDesc(CommonEntity::getCreateTime));
+    public CommonResult<List<BizRechargePlanConfig>> list(BizRechargePlanConfigPageParam bizRechargePlanConfigPageParam) {
+        QueryWrapper<BizRechargePlanConfig> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isNotEmpty(bizRechargePlanConfigPageParam.getOrgId())){
+            queryWrapper.lambda().eq(BizRechargePlanConfig::getOrgId,bizRechargePlanConfigPageParam.getOrgId());
+        }
+        queryWrapper.lambda().eq(BizRechargePlanConfig::getStatus, "ENABLE");
+        queryWrapper.lambda().orderByDesc(CommonEntity::getCreateTime);
+        List<BizRechargePlanConfig> planConfigs = bizRechargePlanConfigService.list(queryWrapper);
         return CommonResult.data(planConfigs);
     }
 

+ 6 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/entity/BizRechargePlanConfig.java

@@ -61,5 +61,11 @@ public class BizRechargePlanConfig extends CommonEntity {
     @Schema(description = "状态:ENABLE.启用 DISABLED.停用")
     private String status;
 
+    /**门店id*/
+    private String orgId;
+
+    @TableField(exist = false)
+    private String orgName;
+
 
 }

+ 5 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/mapper/BizRechargePlanConfigMapper.java

@@ -12,7 +12,11 @@
  */
 package vip.xiaonuo.biz.modular.rechargeplanconfig.mapper;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import vip.xiaonuo.biz.modular.disablerecord.entity.BizDisableRecord;
 import vip.xiaonuo.biz.modular.rechargeplanconfig.entity.BizRechargePlanConfig;
 
 /**
@@ -22,4 +26,5 @@ import vip.xiaonuo.biz.modular.rechargeplanconfig.entity.BizRechargePlanConfig;
  * @date  2025/02/04 16:32
  **/
 public interface BizRechargePlanConfigMapper extends BaseMapper<BizRechargePlanConfig> {
+    Page<BizRechargePlanConfig> getPageList(@Param("page") Page<BizRechargePlanConfig> page, @Param("ew") QueryWrapper<BizRechargePlanConfig> ew);
 }

+ 17 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/mapper/mapping/BizRechargePlanConfigMapper.xml

@@ -2,4 +2,20 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="vip.xiaonuo.biz.modular.rechargeplanconfig.mapper.BizRechargePlanConfigMapper">
 
-</mapper>
+    <select id="getPageList"
+            resultType="vip.xiaonuo.biz.modular.rechargeplanconfig.entity.BizRechargePlanConfig">
+        select
+            brpc.id,
+            brpc.recharge_amount,
+            brpc.coupon_amount,
+            brpc.coupon_num,
+            brpc.account_balance,
+            brpc.rebate_ratio,
+            brpc.status,
+            brpc.org_id,
+            so.name orgName
+        from biz_recharge_plan_config brpc
+        left join SYS_ORG so on brpc.org_id = so.ID
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigAddParam.java

@@ -51,4 +51,7 @@ public class BizRechargePlanConfigAddParam {
     @Schema(description = "返点比例(代金券)")
     private BigDecimal rebateRatio;
 
+    /**门店id*/
+    private String orgId;
+
 }

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigEditParam.java

@@ -56,4 +56,7 @@ public class BizRechargePlanConfigEditParam {
     @Schema(description = "返点比例(代金券)")
     private BigDecimal rebateRatio;
 
+    /**门店id*/
+    private String orgId;
+
 }

+ 2 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/param/BizRechargePlanConfigPageParam.java

@@ -52,4 +52,6 @@ public class BizRechargePlanConfigPageParam {
     @Schema(description = "状态")
     private String status;
 
+    private String orgId;
+
 }

+ 7 - 3
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargeplanconfig/service/impl/BizRechargePlanConfigServiceImpl.java

@@ -48,10 +48,14 @@ public class BizRechargePlanConfigServiceImpl extends ServiceImpl<BizRechargePla
     public Page<BizRechargePlanConfig> page(BizRechargePlanConfigPageParam bizRechargePlanConfigPageParam) {
         QueryWrapper<BizRechargePlanConfig> queryWrapper = new QueryWrapper<BizRechargePlanConfig>().checkSqlInjection();
         if (ObjectUtil.isNotEmpty(bizRechargePlanConfigPageParam.getStatus())) {
-            queryWrapper.lambda().eq(BizRechargePlanConfig::getStatus, bizRechargePlanConfigPageParam.getStatus());
+            queryWrapper.eq("brpc.status", bizRechargePlanConfigPageParam.getStatus());
         }
-        queryWrapper.lambda().orderByDesc(BizRechargePlanConfig::getCreateTime);
-        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+        if (ObjectUtil.isNotEmpty(bizRechargePlanConfigPageParam.getOrgId())){
+            queryWrapper.eq("brpc.org_id",bizRechargePlanConfigPageParam.getOrgId());
+        }
+        queryWrapper.eq("brpc.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("brpc.create_time");
+        return this.getBaseMapper().getPageList(CommonPageRequest.defaultPage(), queryWrapper);
     }
 
     @Transactional(rollbackFor = Exception.class)

+ 4 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargerecord/mapper/mapping/BizRechargeRecordMapper.xml

@@ -12,10 +12,10 @@
             t.plan_account_balance,
             t.recharge_amount,
             t.recharge_time,
-            t.old_account_balance,
-            t.old_voucher_balance,
-            t.new_account_balance,
-            t.new_voucher_balance,
+            IFNULL(t.old_account_balance,0) old_account_balance,
+            IFNULL(t.old_voucher_balance,0) old_voucher_balance,
+            IFNULL(t.new_account_balance,0) new_account_balance,
+            IFNULL(t.new_voucher_balance,0) new_voucher_balance,
             t.recharge_plan_describe,
             t.order_no,
             t.wx_pay_amount,

+ 4 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargerecord/service/impl/BizRechargeRecordServiceImpl.java

@@ -34,6 +34,7 @@ import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
 import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
@@ -131,6 +132,9 @@ public class BizRechargeRecordServiceImpl extends ServiceImpl<BizRechargeRecordM
         if (ObjectUtil.isNull(bizUser)) {
             throw new CommonException("未查询到该用户信息");
         }
+        if (StringUtils.equals(bizUser.getUserStatus(),"DISABLED")){
+            throw new CommonException("用户账号冻结,不可充值!");
+        }
         if (ObjectUtil.isNotEmpty(bizRechargeRecordAddParam.getRechargePlanId())) {
             // 校验充值方案
             BizRechargePlanConfig bizRechargePlanConfig = bizRechargePlanConfigMapper.selectById(bizRechargeRecordAddParam.getRechargePlanId());

+ 36 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/controller/BizUserController.java

@@ -14,7 +14,9 @@ package vip.xiaonuo.biz.modular.user.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
@@ -23,10 +25,8 @@ import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import org.springframework.http.MediaType;
 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 org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.biz.modular.org.entity.BizOrg;
 import vip.xiaonuo.biz.modular.position.entity.BizPosition;
 import vip.xiaonuo.biz.modular.user.entity.BizUser;
@@ -157,6 +157,15 @@ public class BizUserController {
         return CommonResult.ok();
     }
 
+    @Operation(summary = "会员管理禁用人员")
+    @CommonLog("会员管理禁用人员")
+    @SaCheckPermission("/biz/user/disableCustomer")
+    @PostMapping("/biz/user/disableCustomer")
+    public CommonResult<String> disableCustomer(@RequestBody BizUserIdParam bizUserIdParam) {
+        bizUserService.disableCustomer(bizUserIdParam);
+        return CommonResult.ok();
+    }
+
     /**
      * 启用人员
      *
@@ -336,6 +345,29 @@ public class BizUserController {
         return CommonResult.ok();
     }
 
+    /***
+     * 下载导入模板
+     * @param response
+     * @throws IOException
+     */
+    @Operation(summary = "下载导入模板")
+    @GetMapping(value = "/biz/user/down", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    public void downloadImportUserTemplate(HttpServletResponse response) throws IOException {
+        bizUserService.downloadImportTemplate(response);
+    }
+
+    /**
+     * 信息导入
+     * @param file
+     * @return
+     */
+    @ApiOperationSupport(order = 16)
+    @Operation(summary = "信息导入")
+    @PostMapping("/biz/user/import")
+    public CommonResult<JSONObject> importItem(@RequestPart("file") MultipartFile file) {
+        return CommonResult.data(bizUserService.importItem(file));
+    }
+
 
 
 

+ 13 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/param/BizUserAddParam.java

@@ -17,6 +17,8 @@ import jakarta.validation.constraints.NotBlank;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.math.BigDecimal;
+
 /**
  * 人员添加参数
  *
@@ -44,7 +46,7 @@ public class BizUserAddParam {
 
     /** 岗位id */
     @Schema(description = "岗位id", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "positionId不能为空")
+    /*@NotBlank(message = "positionId不能为空")*/
     private String positionId;
 
     /** 岗级 */
@@ -174,4 +176,14 @@ public class BizUserAddParam {
     /** 扩展信息 */
     @Schema(description = "扩展信息")
     private String extJson;
+
+    /**用户类型: 1. 管理员 2.门店 3.会员*/
+    private String userType;
+
+    /**糕点(账户余额)*/
+    private BigDecimal accountBalance;
+
+    /**积分(代金券积分)*/
+    private BigDecimal voucherBalance;
+
 }

+ 20 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/param/BizUserImport.java

@@ -0,0 +1,20 @@
+package vip.xiaonuo.biz.modular.user.param;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BizUserImport {
+    /**姓名*/
+    private String name;
+
+    /**手机号*/
+    private String phone;
+
+    /**糕点(账户余额)*/
+    private String accountBalance;
+
+    /**积分(代金券积分)*/
+    private String voucherBalance;
+}

+ 11 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/service/BizUserService.java

@@ -13,9 +13,11 @@
 package vip.xiaonuo.biz.modular.user.service;
 
 import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.biz.modular.org.entity.BizOrg;
 import vip.xiaonuo.biz.modular.position.entity.BizPosition;
 import vip.xiaonuo.biz.modular.user.entity.BizUser;
@@ -57,6 +59,8 @@ public interface BizUserService extends IService<BizUser> {
      */
     void add(BizUserAddParam bizUserAddParam);
 
+    void addUser(BizUserAddParam bizUserAddParam);
+
     /**
      * 编辑人员
      *
@@ -97,6 +101,8 @@ public interface BizUserService extends IService<BizUser> {
      **/
     void disableUser(BizUserIdParam bizUserIdParam);
 
+    void disableCustomer(BizUserIdParam bizUserIdParam);
+
     /**
      * 启用人员
      *
@@ -195,4 +201,9 @@ public interface BizUserService extends IService<BizUser> {
 
 
     void smsSend(SmsSendParam smsSendParam);
+
+    /**导出模板*/
+    void downloadImportTemplate(HttpServletResponse response) throws IOException;
+
+    JSONObject importItem(MultipartFile file);
 }

+ 197 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/service/impl/BizUserServiceImpl.java

@@ -24,6 +24,7 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.img.ImgUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.core.lang.tree.TreeNode;
 import cn.hutool.core.lang.tree.TreeUtil;
@@ -31,6 +32,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.PhoneUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.excel.EasyExcel;
@@ -48,6 +50,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fhs.trans.service.impl.TransService;
+import com.google.common.collect.Maps;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import org.apache.commons.compress.utils.Lists;
@@ -56,13 +59,21 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.biz.core.enums.BizBuildInEnum;
 import vip.xiaonuo.biz.core.enums.BizDataTypeEnum;
 import vip.xiaonuo.biz.modular.consumptionrecord.entity.ConsumptionRecord;
 import vip.xiaonuo.biz.modular.consumptionrecord.service.ConsumptionRecordService;
 import vip.xiaonuo.biz.modular.consumptionrecord.service.impl.ConsumptionRecordServiceImpl;
+import vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord;
+import vip.xiaonuo.biz.modular.couponrecord.param.BizCouponRecordPageParam;
+import vip.xiaonuo.biz.modular.couponrecord.service.BizCouponRecordService;
+import vip.xiaonuo.biz.modular.disablerecord.entity.BizDisableRecord;
+import vip.xiaonuo.biz.modular.disablerecord.service.BizDisableRecordService;
 import vip.xiaonuo.biz.modular.org.entity.BizOrg;
 import vip.xiaonuo.biz.modular.org.service.BizOrgService;
 import vip.xiaonuo.biz.modular.position.entity.BizPosition;
@@ -92,10 +103,8 @@ import vip.xiaonuo.dev.api.DevSmsApi;
 import vip.xiaonuo.sys.api.SysRoleApi;
 import vip.xiaonuo.sys.api.SysUserApi;
 
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
+import java.math.BigDecimal;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -141,6 +150,10 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
     private BizRecommendRecordMapper bizRecommendRecordMapper;
     @Resource
     private ConsumptionRecordService consumptionRecordService;
+    @Resource
+    private BizDisableRecordService bizDisableRecordService;
+    @Resource
+    private BizCouponRecordService bizCouponRecordService;
 
 
     @Override
@@ -236,12 +249,19 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
         bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
         // 设置状态
         bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
+        bizUser.setUserReferralCode(DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN) + RandomUtil.randomNumbers(4));
         this.save(bizUser);
 
         // 发布增加事件
         CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(bizUser));
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void addUser(BizUserAddParam bizUserAddParam) {
+
+    }
+
     private void checkParam(BizUserAddParam bizUserAddParam) {
         // 校验数据范围
         List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
@@ -407,6 +427,49 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
                 bizUserIdParam.getId()).set(BizUser::getUserStatus, BizUserStatusEnum.DISABLED.getValue()));
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void disableCustomer(BizUserIdParam bizUserIdParam) {
+        BizUser bizUser = this.detail(bizUserIdParam);
+        BigDecimal accountBalance = bizUser.getAccountBalance();
+        BigDecimal voucherBalance = bizUser.getVoucherBalance();
+        // 校验数据范围
+        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
+        if (ObjectUtil.isNotEmpty(loginUserDataScope)) {
+            if (!loginUserDataScope.contains(bizUser.getOrgId())) {
+                throw new CommonException("您没有权限禁用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
+            }
+        } else {
+            if (!bizUser.getId().equals(StpUtil.getLoginIdAsString())) {
+                throw new CommonException("您没有权限禁用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
+            }
+        }
+        //账户余额和代金券金额清0
+        this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId,
+                bizUserIdParam.getId()).set(BizUser::getUserStatus, BizUserStatusEnum.DISABLED.getValue())
+                .set(BizUser::getAccountBalance,new BigDecimal(0)).set(BizUser::getVoucherBalance,new BigDecimal(0)));
+
+        BizDisableRecord bizDisableRecord = new BizDisableRecord();
+        bizDisableRecord.setUserId(bizUser.getId());
+        bizDisableRecord.setAccountBalance(accountBalance);
+        bizDisableRecord.setVoucherBalance(voucherBalance);
+        BizCouponRecordPageParam bizCouponRecordPageParam = new BizCouponRecordPageParam();
+        bizCouponRecordPageParam.setUserId(bizUser.getId());
+        StringBuffer buffer = new StringBuffer();
+        List<BizCouponRecord> couponNoList = bizCouponRecordService.getList(bizCouponRecordPageParam);
+        //所有未核销的蛋糕券都核销掉
+        for(BizCouponRecord bizCouponRecord : couponNoList){
+            bizCouponRecord.setCouponStatus("1");
+            bizCouponRecord.setDestroyStatus(1);
+            buffer.append(bizCouponRecord.getCouponNo()+",");
+            bizCouponRecordService.updateById(bizCouponRecord);
+        }
+        if(ObjectUtil.isNotEmpty(buffer)){
+            bizDisableRecord.setCouponCode(buffer.substring(0,buffer.length()-1));
+        }
+        bizDisableRecordService.save(bizDisableRecord);
+    }
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void enableUser(BizUserIdParam bizUserIdParam) {
@@ -937,4 +1000,134 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
         //保存5分钟
         commonCacheOperator.put(smsSendParam.getPhone(), code, 300);
     }
+
+    @Override
+    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
+        try {
+            InputStream inputStream = POICacheManager.getFile("user.xlsx");
+            byte[] bytes = IoUtil.readBytes(inputStream);
+            CommonDownloadUtil.download("会员信息导入模板.xlsx", bytes, response);
+        } catch (Exception e) {
+            log.error(">>> 下载会员信息导入模板失败:", e);
+            CommonResponseUtil.renderError(response, "下载会员信息导入模板失败");
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public JSONObject importItem(MultipartFile file) {
+        try {
+            int successCount = 0;
+            int errorCount = 0;
+            JSONArray errorDetail = JSONUtil.createArray();
+            String fileName = file.getOriginalFilename();
+            // 创建临时文件
+            File tempFile = null;
+            if (fileName.endsWith(".xlsx")) {
+                tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + "user.xlsx"));
+            } else if (fileName.endsWith(".xls")) {
+                tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + "user.xlsx"));
+            } else {
+                throw new CommonException("导入文件格式不正确!");
+            }
+            // 读取excel
+            Integer excelRow = this.getExcelRow(tempFile);
+            List<BizUserImport> itemImportParamList = EasyExcel.read(tempFile).head(BizUserImport.class).sheet()
+                    .headRowNumber(excelRow).doReadSync();
+            for (int i = 0; i < itemImportParamList.size(); i++) {
+                JSONObject jsonObject = this.doImport(itemImportParamList.get(i), i);
+                if (jsonObject.getBool("success")) {
+                    successCount += 1;
+                } else {
+                    errorCount += 1;
+                    errorDetail.add(jsonObject);
+                }
+            }
+            return JSONUtil.createObj()
+                    .set("totalCount", itemImportParamList.size())
+                    .set("successCount", successCount).set("errorCount", errorCount).set("errorDetail", errorDetail);
+        } catch (Exception e) {
+            log.error(">>> 物资需求单导入失败:", e);
+            throw new CommonException("物资需求单导入失败");
+        }
+    }
+
+    //表头校验,获取读取的数据行数
+    private Integer getExcelRow(File file) {
+        FileInputStream input = null;
+
+        try {
+            input = new FileInputStream(file);
+            Workbook workbook = WorkbookFactory.create(input);
+            Sheet sheet = workbook.getSheetAt(0);
+
+            String headName = sheet.getRow(0).getCell(0).getStringCellValue();
+            //关闭流
+            input.close();
+            if ("日期".equals(headName)) {
+                return 1;
+            }
+        } catch (IOException e) {
+
+        }
+
+        return 2;
+    }
+
+    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
+    public JSONObject doImport(BizUserImport bizUserImport, int i) {
+        //姓名
+        String name = bizUserImport.getName();
+        //手机号码
+        String phone = bizUserImport.getPhone();
+        //糕点
+        String accountBalance = bizUserImport.getAccountBalance();
+        //积分
+        String voucherBalance = bizUserImport.getVoucherBalance();
+        if (ObjectUtil.hasEmpty(name,phone)) {
+            return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
+        }else{
+            try {
+                if (!PhoneUtil.isMobile(phone)) {
+                    return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "手机号码:"+phone+"格式错误");
+                }
+                if (this.count(new LambdaQueryWrapper<BizUser>()
+                        .eq(BizUser::getPhone, CommonCryptogramUtil.doSm4CbcEncrypt(phone))) > 0) {
+                    return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "存在重复的手机号,手机号为:"+phone);
+                }
+                if(!isNonNegativeInteger(accountBalance)){
+                    return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "糕点填写大于等于0的数字");
+                }
+                if(!isNonNegativeInteger(voucherBalance)){
+                    return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "积分填写大于等于0的数字");
+                }
+
+                BizUser bizUser = new BizUser();
+                BeanUtil.copyProperties(bizUserImport, bizUser);
+                bizUser.setAccount(phone);
+                bizUser.setOrgId("1543842934270394368");
+                bizUser.setUserType(3);
+                bizUser.setAccountBalance(new BigDecimal(accountBalance));
+                bizUser.setVoucherBalance(new BigDecimal(voucherBalance));
+                // 设置默认头像
+                bizUser.setAvatar(CommonAvatarUtil.generateImg(bizUser.getName()));
+                // 设置密码
+                bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
+                // 设置状态
+                bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
+                bizUser.setUserReferralCode(DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN) + RandomUtil.randomNumbers(4));
+                this.save(bizUser);
+                // 返回成功
+                return JSONUtil.createObj().set("success", true);
+            } catch (Exception e) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                log.error(">>> 数据导入异常:", e);
+                return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常:" + e);
+            }
+
+        }
+    }
+    public static boolean isNonNegativeInteger(String str) {
+        return str != null && str.matches("^\\d*\\.?\\d+$");
+    }
 }

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/wx/WxPayNotifyController.java

@@ -1,5 +1,6 @@
 package vip.xiaonuo.biz.modular.wx;
 
+import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.ObjectId;
@@ -161,6 +162,8 @@ public class WxPayNotifyController {
                     BizCouponRecord bizCouponRecord = new BizCouponRecord();
                     bizCouponRecord.setCouponNo(CommonCouponGeneratorUtil.generateCouponCode());
                     bizCouponRecord.setTime(date);
+                    bizCouponRecord.setStartTime(date);
+                    bizCouponRecord.setEndTime(DateUtil.offset(date, DateField.YEAR,1));
                     bizCouponRecord.setRechargePlanId(bizRechargeRecord.getRechargePlanId());
                     bizCouponRecord.setRechargeRecordId(bizRechargeRecord.getId());
                     bizCouponRecordService.save(bizCouponRecord);

BIN
snowy-plugin/snowy-plugin-biz/src/main/resources/user.xlsx