feat(用户管理): 添加微信会员绑定功能
- 在用户管理页面新增添加会员弹窗及表单 - 添加绑定微信会员的API接口 - 设置默认企业ID用于测试 - 实现表单验证及提交逻辑
This commit is contained in:
parent
9163a1e322
commit
59b19cd9e3
|
|
@ -107,6 +107,18 @@ export interface BindQyUserCommand {
|
||||||
idNum: string;
|
idNum: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BindWxMpUserCommand {
|
||||||
|
/** 企业ID */
|
||||||
|
corpid: string;
|
||||||
|
/** 动态码 */
|
||||||
|
dynamicCode: string;
|
||||||
|
/** 真实姓名 */
|
||||||
|
name: string;
|
||||||
|
/** 身份证号码 */
|
||||||
|
idNum: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getAb98UserListApi = (params: Ab98UserQuery) => {
|
export const getAb98UserListApi = (params: Ab98UserQuery) => {
|
||||||
return http.request<ResponseData<PageDTO<Ab98UserDTO>>>("get", "/ab98/users", { params });
|
return http.request<ResponseData<PageDTO<Ab98UserDTO>>>("get", "/ab98/users", { params });
|
||||||
};
|
};
|
||||||
|
|
@ -129,4 +141,9 @@ export const getAb98UserDetailApi = (id: number, corpid: string) => {
|
||||||
|
|
||||||
export const bindQyUserApi = (data: BindQyUserCommand) => {
|
export const bindQyUserApi = (data: BindQyUserCommand) => {
|
||||||
return http.request<ResponseData<void>>("post", "/ab98/users/bindQyUser", { data });
|
return http.request<ResponseData<void>>("post", "/ab98/users/bindQyUser", { data });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const bindWxMpUser = (data: BindWxMpUserCommand) => {
|
||||||
|
return http.request<ResponseData<void>>("post", "/ab98/users/bindWxMpUser", { data });
|
||||||
};
|
};
|
||||||
|
|
@ -7,7 +7,7 @@ import { QyUserLoginDTO } from "@/api/common/login";
|
||||||
|
|
||||||
export const useWxStore = defineStore("wx", () => {
|
export const useWxStore = defineStore("wx", () => {
|
||||||
// 授权企业id
|
// 授权企业id
|
||||||
const corpid = ref<string>("")
|
const corpid = ref<string>("wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw")
|
||||||
// 微信授权 code
|
// 微信授权 code
|
||||||
const code = ref<string>("")
|
const code = ref<string>("")
|
||||||
// 防止 CSRF 攻击的 state 参数
|
// 防止 CSRF 攻击的 state 参数
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, watch } from "vue";
|
import { onMounted, reactive, ref, watch } from "vue";
|
||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||||
import { getAb98UserListApi, type Ab98UserDTO, Ab98UserQuery } from "@/api/ab98/user";
|
import { getAb98UserListApi, type Ab98UserDTO, Ab98UserQuery, bindWxMpUser, type BindWxMpUserCommand } 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 { useWxStore } from "@/store/modules/wx";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
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";
|
||||||
import View from "@iconify-icons/ep/view";
|
import View from "@iconify-icons/ep/view";
|
||||||
|
import Plus from "@iconify-icons/ep/plus";
|
||||||
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";
|
||||||
|
|
@ -31,6 +33,17 @@ const searchFormParams = reactive<Ab98UserQuery & { search?: string }>({
|
||||||
search: undefined
|
search: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加会员弹窗相关状态
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const addMemberFormRef = ref();
|
||||||
|
const addMemberLoading = ref(false);
|
||||||
|
const addMemberForm = reactive<BindWxMpUserCommand>({
|
||||||
|
corpid: wxStore.corpid || "",
|
||||||
|
dynamicCode: "",
|
||||||
|
name: "",
|
||||||
|
idNum: ""
|
||||||
|
});
|
||||||
|
|
||||||
const pageLoading = ref(false);
|
const pageLoading = ref(false);
|
||||||
const dataList = ref<Ab98UserDTO[]>([]);
|
const dataList = ref<Ab98UserDTO[]>([]);
|
||||||
const pagination = reactive<PaginationProps>({
|
const pagination = reactive<PaginationProps>({
|
||||||
|
|
@ -106,6 +119,58 @@ const handleViewDetail = (row: Ab98UserDTO) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 打开添加会员弹窗
|
||||||
|
const openAddMemberDialog = () => {
|
||||||
|
dialogVisible.value = true;
|
||||||
|
// 重置表单
|
||||||
|
addMemberForm.dynamicCode = "";
|
||||||
|
addMemberForm.name = "";
|
||||||
|
addMemberForm.idNum = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
addMemberFormRef.value?.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交添加会员表单
|
||||||
|
const submitAddMember = async () => {
|
||||||
|
if (!addMemberFormRef.value) return;
|
||||||
|
|
||||||
|
await addMemberFormRef.value.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
addMemberLoading.value = true;
|
||||||
|
await bindWxMpUser(addMemberForm);
|
||||||
|
ElMessage.success("会员添加成功");
|
||||||
|
closeDialog();
|
||||||
|
// 刷新列表
|
||||||
|
getList();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("添加会员失败:", error);
|
||||||
|
ElMessage.error("添加会员失败,请重试");
|
||||||
|
} finally {
|
||||||
|
addMemberLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const addMemberRules = reactive({
|
||||||
|
dynamicCode: [
|
||||||
|
{ required: true, message: "请输入动态码", trigger: "blur" }
|
||||||
|
],
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "请输入姓名", trigger: "blur" }
|
||||||
|
],
|
||||||
|
idNum: [
|
||||||
|
{ required: true, message: "请输入身份证号", trigger: "blur" },
|
||||||
|
{ pattern: /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/, message: "请输入正确的身份证号", trigger: "blur" }
|
||||||
|
] as any
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
getAb98UserTagNamesApi().then(res => {
|
getAb98UserTagNamesApi().then(res => {
|
||||||
|
|
@ -138,6 +203,13 @@ onMounted(() => {
|
||||||
重置
|
重置
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item class="space-item">
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="success" :icon="useRenderIcon(Plus)" @click="openAddMemberDialog">
|
||||||
|
添加会员
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
|
@ -175,6 +247,29 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加会员弹窗 -->
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加会员" width="500px" :close-on-click-modal="false">
|
||||||
|
<el-form ref="addMemberFormRef" :model="addMemberForm" :rules="addMemberRules" label-width="100px">
|
||||||
|
<el-form-item label="动态码" prop="dynamicCode">
|
||||||
|
<el-input v-model="addMemberForm.dynamicCode" placeholder="请输入动态码" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input v-model="addMemberForm.name" placeholder="请输入姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idNum">
|
||||||
|
<el-input v-model="addMemberForm.idNum" placeholder="请输入身份证号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="addMemberLoading" @click="submitAddMember">
|
||||||
|
确认添加
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -272,4 +367,8 @@ onMounted(() => {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.space-item {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue