|
|
@@ -36,6 +36,62 @@
|
|
|
<div class="pull-right">{{ user.createTime }}</div>
|
|
|
</li>
|
|
|
</ul>
|
|
|
+ <!-- 操作区域 - 优化布局 -->
|
|
|
+ <div class="action-section">
|
|
|
+ <!-- 绑定会员按钮 -->
|
|
|
+ <el-button
|
|
|
+ v-if="!user.fsUserId"
|
|
|
+ type="primary"
|
|
|
+ icon="el-icon-user"
|
|
|
+ @click="handleBindMember"
|
|
|
+ class="action-btn"
|
|
|
+ :loading="bindLoading"
|
|
|
+ >绑定会员</el-button>
|
|
|
+
|
|
|
+ <!-- 已绑定会员列表 -->
|
|
|
+ <div v-if="user.fsUserIdArray && user.fsUserIdArray.length > 0" class="bound-members">
|
|
|
+ <div class="bound-header">
|
|
|
+ <el-tag type="success" effect="dark" size="small">已绑定会员</el-tag>
|
|
|
+ <span class="bound-count">{{ user.fsUserIdArray.length }}个</span>
|
|
|
+ </div>
|
|
|
+ <div class="member-list">
|
|
|
+ <div
|
|
|
+ v-for="(fsUserId, index) in user.fsUserIdArray"
|
|
|
+ :key="index"
|
|
|
+ class="member-item"
|
|
|
+ >
|
|
|
+ <span class="member-id">
|
|
|
+ <i class="el-icon-user-solid"></i>
|
|
|
+ {{ fsUserId }}
|
|
|
+ </span>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="danger"
|
|
|
+ icon="el-icon-delete"
|
|
|
+ @click="handleUnbindSpecificMember(fsUserId)"
|
|
|
+ circle
|
|
|
+ title="解绑"
|
|
|
+ ></el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 微信服务号绑定 -->
|
|
|
+ <div v-if="needWxTemplateMsg" class="wechat-section">
|
|
|
+ <div v-if="user.wechatBindStatus" class="wechat-bound">
|
|
|
+ <el-tag type="success" effect="dark" size="small">
|
|
|
+ <i class="el-icon-wechat"></i> 已绑定服务号通知
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ <el-button
|
|
|
+ v-else
|
|
|
+ type="primary"
|
|
|
+ @click="openWechatBindDialog"
|
|
|
+ icon="el-icon-wechat"
|
|
|
+ class="wechat-btn"
|
|
|
+ >订阅服务号通知</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<div class="text-center" style="margin-top: 20px;" v-if="needWxTemplateMsg">
|
|
|
<div v-if="user.wechatBindStatus">
|
|
|
<el-tag type="success">已绑定服务号通知</el-tag>
|
|
|
@@ -86,7 +142,7 @@
|
|
|
import userAvatar from "./userAvatar";
|
|
|
import userInfo from "./userInfo";
|
|
|
import resetPwd from "./resetPwd";
|
|
|
-import { getUserProfile } from "@/api/company/companyUser";
|
|
|
+import { getUserProfile,getSaleBindUserList, bindSaleAndFsUser, unbindSaleAndFsUser } from "@/api/company/companyUser";
|
|
|
import { getWechatBindQrcode, checkWechatBindStatus } from "@/api/wechat";
|
|
|
export default {
|
|
|
name: "Profile",
|
|
|
@@ -101,6 +157,27 @@ export default {
|
|
|
wechatQrcode: "",
|
|
|
wechatBindTimer: null,
|
|
|
needWxTemplateMsg: false,
|
|
|
+
|
|
|
+ bindLoading: false,
|
|
|
+ confirmLoading: false,
|
|
|
+ // 绑定会员相关数据
|
|
|
+ member: {
|
|
|
+ open: false,
|
|
|
+ title: "绑定会员"
|
|
|
+ },
|
|
|
+ memberList: [],
|
|
|
+ selectedMember: null,
|
|
|
+ currentCompanyId: null,
|
|
|
+ memberTotal: 0,
|
|
|
+ loading: false,
|
|
|
+ // 添加筛选参数
|
|
|
+ memberQueryParams: {
|
|
|
+ nickName: null,
|
|
|
+ phone: null,
|
|
|
+ userId: null,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
+ },
|
|
|
};
|
|
|
},
|
|
|
created() {
|
|
|
@@ -110,6 +187,80 @@ export default {
|
|
|
this.getUser();
|
|
|
},
|
|
|
methods: {
|
|
|
+
|
|
|
+ handleBindMember() {
|
|
|
+ this.currentCompanyId = this.user.userId;
|
|
|
+ this.resetMemberQuery();
|
|
|
+ this.selectedMember = null;
|
|
|
+ this.member.open = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ resetMemberQuery() {
|
|
|
+ this.memberQueryParams = {
|
|
|
+ nickName: null,
|
|
|
+ phone: null,
|
|
|
+ userId: null,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
+ };
|
|
|
+ this.getMemberList();
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ getMemberList() {
|
|
|
+ this.loading = true;
|
|
|
+ getSaleBindUserList({
|
|
|
+ pageNum: this.memberQueryParams.pageNum,
|
|
|
+ pageSize: this.memberQueryParams.pageSize,
|
|
|
+ nickName: this.memberQueryParams.nickName,
|
|
|
+ phone: this.memberQueryParams.phone,
|
|
|
+ userId: this.memberQueryParams.userId
|
|
|
+ })
|
|
|
+ .then(response => {
|
|
|
+ this.memberList = response.rows || [];
|
|
|
+ this.memberTotal = response.total || 0;
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ console.error('获取会员列表失败:', error);
|
|
|
+ this.$message.error('获取会员列表失败');
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ handleUnbindSpecificMember(fsUserId) {
|
|
|
+ this.$confirm(`确定要解除与会员 ${fsUserId} 的绑定吗?`, "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ const unbindData = {
|
|
|
+ companyUserId: this.user.userId,
|
|
|
+ userId: fsUserId
|
|
|
+ };
|
|
|
+
|
|
|
+ unbindSaleAndFsUser(unbindData)
|
|
|
+ .then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.$message.success("解绑成功");
|
|
|
+ this.getUser();
|
|
|
+ } else {
|
|
|
+ this.$message.error(response.msg || "解绑失败");
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ console.error("解绑失败:", error);
|
|
|
+ this.$message.error("解绑失败");
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.info("已取消解绑");
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
getUser() {
|
|
|
getUserProfile().then(response => {
|
|
|
this.user = response.data;
|
|
|
@@ -146,3 +297,370 @@ export default {
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
+<style scoped>
|
|
|
+/* 个人信息卡片样式 */
|
|
|
+.profile-card {
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-card :deep(.el-card__header) {
|
|
|
+ padding: 15px 20px;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ color: white;
|
|
|
+ font-weight: 500;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header i {
|
|
|
+ margin-right: 8px;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 头像区域 */
|
|
|
+.avatar-section {
|
|
|
+ text-align: center;
|
|
|
+ padding: 24px 20px 16px;
|
|
|
+ background: linear-gradient(135deg, #667eea10 0%, #764ba210 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.user-name {
|
|
|
+ margin: 12px 0 0;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #303133;
|
|
|
+}
|
|
|
+
|
|
|
+/* 信息列表 */
|
|
|
+.info-list {
|
|
|
+ list-style: none;
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.info-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px 20px;
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
+ transition: background-color 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.info-item:hover {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+}
|
|
|
+
|
|
|
+.info-item:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.info-label {
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.info-label svg {
|
|
|
+ margin-right: 8px;
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.info-value {
|
|
|
+ color: #303133;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 操作区域 */
|
|
|
+.action-section {
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #fafbfc;
|
|
|
+ border-top: 1px solid #e4e7ed;
|
|
|
+}
|
|
|
+
|
|
|
+.action-btn {
|
|
|
+ width: 100%;
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 已绑定会员列表 */
|
|
|
+.bound-members {
|
|
|
+ margin-top: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.bound-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.bound-count {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ background-color: #f0f2f5;
|
|
|
+ padding: 2px 8px;
|
|
|
+ border-radius: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.member-list {
|
|
|
+ max-height: 200px;
|
|
|
+ overflow-y: auto;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ border-radius: 4px;
|
|
|
+ background-color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.member-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px 12px;
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
+ transition: background-color 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.member-item:hover {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+}
|
|
|
+
|
|
|
+.member-item:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.member-id {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #606266;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.member-id i {
|
|
|
+ margin-right: 6px;
|
|
|
+ color: #409EFF;
|
|
|
+}
|
|
|
+
|
|
|
+/* 微信服务号区域 */
|
|
|
+.wechat-section {
|
|
|
+ margin-top: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.wechat-bound {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.wechat-btn {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 右侧卡片样式 */
|
|
|
+.content-card {
|
|
|
+ border-radius: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.content-card :deep(.el-card__header) {
|
|
|
+ padding: 15px 20px;
|
|
|
+ background-color: #fafbfc;
|
|
|
+ border-bottom: 1px solid #e4e7ed;
|
|
|
+}
|
|
|
+
|
|
|
+/* 绑定会员对话框样式 - 无背景色 */
|
|
|
+.bind-member-dialog :deep(.el-dialog__body) {
|
|
|
+ padding: 20px 24px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 筛选表单 - 无背景色,优化排版 */
|
|
|
+.filter-container {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ padding: 0 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-row {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-buttons {
|
|
|
+ text-align: right;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-buttons .el-button {
|
|
|
+ margin-left: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-buttons .el-button:first-child {
|
|
|
+ margin-left: 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格区域 */
|
|
|
+.table-section {
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ border-radius: 6px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.member-table :deep(th) {
|
|
|
+ background-color: #f2f6fc;
|
|
|
+ color: #303133;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 13px;
|
|
|
+}
|
|
|
+
|
|
|
+.status-tag {
|
|
|
+ min-width: 70px;
|
|
|
+}
|
|
|
+
|
|
|
+.status-tag i {
|
|
|
+ margin-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.nickname-cell, .phone-cell {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.nickname-cell i, .phone-cell i {
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.no-data {
|
|
|
+ color: #c0c4cc;
|
|
|
+}
|
|
|
+
|
|
|
+/* 分页样式 - 支持每页条数选择 */
|
|
|
+.pagination-wrapper {
|
|
|
+ padding: 16px;
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-top: 1px solid #e4e7ed;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-pagination :deep(.el-pagination) {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-pagination :deep(.el-pagination__sizes) {
|
|
|
+ margin-right: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-data {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 40px 0;
|
|
|
+ color: #909399;
|
|
|
+ background-color: #ffffff;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-data i {
|
|
|
+ font-size: 40px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #dcdfe6;
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.selected-info {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #606266;
|
|
|
+ background-color: #f0f9eb;
|
|
|
+ padding: 6px 12px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #e1f3d8;
|
|
|
+}
|
|
|
+
|
|
|
+/* 微信对话框样式 */
|
|
|
+.wechat-dialog :deep(.el-dialog__body) {
|
|
|
+ padding: 30px 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-container {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-img {
|
|
|
+ width: 260px;
|
|
|
+ height: 260px;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ padding: 10px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background-color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-loading {
|
|
|
+ width: 260px;
|
|
|
+ height: 260px;
|
|
|
+ margin: 0 auto;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-radius: 8px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-loading i {
|
|
|
+ font-size: 32px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-tip {
|
|
|
+ margin-top: 16px;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.qrcode-tip i {
|
|
|
+ color: #07C160;
|
|
|
+ margin-right: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 响应式调整 */
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .filter-container .el-col {
|
|
|
+ width: 100%;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-buttons {
|
|
|
+ text-align: left;
|
|
|
+ margin-top: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-buttons .el-button {
|
|
|
+ margin-left: 0;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-footer {
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .selected-info {
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|