|
|
@@ -0,0 +1,396 @@
|
|
|
+<template>
|
|
|
+ <div class="table-box button-table friend-relation-container">
|
|
|
+ <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
|
|
|
+ <!-- 表格 header 按钮 -->
|
|
|
+ <template #tableHeader="scope">
|
|
|
+ <div class="header-button">
|
|
|
+ <el-button type="primary" @click="openAddDialog"> 添加好友 </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 状态列 -->
|
|
|
+ <template #status="scope">
|
|
|
+ <el-tag :type="getStatusType(scope.row.status)">
|
|
|
+ {{ getStatusText(scope.row.status) }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 表格操作 -->
|
|
|
+ <template #operation="scope">
|
|
|
+ <el-button link type="primary" @click="editRow(scope.row)"> 编辑 </el-button>
|
|
|
+ <el-button link type="primary" @click="deleteRow(scope.row)"> 删除 </el-button>
|
|
|
+ <el-button v-if="scope.row.status === 0" link type="primary" @click="handleApprove(scope.row)"> 同意 </el-button>
|
|
|
+ </template>
|
|
|
+ </ProTable>
|
|
|
+
|
|
|
+ <!-- 添加/编辑好友对话框 -->
|
|
|
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px" @close="closeDialog">
|
|
|
+ <el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
|
|
|
+ <el-form-item label="好友名称" prop="friendName">
|
|
|
+ <el-input v-model="formData.friendName" placeholder="请输入好友名称" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="好友手机号" prop="friendPhone">
|
|
|
+ <el-input v-model="formData.friendPhone" placeholder="请输入手机号" maxlength="11" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="好友备注" prop="remark">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.remark"
|
|
|
+ type="textarea"
|
|
|
+ :rows="3"
|
|
|
+ placeholder="请输入备注信息"
|
|
|
+ maxlength="200"
|
|
|
+ show-word-limit
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="关系类型" prop="relationType">
|
|
|
+ <el-select v-model="formData.relationType" placeholder="请选择关系类型" style="width: 100%">
|
|
|
+ <el-option v-for="item in relationTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="赠送优惠券" prop="couponList">
|
|
|
+ <div class="coupon-list">
|
|
|
+ <div v-for="(item, index) in formData.couponList" :key="index" class="coupon-item">
|
|
|
+ <el-select v-model="item.couponId" placeholder="请选择优惠券" style="width: 300px; margin-right: 10px">
|
|
|
+ <el-option v-for="coupon in availableCoupons" :key="coupon.id" :label="coupon.name" :value="coupon.id" />
|
|
|
+ </el-select>
|
|
|
+ <el-input-number
|
|
|
+ v-model="item.quantity"
|
|
|
+ :min="1"
|
|
|
+ :max="100"
|
|
|
+ placeholder="数量"
|
|
|
+ style="width: 120px; margin-right: 10px"
|
|
|
+ />
|
|
|
+ <el-button type="danger" link @click="removeCoupon(index)"> 删除 </el-button>
|
|
|
+ </div>
|
|
|
+ <el-button type="primary" link @click="addCoupon" style="margin-top: 10px">
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
+ 添加优惠券
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="closeDialog"> 取消 </el-button>
|
|
|
+ <el-button type="primary" @click="handleSubmit"> 确定 </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="tsx" name="friendRelation">
|
|
|
+import { computed, onMounted, reactive, ref } from "vue";
|
|
|
+import type { FormInstance, FormRules } from "element-plus";
|
|
|
+import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
+import { Plus } from "@element-plus/icons-vue";
|
|
|
+import ProTable from "@/components/ProTable/index.vue";
|
|
|
+import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
|
|
+import { localGet } from "@/utils";
|
|
|
+// import { getFriendRelationList, addFriendRelation, updateFriendRelation, deleteFriendRelation, approveFriend } from "@/api/modules/friendRelation";
|
|
|
+
|
|
|
+// ProTable 实例
|
|
|
+const proTable = ref<ProTableInstance>();
|
|
|
+
|
|
|
+// 对话框相关
|
|
|
+const dialogVisible = ref(false);
|
|
|
+const dialogTitle = computed(() => (isEdit.value ? "编辑好友" : "添加好友"));
|
|
|
+const isEdit = ref(false);
|
|
|
+const currentEditId = ref("");
|
|
|
+
|
|
|
+// 表单引用
|
|
|
+const formRef = ref<FormInstance>();
|
|
|
+
|
|
|
+// 关系类型选项
|
|
|
+const relationTypeOptions = [
|
|
|
+ { label: "普通好友", value: 1 },
|
|
|
+ { label: "亲密好友", value: 2 },
|
|
|
+ { label: "商业伙伴", value: 3 }
|
|
|
+];
|
|
|
+
|
|
|
+// 可用优惠券列表(模拟数据)
|
|
|
+const availableCoupons = ref([
|
|
|
+ { id: 1, name: "满100减20代金券" },
|
|
|
+ { id: 2, name: "8折优惠券" },
|
|
|
+ { id: 3, name: "满200减50代金券" }
|
|
|
+]);
|
|
|
+
|
|
|
+// 表单数据
|
|
|
+const formData = reactive({
|
|
|
+ friendName: "",
|
|
|
+ friendPhone: "",
|
|
|
+ remark: "",
|
|
|
+ relationType: "",
|
|
|
+ couponList: [] as Array<{ couponId: string | number; quantity: number }>
|
|
|
+});
|
|
|
+
|
|
|
+// 表单验证规则
|
|
|
+const formRules = reactive<FormRules>({
|
|
|
+ friendName: [{ required: true, message: "请输入好友名称", trigger: "blur" }],
|
|
|
+ friendPhone: [
|
|
|
+ { required: true, message: "请输入手机号", trigger: "blur" },
|
|
|
+ {
|
|
|
+ pattern: /^1[3-9]\d{9}$/,
|
|
|
+ message: "请输入正确的手机号",
|
|
|
+ trigger: "blur"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ relationType: [{ required: true, message: "请选择关系类型", trigger: "change" }]
|
|
|
+});
|
|
|
+
|
|
|
+// 表格列配置
|
|
|
+const columns = reactive<ColumnProps<any>[]>([
|
|
|
+ {
|
|
|
+ prop: "friendName",
|
|
|
+ label: "好友名称",
|
|
|
+ search: {
|
|
|
+ el: "input"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: "friendPhone",
|
|
|
+ label: "手机号"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: "relationType",
|
|
|
+ label: "关系类型",
|
|
|
+ search: {
|
|
|
+ el: "select",
|
|
|
+ props: { placeholder: "请选择" }
|
|
|
+ },
|
|
|
+ enum: relationTypeOptions,
|
|
|
+ fieldNames: { label: "label", value: "value" },
|
|
|
+ render: (scope: any) => {
|
|
|
+ const type = relationTypeOptions.find(item => item.value === scope.row.relationType);
|
|
|
+ return type?.label || "--";
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: "createTime",
|
|
|
+ label: "添加时间",
|
|
|
+ render: (scope: any) => {
|
|
|
+ return scope.row.createTime?.replace(/-/g, "/") || "--";
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: "status",
|
|
|
+ label: "状态"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: "remark",
|
|
|
+ label: "备注",
|
|
|
+ render: (scope: any) => {
|
|
|
+ return scope.row.remark || "--";
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { prop: "operation", label: "操作", fixed: "right", width: 250 }
|
|
|
+]);
|
|
|
+
|
|
|
+// 初始化请求参数
|
|
|
+const initParam = reactive({
|
|
|
+ storeId: localGet("createdId") || ""
|
|
|
+});
|
|
|
+
|
|
|
+// 数据回调处理
|
|
|
+const dataCallback = (data: any) => {
|
|
|
+ return {
|
|
|
+ list: data?.records || [],
|
|
|
+ total: data?.total || 0
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+// 获取表格列表
|
|
|
+const getTableList = (params: any) => {
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
+ // return getFriendRelationList(params);
|
|
|
+
|
|
|
+ // 临时方案:返回模拟数据
|
|
|
+ return new Promise(resolve => {
|
|
|
+ setTimeout(() => {
|
|
|
+ const mockData = generateMockData();
|
|
|
+ resolve({
|
|
|
+ code: 200,
|
|
|
+ data: {
|
|
|
+ records: mockData,
|
|
|
+ total: mockData.length
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 生成模拟数据
|
|
|
+const generateMockData = () => {
|
|
|
+ return Array.from({ length: 5 }, (_, i) => ({
|
|
|
+ id: i + 1,
|
|
|
+ friendName: `好友${i + 1}`,
|
|
|
+ friendPhone: `138${String(i).padStart(8, "0")}`,
|
|
|
+ relationType: (i % 3) + 1,
|
|
|
+ createTime: "2025-03-01",
|
|
|
+ status: i % 3, // 0-待同意, 1-已同意, 2-已拒绝
|
|
|
+ remark: i % 2 === 0 ? `备注信息${i + 1}` : ""
|
|
|
+ }));
|
|
|
+};
|
|
|
+
|
|
|
+// 获取状态文本
|
|
|
+const getStatusText = (status: number) => {
|
|
|
+ const statusMap: Record<number, string> = {
|
|
|
+ 0: "待同意",
|
|
|
+ 1: "已同意",
|
|
|
+ 2: "已拒绝"
|
|
|
+ };
|
|
|
+ return statusMap[status] || "--";
|
|
|
+};
|
|
|
+
|
|
|
+// 获取状态类型
|
|
|
+const getStatusType = (status: number) => {
|
|
|
+ const typeMap: Record<number, string> = {
|
|
|
+ 0: "warning",
|
|
|
+ 1: "success",
|
|
|
+ 2: "info"
|
|
|
+ };
|
|
|
+ return typeMap[status] || "";
|
|
|
+};
|
|
|
+
|
|
|
+// 打开添加对话框
|
|
|
+const openAddDialog = () => {
|
|
|
+ isEdit.value = false;
|
|
|
+ dialogVisible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+// 关闭对话框
|
|
|
+const closeDialog = () => {
|
|
|
+ dialogVisible.value = false;
|
|
|
+ formRef.value?.resetFields();
|
|
|
+ Object.assign(formData, {
|
|
|
+ friendName: "",
|
|
|
+ friendPhone: "",
|
|
|
+ remark: "",
|
|
|
+ relationType: "",
|
|
|
+ couponList: []
|
|
|
+ });
|
|
|
+ currentEditId.value = "";
|
|
|
+};
|
|
|
+
|
|
|
+// 添加优惠券
|
|
|
+const addCoupon = () => {
|
|
|
+ formData.couponList.push({
|
|
|
+ couponId: "",
|
|
|
+ quantity: 1
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 移除优惠券
|
|
|
+const removeCoupon = (index: number) => {
|
|
|
+ formData.couponList.splice(index, 1);
|
|
|
+};
|
|
|
+
|
|
|
+// 编辑行数据
|
|
|
+const editRow = (row: any) => {
|
|
|
+ isEdit.value = true;
|
|
|
+ currentEditId.value = row.id;
|
|
|
+ Object.assign(formData, {
|
|
|
+ friendName: row.friendName,
|
|
|
+ friendPhone: row.friendPhone,
|
|
|
+ remark: row.remark,
|
|
|
+ relationType: row.relationType,
|
|
|
+ couponList: []
|
|
|
+ });
|
|
|
+ dialogVisible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+// 删除行数据
|
|
|
+const deleteRow = (row: any) => {
|
|
|
+ ElMessageBox.confirm("确定要删除这个好友吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ })
|
|
|
+ .then(async () => {
|
|
|
+ try {
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
+ // await deleteFriendRelation({ id: row.id });
|
|
|
+
|
|
|
+ ElMessage.success("删除成功");
|
|
|
+ proTable.value?.getTableList();
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error("删除失败");
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // 用户取消删除
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 同意好友申请
|
|
|
+const handleApprove = async (row: any) => {
|
|
|
+ try {
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
+ // await approveFriend({ id: row.id });
|
|
|
+
|
|
|
+ ElMessage.success("已同意好友申请");
|
|
|
+ proTable.value?.getTableList();
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error("操作失败");
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 提交表单
|
|
|
+const handleSubmit = async () => {
|
|
|
+ if (!formRef.value) return;
|
|
|
+
|
|
|
+ await formRef.value.validate(async (valid: boolean) => {
|
|
|
+ if (valid) {
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ ...formData,
|
|
|
+ id: isEdit.value ? currentEditId.value : undefined
|
|
|
+ };
|
|
|
+
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
+ // if (isEdit.value) {
|
|
|
+ // await updateFriendRelation(params);
|
|
|
+ // } else {
|
|
|
+ // await addFriendRelation(params);
|
|
|
+ // }
|
|
|
+
|
|
|
+ ElMessage.success(isEdit.value ? "编辑成功" : "添加成功");
|
|
|
+ closeDialog();
|
|
|
+ proTable.value?.getTableList();
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error(isEdit.value ? "编辑失败" : "添加失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 页面加载时触发查询
|
|
|
+onMounted(() => {
|
|
|
+ proTable.value?.getTableList();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.friend-relation-container {
|
|
|
+ .header-button {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+ .coupon-list {
|
|
|
+ .coupon-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .dialog-footer {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|