feat: member detail
							parent
							
								
									2583d14455
								
							
						
					
					
						commit
						8ad0bbc427
					
				|  | @ -0,0 +1,82 @@ | |||
| <script setup lang="ts"> | ||||
| import type { MemberUserApi } from '#/api/member/user'; | ||||
| import type { PayWalletApi } from '#/api/pay/wallet/balance'; | ||||
| 
 | ||||
| import { Card } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useDescription } from '#/components/description'; | ||||
| import { fenToYuan } from '#/utils'; | ||||
| 
 | ||||
| withDefaults( | ||||
|   defineProps<{ | ||||
|     mode?: 'kefu' | 'member'; | ||||
|     user: MemberUserApi.User; | ||||
|     wallet: PayWalletApi.WalletVO; | ||||
|   }>(), | ||||
|   { | ||||
|     mode: 'member', | ||||
|   }, | ||||
| ); | ||||
| 
 | ||||
| const [Description] = useDescription({ | ||||
|   componentProps: { | ||||
|     bordered: false, | ||||
|     class: 'mx-4', | ||||
|   }, | ||||
|   schema: [ | ||||
|     { | ||||
|       field: 'levelName', | ||||
|       label: '等级', | ||||
|       content: (data) => data.levelName || '无', | ||||
|     }, | ||||
|     { | ||||
|       field: 'experience', | ||||
|       label: '成长值', | ||||
|       content: (data) => data.experience || 0, | ||||
|     }, | ||||
|     { | ||||
|       field: 'point', | ||||
|       label: '当前积分', | ||||
|       content: (data) => data.point || 0, | ||||
|     }, | ||||
|     { | ||||
|       field: 'totalPoint', | ||||
|       label: '总积分', | ||||
|       content: (data) => data.totalPoint || 0, | ||||
|     }, | ||||
|     { | ||||
|       field: 'balance', | ||||
|       label: '当前余额', | ||||
|       content: (data) => fenToYuan(data.balance || 0), | ||||
|     }, | ||||
|     { | ||||
|       field: 'totalExpense', | ||||
|       label: '支出金额', | ||||
|       content: (data) => fenToYuan(data.totalExpense || 0), | ||||
|     }, | ||||
|     { | ||||
|       field: 'totalRecharge', | ||||
|       label: '充值金额', | ||||
|       content: (data) => fenToYuan(data.totalRecharge || 0), | ||||
|     }, | ||||
|   ], | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Card> | ||||
|     <template #title> | ||||
|       <slot name="title"></slot> | ||||
|     </template> | ||||
|     <template #extra> | ||||
|       <slot name="extra"></slot> | ||||
|     </template> | ||||
|     <Description | ||||
|       :column="mode === 'member' ? 2 : 1" | ||||
|       :data="{ | ||||
|         ...user, | ||||
|         ...wallet, | ||||
|       }" | ||||
|     /> | ||||
|   </Card> | ||||
| </template> | ||||
|  | @ -0,0 +1,96 @@ | |||
| <script setup lang="ts"> | ||||
| import type { MemberUserApi } from '#/api/member/user'; | ||||
| 
 | ||||
| import { h } from 'vue'; | ||||
| 
 | ||||
| import { formatDate } from '@vben/utils'; | ||||
| 
 | ||||
| import { Avatar, Card, Col, Row } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useDescription } from '#/components/description'; | ||||
| import { DictTag } from '#/components/dict-tag'; | ||||
| import { DICT_TYPE } from '#/utils'; | ||||
| 
 | ||||
| withDefaults( | ||||
|   defineProps<{ mode?: 'kefu' | 'member'; user: MemberUserApi.User }>(), | ||||
|   { | ||||
|     mode: 'member', | ||||
|   }, | ||||
| ); | ||||
| 
 | ||||
