feat(用户模块): 添加借呗相关字段及金额显示功能

在用户DTO中新增借呗相关字段(余额、已使用、额度)
添加货币单位转换工具函数用于分转元显示
在用户列表和详情页展示借呗信息
修改用户详情接口增加企业ID参数
This commit is contained in:
dzq 2025-11-24 17:11:11 +08:00
parent f1382e945e
commit 040fb4acaa
4 changed files with 100 additions and 4 deletions

View File

@ -25,6 +25,12 @@ export interface Ab98UserDTO {
address?: string; address?: string;
/** 是否已注册0未注册 1已注册 */ /** 是否已注册0未注册 1已注册 */
registered?: boolean; registered?: boolean;
/** 剩余借呗(单位:分) */
balance?: number;
/** 已使用借呗 (单位:分) */
useBalance?: number;
/** 借呗额度 (单位:分) */
balanceLimit?: number;
} }
export interface Ab98UserDetailDTO { export interface Ab98UserDetailDTO {
/** 主键ID */ /** 主键ID */
@ -52,9 +58,18 @@ export interface Ab98UserDetailDTO {
/** 是否已注册0未注册 1已注册 */ /** 是否已注册0未注册 1已注册 */
registered?: boolean; registered?: boolean;
createTime?: string; createTime?: string;
/** 剩余借呗(单位:分) */
balance?: number;
/** 已使用借呗(单位:分) */
useBalance?: number;
/** 借呗额度(单位:分) */
balanceLimit?: number;
} }
export interface Ab98UserQuery extends BasePageQuery { export interface Ab98UserQuery extends BasePageQuery {
/** 企业ID导出列企业ID */
corpid: string;
/** 真实姓名 */ /** 真实姓名 */
name?: string; name?: string;
/** 手机号码 */ /** 手机号码 */
@ -106,8 +121,8 @@ export const deleteAb98UserApi = (ids: number[]) => {
return http.request<ResponseData<void>>("delete", `/ab98/users/${ids.join(',')}`); return http.request<ResponseData<void>>("delete", `/ab98/users/${ids.join(',')}`);
}; };
export const getAb98UserDetailApi = (id: number) => { export const getAb98UserDetailApi = (id: number, corpid: string) => {
return http.request<ResponseData<Ab98UserDetailDTO>>("get", `/ab98/users/detail/${id}`); return http.request<ResponseData<Ab98UserDetailDTO>>("get", `/ab98/users/detail/${id}`, { params: { corpid } });
}; };
export const bindQyUserApi = (data: BindQyUserCommand) => { export const bindQyUserApi = (data: BindQyUserCommand) => {

68
src/utils/currency.ts Normal file
View File

@ -0,0 +1,68 @@
/**
*
*
*/
/**
*
* @param amount
* @param precision 2
* @returns
*/
export function fenToYuan(amount: number | string | null | undefined, precision: number = 2): string {
// 处理空值、null、undefined
if (amount === null || amount === undefined || amount === '') {
return '0';
}
// 转换为数字
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
// 如果转换后不是有效数字返回0
if (isNaN(numAmount)) {
return '0';
}
// 将分转换为元除以100
const yuanAmount = numAmount / 100;
// 按指定精度格式化
return yuanAmount.toFixed(precision);
}
/**
*
* @param amount
* @param precision 2
* @returns
*/
export function fenToYuanNumber(amount: number | string | null | undefined, precision: number = 2): number {
// 处理空值、null、undefined
if (amount === null || amount === undefined || amount === '') {
return 0;
}
// 转换为数字
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
// 如果转换后不是有效数字返回0
if (isNaN(numAmount)) {
return 0;
}
// 将分转换为元除以100
const yuanAmount = numAmount / 100;
// 按指定精度格式化并返回数字
return parseFloat(yuanAmount.toFixed(precision));
}
/**
*
* @param amount
* @param precision 2
* @returns
*/
export function formatFenToYuan(amount: number | string | null | undefined, precision: number = 2): string {
return `${fenToYuan(amount, precision)}`;
}

View File

@ -6,12 +6,15 @@ import { getOrderListApi, type OrderDTO } from "@/api/shop/order";
import { Ab98UserTagDTO, addAb98UserTagApi, deleteAb98UserTagConfirmApi, getAb98UserTagListApi } from "@/api/ab98/tag"; import { Ab98UserTagDTO, addAb98UserTagApi, deleteAb98UserTagConfirmApi, getAb98UserTagListApi } from "@/api/ab98/tag";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { PureTableBar } from "@/components/RePureTableBar"; import { PureTableBar } from "@/components/RePureTableBar";
import { useWxStore } from "@/store/modules/wx";
import { formatFenToYuan } from "@/utils/currency";
defineOptions({ defineOptions({
name: "Ab98UserDetail" name: "Ab98UserDetail"
}); });
const route = useRoute(); const route = useRoute();
const wxStore = useWxStore();
const userInfo = ref<Ab98UserDetailDTO>({}); const userInfo = ref<Ab98UserDetailDTO>({});
const loading = ref(false); const loading = ref(false);
const tags = ref<Ab98UserTagDTO[]>([]); const tags = ref<Ab98UserTagDTO[]>([]);
@ -64,7 +67,7 @@ async function fetchUserDetail() {
try { try {
loading.value = true; loading.value = true;
const userId = route.query.id; const userId = route.query.id;
const { data } = await getAb98UserDetailApi(Number(userId)); const { data } = await getAb98UserDetailApi(Number(userId), wxStore.corpid);
userInfo.value = data; userInfo.value = data;
await fetchUserTags(); await fetchUserTags();
} finally { } finally {
@ -166,6 +169,10 @@ onMounted(() => {
<el-descriptions-item label="会员ID">{{ userInfo.ab98UserId }}</el-descriptions-item> <el-descriptions-item label="会员ID">{{ userInfo.ab98UserId }}</el-descriptions-item>
<el-descriptions-item label="微信openid">{{ userInfo.openid }}</el-descriptions-item> <el-descriptions-item label="微信openid">{{ userInfo.openid }}</el-descriptions-item>
<el-descriptions-item label="注册时间" :span="2">{{ userInfo.createTime }}</el-descriptions-item> <el-descriptions-item label="注册时间" :span="2">{{ userInfo.createTime }}</el-descriptions-item>
<el-descriptions-item label="借呗额度" :span="2">{{ formatFenToYuan(userInfo.balanceLimit)
}}</el-descriptions-item>
<el-descriptions-item label="剩余借呗">{{ formatFenToYuan(userInfo.balance) }}</el-descriptions-item>
<el-descriptions-item label="已使用借呗">{{ formatFenToYuan(userInfo.useBalance) }}</el-descriptions-item>
<el-descriptions-item label="标签" :span="2"> <el-descriptions-item label="标签" :span="2">
<div class="tag-container"> <div class="tag-container">
<div class="user-tags" v-if="tags.length > 0"> <div class="user-tags" v-if="tags.length > 0">

View File

@ -4,6 +4,7 @@ import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getAb98UserListApi, type Ab98UserDTO, Ab98UserQuery } from "@/api/ab98/user"; import { getAb98UserListApi, type Ab98UserDTO, Ab98UserQuery } from "@/api/ab98/user";
import { type PaginationProps } from "@pureadmin/table"; import { type PaginationProps } from "@pureadmin/table";
import { CommonUtils } from "@/utils/common"; import { CommonUtils } from "@/utils/common";
import { useWxStore } from "@/store/modules/wx";
import Search from "@iconify-icons/ep/search"; import Search from "@iconify-icons/ep/search";
import Refresh from "@iconify-icons/ep/refresh"; import Refresh from "@iconify-icons/ep/refresh";
@ -11,6 +12,7 @@ import View from "@iconify-icons/ep/view";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags"; import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { getAb98UserTagNamesApi } from "@/api/ab98/tag"; import { getAb98UserTagNamesApi } from "@/api/ab98/tag";
import { formatFenToYuan } from "@/utils/currency";
defineOptions({ defineOptions({
name: "Ab98User" name: "Ab98User"
@ -18,8 +20,10 @@ defineOptions({
const router = useRouter(); const router = useRouter();
const formRef = ref(); const formRef = ref();
const wxStore = useWxStore();
const tagOptions = ref<string[]>([]); const tagOptions = ref<string[]>([]);
const searchFormParams = reactive<Ab98UserQuery & { search?: string }>({ const searchFormParams = reactive<Ab98UserQuery & { search?: string }>({
corpid: wxStore.corpid || "",
name: undefined, name: undefined,
tel: undefined, tel: undefined,
idnum: undefined, idnum: undefined,
@ -154,6 +158,7 @@ onMounted(() => {
<div class="name">姓名{{ item.name }}</div> <div class="name">姓名{{ item.name }}</div>
<div class="gender">性别{{ item.sex === '男' ? '男' : item.sex === '女' ? '女' : '' }}</div> <div class="gender">性别{{ item.sex === '男' ? '男' : item.sex === '女' ? '女' : '' }}</div>
<div class="tel">电话{{ item.tel }}</div> <div class="tel">电话{{ item.tel }}</div>
<div class="balance">剩余借呗{{ formatFenToYuan(item.balance) }}</div>
</div> </div>
</div> </div>
<div class="idnum">身份证号{{ item.idnum }}</div> <div class="idnum">身份证号{{ item.idnum }}</div>
@ -209,7 +214,8 @@ onMounted(() => {
.name, .name,
.gender, .gender,
.tel { .tel,
.balance {
font-size: 14px; font-size: 14px;
color: #606266; color: #606266;
margin-bottom: 6px; margin-bottom: 6px;