| const [Description] = useDescription({ | ||||
|   componentProps: { | ||||
|     bordered: false, | ||||
|     class: 'mx-4', | ||||
|   }, | ||||
|   schema: [ | ||||
|     { | ||||
|       field: 'name', | ||||
|       label: '用户名', | ||||
|     }, | ||||
|     { | ||||
|       field: 'nickname', | ||||
|       label: '昵称', | ||||
|     }, | ||||
|     { | ||||
|       field: 'mobile', | ||||
|       label: '手机号', | ||||
|     }, | ||||
|     { | ||||
|       field: 'sex', | ||||
|       label: '性别', | ||||
|       content: (data) => | ||||
|         h(DictTag, { | ||||
|           type: DICT_TYPE.SYSTEM_USER_SEX, | ||||
|           value: data.sex, | ||||
|         }), | ||||
|     }, | ||||
|     { | ||||
|       field: 'areaName', | ||||
|       label: '所在地', | ||||
|     }, | ||||
|     { | ||||
|       field: 'registerIp', | ||||
|       label: '注册 IP', | ||||
|     }, | ||||
|     { | ||||
|       field: 'birthday', | ||||
|       label: '生日', | ||||
|       content: (data) => formatDate(data.birthday)?.toString() || '空', | ||||
|     }, | ||||
|     { | ||||
|       field: 'createTime', | ||||
|       label: '注册时间', | ||||
|       content: (data) => formatDate(data.createTime)?.toString() || '空', | ||||
|     }, | ||||
|     { | ||||
|       field: 'loginDate', | ||||
|       label: '最后登录时间', | ||||
|       content: (data) => formatDate(data.loginDate)?.toString() || '空', | ||||
|     }, | ||||
|   ], | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Card> | ||||
|     <template #title> | ||||
|       <slot name="title"></slot> | ||||
|     </template> | ||||
|     <template #extra> | ||||
|       <slot name="extra"></slot> | ||||
|     </template> | ||||
|     <Row v-if="mode === 'member'" :gutter="24"> | ||||
|       <Col :span="4"> | ||||
|         <Avatar :size="140" shape="square" :src="user.avatar" /> | ||||
|       </Col> | ||||
|       <Col :span="20"> | ||||
|         <Description :column="2" :data="user" /> | ||||
|       </Col> | ||||
|     </Row> | ||||
|     <template v-else-if="mode === 'kefu'"> | ||||
|       <Avatar :size="140" shape="square" :src="user.avatar" /> | ||||
|       <Description :column="1" :data="user" /> | ||||
|     </template> | ||||
|   </Card> | ||||
| </template> | ||||
|  | @ -0,0 +1,81 @@ | |||
| <script lang="ts" setup> | ||||
| import type { VxeTableGridOptions } from '#/adapter/vxe-table'; | ||||
| import type { MemberPointRecordApi } from '#/api/member/point/record'; | ||||
| 
 | ||||
| import { Tag } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||
| import { getRecordPage } from '#/api/member/point/record'; | ||||
| import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; | ||||
| import { useGridColumns } from '#/views/member/point/record/data'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|   userId: number; | ||||
| }>(); | ||||
| 
 | ||||
| const [Grid] = useVbenVxeGrid({ | ||||
|   formOptions: { | ||||
|     schema: [ | ||||
|       { | ||||
|         fieldName: 'bizType', | ||||
|         label: '业务类型', | ||||
|         component: 'Select', | ||||
|         componentProps: { | ||||
|           allowClear: true, | ||||
|           options: getDictOptions(DICT_TYPE.MEMBER_POINT_BIZ_TYPE, 'number'), | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         fieldName: 'title', | ||||
|         label: '积分标题', | ||||
|         component: 'Input', | ||||
|       }, | ||||
|       { | ||||
|         fieldName: 'createDate', | ||||
|         label: '获得时间', | ||||
|         component: 'RangePicker', | ||||
|         componentProps: { | ||||
|           ...getRangePickerDefaultProps(), | ||||
|           allowClear: true, | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   gridOptions: { | ||||
|     columns: useGridColumns(), | ||||
|     keepSource: true, | ||||
|     pagerConfig: { | ||||
|       pageSize: 10, | ||||
|     }, | ||||
|     proxyConfig: { | ||||
|       ajax: { | ||||
|         query: async ({ page }, formValues) => { | ||||
|           return await getRecordPage({ | ||||
|             pageNo: page.currentPage, | ||||
|             pageSize: page.pageSize, | ||||
|             userId: props.userId, | ||||
|             ...formValues, | ||||
|           }); | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     rowConfig: { | ||||
|       keyField: 'id', | ||||
|     }, | ||||
|     toolbarConfig: { | ||||
|       refresh: { code: 'query' }, | ||||
|       search: true, | ||||
|     }, | ||||
|   } as VxeTableGridOptions<MemberPointRecordApi.Record>, | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Grid> | ||||
|     <template #point="{ row }"> | ||||
|       <Tag :color="row.point > 0 ? '#108ee9' : '#f50'"> | ||||
|         {{ row.point > 0 ? `+${row.point}` : row.point }} | ||||
|       </Tag> | ||||
|     </template> | ||||
|   </Grid> | ||||
| </template> | ||||
|  | @ -0,0 +1,72 @@ | |||
| <script lang="ts" setup> | ||||
| import type { VxeTableGridOptions } from '#/adapter/vxe-table'; | ||||
| import type { MemberSignInRecordApi } from '#/api/member/signin/record'; | ||||
| 
 | ||||
| import { Tag } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||
| import { getSignInRecordPage } from '#/api/member/signin/record'; | ||||
| import { getRangePickerDefaultProps } from '#/utils'; | ||||
| import { useGridColumns } from '#/views/member/signin/record/data'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|   userId: number; | ||||
| }>(); | ||||
| 
 | ||||
| const [Grid] = useVbenVxeGrid({ | ||||
|   formOptions: { | ||||
|     schema: [ | ||||
|       { | ||||
|         fieldName: 'day', | ||||
|         label: '签到天数', | ||||
|         component: 'Input', | ||||
|       }, | ||||
|       { | ||||
|         fieldName: 'createTime', | ||||
|         label: '签到时间', | ||||
|         component: 'RangePicker', | ||||
|         componentProps: { | ||||
|           ...getRangePickerDefaultProps(), | ||||
|           allowClear: true, | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   gridOptions: { | ||||
|     columns: useGridColumns(), | ||||
|     keepSource: true, | ||||
|     pagerConfig: { | ||||
|       pageSize: 10, | ||||
|     }, | ||||
|     proxyConfig: { | ||||
|       ajax: { | ||||
|         query: async ({ page }, formValues) => { | ||||
|           return await getSignInRecordPage({ | ||||
|             pageNo: page.currentPage, | ||||
|             pageSize: page.pageSize, | ||||
|             userId: props.userId, | ||||
|             ...formValues, | ||||
|           }); | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     rowConfig: { | ||||
|       keyField: 'id', | ||||
|     }, | ||||
|     toolbarConfig: { | ||||
|       refresh: { code: 'query' }, | ||||
|       search: true, | ||||
|     }, | ||||
|   } as VxeTableGridOptions<MemberSignInRecordApi.SignInRecord>, | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Grid> | ||||
|     <template #point="{ row }"> | ||||
|       <Tag :color="row.point > 0 ? '#108ee9' : '#f50'"> | ||||
|         {{ row.point > 0 ? `+${row.point}` : row.point }} | ||||
|       </Tag> | ||||
|     </template> | ||||
|   </Grid> | ||||
| </template> | ||||
		Loading…
	
		Reference in New Issue
	
	 xingyu4j
						xingyu4j