mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-11 03:18:56 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -90,74 +90,74 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { getUserRecharge } from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "recharge",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
},
|
||||
selectDate: null,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
rechargeWayText(way) {
|
||||
if (way === "ALIPAY") return "支付宝";
|
||||
if (way === "WECHAT") return "微信";
|
||||
if (way === "BANK_TRANSFER") return "线下转账";
|
||||
return "";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserRecharge(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "recharge" });
|
||||
|
||||
// 模板 el-form 的 ref(原 ref="searchForm",与 data 同名会互相覆盖,改名为 searchFormRef)
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
});
|
||||
const selectDate = ref(null);
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
function rechargeWayText(way) {
|
||||
if (way === "ALIPAY") return "支付宝";
|
||||
if (way === "WECHAT") return "微信";
|
||||
if (way === "BANK_TRANSFER") return "线下转账";
|
||||
return "";
|
||||
}
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getDataList();
|
||||
}
|
||||
function selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
searchForm.startDate = v[0];
|
||||
searchForm.endDate = v[1];
|
||||
} else {
|
||||
searchForm.startDate = "";
|
||||
searchForm.endDate = "";
|
||||
}
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getUserRecharge(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -85,75 +85,75 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { getUserWallet } from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "walletLog",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
},
|
||||
selectDate: null,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
serviceTypeText(type) {
|
||||
if (type === "WALLET_WITHDRAWAL") return "余额提现";
|
||||
if (type === "WALLET_PAY") return "余额支付";
|
||||
if (type === "WALLET_REFUND") return "余额退款";
|
||||
if (type === "WALLET_RECHARGE") return "余额充值";
|
||||
return "佣金提成";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserWallet(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "walletLog" });
|
||||
|
||||
// 模板 el-form 的 ref(原 ref="searchForm",与 data 同名会互相覆盖,改名为 searchFormRef)
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
});
|
||||
const selectDate = ref(null);
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
function serviceTypeText(type) {
|
||||
if (type === "WALLET_WITHDRAWAL") return "余额提现";
|
||||
if (type === "WALLET_PAY") return "余额支付";
|
||||
if (type === "WALLET_REFUND") return "余额退款";
|
||||
if (type === "WALLET_RECHARGE") return "余额充值";
|
||||
return "佣金提成";
|
||||
}
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getDataList();
|
||||
}
|
||||
function selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
searchForm.startDate = v[0];
|
||||
searchForm.endDate = v[1];
|
||||
} else {
|
||||
searchForm.startDate = "";
|
||||
searchForm.endDate = "";
|
||||
}
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getUserWallet(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -169,168 +169,169 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { getUserWithdrawApply, withdrawApply } from "@/api/member";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "withdrawApply",
|
||||
data() {
|
||||
return {
|
||||
modalTitle: "",
|
||||
loading: true,
|
||||
audit: "",
|
||||
roleModalVisible: false,
|
||||
queryModalVisible: false,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
applyStatus: "",
|
||||
},
|
||||
selectDate: null,
|
||||
submitLoading: false,
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
showList: {},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
paramTypeFilter(val) {
|
||||
if (val === "APPLY") return "申请中";
|
||||
if (val === "VIA_AUDITING") return "审核通过(提现成功)";
|
||||
if (val === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (val === "FAIL_AUDITING") return "审核拒绝";
|
||||
if (val === "SUCCESS") return "提现成功";
|
||||
if (val === "ERROR") return "提现失败";
|
||||
return "未知状态";
|
||||
},
|
||||
applyStatusText(status) {
|
||||
if (status === "APPLY") return "申请中";
|
||||
if (status === "VIA_AUDITING") return "审核通过";
|
||||
if (status === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (status === "SUCCESS") return "提现成功";
|
||||
if (status === "ERROR") return "提现失败";
|
||||
return "审核拒绝";
|
||||
},
|
||||
applyStatusTagType(status) {
|
||||
if (status === "APPLY") return "warning";
|
||||
if (status === "VIA_AUDITING") return "success";
|
||||
if (status === "WAIT_USER_CONFIRM") return "warning";
|
||||
if (status === "SUCCESS") return "primary";
|
||||
if (status === "ERROR") return "primary";
|
||||
return "danger";
|
||||
},
|
||||
openAudit(row) {
|
||||
this.showList = { ...row };
|
||||
this.audit = "";
|
||||
this.roleModalVisible = true;
|
||||
},
|
||||
openQuery(row) {
|
||||
this.showList = { ...row };
|
||||
this.modalTitle = "查看";
|
||||
this.queryModalVisible = true;
|
||||
},
|
||||
submitRole(res) {
|
||||
const params = {};
|
||||
params.applyId = this.showList.id;
|
||||
params.result = res;
|
||||
params.remark = this.audit;
|
||||
if (res === false && params.remark === "") {
|
||||
ElMessage.error("审核备注不能为空");
|
||||
return;
|
||||
defineOptions({ name: "withdrawApply" });
|
||||
|
||||
// 模板 el-form 的 ref(原 ref="searchForm",与 data 同名会互相覆盖,改名为 searchFormRef)
|
||||
const searchFormRef = ref(null);
|
||||
// 模板 el-table 的 ref
|
||||
const table = ref(null);
|
||||
|
||||
const modalTitle = ref("");
|
||||
const loading = ref(true);
|
||||
const audit = ref("");
|
||||
const roleModalVisible = ref(false);
|
||||
const queryModalVisible = ref(false);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
applyStatus: "",
|
||||
});
|
||||
const selectDate = ref(null);
|
||||
const submitLoading = ref(false);
|
||||
const selectList = ref([]);
|
||||
const selectCount = ref(0);
|
||||
const showList = ref({});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
function paramTypeFilter(val) {
|
||||
if (val === "APPLY") return "申请中";
|
||||
if (val === "VIA_AUDITING") return "审核通过(提现成功)";
|
||||
if (val === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (val === "FAIL_AUDITING") return "审核拒绝";
|
||||
if (val === "SUCCESS") return "提现成功";
|
||||
if (val === "ERROR") return "提现失败";
|
||||
return "未知状态";
|
||||
}
|
||||
function applyStatusText(status) {
|
||||
if (status === "APPLY") return "申请中";
|
||||
if (status === "VIA_AUDITING") return "审核通过";
|
||||
if (status === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (status === "SUCCESS") return "提现成功";
|
||||
if (status === "ERROR") return "提现失败";
|
||||
return "审核拒绝";
|
||||
}
|
||||
function applyStatusTagType(status) {
|
||||
if (status === "APPLY") return "warning";
|
||||
if (status === "VIA_AUDITING") return "success";
|
||||
if (status === "WAIT_USER_CONFIRM") return "warning";
|
||||
if (status === "SUCCESS") return "primary";
|
||||
if (status === "ERROR") return "primary";
|
||||
return "danger";
|
||||
}
|
||||
function openAudit(row) {
|
||||
showList.value = { ...row };
|
||||
audit.value = "";
|
||||
roleModalVisible.value = true;
|
||||
}
|
||||
function openQuery(row) {
|
||||
showList.value = { ...row };
|
||||
modalTitle.value = "查看";
|
||||
queryModalVisible.value = true;
|
||||
}
|
||||
function submitRole(res) {
|
||||
const params = {};
|
||||
params.applyId = showList.value.id;
|
||||
params.result = res;
|
||||
params.remark = audit.value;
|
||||
if (res === false && params.remark === "") {
|
||||
ElMessage.error("审核备注不能为空");
|
||||
return;
|
||||
}
|
||||
submitLoading.value = true;
|
||||
withdrawApply(params)
|
||||
.then((result) => {
|
||||
const success = result === true || (result && result.success === true);
|
||||
if (success) {
|
||||
ElMessage.success("操作成功");
|
||||
roleModalVisible.value = false;
|
||||
queryModalVisible.value = false;
|
||||
audit.value = "";
|
||||
showList.value = {};
|
||||
getDataList();
|
||||
}
|
||||
this.submitLoading = true;
|
||||
withdrawApply(params)
|
||||
.then((result) => {
|
||||
const success = result === true || (result && result.success === true);
|
||||
if (success) {
|
||||
ElMessage.success("操作成功");
|
||||
this.roleModalVisible = false;
|
||||
this.queryModalVisible = false;
|
||||
this.audit = "";
|
||||
this.showList = {};
|
||||
this.getDataList();
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
handleReset() {
|
||||
this.$refs.searchForm.resetFields();
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.selectDate = null;
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
this.searchForm.memberName = "";
|
||||
this.getDataList();
|
||||
},
|
||||
changeSort(e) {
|
||||
this.searchForm.sort = e.prop || e.key;
|
||||
this.searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
|
||||
if (!e.order) {
|
||||
this.searchForm.order = "";
|
||||
}
|
||||
this.getDataList();
|
||||
},
|
||||
clearSelectAll() {
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clearSelection();
|
||||
}
|
||||
},
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserWithdrawApply(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false;
|
||||
});
|
||||
}
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getDataList();
|
||||
clearSelectAll();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getDataList();
|
||||
}
|
||||
function handleReset() {
|
||||
searchFormRef.value.resetFields();
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
selectDate.value = null;
|
||||
searchForm.startDate = "";
|
||||
searchForm.endDate = "";
|
||||
searchForm.memberName = "";
|
||||
getDataList();
|
||||
}
|
||||
function changeSort(e) {
|
||||
searchForm.sort = e.prop || e.key;
|
||||
searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
|
||||
if (!e.order) {
|
||||
searchForm.order = "";
|
||||
}
|
||||
getDataList();
|
||||
}
|
||||
function clearSelectAll() {
|
||||
if (table.value) {
|
||||
table.value.clearSelection();
|
||||
}
|
||||
}
|
||||
function changeSelect(e) {
|
||||
selectList.value = e;
|
||||
selectCount.value = e.length;
|
||||
}
|
||||
function selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
searchForm.startDate = v[0];
|
||||
searchForm.endDate = v[1];
|
||||
} else {
|
||||
searchForm.startDate = "";
|
||||
searchForm.endDate = "";
|
||||
}
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getUserWithdrawApply(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ops a {
|
||||
|
||||
@@ -343,7 +343,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, computed, nextTick, onMounted } from "vue";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import { getPlatformCoupon } from "@/api/promotion";
|
||||
import { formatPromotionCouponValidityHtml } from "@/utils/promotions";
|
||||
@@ -351,6 +352,8 @@ import couponTemplate from "@/views/promotions/coupon/coupon.vue";
|
||||
import uploadPicInput from "@/components/lili/upload-pic-input.vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
defineOptions({ name: "memberBenefit" });
|
||||
|
||||
const GIFT_POINT = "GIFT_POINT";
|
||||
const COUPON_PACKAGE = "COUPON_PACKAGE";
|
||||
|
||||
@@ -368,496 +371,490 @@ const buildDefaultForm = () => ({
|
||||
couponPackageRows: [],
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "memberBenefit",
|
||||
components: {
|
||||
uploadPicInput,
|
||||
couponTemplate,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
benefitTypeOptions: [],
|
||||
loading: false,
|
||||
total: 0,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
// 模板 ref(couponPicker 为优惠券选择组件,addForm/editForm 为表单)
|
||||
const couponPicker = ref(null);
|
||||
const addForm = ref(null);
|
||||
const editForm = ref(null);
|
||||
// 动态 ref 映射表(原 this.$refs[refName])
|
||||
const formRefs = { addForm, editForm };
|
||||
|
||||
const benefitTypeOptions = ref([]);
|
||||
const loading = ref(false);
|
||||
const total = ref(0);
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const data = ref([]);
|
||||
const addFlag = ref(false);
|
||||
const editFlag = ref(false);
|
||||
const submitAddLoading = ref(false);
|
||||
const submitEditLoading = ref(false);
|
||||
const formAdd = ref(buildDefaultForm());
|
||||
const formEdit = ref(buildDefaultForm());
|
||||
const couponPickerVisible = ref(false);
|
||||
const couponPickerWhich = ref("add");
|
||||
|
||||
// 动态表单映射表(原 this[formKey])
|
||||
const formMap = { formAdd, formEdit };
|
||||
|
||||
const rulesAdd = computed(() => buildFormRules("add"));
|
||||
const rulesEdit = computed(() => buildFormRules("edit"));
|
||||
const couponPickerSelectedList = computed(() => {
|
||||
const form = couponPickerWhich.value === "add" ? formAdd.value : formEdit.value;
|
||||
return (form.couponPackageRows || []).map((r) => ({
|
||||
id: r.couponId,
|
||||
couponName: r.couponName || "",
|
||||
}));
|
||||
});
|
||||
|
||||
function benefitTypeLabel(v) {
|
||||
if (!v) return "-";
|
||||
const opt = benefitTypeOptions.value.find((o) => o.value === v);
|
||||
return opt ? opt.description : v;
|
||||
}
|
||||
function touchFormField(refName, field) {
|
||||
nextTick(() => {
|
||||
const ref = formRefs[refName]?.value;
|
||||
if (ref && typeof ref.validateField === "function") {
|
||||
// validateField rejects on failure; catch to avoid dev-server [object Object] overlay
|
||||
ref.validateField(field, () => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
function onCouponQuantityChange(which, index, val) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
formMap[formKey].value.couponPackageRows[index].quantity = val;
|
||||
touchFormField(refName, "couponPackageRows");
|
||||
}
|
||||
function buildFormRules(which) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
return {
|
||||
benefitType: [{ required: true, message: "请选择权益类型", trigger: "change" }],
|
||||
benefitName: [{ required: true, message: "请输入权益名称", trigger: "blur" }],
|
||||
benefitLogo: [{ required: true, message: "请配置权益LOGO", trigger: "change" }],
|
||||
benefitSort: [{ required: true, type: "number", message: "请输入排序", trigger: "change" }],
|
||||
benefitState: [{ required: true, message: "请选择启用状态", trigger: "change" }],
|
||||
giftPoint: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const form = formMap[formKey].value;
|
||||
validateGiftPoint(form, value, callback);
|
||||
},
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
data: [],
|
||||
addFlag: false,
|
||||
editFlag: false,
|
||||
submitAddLoading: false,
|
||||
submitEditLoading: false,
|
||||
formAdd: buildDefaultForm(),
|
||||
formEdit: buildDefaultForm(),
|
||||
couponPickerVisible: false,
|
||||
couponPickerWhich: "add",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
rulesAdd() {
|
||||
return this.buildFormRules("add");
|
||||
},
|
||||
rulesEdit() {
|
||||
return this.buildFormRules("edit");
|
||||
},
|
||||
couponPickerSelectedList() {
|
||||
const form = this.couponPickerWhich === "add" ? this.formAdd : this.formEdit;
|
||||
return (form.couponPackageRows || []).map((r) => ({
|
||||
id: r.couponId,
|
||||
couponName: r.couponName || "",
|
||||
],
|
||||
couponPackageRows: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const form = formMap[formKey].value;
|
||||
validateCouponPackage(form, callback);
|
||||
},
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
function validateGiftPoint(form, value, callback) {
|
||||
if (form.benefitType !== GIFT_POINT) return callback();
|
||||
if (value === null || value === undefined || value === "") {
|
||||
return callback(new Error("请输入赠送积分"));
|
||||
}
|
||||
const n = Number(value);
|
||||
if (Number.isNaN(n) || n < 0 || n > 99999) {
|
||||
return callback(new Error("赠送积分范围为 0-99999"));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
function validateCouponPackage(form, callback) {
|
||||
if (form.benefitType !== COUPON_PACKAGE) return callback();
|
||||
const rows = form.couponPackageRows || [];
|
||||
if (!rows.length) {
|
||||
return callback(new Error("请添加至少一张优惠券"));
|
||||
}
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const q = Number(rows[i].quantity);
|
||||
if (Number.isNaN(q) || q < 1 || q > 10) {
|
||||
return callback(new Error("每张券赠送张数需在 1~10 之间"));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
function formatCouponFace(row) {
|
||||
if (!row) return "-";
|
||||
if (row.price !== undefined && row.price !== null && row.price !== "") {
|
||||
return `¥${row.price}`;
|
||||
}
|
||||
if (row.couponDiscount !== undefined && row.couponDiscount !== null && row.couponDiscount !== "") {
|
||||
return `${row.couponDiscount}折`;
|
||||
}
|
||||
return "-";
|
||||
}
|
||||
function formatCouponValidity(row) {
|
||||
return formatPromotionCouponValidityHtml(row);
|
||||
}
|
||||
function buildCouponDisplayRow(detail, quantity) {
|
||||
const qty = Math.min(10, Math.max(1, Number(quantity) || 1));
|
||||
return {
|
||||
couponId: detail.id,
|
||||
quantity: qty,
|
||||
couponName: detail.couponName || "",
|
||||
faceValueLabel: formatCouponFace(detail),
|
||||
validRange: formatCouponValidity(detail),
|
||||
};
|
||||
}
|
||||
function buildBenefitConfigString(slice) {
|
||||
const { benefitType, giftPoint, couponPackageRows } = slice;
|
||||
if (benefitType === GIFT_POINT) {
|
||||
return JSON.stringify({ giftPoint: Number(giftPoint) });
|
||||
}
|
||||
if (benefitType === COUPON_PACKAGE) {
|
||||
const coupons = (couponPackageRows || []).map((r) => ({
|
||||
couponId: String(r.couponId),
|
||||
quantity: Math.min(10, Math.max(1, Number(r.quantity) || 1)),
|
||||
}));
|
||||
return JSON.stringify({ coupons });
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function parseGiftPointFromConfig(benefitType, benefitConfigStr) {
|
||||
if (benefitType !== GIFT_POINT || !benefitConfigStr) return null;
|
||||
try {
|
||||
const o = JSON.parse(benefitConfigStr);
|
||||
if (o && typeof o.giftPoint !== "undefined") {
|
||||
const n = Number(o.giftPoint);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
} catch (e) {
|
||||
/* ignore */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function onAddBenefitTypeChange(val) {
|
||||
if (val !== GIFT_POINT) {
|
||||
formAdd.value.giftPoint = null;
|
||||
}
|
||||
if (val !== COUPON_PACKAGE) {
|
||||
formAdd.value.couponPackageRows = [];
|
||||
}
|
||||
if (addForm.value && val !== GIFT_POINT) {
|
||||
touchFormField("addForm", "giftPoint");
|
||||
}
|
||||
if (addForm.value && val !== COUPON_PACKAGE) {
|
||||
touchFormField("addForm", "couponPackageRows");
|
||||
}
|
||||
}
|
||||
function onEditBenefitTypeChange(val) {
|
||||
if (val !== GIFT_POINT) {
|
||||
formEdit.value.giftPoint = null;
|
||||
}
|
||||
if (val !== COUPON_PACKAGE) {
|
||||
formEdit.value.couponPackageRows = [];
|
||||
}
|
||||
if (editForm.value && val !== GIFT_POINT) {
|
||||
touchFormField("editForm", "giftPoint");
|
||||
}
|
||||
if (editForm.value && val !== COUPON_PACKAGE) {
|
||||
touchFormField("editForm", "couponPackageRows");
|
||||
}
|
||||
}
|
||||
function parseCouponsFromConfig(str) {
|
||||
if (!str) return [];
|
||||
try {
|
||||
const o = JSON.parse(str);
|
||||
if (o && Array.isArray(o.coupons)) {
|
||||
return o.coupons.map((c) => ({
|
||||
couponId: c.couponId,
|
||||
quantity: c.quantity,
|
||||
}));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
benefitTypeLabel(v) {
|
||||
if (!v) return "-";
|
||||
const opt = this.benefitTypeOptions.find((o) => o.value === v);
|
||||
return opt ? opt.description : v;
|
||||
},
|
||||
touchFormField(refName, field) {
|
||||
this.$nextTick(() => {
|
||||
const ref = this.$refs[refName];
|
||||
if (ref && typeof ref.validateField === "function") {
|
||||
// validateField rejects on failure; catch to avoid dev-server [object Object] overlay
|
||||
ref.validateField(field, () => {});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
/* ignore */
|
||||
}
|
||||
return [];
|
||||
}
|
||||
function normalizeCouponFaceFromDetail(item) {
|
||||
let face = formatCouponFace(item);
|
||||
if (face !== "-") return face;
|
||||
const raw = item.faceValueText;
|
||||
if (raw == null || raw === "") return "-";
|
||||
return String(raw)
|
||||
.replace(/^减免现金\s*/, "")
|
||||
.replace(/^减免\s*/, "")
|
||||
.trim() || "-";
|
||||
}
|
||||
function mapCouponItemsToPackageRows(items) {
|
||||
if (!Array.isArray(items)) return [];
|
||||
return items.map((item) => {
|
||||
const face = normalizeCouponFaceFromDetail(item);
|
||||
const validHtml = item.validityText
|
||||
? String(item.validityText).replace(/\n/g, "<br/>")
|
||||
: "-";
|
||||
return {
|
||||
couponId: item.couponId,
|
||||
quantity: Math.min(10, Math.max(1, Number(item.quantity) || 1)),
|
||||
couponName: item.couponName || "",
|
||||
faceValueLabel: face,
|
||||
validRange: validHtml,
|
||||
};
|
||||
});
|
||||
}
|
||||
async function hydrateCouponRowsForEdit(snippets) {
|
||||
const rows = [];
|
||||
for (const s of snippets) {
|
||||
const cid = s.couponId;
|
||||
const qty = s.quantity;
|
||||
try {
|
||||
const res = await getPlatformCoupon(cid);
|
||||
if (res && res.success && res.result) {
|
||||
rows.push(buildCouponDisplayRow(res.result, qty));
|
||||
} else {
|
||||
rows.push({
|
||||
couponId: cid,
|
||||
quantity: Math.min(10, Math.max(1, Number(qty) || 1)),
|
||||
couponName: String(cid),
|
||||
faceValueLabel: "-",
|
||||
validRange: "-",
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
rows.push({
|
||||
couponId: cid,
|
||||
quantity: Math.min(10, Math.max(1, Number(qty) || 1)),
|
||||
couponName: String(cid),
|
||||
faceValueLabel: "-",
|
||||
validRange: "-",
|
||||
});
|
||||
},
|
||||
onCouponQuantityChange(which, index, val) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
this[formKey].couponPackageRows[index].quantity = val;
|
||||
this.touchFormField(refName, "couponPackageRows");
|
||||
},
|
||||
buildFormRules(which) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
return {
|
||||
benefitType: [{ required: true, message: "请选择权益类型", trigger: "change" }],
|
||||
benefitName: [{ required: true, message: "请输入权益名称", trigger: "blur" }],
|
||||
benefitLogo: [{ required: true, message: "请配置权益LOGO", trigger: "change" }],
|
||||
benefitSort: [{ required: true, type: "number", message: "请输入排序", trigger: "change" }],
|
||||
benefitState: [{ required: true, message: "请选择启用状态", trigger: "change" }],
|
||||
giftPoint: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const form = this[formKey];
|
||||
this.validateGiftPoint(form, value, callback);
|
||||
},
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
couponPackageRows: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const form = this[formKey];
|
||||
this.validateCouponPackage(form, callback);
|
||||
},
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
formEdit.value.couponPackageRows = rows;
|
||||
}
|
||||
function handleCouponPickerClose() {
|
||||
couponPickerVisible.value = false;
|
||||
}
|
||||
function openCouponPicker(which) {
|
||||
couponPickerWhich.value = which;
|
||||
couponPickerVisible.value = true;
|
||||
}
|
||||
function confirmCouponPicker() {
|
||||
const list = couponPicker.value?.getSelection?.() || [];
|
||||
if (!list.length) {
|
||||
ElMessage.warning("请至少选择一张优惠券");
|
||||
return;
|
||||
}
|
||||
onCouponTemplateSelected(list);
|
||||
couponPickerVisible.value = false;
|
||||
}
|
||||
function onCouponTemplateSelected(selectedRows) {
|
||||
const which = couponPickerWhich.value;
|
||||
const form = which === "add" ? formAdd.value : formEdit.value;
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
const list = selectedRows || [];
|
||||
const rows = list.map((row) => {
|
||||
const existing = (form.couponPackageRows || []).find((r) => String(r.couponId) === String(row.id));
|
||||
const qty = existing ? existing.quantity : 1;
|
||||
return buildCouponDisplayRow(row, qty);
|
||||
});
|
||||
form.couponPackageRows = rows;
|
||||
touchFormField(refName, "couponPackageRows");
|
||||
}
|
||||
function removeCouponRow(which, index) {
|
||||
const form = which === "add" ? formAdd.value : formEdit.value;
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
form.couponPackageRows.splice(index, 1);
|
||||
touchFormField(refName, "couponPackageRows");
|
||||
}
|
||||
function init() {
|
||||
loadBenefitTypes();
|
||||
getData();
|
||||
}
|
||||
function loadBenefitTypes() {
|
||||
API_Member.getMemberBenefitTypes().then((res) => {
|
||||
if (res && res.success && Array.isArray(res.result)) {
|
||||
benefitTypeOptions.value = res.result;
|
||||
} else {
|
||||
benefitTypeOptions.value = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function changePage(page) {
|
||||
searchForm.value.pageNumber = page;
|
||||
getData();
|
||||
}
|
||||
function changePageSize(size) {
|
||||
searchForm.value.pageSize = size;
|
||||
searchForm.value.pageNumber = 1;
|
||||
getData();
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
const params = { ...searchForm.value };
|
||||
API_Member.getMemberBenefitByPage(params).then((res) => {
|
||||
loading.value = false;
|
||||
if (res && res.success && res.result) {
|
||||
data.value = Array.isArray(res.result.records) ? res.result.records : [];
|
||||
total.value = Number(res.result.total) || 0;
|
||||
} else {
|
||||
data.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
function openAdd() {
|
||||
addFlag.value = true;
|
||||
submitAddLoading.value = false;
|
||||
nextTick(() => {
|
||||
if (addForm.value) addForm.value.resetFields();
|
||||
formAdd.value = buildDefaultForm();
|
||||
});
|
||||
}
|
||||
function submitAdd() {
|
||||
if (!addForm.value) {
|
||||
ElMessage.warning("表单未就绪,请稍后重试");
|
||||
return;
|
||||
}
|
||||
addForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitAddLoading.value = true;
|
||||
const { giftPoint, couponPackageRows, ...rest } = formAdd.value;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitConfig: buildBenefitConfigString({
|
||||
benefitType: formAdd.value.benefitType,
|
||||
giftPoint,
|
||||
couponPackageRows,
|
||||
}),
|
||||
};
|
||||
API_Member.addMemberBenefit(payload).then((res) => {
|
||||
submitAddLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
addFlag.value = false;
|
||||
getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
} else {
|
||||
ElMessage.error("添加失败");
|
||||
}
|
||||
}).catch(() => {
|
||||
submitAddLoading.value = false;
|
||||
ElMessage.error("网络异常,请稍后重试");
|
||||
});
|
||||
});
|
||||
}
|
||||
function openEdit(row) {
|
||||
editFlag.value = true;
|
||||
submitEditLoading.value = false;
|
||||
nextTick(() => {
|
||||
if (editForm.value) editForm.value.resetFields();
|
||||
});
|
||||
API_Member.getMemberBenefit(row.id).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
const raw = res.result;
|
||||
const detail = raw.benefit != null ? raw.benefit : raw;
|
||||
const couponItems = raw.couponItems;
|
||||
const bt = detail.benefitType || "";
|
||||
const parsed = parseGiftPointFromConfig(bt, detail.benefitConfig || "");
|
||||
const couponSnippets = parseCouponsFromConfig(detail.benefitConfig || "");
|
||||
|
||||
let couponRows = [];
|
||||
if (bt === COUPON_PACKAGE && Array.isArray(couponItems) && couponItems.length) {
|
||||
couponRows = mapCouponItemsToPackageRows(couponItems);
|
||||
}
|
||||
|
||||
formEdit.value = {
|
||||
id: detail.id || row.id || "",
|
||||
benefitName: detail.benefitName || "",
|
||||
benefitCode: detail.benefitCode || "",
|
||||
benefitType: bt,
|
||||
benefitLogo: detail.benefitLogo || "",
|
||||
benefitDesc: detail.benefitDesc || "",
|
||||
benefitSort: Number(detail.benefitSort) > 0 ? Number(detail.benefitSort) : 1,
|
||||
benefitState: detail.benefitState || "OPEN",
|
||||
benefitConfig: detail.benefitConfig || "",
|
||||
giftPoint: bt === GIFT_POINT ? (parsed !== null ? parsed : null) : null,
|
||||
couponPackageRows: couponRows,
|
||||
};
|
||||
},
|
||||
validateGiftPoint(form, value, callback) {
|
||||
if (form.benefitType !== GIFT_POINT) return callback();
|
||||
if (value === null || value === undefined || value === "") {
|
||||
return callback(new Error("请输入赠送积分"));
|
||||
|
||||
if (bt === COUPON_PACKAGE && couponRows.length === 0 && couponSnippets.length) {
|
||||
hydrateCouponRowsForEdit(couponSnippets);
|
||||
}
|
||||
const n = Number(value);
|
||||
if (Number.isNaN(n) || n < 0 || n > 99999) {
|
||||
return callback(new Error("赠送积分范围为 0-99999"));
|
||||
}
|
||||
});
|
||||
}
|
||||
function submitEdit() {
|
||||
if (!editForm.value) {
|
||||
ElMessage.warning("表单未就绪,请稍后重试");
|
||||
return;
|
||||
}
|
||||
editForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitEditLoading.value = true;
|
||||
const { id, giftPoint, couponPackageRows, ...rest } = formEdit.value;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitConfig: buildBenefitConfigString({
|
||||
benefitType: formEdit.value.benefitType,
|
||||
giftPoint,
|
||||
couponPackageRows,
|
||||
}),
|
||||
};
|
||||
API_Member.updateMemberBenefit(id, payload).then((res) => {
|
||||
submitEditLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
editFlag.value = false;
|
||||
getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
} else {
|
||||
ElMessage.error("修改失败");
|
||||
}
|
||||
callback();
|
||||
},
|
||||
validateCouponPackage(form, callback) {
|
||||
if (form.benefitType !== COUPON_PACKAGE) return callback();
|
||||
const rows = form.couponPackageRows || [];
|
||||
if (!rows.length) {
|
||||
return callback(new Error("请添加至少一张优惠券"));
|
||||
}
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const q = Number(rows[i].quantity);
|
||||
if (Number.isNaN(q) || q < 1 || q > 10) {
|
||||
return callback(new Error("每张券赠送张数需在 1~10 之间"));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
},
|
||||
formatCouponFace(row) {
|
||||
if (!row) return "-";
|
||||
if (row.price !== undefined && row.price !== null && row.price !== "") {
|
||||
return `¥${row.price}`;
|
||||
}
|
||||
if (row.couponDiscount !== undefined && row.couponDiscount !== null && row.couponDiscount !== "") {
|
||||
return `${row.couponDiscount}折`;
|
||||
}
|
||||
return "-";
|
||||
},
|
||||
formatCouponValidity(row) {
|
||||
return formatPromotionCouponValidityHtml(row);
|
||||
},
|
||||
buildCouponDisplayRow(detail, quantity) {
|
||||
const qty = Math.min(10, Math.max(1, Number(quantity) || 1));
|
||||
return {
|
||||
couponId: detail.id,
|
||||
quantity: qty,
|
||||
couponName: detail.couponName || "",
|
||||
faceValueLabel: this.formatCouponFace(detail),
|
||||
validRange: this.formatCouponValidity(detail),
|
||||
};
|
||||
},
|
||||
buildBenefitConfigString(slice) {
|
||||
const { benefitType, giftPoint, couponPackageRows } = slice;
|
||||
if (benefitType === GIFT_POINT) {
|
||||
return JSON.stringify({ giftPoint: Number(giftPoint) });
|
||||
}
|
||||
if (benefitType === COUPON_PACKAGE) {
|
||||
const coupons = (couponPackageRows || []).map((r) => ({
|
||||
couponId: String(r.couponId),
|
||||
quantity: Math.min(10, Math.max(1, Number(r.quantity) || 1)),
|
||||
}));
|
||||
return JSON.stringify({ coupons });
|
||||
}
|
||||
return "";
|
||||
},
|
||||
parseGiftPointFromConfig(benefitType, benefitConfigStr) {
|
||||
if (benefitType !== GIFT_POINT || !benefitConfigStr) return null;
|
||||
try {
|
||||
const o = JSON.parse(benefitConfigStr);
|
||||
if (o && typeof o.giftPoint !== "undefined") {
|
||||
const n = Number(o.giftPoint);
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
} catch (e) {
|
||||
/* ignore */
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onAddBenefitTypeChange(val) {
|
||||
if (val !== GIFT_POINT) {
|
||||
this.formAdd.giftPoint = null;
|
||||
}
|
||||
if (val !== COUPON_PACKAGE) {
|
||||
this.formAdd.couponPackageRows = [];
|
||||
}
|
||||
if (this.$refs.addForm && val !== GIFT_POINT) {
|
||||
this.touchFormField("addForm", "giftPoint");
|
||||
}
|
||||
if (this.$refs.addForm && val !== COUPON_PACKAGE) {
|
||||
this.touchFormField("addForm", "couponPackageRows");
|
||||
}
|
||||
},
|
||||
onEditBenefitTypeChange(val) {
|
||||
if (val !== GIFT_POINT) {
|
||||
this.formEdit.giftPoint = null;
|
||||
}
|
||||
if (val !== COUPON_PACKAGE) {
|
||||
this.formEdit.couponPackageRows = [];
|
||||
}
|
||||
if (this.$refs.editForm && val !== GIFT_POINT) {
|
||||
this.touchFormField("editForm", "giftPoint");
|
||||
}
|
||||
if (this.$refs.editForm && val !== COUPON_PACKAGE) {
|
||||
this.touchFormField("editForm", "couponPackageRows");
|
||||
}
|
||||
},
|
||||
parseCouponsFromConfig(str) {
|
||||
if (!str) return [];
|
||||
try {
|
||||
const o = JSON.parse(str);
|
||||
if (o && Array.isArray(o.coupons)) {
|
||||
return o.coupons.map((c) => ({
|
||||
couponId: c.couponId,
|
||||
quantity: c.quantity,
|
||||
}));
|
||||
}
|
||||
} catch (e) {
|
||||
/* ignore */
|
||||
}
|
||||
return [];
|
||||
},
|
||||
normalizeCouponFaceFromDetail(item) {
|
||||
let face = this.formatCouponFace(item);
|
||||
if (face !== "-") return face;
|
||||
const raw = item.faceValueText;
|
||||
if (raw == null || raw === "") return "-";
|
||||
return String(raw)
|
||||
.replace(/^减免现金\s*/, "")
|
||||
.replace(/^减免\s*/, "")
|
||||
.trim() || "-";
|
||||
},
|
||||
mapCouponItemsToPackageRows(items) {
|
||||
if (!Array.isArray(items)) return [];
|
||||
return items.map((item) => {
|
||||
const face = this.normalizeCouponFaceFromDetail(item);
|
||||
const validHtml = item.validityText
|
||||
? String(item.validityText).replace(/\n/g, "<br/>")
|
||||
: "-";
|
||||
return {
|
||||
couponId: item.couponId,
|
||||
quantity: Math.min(10, Math.max(1, Number(item.quantity) || 1)),
|
||||
couponName: item.couponName || "",
|
||||
faceValueLabel: face,
|
||||
validRange: validHtml,
|
||||
};
|
||||
});
|
||||
},
|
||||
async hydrateCouponRowsForEdit(snippets) {
|
||||
const rows = [];
|
||||
for (const s of snippets) {
|
||||
const cid = s.couponId;
|
||||
const qty = s.quantity;
|
||||
try {
|
||||
const res = await getPlatformCoupon(cid);
|
||||
if (res && res.success && res.result) {
|
||||
rows.push(this.buildCouponDisplayRow(res.result, qty));
|
||||
} else {
|
||||
rows.push({
|
||||
couponId: cid,
|
||||
quantity: Math.min(10, Math.max(1, Number(qty) || 1)),
|
||||
couponName: String(cid),
|
||||
faceValueLabel: "-",
|
||||
validRange: "-",
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
rows.push({
|
||||
couponId: cid,
|
||||
quantity: Math.min(10, Math.max(1, Number(qty) || 1)),
|
||||
couponName: String(cid),
|
||||
faceValueLabel: "-",
|
||||
validRange: "-",
|
||||
});
|
||||
}
|
||||
}
|
||||
this.formEdit.couponPackageRows = rows;
|
||||
},
|
||||
handleCouponPickerClose() {
|
||||
this.couponPickerVisible = false;
|
||||
},
|
||||
openCouponPicker(which) {
|
||||
this.couponPickerWhich = which;
|
||||
this.couponPickerVisible = true;
|
||||
},
|
||||
confirmCouponPicker() {
|
||||
const list = this.$refs.couponPicker?.getSelection?.() || [];
|
||||
if (!list.length) {
|
||||
ElMessage.warning("请至少选择一张优惠券");
|
||||
return;
|
||||
}
|
||||
this.onCouponTemplateSelected(list);
|
||||
this.couponPickerVisible = false;
|
||||
},
|
||||
onCouponTemplateSelected(selectedRows) {
|
||||
const which = this.couponPickerWhich;
|
||||
const form = which === "add" ? this.formAdd : this.formEdit;
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
const list = selectedRows || [];
|
||||
const rows = list.map((row) => {
|
||||
const existing = (form.couponPackageRows || []).find((r) => String(r.couponId) === String(row.id));
|
||||
const qty = existing ? existing.quantity : 1;
|
||||
return this.buildCouponDisplayRow(row, qty);
|
||||
});
|
||||
form.couponPackageRows = rows;
|
||||
this.touchFormField(refName, "couponPackageRows");
|
||||
},
|
||||
removeCouponRow(which, index) {
|
||||
const form = which === "add" ? this.formAdd : this.formEdit;
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
form.couponPackageRows.splice(index, 1);
|
||||
this.touchFormField(refName, "couponPackageRows");
|
||||
},
|
||||
init() {
|
||||
this.loadBenefitTypes();
|
||||
this.getData();
|
||||
},
|
||||
loadBenefitTypes() {
|
||||
API_Member.getMemberBenefitTypes().then((res) => {
|
||||
if (res && res.success && Array.isArray(res.result)) {
|
||||
this.benefitTypeOptions = res.result;
|
||||
}).catch(() => {
|
||||
submitEditLoading.value = false;
|
||||
ElMessage.error("网络异常,请稍后重试");
|
||||
});
|
||||
});
|
||||
}
|
||||
function onBenefitStateSwitch(row, checked) {
|
||||
const nextState = checked ? "OPEN" : "CLOSE";
|
||||
const prevState = row.benefitState;
|
||||
if (nextState === prevState) return;
|
||||
const text = checked ? "开启" : "关闭";
|
||||
ElMessageBox.confirm(`确定${text}该客户权益?`, "提示", { type: "warning" }).then(() => {
|
||||
row._benefitStateLoading = true;
|
||||
return API_Member.updateMemberBenefitState(row.id, nextState)
|
||||
.then((res) => {
|
||||
row._benefitStateLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success(`${text}成功`);
|
||||
row.benefitState = nextState;
|
||||
} else {
|
||||
this.benefitTypeOptions = [];
|
||||
getData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
row._benefitStateLoading = false;
|
||||
});
|
||||
},
|
||||
changePage(page) {
|
||||
this.searchForm.pageNumber = page;
|
||||
this.getData();
|
||||
},
|
||||
changePageSize(size) {
|
||||
this.searchForm.pageSize = size;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
const params = { ...this.searchForm };
|
||||
API_Member.getMemberBenefitByPage(params).then((res) => {
|
||||
this.loading = false;
|
||||
if (res && res.success && res.result) {
|
||||
this.data = Array.isArray(res.result.records) ? res.result.records : [];
|
||||
this.total = Number(res.result.total) || 0;
|
||||
} else {
|
||||
this.data = [];
|
||||
this.total = 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
openAdd() {
|
||||
this.addFlag = true;
|
||||
this.submitAddLoading = false;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.addForm) this.$refs.addForm.resetFields();
|
||||
this.formAdd = buildDefaultForm();
|
||||
});
|
||||
},
|
||||
submitAdd() {
|
||||
if (!this.$refs.addForm) {
|
||||
ElMessage.warning("表单未就绪,请稍后重试");
|
||||
return;
|
||||
}).catch(() => {});
|
||||
}
|
||||
function remove(row) {
|
||||
ElMessageBox.confirm("确定删除该客户权益?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberBenefit(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
this.$refs.addForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitAddLoading = true;
|
||||
const { giftPoint, couponPackageRows, ...rest } = this.formAdd;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitConfig: this.buildBenefitConfigString({
|
||||
benefitType: this.formAdd.benefitType,
|
||||
giftPoint,
|
||||
couponPackageRows,
|
||||
}),
|
||||
};
|
||||
API_Member.addMemberBenefit(payload).then((res) => {
|
||||
this.submitAddLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
this.addFlag = false;
|
||||
this.getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
} else {
|
||||
ElMessage.error("添加失败");
|
||||
}
|
||||
}).catch(() => {
|
||||
this.submitAddLoading = false;
|
||||
ElMessage.error("网络异常,请稍后重试");
|
||||
});
|
||||
});
|
||||
},
|
||||
openEdit(row) {
|
||||
this.editFlag = true;
|
||||
this.submitEditLoading = false;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.editForm) this.$refs.editForm.resetFields();
|
||||
});
|
||||
API_Member.getMemberBenefit(row.id).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
const raw = res.result;
|
||||
const detail = raw.benefit != null ? raw.benefit : raw;
|
||||
const couponItems = raw.couponItems;
|
||||
const bt = detail.benefitType || "";
|
||||
const parsed = this.parseGiftPointFromConfig(bt, detail.benefitConfig || "");
|
||||
const couponSnippets = this.parseCouponsFromConfig(detail.benefitConfig || "");
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
let couponRows = [];
|
||||
if (bt === COUPON_PACKAGE && Array.isArray(couponItems) && couponItems.length) {
|
||||
couponRows = this.mapCouponItemsToPackageRows(couponItems);
|
||||
}
|
||||
|
||||
this.formEdit = {
|
||||
id: detail.id || row.id || "",
|
||||
benefitName: detail.benefitName || "",
|
||||
benefitCode: detail.benefitCode || "",
|
||||
benefitType: bt,
|
||||
benefitLogo: detail.benefitLogo || "",
|
||||
benefitDesc: detail.benefitDesc || "",
|
||||
benefitSort: Number(detail.benefitSort) > 0 ? Number(detail.benefitSort) : 1,
|
||||
benefitState: detail.benefitState || "OPEN",
|
||||
benefitConfig: detail.benefitConfig || "",
|
||||
giftPoint: bt === GIFT_POINT ? (parsed !== null ? parsed : null) : null,
|
||||
couponPackageRows: couponRows,
|
||||
};
|
||||
|
||||
if (bt === COUPON_PACKAGE && couponRows.length === 0 && couponSnippets.length) {
|
||||
this.hydrateCouponRowsForEdit(couponSnippets);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
submitEdit() {
|
||||
if (!this.$refs.editForm) {
|
||||
ElMessage.warning("表单未就绪,请稍后重试");
|
||||
return;
|
||||
}
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitEditLoading = true;
|
||||
const { id, giftPoint, couponPackageRows, ...rest } = this.formEdit;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitConfig: this.buildBenefitConfigString({
|
||||
benefitType: this.formEdit.benefitType,
|
||||
giftPoint,
|
||||
couponPackageRows,
|
||||
}),
|
||||
};
|
||||
API_Member.updateMemberBenefit(id, payload).then((res) => {
|
||||
this.submitEditLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
this.editFlag = false;
|
||||
this.getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
} else {
|
||||
ElMessage.error("修改失败");
|
||||
}
|
||||
}).catch(() => {
|
||||
this.submitEditLoading = false;
|
||||
ElMessage.error("网络异常,请稍后重试");
|
||||
});
|
||||
});
|
||||
},
|
||||
onBenefitStateSwitch(row, checked) {
|
||||
const nextState = checked ? "OPEN" : "CLOSE";
|
||||
const prevState = row.benefitState;
|
||||
if (nextState === prevState) return;
|
||||
const text = checked ? "开启" : "关闭";
|
||||
ElMessageBox.confirm(`确定${text}该客户权益?`, "提示", { type: "warning" }).then(() => {
|
||||
row._benefitStateLoading = true;
|
||||
return API_Member.updateMemberBenefitState(row.id, nextState)
|
||||
.then((res) => {
|
||||
row._benefitStateLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success(`${text}成功`);
|
||||
row.benefitState = nextState;
|
||||
} else {
|
||||
this.getData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
row._benefitStateLoading = false;
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
remove(row) {
|
||||
ElMessageBox.confirm("确定删除该客户权益?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberBenefit(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="90px"
|
||||
@@ -78,7 +78,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import * as API_Member from "@/api/member";
|
||||
|
||||
const RULE_OPTIONS = [
|
||||
@@ -95,79 +96,76 @@ const RULE_OPTIONS = [
|
||||
{ value: "SHARE_BUY", label: "分享购买" },
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "memberGradeExperienceLog",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
total: 0,
|
||||
data: [],
|
||||
ruleOptions: RULE_OPTIONS,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
memberMobile: "",
|
||||
ruleKey: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
formatExperienceValue(row) {
|
||||
const v = row.value ?? row.variableExperience ?? row.experience ?? row.variableValue;
|
||||
return v == null ? "-" : v;
|
||||
},
|
||||
formatMaxValue(row) {
|
||||
const v = row.maxValue ?? row.maxExperience ?? row.limitValue;
|
||||
return v == null ? "-" : v;
|
||||
},
|
||||
findRuleName(ruleKey) {
|
||||
const hit = this.ruleOptions.find((item) => item.value === ruleKey);
|
||||
return hit ? hit.label : "";
|
||||
},
|
||||
init() {
|
||||
this.getData();
|
||||
},
|
||||
buildParams() {
|
||||
const params = {
|
||||
pageNumber: this.searchForm.pageNumber,
|
||||
pageSize: this.searchForm.pageSize,
|
||||
};
|
||||
if (this.searchForm.memberMobile) params.mobile = this.searchForm.memberMobile;
|
||||
if (this.searchForm.ruleKey) params.ruleKey = this.searchForm.ruleKey;
|
||||
return params;
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberExperienceByPage(this.buildParams())
|
||||
.then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.data = res.result.records || [];
|
||||
this.total = res.result.total || 0;
|
||||
} else {
|
||||
this.data = [];
|
||||
this.total = 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getData();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "memberGradeExperienceLog" });
|
||||
|
||||
const searchFormRef = ref(null);
|
||||
|
||||
const loading = ref(false);
|
||||
const total = ref(0);
|
||||
const data = ref([]);
|
||||
const ruleOptions = RULE_OPTIONS;
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
memberMobile: "",
|
||||
ruleKey: "",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
function formatExperienceValue(row) {
|
||||
const v = row.value ?? row.variableExperience ?? row.experience ?? row.variableValue;
|
||||
return v == null ? "-" : v;
|
||||
}
|
||||
function formatMaxValue(row) {
|
||||
const v = row.maxValue ?? row.maxExperience ?? row.limitValue;
|
||||
return v == null ? "-" : v;
|
||||
}
|
||||
function findRuleName(ruleKey) {
|
||||
const hit = ruleOptions.find((item) => item.value === ruleKey);
|
||||
return hit ? hit.label : "";
|
||||
}
|
||||
function init() {
|
||||
getData();
|
||||
}
|
||||
function buildParams() {
|
||||
const params = {
|
||||
pageNumber: searchForm.pageNumber,
|
||||
pageSize: searchForm.pageSize,
|
||||
};
|
||||
if (searchForm.memberMobile) params.mobile = searchForm.memberMobile;
|
||||
if (searchForm.ruleKey) params.ruleKey = searchForm.ruleKey;
|
||||
return params;
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
API_Member.getMemberExperienceByPage(buildParams())
|
||||
.then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
data.value = res.result.records || [];
|
||||
total.value = res.result.total || 0;
|
||||
} else {
|
||||
data.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
getData();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getData();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = v;
|
||||
getData();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -237,10 +237,13 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { getSetting, setSetting } from "@/api/index";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
defineOptions({ name: "memberGradeExperienceSetting" });
|
||||
|
||||
const RULE_OPTIONS = [
|
||||
{ ruleKey: "CONSUME", ruleName: "消费" },
|
||||
{ ruleKey: "REGISTER", ruleName: "注册" },
|
||||
@@ -268,176 +271,169 @@ const defaultForm = () => ({
|
||||
description: "",
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "memberGradeExperienceSetting",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
submitLoading: false,
|
||||
form: defaultForm(),
|
||||
const loading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const form = ref(defaultForm());
|
||||
|
||||
function formatInputValue(v) {
|
||||
return v == null ? "" : String(v);
|
||||
}
|
||||
function getRawInputValue(v) {
|
||||
return v && v.target ? v.target.value : v;
|
||||
}
|
||||
function updateRuleEnabled(index, enabled) {
|
||||
const item = form.value.items[index] || {};
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
enabled: !!enabled,
|
||||
};
|
||||
}
|
||||
function updateRuleValue(index, v) {
|
||||
const raw = getRawInputValue(v);
|
||||
const next = Number(raw);
|
||||
const item = form.value.items[index] || {};
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
value: Number.isFinite(next) ? next : null,
|
||||
};
|
||||
}
|
||||
function commitRuleValue(index) {
|
||||
const item = form.value.items[index] || {};
|
||||
const next = Number(item.value);
|
||||
let value = 1;
|
||||
if (Number.isFinite(next)) {
|
||||
if (next < 1) value = 1;
|
||||
else if (next > 100) value = 100;
|
||||
else value = Math.floor(next);
|
||||
}
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
value,
|
||||
};
|
||||
}
|
||||
function updateRuleMaxValue(index, v) {
|
||||
const raw = getRawInputValue(v);
|
||||
const item = form.value.items[index] || {};
|
||||
if (raw == null || raw === "") {
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
formatInputValue(v) {
|
||||
return v == null ? "" : String(v);
|
||||
},
|
||||
getRawInputValue(v) {
|
||||
return v && v.target ? v.target.value : v;
|
||||
},
|
||||
updateRuleEnabled(index, enabled) {
|
||||
const item = this.form.items[index] || {};
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
enabled: !!enabled,
|
||||
};
|
||||
},
|
||||
updateRuleValue(index, v) {
|
||||
const raw = this.getRawInputValue(v);
|
||||
const next = Number(raw);
|
||||
const item = this.form.items[index] || {};
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
value: Number.isFinite(next) ? next : null,
|
||||
};
|
||||
},
|
||||
commitRuleValue(index) {
|
||||
const item = this.form.items[index] || {};
|
||||
const next = Number(item.value);
|
||||
let value = 1;
|
||||
if (Number.isFinite(next)) {
|
||||
if (next < 1) value = 1;
|
||||
else if (next > 100) value = 100;
|
||||
else value = Math.floor(next);
|
||||
}
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
value,
|
||||
};
|
||||
},
|
||||
updateRuleMaxValue(index, v) {
|
||||
const raw = this.getRawInputValue(v);
|
||||
const item = this.form.items[index] || {};
|
||||
if (raw == null || raw === "") {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
};
|
||||
return;
|
||||
}
|
||||
const next = Number(raw);
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) ? next : null,
|
||||
};
|
||||
},
|
||||
commitRuleMaxValue(index) {
|
||||
const item = this.form.items[index] || {};
|
||||
if (item.maxValue == null || item.maxValue === "") {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
};
|
||||
return;
|
||||
}
|
||||
const next = Number(item.maxValue);
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) && next >= 1 ? Math.floor(next) : null,
|
||||
};
|
||||
},
|
||||
normalizeConfig(val) {
|
||||
if (!val) return {};
|
||||
if (typeof val === "string") {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (typeof val === "object") return val;
|
||||
return;
|
||||
}
|
||||
const next = Number(raw);
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) ? next : null,
|
||||
};
|
||||
}
|
||||
function commitRuleMaxValue(index) {
|
||||
const item = form.value.items[index] || {};
|
||||
if (item.maxValue == null || item.maxValue === "") {
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
};
|
||||
return;
|
||||
}
|
||||
const next = Number(item.maxValue);
|
||||
form.value.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) && next >= 1 ? Math.floor(next) : null,
|
||||
};
|
||||
}
|
||||
function normalizeConfig(val) {
|
||||
if (!val) return {};
|
||||
if (typeof val === "string") {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
return {};
|
||||
},
|
||||
normalizeItems(items) {
|
||||
const map = {};
|
||||
if (Array.isArray(items)) {
|
||||
items.forEach((item) => {
|
||||
if (!item || !item.ruleKey) return;
|
||||
map[item.ruleKey] = item;
|
||||
});
|
||||
}
|
||||
return RULE_OPTIONS.map((rule) => {
|
||||
const hit = map[rule.ruleKey] || {};
|
||||
return {
|
||||
ruleKey: rule.ruleKey,
|
||||
ruleName: hit.ruleName || rule.ruleName,
|
||||
enabled: !!hit.enabled,
|
||||
value: Number(hit.value) > 0 ? Number(hit.value) : 1,
|
||||
maxValue: hit.maxValue == null || hit.maxValue === "" ? null : Number(hit.maxValue),
|
||||
}
|
||||
}
|
||||
if (typeof val === "object") return val;
|
||||
return {};
|
||||
}
|
||||
function normalizeItems(items) {
|
||||
const map = {};
|
||||
if (Array.isArray(items)) {
|
||||
items.forEach((item) => {
|
||||
if (!item || !item.ruleKey) return;
|
||||
map[item.ruleKey] = item;
|
||||
});
|
||||
}
|
||||
return RULE_OPTIONS.map((rule) => {
|
||||
const hit = map[rule.ruleKey] || {};
|
||||
return {
|
||||
ruleKey: rule.ruleKey,
|
||||
ruleName: hit.ruleName || rule.ruleName,
|
||||
enabled: !!hit.enabled,
|
||||
value: Number(hit.value) > 0 ? Number(hit.value) : 1,
|
||||
maxValue: hit.maxValue == null || hit.maxValue === "" ? null : Number(hit.maxValue),
|
||||
};
|
||||
});
|
||||
}
|
||||
function loadData() {
|
||||
loading.value = true;
|
||||
getSetting("EXPERIENCE_SETTING")
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const cfg = normalizeConfig(res.result);
|
||||
form.value = {
|
||||
items: normalizeItems(cfg.items),
|
||||
description: cfg.description || "",
|
||||
};
|
||||
});
|
||||
},
|
||||
loadData() {
|
||||
this.loading = true;
|
||||
getSetting("EXPERIENCE_SETTING")
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const cfg = this.normalizeConfig(res.result);
|
||||
this.form = {
|
||||
items: this.normalizeItems(cfg.items),
|
||||
description: cfg.description || "",
|
||||
};
|
||||
} else {
|
||||
this.form = defaultForm();
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
validateForm() {
|
||||
const invalid = this.form.items.find((item) => {
|
||||
const v = Number(item.value);
|
||||
if (!Number.isInteger(v) || v < 1 || v > 100) return true;
|
||||
if (item.maxValue != null && item.maxValue !== "") {
|
||||
const m = Number(item.maxValue);
|
||||
if (!Number.isInteger(m) || m < 1) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (invalid) {
|
||||
ElMessage.error("请检查经验值配置,经验值范围为1-100,限额需为正整数");
|
||||
return false;
|
||||
} else {
|
||||
form.value = defaultForm();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
submit() {
|
||||
if (!this.validateForm()) return;
|
||||
const payload = {
|
||||
items: this.form.items.map((item) => ({
|
||||
ruleKey: item.ruleKey,
|
||||
ruleName: item.ruleName,
|
||||
enabled: !!item.enabled,
|
||||
value: Number(item.value),
|
||||
maxValue: item.maxValue == null || item.maxValue === "" ? null : Number(item.maxValue),
|
||||
})),
|
||||
description: this.form.description || "",
|
||||
};
|
||||
this.submitLoading = true;
|
||||
setSetting("EXPERIENCE_SETTING", payload)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("保存成功");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
function validateForm() {
|
||||
const invalid = form.value.items.find((item) => {
|
||||
const v = Number(item.value);
|
||||
if (!Number.isInteger(v) || v < 1 || v > 100) return true;
|
||||
if (item.maxValue != null && item.maxValue !== "") {
|
||||
const m = Number(item.maxValue);
|
||||
if (!Number.isInteger(m) || m < 1) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (invalid) {
|
||||
ElMessage.error("请检查经验值配置,经验值范围为1-100,限额需为正整数");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function submit() {
|
||||
if (!validateForm()) return;
|
||||
const payload = {
|
||||
items: form.value.items.map((item) => ({
|
||||
ruleKey: item.ruleKey,
|
||||
ruleName: item.ruleName,
|
||||
enabled: !!item.enabled,
|
||||
value: Number(item.value),
|
||||
maxValue: item.maxValue == null || item.maxValue === "" ? null : Number(item.maxValue),
|
||||
})),
|
||||
description: form.value.description || "",
|
||||
};
|
||||
submitLoading.value = true;
|
||||
setSetting("EXPERIENCE_SETTING", payload)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("保存成功");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -178,11 +178,14 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, nextTick, onMounted } from "vue";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import uploadPicInput from "@/components/lili/upload-pic-input";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
defineOptions({ name: "memberGrade" });
|
||||
|
||||
const buildDefaultForm = () => ({
|
||||
id: "",
|
||||
gradeName: "",
|
||||
@@ -209,254 +212,248 @@ function syncOrderedBenefitIds(prevOrder, selected) {
|
||||
return out;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "memberGrade",
|
||||
components: {
|
||||
uploadPicInput,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
data: [],
|
||||
addFlag: false,
|
||||
editFlag: false,
|
||||
submitAddLoading: false,
|
||||
submitEditLoading: false,
|
||||
formAdd: buildDefaultForm(),
|
||||
formEdit: buildDefaultForm(),
|
||||
addBenefitOrder: [],
|
||||
editBenefitOrder: [],
|
||||
benefitOptions: [],
|
||||
benefitTypeOptions: [],
|
||||
benefitOptionsLoading: false,
|
||||
editDetailLoading: false,
|
||||
rules: {
|
||||
gradeName: [{ required: true, message: "请输入等级名称", trigger: "blur" }],
|
||||
gradeImage: [{ required: true, message: "请上传等级图标", trigger: "change" }],
|
||||
requiredExperience: [{ required: true, type: "number", message: "请输入所需经验值", trigger: "change" }],
|
||||
gradeSort: [{ required: true, type: "number", message: "请输入等级排序", trigger: "change" }],
|
||||
gradeState: [{ required: true, message: "请选择等级开关", trigger: "change" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
benefitOptionLabel(b) {
|
||||
if (!b) return "";
|
||||
const name = b.benefitName || String(b.id);
|
||||
const opt = this.benefitTypeOptions.find((o) => o.value === b.benefitType);
|
||||
const typeText = opt ? opt.description : b.benefitType || "";
|
||||
return typeText ? `${name}(${typeText})` : name;
|
||||
},
|
||||
onAddBenefitIdsChange(val) {
|
||||
this.addBenefitOrder = syncOrderedBenefitIds(this.addBenefitOrder, val);
|
||||
},
|
||||
onEditBenefitIdsChange(val) {
|
||||
this.editBenefitOrder = syncOrderedBenefitIds(this.editBenefitOrder, val);
|
||||
},
|
||||
loadBenefitTypes() {
|
||||
API_Member.getMemberBenefitTypes().then((res) => {
|
||||
if (res && res.success && Array.isArray(res.result)) {
|
||||
this.benefitTypeOptions = res.result;
|
||||
} else {
|
||||
this.benefitTypeOptions = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
loadBenefitOptions() {
|
||||
this.benefitOptionsLoading = true;
|
||||
const pageSize = 500;
|
||||
const fetchPage = (pageNumber) =>
|
||||
API_Member.getMemberBenefitByPage({ pageNumber, pageSize, sort: "benefitSort", order: "asc" });
|
||||
return fetchPage(1)
|
||||
.then((res) => {
|
||||
if (!(res && res.success && res.result)) {
|
||||
this.benefitOptions = [];
|
||||
return;
|
||||
}
|
||||
const records = Array.isArray(res.result.records) ? res.result.records : [];
|
||||
const total = Number(res.result.total) || records.length;
|
||||
let all = records.slice();
|
||||
if (total > pageSize) {
|
||||
const pages = Math.ceil(total / pageSize);
|
||||
const rest = [];
|
||||
for (let p = 2; p <= pages; p++) {
|
||||
rest.push(fetchPage(p));
|
||||
}
|
||||
return Promise.all(rest).then((results) => {
|
||||
results.forEach((r) => {
|
||||
if (r && r.success && r.result && Array.isArray(r.result.records)) {
|
||||
all = all.concat(r.result.records);
|
||||
}
|
||||
});
|
||||
this.benefitOptions = all;
|
||||
});
|
||||
}
|
||||
this.benefitOptions = all;
|
||||
})
|
||||
.catch(() => {
|
||||
this.benefitOptions = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.benefitOptionsLoading = false;
|
||||
});
|
||||
},
|
||||
parseBenefitIdsFromString(str) {
|
||||
return String(str || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
},
|
||||
fillEditFormFromGrade(grade, benefitsOrderedIds) {
|
||||
this.formEdit = {
|
||||
id: grade.id || "",
|
||||
gradeName: grade.gradeName || "",
|
||||
isDefault: grade.isDefault === true,
|
||||
gradeImage: grade.gradeImage || "",
|
||||
gradeBackground: grade.gradeBackground || "",
|
||||
gradeFontColor: grade.gradeFontColor || "",
|
||||
requiredExperience: Number(grade.requiredExperience) > 0 ? Number(grade.requiredExperience) : 1,
|
||||
gradeSort: Number(grade.gradeSort) > 0 ? Number(grade.gradeSort) : 1,
|
||||
gradeState: grade.gradeState || "OPEN",
|
||||
benefitIds: grade.benefitIds || "",
|
||||
};
|
||||
this.editBenefitOrder = (benefitsOrderedIds || []).map((id) => String(id));
|
||||
},
|
||||
init() {
|
||||
this.getData();
|
||||
this.loadBenefitTypes();
|
||||
this.loadBenefitOptions();
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberGradeByPage().then((res) => {
|
||||
this.loading = false;
|
||||
if (res && res.success) {
|
||||
this.data = Array.isArray(res.result) ? res.result : [];
|
||||
}
|
||||
});
|
||||
},
|
||||
openAdd() {
|
||||
this.addFlag = true;
|
||||
this.submitAddLoading = false;
|
||||
if (!this.benefitOptions.length && !this.benefitOptionsLoading) {
|
||||
this.loadBenefitOptions();
|
||||
// 模板 el-form 的 ref(ref="addForm" / ref="editForm")
|
||||
const addForm = ref(null);
|
||||
const editForm = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const data = ref([]);
|
||||
const addFlag = ref(false);
|
||||
const editFlag = ref(false);
|
||||
const submitAddLoading = ref(false);
|
||||
const submitEditLoading = ref(false);
|
||||
const formAdd = ref(buildDefaultForm());
|
||||
const formEdit = ref(buildDefaultForm());
|
||||
const addBenefitOrder = ref([]);
|
||||
const editBenefitOrder = ref([]);
|
||||
const benefitOptions = ref([]);
|
||||
const benefitTypeOptions = ref([]);
|
||||
const benefitOptionsLoading = ref(false);
|
||||
const editDetailLoading = ref(false);
|
||||
const rules = ref({
|
||||
gradeName: [{ required: true, message: "请输入等级名称", trigger: "blur" }],
|
||||
gradeImage: [{ required: true, message: "请上传等级图标", trigger: "change" }],
|
||||
requiredExperience: [{ required: true, type: "number", message: "请输入所需经验值", trigger: "change" }],
|
||||
gradeSort: [{ required: true, type: "number", message: "请输入等级排序", trigger: "change" }],
|
||||
gradeState: [{ required: true, message: "请选择等级开关", trigger: "change" }],
|
||||
});
|
||||
|
||||
function benefitOptionLabel(b) {
|
||||
if (!b) return "";
|
||||
const name = b.benefitName || String(b.id);
|
||||
const opt = benefitTypeOptions.value.find((o) => o.value === b.benefitType);
|
||||
const typeText = opt ? opt.description : b.benefitType || "";
|
||||
return typeText ? `${name}(${typeText})` : name;
|
||||
}
|
||||
function onAddBenefitIdsChange(val) {
|
||||
addBenefitOrder.value = syncOrderedBenefitIds(addBenefitOrder.value, val);
|
||||
}
|
||||
function onEditBenefitIdsChange(val) {
|
||||
editBenefitOrder.value = syncOrderedBenefitIds(editBenefitOrder.value, val);
|
||||
}
|
||||
function loadBenefitTypes() {
|
||||
API_Member.getMemberBenefitTypes().then((res) => {
|
||||
if (res && res.success && Array.isArray(res.result)) {
|
||||
benefitTypeOptions.value = res.result;
|
||||
} else {
|
||||
benefitTypeOptions.value = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function loadBenefitOptions() {
|
||||
benefitOptionsLoading.value = true;
|
||||
const pageSize = 500;
|
||||
const fetchPage = (pageNumber) =>
|
||||
API_Member.getMemberBenefitByPage({ pageNumber, pageSize, sort: "benefitSort", order: "asc" });
|
||||
return fetchPage(1)
|
||||
.then((res) => {
|
||||
if (!(res && res.success && res.result)) {
|
||||
benefitOptions.value = [];
|
||||
return;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.addForm) this.$refs.addForm.resetFields();
|
||||
this.formAdd = buildDefaultForm();
|
||||
this.addBenefitOrder = [];
|
||||
});
|
||||
},
|
||||
submitAdd() {
|
||||
this.$refs.addForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitAddLoading = true;
|
||||
const { benefitIds: _omit, ...rest } = this.formAdd;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitIds: (this.addBenefitOrder || []).join(","),
|
||||
};
|
||||
API_Member.addMemberGrade(payload).then((res) => {
|
||||
this.submitAddLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
this.addFlag = false;
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
openEdit(row) {
|
||||
this.editFlag = true;
|
||||
this.submitEditLoading = false;
|
||||
this.editDetailLoading = true;
|
||||
if (!this.benefitOptions.length && !this.benefitOptionsLoading) {
|
||||
this.loadBenefitOptions();
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.editForm) this.$refs.editForm.resetFields();
|
||||
});
|
||||
API_Member.getMemberGrade(row.id)
|
||||
.then((res) => {
|
||||
this.editDetailLoading = false;
|
||||
if (res && res.success && res.result) {
|
||||
const raw = res.result;
|
||||
const grade = raw.grade != null ? raw.grade : raw;
|
||||
const benefits = Array.isArray(raw.benefits) ? raw.benefits : [];
|
||||
const orderedIds = benefits.length
|
||||
? benefits.map((b) => b.id).filter((id) => id != null && id !== "")
|
||||
: String(grade.benefitIds || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
this.fillEditFormFromGrade(grade, orderedIds);
|
||||
} else {
|
||||
this.fillEditFormFromGrade(row, this.parseBenefitIdsFromString(row.benefitIds));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.editDetailLoading = false;
|
||||
this.fillEditFormFromGrade(row, this.parseBenefitIdsFromString(row.benefitIds));
|
||||
});
|
||||
},
|
||||
submitEdit() {
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitEditLoading = true;
|
||||
const { id, benefitIds: _omit, ...rest } = this.formEdit;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitIds: (this.editBenefitOrder || []).join(","),
|
||||
};
|
||||
API_Member.updateMemberGrade(id, payload).then((res) => {
|
||||
this.submitEditLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
this.editFlag = false;
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
onGradeStateSwitch(row, checked) {
|
||||
const nextState = checked ? "OPEN" : "CLOSE";
|
||||
const prevState = row.gradeState;
|
||||
if (nextState === prevState) return;
|
||||
const text = checked ? "开启" : "关闭";
|
||||
ElMessageBox.confirm(`确定${text}该客户等级?`, "提示", { type: "warning" }).then(() => {
|
||||
row._gradeStateLoading = true;
|
||||
return API_Member.updateMemberGradeState(row.id, nextState)
|
||||
.then((res) => {
|
||||
row._gradeStateLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success(`${text}成功`);
|
||||
row.gradeState = nextState;
|
||||
} else {
|
||||
this.getData();
|
||||
const records = Array.isArray(res.result.records) ? res.result.records : [];
|
||||
const total = Number(res.result.total) || records.length;
|
||||
let all = records.slice();
|
||||
if (total > pageSize) {
|
||||
const pages = Math.ceil(total / pageSize);
|
||||
const rest = [];
|
||||
for (let p = 2; p <= pages; p++) {
|
||||
rest.push(fetchPage(p));
|
||||
}
|
||||
return Promise.all(rest).then((results) => {
|
||||
results.forEach((r) => {
|
||||
if (r && r.success && r.result && Array.isArray(r.result.records)) {
|
||||
all = all.concat(r.result.records);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
row._gradeStateLoading = false;
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
remove(row) {
|
||||
ElMessageBox.confirm("确定删除该客户等级?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberGrade(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
benefitOptions.value = all;
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
}
|
||||
benefitOptions.value = all;
|
||||
})
|
||||
.catch(() => {
|
||||
benefitOptions.value = [];
|
||||
})
|
||||
.finally(() => {
|
||||
benefitOptionsLoading.value = false;
|
||||
});
|
||||
}
|
||||
function parseBenefitIdsFromString(str) {
|
||||
return String(str || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
function fillEditFormFromGrade(grade, benefitsOrderedIds) {
|
||||
formEdit.value = {
|
||||
id: grade.id || "",
|
||||
gradeName: grade.gradeName || "",
|
||||
isDefault: grade.isDefault === true,
|
||||
gradeImage: grade.gradeImage || "",
|
||||
gradeBackground: grade.gradeBackground || "",
|
||||
gradeFontColor: grade.gradeFontColor || "",
|
||||
requiredExperience: Number(grade.requiredExperience) > 0 ? Number(grade.requiredExperience) : 1,
|
||||
gradeSort: Number(grade.gradeSort) > 0 ? Number(grade.gradeSort) : 1,
|
||||
gradeState: grade.gradeState || "OPEN",
|
||||
benefitIds: grade.benefitIds || "",
|
||||
};
|
||||
editBenefitOrder.value = (benefitsOrderedIds || []).map((id) => String(id));
|
||||
}
|
||||
function init() {
|
||||
getData();
|
||||
loadBenefitTypes();
|
||||
loadBenefitOptions();
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
API_Member.getMemberGradeByPage().then((res) => {
|
||||
loading.value = false;
|
||||
if (res && res.success) {
|
||||
data.value = Array.isArray(res.result) ? res.result : [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function openAdd() {
|
||||
addFlag.value = true;
|
||||
submitAddLoading.value = false;
|
||||
if (!benefitOptions.value.length && !benefitOptionsLoading.value) {
|
||||
loadBenefitOptions();
|
||||
}
|
||||
nextTick(() => {
|
||||
if (addForm.value) addForm.value.resetFields();
|
||||
formAdd.value = buildDefaultForm();
|
||||
addBenefitOrder.value = [];
|
||||
});
|
||||
}
|
||||
function submitAdd() {
|
||||
addForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitAddLoading.value = true;
|
||||
const { benefitIds: _omit, ...rest } = formAdd.value;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitIds: (addBenefitOrder.value || []).join(","),
|
||||
};
|
||||
API_Member.addMemberGrade(payload).then((res) => {
|
||||
submitAddLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
addFlag.value = false;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function openEdit(row) {
|
||||
editFlag.value = true;
|
||||
submitEditLoading.value = false;
|
||||
editDetailLoading.value = true;
|
||||
if (!benefitOptions.value.length && !benefitOptionsLoading.value) {
|
||||
loadBenefitOptions();
|
||||
}
|
||||
nextTick(() => {
|
||||
if (editForm.value) editForm.value.resetFields();
|
||||
});
|
||||
API_Member.getMemberGrade(row.id)
|
||||
.then((res) => {
|
||||
editDetailLoading.value = false;
|
||||
if (res && res.success && res.result) {
|
||||
const raw = res.result;
|
||||
const grade = raw.grade != null ? raw.grade : raw;
|
||||
const benefits = Array.isArray(raw.benefits) ? raw.benefits : [];
|
||||
const orderedIds = benefits.length
|
||||
? benefits.map((b) => b.id).filter((id) => id != null && id !== "")
|
||||
: String(grade.benefitIds || "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
fillEditFormFromGrade(grade, orderedIds);
|
||||
} else {
|
||||
fillEditFormFromGrade(row, parseBenefitIdsFromString(row.benefitIds));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
editDetailLoading.value = false;
|
||||
fillEditFormFromGrade(row, parseBenefitIdsFromString(row.benefitIds));
|
||||
});
|
||||
}
|
||||
function submitEdit() {
|
||||
editForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitEditLoading.value = true;
|
||||
const { id, benefitIds: _omit, ...rest } = formEdit.value;
|
||||
const payload = {
|
||||
...rest,
|
||||
benefitIds: (editBenefitOrder.value || []).join(","),
|
||||
};
|
||||
API_Member.updateMemberGrade(id, payload).then((res) => {
|
||||
submitEditLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
editFlag.value = false;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function onGradeStateSwitch(row, checked) {
|
||||
const nextState = checked ? "OPEN" : "CLOSE";
|
||||
const prevState = row.gradeState;
|
||||
if (nextState === prevState) return;
|
||||
const text = checked ? "开启" : "关闭";
|
||||
ElMessageBox.confirm(`确定${text}该客户等级?`, "提示", { type: "warning" }).then(() => {
|
||||
row._gradeStateLoading = true;
|
||||
return API_Member.updateMemberGradeState(row.id, nextState)
|
||||
.then((res) => {
|
||||
row._gradeStateLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success(`${text}成功`);
|
||||
row.gradeState = nextState;
|
||||
} else {
|
||||
getData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
row._gradeStateLoading = false;
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
function remove(row) {
|
||||
ElMessageBox.confirm("确定删除该客户等级?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberGrade(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.ops a {
|
||||
|
||||
@@ -70,137 +70,136 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { nextTick, onMounted, reactive, ref } from "vue";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "memberGroup",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
addFlag: false,
|
||||
editFlag: false,
|
||||
submitAddLoading: false,
|
||||
submitEditLoading: false,
|
||||
formAdd: {
|
||||
groupName: "",
|
||||
description: "",
|
||||
},
|
||||
formEdit: {
|
||||
id: "",
|
||||
groupName: "",
|
||||
description: "",
|
||||
},
|
||||
rulesAdd: {
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
rulesEdit: {
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getData();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberGroupByPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res && res.success && res.result) {
|
||||
this.data = res.result.records || [];
|
||||
this.total = res.result.total || 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
openAdd() {
|
||||
this.addFlag = true;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.addForm) this.$refs.addForm.resetFields();
|
||||
this.formAdd = { groupName: "", description: "" };
|
||||
});
|
||||
},
|
||||
submitAdd() {
|
||||
this.$refs.addForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitAddLoading = true;
|
||||
API_Member.addMemberGroup(this.formAdd).then((res) => {
|
||||
this.submitAddLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
this.addFlag = false;
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
openEdit(row) {
|
||||
this.editFlag = true;
|
||||
this.submitEditLoading = false;
|
||||
API_Member.getMemberGroup(row.id).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.formEdit = {
|
||||
id: res.result.id,
|
||||
groupName: res.result.groupName || "",
|
||||
description: res.result.description || "",
|
||||
};
|
||||
} else {
|
||||
this.formEdit = {
|
||||
id: row.id,
|
||||
groupName: row.groupName || "",
|
||||
description: row.description || "",
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
submitEdit() {
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitEditLoading = true;
|
||||
const { id, groupName, description } = this.formEdit;
|
||||
API_Member.updateMemberGroup(id, { groupName, description }).then((res) => {
|
||||
this.submitEditLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
this.editFlag = false;
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
remove(row) {
|
||||
ElMessageBox.confirm("确定删除该分组?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberGroup(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "memberGroup" });
|
||||
|
||||
const addForm = ref(null);
|
||||
const editForm = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const addFlag = ref(false);
|
||||
const editFlag = ref(false);
|
||||
const submitAddLoading = ref(false);
|
||||
const submitEditLoading = ref(false);
|
||||
const formAdd = ref({
|
||||
groupName: "",
|
||||
description: "",
|
||||
});
|
||||
const formEdit = ref({
|
||||
id: "",
|
||||
groupName: "",
|
||||
description: "",
|
||||
});
|
||||
const rulesAdd = reactive({
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
});
|
||||
const rulesEdit = reactive({
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
function init() {
|
||||
getData();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getData();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = v;
|
||||
getData();
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
API_Member.getMemberGroupByPage(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res && res.success && res.result) {
|
||||
data.value = res.result.records || [];
|
||||
total.value = res.result.total || 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
function openAdd() {
|
||||
addFlag.value = true;
|
||||
nextTick(() => {
|
||||
if (addForm.value) addForm.value.resetFields();
|
||||
formAdd.value = { groupName: "", description: "" };
|
||||
});
|
||||
}
|
||||
function submitAdd() {
|
||||
addForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitAddLoading.value = true;
|
||||
API_Member.addMemberGroup(formAdd.value).then((res) => {
|
||||
submitAddLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
addFlag.value = false;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function openEdit(row) {
|
||||
editFlag.value = true;
|
||||
submitEditLoading.value = false;
|
||||
API_Member.getMemberGroup(row.id).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
formEdit.value = {
|
||||
id: res.result.id,
|
||||
groupName: res.result.groupName || "",
|
||||
description: res.result.description || "",
|
||||
};
|
||||
} else {
|
||||
formEdit.value = {
|
||||
id: row.id,
|
||||
groupName: row.groupName || "",
|
||||
description: row.description || "",
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
function submitEdit() {
|
||||
editForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
submitEditLoading.value = true;
|
||||
const { id, groupName, description } = formEdit.value;
|
||||
API_Member.updateMemberGroup(id, { groupName, description }).then((res) => {
|
||||
submitEditLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
editFlag.value = false;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function remove(row) {
|
||||
ElMessageBox.confirm("确定删除该分组?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.deleteMemberGroup(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
getData();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
<el-dialog v-model="addFlag" title="添加会员" width="500px" destroy-on-close class="add-member-dialog">
|
||||
<el-form
|
||||
ref="addMemberForm"
|
||||
ref="addMemberFormRef"
|
||||
:model="addMemberForm"
|
||||
:rules="addRule"
|
||||
label-width="100px"
|
||||
@@ -210,7 +210,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="descFlag" :title="descTitle" width="500px" destroy-on-close>
|
||||
<el-form ref="form" :model="form" :rules="ruleValidate" label-width="80px">
|
||||
<el-form ref="formRef" :model="form" :rules="ruleValidate" label-width="80px">
|
||||
<el-input v-model="form.id" style="display: none" />
|
||||
<el-form-item label="头像">
|
||||
<img :src="form.face || defaultPic" class="face" />
|
||||
@@ -251,7 +251,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="walletIncreaseFlag" title="增加余额" width="420px" destroy-on-close>
|
||||
<el-form ref="walletIncreaseForm" :model="walletIncreaseForm" :rules="walletIncreaseRule" label-width="90px">
|
||||
<el-form ref="walletIncreaseFormRef" :model="walletIncreaseForm" :rules="walletIncreaseRule" label-width="90px">
|
||||
<el-form-item label="充值金额" prop="rechargeMoney">
|
||||
<el-input-number v-model="walletIncreaseForm.rechargeMoney" :min="0.01" :precision="2" style="width: 240px" />
|
||||
</el-form-item>
|
||||
@@ -263,7 +263,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="memberPointFlag" title="修改积分" width="420px" destroy-on-close>
|
||||
<el-form ref="memberPointForm" :model="memberPointForm" :rules="memberPointRule" label-width="90px">
|
||||
<el-form ref="memberPointFormRef" :model="memberPointForm" :rules="memberPointRule" label-width="90px">
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-radio-group v-model="memberPointForm.type">
|
||||
<el-radio-button value="INCREASE">增加</el-radio-button>
|
||||
@@ -281,7 +281,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="memberGroupFlag" title="设定会员分组" width="420px" destroy-on-close>
|
||||
<el-form ref="memberGroupForm" :model="memberGroupForm" :rules="memberGroupRule" label-width="90px">
|
||||
<el-form ref="memberGroupFormRef" :model="memberGroupForm" :rules="memberGroupRule" label-width="90px">
|
||||
<el-form-item label="会员分组" prop="groupId">
|
||||
<el-select v-model="memberGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<el-option
|
||||
@@ -300,13 +300,14 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="picModelFlag" width="1200px">
|
||||
<ossManage ref="ossManage" @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" />
|
||||
<ossManage ref="ossManageRef" @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" />
|
||||
</el-dialog>
|
||||
<multipleMap ref="map" @callback="selectedRegion" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, watch, nextTick, onMounted } from "vue";
|
||||
import { ArrowDown } from "@element-plus/icons-vue";
|
||||
import multipleMap from "@/components/map/multiple-map";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
@@ -314,451 +315,456 @@ import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import * as RegExp from "@/libs/RegExp.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { customRouterPush } from "@/utils/filters";
|
||||
import { md5 } from "@/utils/md5.js";
|
||||
import defaultPic from "@/assets/default.png";
|
||||
|
||||
export default {
|
||||
name: "member",
|
||||
components: {
|
||||
multipleMap,
|
||||
ossManage,
|
||||
ArrowDown,
|
||||
defineOptions({ name: "member" });
|
||||
|
||||
const props = defineProps({
|
||||
selectedMember: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
props: {
|
||||
selectedMember: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
selectedList: {
|
||||
type: null,
|
||||
default: () => [],
|
||||
},
|
||||
checkboxSelect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
selectedList: {
|
||||
type: null,
|
||||
default: () => [],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultPic,
|
||||
descTitle: "",
|
||||
descFlag: false,
|
||||
loading: true,
|
||||
addFlag: false,
|
||||
addMemberForm: {
|
||||
mobile: "",
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
order: "desc",
|
||||
id: "",
|
||||
username: "",
|
||||
mobile: "",
|
||||
disabled: "OPEN",
|
||||
groupId: "",
|
||||
},
|
||||
picModelFlag: false,
|
||||
form: {},
|
||||
walletIncreaseFlag: false,
|
||||
walletIncreaseLoading: false,
|
||||
walletIncreaseForm: {
|
||||
memberId: "",
|
||||
rechargeMoney: null,
|
||||
},
|
||||
walletIncreaseRule: {
|
||||
rechargeMoney: [
|
||||
{ required: true, type: "number", message: "请输入充值金额", trigger: "change" },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (typeof value !== "number" || value <= 0) {
|
||||
callback(new Error("充值金额必须大于0"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
},
|
||||
memberPointFlag: false,
|
||||
memberPointLoading: false,
|
||||
memberPointForm: {
|
||||
memberId: "",
|
||||
point: null,
|
||||
type: "INCREASE",
|
||||
},
|
||||
selectedRows: [],
|
||||
memberGroupFlag: false,
|
||||
memberGroupLoading: false,
|
||||
memberGroupForm: {
|
||||
groupId: "",
|
||||
},
|
||||
memberGroupRule: {
|
||||
groupId: [{ required: true, message: "请选择会员分组", trigger: "change" }],
|
||||
},
|
||||
memberGroupList: [],
|
||||
memberGradeList: [],
|
||||
memberPointRule: {
|
||||
type: [{ required: true, message: "请选择类型", trigger: "change" }],
|
||||
point: [
|
||||
{ required: true, type: "number", message: "请输入积分", trigger: "change" },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (typeof value !== "number" || value <= 0) {
|
||||
callback(new Error("积分必须大于0"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
},
|
||||
addRule: {
|
||||
mobile: [
|
||||
{ required: true, message: "请输入手机号码" },
|
||||
{ pattern: RegExp.mobile, message: "请输入正确的手机号" },
|
||||
],
|
||||
username: [{ required: true, message: "请输入客户名称" }],
|
||||
password: [{ required: true, message: "请输入密码" }],
|
||||
},
|
||||
ruleValidate: {},
|
||||
data: [],
|
||||
total: 0,
|
||||
selectMember: [],
|
||||
};
|
||||
checkboxSelect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
watch: {
|
||||
selectedList: {
|
||||
handler(val) {
|
||||
this.selectMember = JSON.parse(JSON.stringify(val));
|
||||
this.init(this.data);
|
||||
});
|
||||
const emit = defineEmits(["callback"]);
|
||||
|
||||
// 模板 el-form/el-table 的模板 ref(原 ref="searchForm"/"addMemberForm"/"form" 等与 data 同名会互相覆盖,
|
||||
// 改名为 xxxRef;ossManage 与 import 同名,改名 ossManageRef)
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
const addMemberFormRef = ref(null);
|
||||
const formRef = ref(null);
|
||||
const walletIncreaseFormRef = ref(null);
|
||||
const memberPointFormRef = ref(null);
|
||||
const memberGroupFormRef = ref(null);
|
||||
const ossManageRef = ref(null);
|
||||
|
||||
const descTitle = ref("");
|
||||
const descFlag = ref(false);
|
||||
const loading = ref(true);
|
||||
const addFlag = ref(false);
|
||||
const addMemberForm = ref({
|
||||
mobile: "",
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
order: "desc",
|
||||
id: "",
|
||||
username: "",
|
||||
mobile: "",
|
||||
disabled: "OPEN",
|
||||
groupId: "",
|
||||
});
|
||||
const picModelFlag = ref(false);
|
||||
const form = ref({});
|
||||
const walletIncreaseFlag = ref(false);
|
||||
const walletIncreaseLoading = ref(false);
|
||||
const walletIncreaseForm = ref({
|
||||
memberId: "",
|
||||
rechargeMoney: null,
|
||||
});
|
||||
const walletIncreaseRule = ref({
|
||||
rechargeMoney: [
|
||||
{ required: true, type: "number", message: "请输入充值金额", trigger: "change" },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (typeof value !== "number" || value <= 0) {
|
||||
callback(new Error("充值金额必须大于0"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
});
|
||||
const memberPointFlag = ref(false);
|
||||
const memberPointLoading = ref(false);
|
||||
const memberPointForm = ref({
|
||||
memberId: "",
|
||||
point: null,
|
||||
type: "INCREASE",
|
||||
});
|
||||
const selectedRows = ref([]);
|
||||
const memberGroupFlag = ref(false);
|
||||
const memberGroupLoading = ref(false);
|
||||
const memberGroupForm = ref({
|
||||
groupId: "",
|
||||
});
|
||||
const memberGroupRule = ref({
|
||||
groupId: [{ required: true, message: "请选择会员分组", trigger: "change" }],
|
||||
});
|
||||
const memberGroupList = ref([]);
|
||||
const memberGradeList = ref([]);
|
||||
const memberPointRule = ref({
|
||||
type: [{ required: true, message: "请选择类型", trigger: "change" }],
|
||||
point: [
|
||||
{ required: true, type: "number", message: "请输入积分", trigger: "change" },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (typeof value !== "number" || value <= 0) {
|
||||
callback(new Error("积分必须大于0"));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
});
|
||||
const addRule = ref({
|
||||
mobile: [
|
||||
{ required: true, message: "请输入手机号码" },
|
||||
{ pattern: RegExp.mobile, message: "请输入正确的手机号" },
|
||||
],
|
||||
username: [{ required: true, message: "请输入客户名称" }],
|
||||
password: [{ required: true, message: "请输入密码" }],
|
||||
});
|
||||
const ruleValidate = ref({});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const selectMember = ref([]);
|
||||
|
||||
watch(
|
||||
() => props.selectedList,
|
||||
(val) => {
|
||||
selectMember.value = JSON.parse(JSON.stringify(val));
|
||||
init(data.value);
|
||||
},
|
||||
methods: {
|
||||
handleMoreCommand(name, row) {
|
||||
if (name === "edit") this.editPerm(row);
|
||||
if (name === "disabled") this.disabled(row);
|
||||
if (name === "increaseWallet") this.openWalletIncrease(row);
|
||||
if (name === "updatePoint") this.openMemberPoint(row);
|
||||
},
|
||||
onSelectionChange(selection) {
|
||||
if (this.selectedMember && this.checkboxSelect) {
|
||||
this.selectMember = selection || [];
|
||||
return;
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
function handleMoreCommand(name, row) {
|
||||
if (name === "edit") editPerm(row);
|
||||
if (name === "disabled") disabled(row);
|
||||
if (name === "increaseWallet") openWalletIncrease(row);
|
||||
if (name === "updatePoint") openMemberPoint(row);
|
||||
}
|
||||
function onSelectionChange(selection) {
|
||||
if (props.selectedMember && props.checkboxSelect) {
|
||||
selectMember.value = selection || [];
|
||||
return;
|
||||
}
|
||||
selectedRows.value = selection || [];
|
||||
}
|
||||
function getSelection() {
|
||||
return selectMember.value || [];
|
||||
}
|
||||
function syncTableSelection() {
|
||||
if (!props.selectedMember || !props.checkboxSelect) {
|
||||
return;
|
||||
}
|
||||
nextTick(() => {
|
||||
clearSelection();
|
||||
data.value.forEach((row) => {
|
||||
if (selectMember.value.some((member) => member.id === row.id)) {
|
||||
table.value?.toggleRowSelection(row, true);
|
||||
}
|
||||
this.selectedRows = selection || [];
|
||||
},
|
||||
getSelection() {
|
||||
return this.selectMember || [];
|
||||
},
|
||||
syncTableSelection() {
|
||||
if (!this.selectedMember || !this.checkboxSelect) {
|
||||
return;
|
||||
});
|
||||
});
|
||||
}
|
||||
function openSetMemberGroup() {
|
||||
memberGroupFlag.value = true;
|
||||
memberGroupLoading.value = false;
|
||||
memberGroupForm.value = { groupId: "" };
|
||||
nextTick(() => {
|
||||
if (memberGroupFormRef.value) memberGroupFormRef.value.resetFields();
|
||||
});
|
||||
loadMemberGroupList();
|
||||
}
|
||||
function loadMemberGroupList() {
|
||||
API_Member.getMemberGroupByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
memberGroupList.value = res.result.records || [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function loadMemberGradeList() {
|
||||
API_Member.getMemberGradeByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
memberGradeList.value = res.result || [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function clearSelection() {
|
||||
table.value?.clearSelection();
|
||||
}
|
||||
function submitSetMemberGroup() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning("请先选择会员");
|
||||
return;
|
||||
}
|
||||
memberGroupFormRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
const memberIds = selectedRows.value.map((item) => item.id);
|
||||
const groupId = memberGroupForm.value.groupId;
|
||||
memberGroupLoading.value = true;
|
||||
Promise.all(
|
||||
memberIds.map((memberId) => API_Member.setMemberUserGroups(memberId, [groupId]))
|
||||
)
|
||||
.then((results) => {
|
||||
memberGroupLoading.value = false;
|
||||
const failed = results.find((res) => !res || !res.success);
|
||||
if (failed) {
|
||||
ElMessage.error(failed.message || "设置失败");
|
||||
return;
|
||||
}
|
||||
ElMessage.success("设置成功");
|
||||
memberGroupFlag.value = false;
|
||||
selectedRows.value = [];
|
||||
clearSelection();
|
||||
getData();
|
||||
})
|
||||
.catch(() => {
|
||||
memberGroupLoading.value = false;
|
||||
ElMessage.error("设置失败,请稍后重试");
|
||||
});
|
||||
});
|
||||
}
|
||||
function callback(val) {
|
||||
selectMember.value.forEach((item) => {
|
||||
item.___selected = false;
|
||||
});
|
||||
val.___selected = !val.___selected;
|
||||
let findUser = selectMember.value.find((item) => item.id == val.id);
|
||||
if (!findUser) {
|
||||
selectMember.value.push(val);
|
||||
} else {
|
||||
selectMember.value.map((item, index) => {
|
||||
if (item.id == findUser.id) {
|
||||
selectMember.value.splice(index, 1);
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.clearSelection();
|
||||
this.data.forEach((row) => {
|
||||
if (this.selectMember.some((member) => member.id === row.id)) {
|
||||
this.$refs.table?.toggleRowSelection(row, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
openSetMemberGroup() {
|
||||
this.memberGroupFlag = true;
|
||||
this.memberGroupLoading = false;
|
||||
this.memberGroupForm = { groupId: "" };
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.memberGroupForm) this.$refs.memberGroupForm.resetFields();
|
||||
});
|
||||
this.loadMemberGroupList();
|
||||
},
|
||||
loadMemberGroupList() {
|
||||
API_Member.getMemberGroupByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.memberGroupList = res.result.records || [];
|
||||
});
|
||||
}
|
||||
emit("callback", val);
|
||||
}
|
||||
function init(list) {
|
||||
list.forEach((item) => {
|
||||
if (selectMember.value.length != 0) {
|
||||
selectMember.value.forEach((member) => {
|
||||
if (member.id == item.id) {
|
||||
item.___selected = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
loadMemberGradeList() {
|
||||
API_Member.getMemberGradeByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.memberGradeList = res.result || [];
|
||||
} else {
|
||||
item.___selected = false;
|
||||
}
|
||||
});
|
||||
data.value = list;
|
||||
}
|
||||
function changePage() {
|
||||
getData();
|
||||
}
|
||||
function changePageSize() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
getData();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.pageSize = 20;
|
||||
getData();
|
||||
}
|
||||
function editPerm(val) {
|
||||
descTitle.value = `查看用户 ${val.username}`;
|
||||
descFlag.value = true;
|
||||
getMemberInfo(val.id);
|
||||
}
|
||||
function addMember() {
|
||||
addMemberForm.value = {
|
||||
mobile: "",
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
addFlag.value = true;
|
||||
nextTick(() => {
|
||||
addMemberFormRef.value?.clearValidate();
|
||||
});
|
||||
}
|
||||
function getMemberInfo(id) {
|
||||
API_Member.getMemberInfoData(id).then((res) => {
|
||||
if (res.result) {
|
||||
form.value = res.result;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
if (!props.selectedMember) {
|
||||
selectedRows.value = [];
|
||||
clearSelection();
|
||||
}
|
||||
API_Member.getMemberListData(searchForm.value).then((res) => {
|
||||
if (res.result.records) {
|
||||
loading.value = false;
|
||||
init(res.result.records);
|
||||
total.value = res.result.total;
|
||||
syncTableSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
function openPicSelector() {
|
||||
picModelFlag.value = true;
|
||||
nextTick(() => {
|
||||
if (ossManageRef.value) {
|
||||
ossManageRef.value.selectImage = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
function callbackSelected(val) {
|
||||
picModelFlag.value = false;
|
||||
form.value.face = val.url;
|
||||
}
|
||||
function addMemberSubmit() {
|
||||
addMemberForm.value.password = md5(addMemberForm.value.password);
|
||||
addMemberFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
API_Member.addMember(addMemberForm.value).then((res) => {
|
||||
if (res.result) {
|
||||
addMemberFormRef.value.resetFields();
|
||||
getData();
|
||||
ElMessage.success("添加成功!");
|
||||
addFlag.value = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
clearSelection() {
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
submitSetMemberGroup() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning("请先选择会员");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
function selectedRegion(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
form.value.region = paths;
|
||||
form.value.regionId = ids;
|
||||
} else {
|
||||
form.value.region = val.data.addr;
|
||||
form.value.regionId = val.data.addrId;
|
||||
}
|
||||
}
|
||||
function detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
}
|
||||
function disabled(v) {
|
||||
let params = {
|
||||
memberIds: [v.id],
|
||||
disabled: false,
|
||||
};
|
||||
ElMessageBox.confirm("确认禁用此会员?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.updateMemberStatus(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("禁用成功");
|
||||
getData();
|
||||
}
|
||||
this.$refs.memberGroupForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
const memberIds = this.selectedRows.map((item) => item.id);
|
||||
const groupId = this.memberGroupForm.groupId;
|
||||
this.memberGroupLoading = true;
|
||||
Promise.all(
|
||||
memberIds.map((memberId) => API_Member.setMemberUserGroups(memberId, [groupId]))
|
||||
)
|
||||
.then((results) => {
|
||||
this.memberGroupLoading = false;
|
||||
const failed = results.find((res) => !res || !res.success);
|
||||
if (failed) {
|
||||
ElMessage.error(failed.message || "设置失败");
|
||||
return;
|
||||
}
|
||||
ElMessage.success("设置成功");
|
||||
this.memberGroupFlag = false;
|
||||
this.selectedRows = [];
|
||||
this.clearSelection();
|
||||
this.getData();
|
||||
})
|
||||
.catch(() => {
|
||||
this.memberGroupLoading = false;
|
||||
ElMessage.error("设置失败,请稍后重试");
|
||||
});
|
||||
});
|
||||
},
|
||||
callback(val) {
|
||||
this.selectMember.forEach((item) => {
|
||||
item.___selected = false;
|
||||
});
|
||||
val.___selected = !val.___selected;
|
||||
let findUser = this.selectMember.find((item) => item.id == val.id);
|
||||
if (!findUser) {
|
||||
this.selectMember.push(val);
|
||||
} else {
|
||||
this.selectMember.map((item, index) => {
|
||||
if (item.id == findUser.id) {
|
||||
this.selectMember.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
init(data) {
|
||||
data.forEach((item) => {
|
||||
if (this.selectMember.length != 0) {
|
||||
this.selectMember.forEach((member) => {
|
||||
if (member.id == item.id) {
|
||||
item.___selected = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
function openWalletIncrease(row) {
|
||||
walletIncreaseLoading.value = false;
|
||||
walletIncreaseForm.value = { memberId: row.id, rechargeMoney: null };
|
||||
walletIncreaseFlag.value = true;
|
||||
nextTick(() => {
|
||||
walletIncreaseFormRef.value && walletIncreaseFormRef.value.resetFields();
|
||||
});
|
||||
}
|
||||
function submitWalletIncrease() {
|
||||
walletIncreaseFormRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
walletIncreaseLoading.value = true;
|
||||
API_Member.increaseMemberWallet({
|
||||
memberId: walletIncreaseForm.value.memberId,
|
||||
rechargeMoney: walletIncreaseForm.value.rechargeMoney,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("充值成功");
|
||||
walletIncreaseFlag.value = false;
|
||||
getData();
|
||||
} else {
|
||||
item.___selected = false;
|
||||
ElMessage.error((res && res.message) || "充值失败");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
walletIncreaseLoading.value = false;
|
||||
});
|
||||
this.data = data;
|
||||
},
|
||||
changePage() {
|
||||
this.getData();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getData();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
editPerm(val) {
|
||||
this.descTitle = `查看用户 ${val.username}`;
|
||||
this.descFlag = true;
|
||||
this.getMemberInfo(val.id);
|
||||
},
|
||||
addMember() {
|
||||
this.addMemberForm = {
|
||||
mobile: "",
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
this.addFlag = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addMemberForm?.clearValidate();
|
||||
});
|
||||
},
|
||||
getMemberInfo(id) {
|
||||
API_Member.getMemberInfoData(id).then((res) => {
|
||||
if (res.result) {
|
||||
this.form = res.result;
|
||||
});
|
||||
}
|
||||
function openMemberPoint(row) {
|
||||
memberPointLoading.value = false;
|
||||
memberPointForm.value = { memberId: row.id, point: null, type: "INCREASE" };
|
||||
memberPointFlag.value = true;
|
||||
nextTick(() => {
|
||||
memberPointFormRef.value && memberPointFormRef.value.resetFields();
|
||||
});
|
||||
}
|
||||
function submitMemberPoint() {
|
||||
memberPointFormRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
memberPointLoading.value = true;
|
||||
API_Member.updateMemberPoint({
|
||||
memberId: memberPointForm.value.memberId,
|
||||
point: memberPointForm.value.point,
|
||||
type: memberPointForm.value.type,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
memberPointFlag.value = false;
|
||||
getData();
|
||||
} else {
|
||||
ElMessage.error((res && res.message) || "修改失败");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
memberPointLoading.value = false;
|
||||
});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
if (!this.selectedMember) {
|
||||
this.selectedRows = [];
|
||||
this.clearSelection();
|
||||
}
|
||||
API_Member.getMemberListData(this.searchForm).then((res) => {
|
||||
if (res.result.records) {
|
||||
this.loading = false;
|
||||
this.init(res.result.records);
|
||||
this.total = res.result.total;
|
||||
this.syncTableSelection();
|
||||
}
|
||||
});
|
||||
},
|
||||
openPicSelector() {
|
||||
this.picModelFlag = true;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.ossManage) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.form.face = val.url;
|
||||
},
|
||||
addMemberSubmit() {
|
||||
this.addMemberForm.password = this.md5(this.addMemberForm.password);
|
||||
this.$refs.addMemberForm.validate((valid) => {
|
||||
if (valid) {
|
||||
API_Member.addMember(this.addMemberForm).then((res) => {
|
||||
if (res.result) {
|
||||
this.$refs.addMemberForm.resetFields();
|
||||
this.getData();
|
||||
ElMessage.success("添加成功!");
|
||||
this.addFlag = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
selectedRegion(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
this.form.region = paths;
|
||||
this.form.regionId = ids;
|
||||
} else {
|
||||
this.form.region = val.data.addr;
|
||||
this.form.regionId = val.data.addrId;
|
||||
}
|
||||
},
|
||||
detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
disabled(v) {
|
||||
let params = {
|
||||
memberIds: [v.id],
|
||||
disabled: false,
|
||||
};
|
||||
ElMessageBox.confirm("确认禁用此会员?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.updateMemberStatus(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("禁用成功");
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
openWalletIncrease(row) {
|
||||
this.walletIncreaseLoading = false;
|
||||
this.walletIncreaseForm = { memberId: row.id, rechargeMoney: null };
|
||||
this.walletIncreaseFlag = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.walletIncreaseForm && this.$refs.walletIncreaseForm.resetFields();
|
||||
});
|
||||
},
|
||||
submitWalletIncrease() {
|
||||
this.$refs.walletIncreaseForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.walletIncreaseLoading = true;
|
||||
API_Member.increaseMemberWallet({
|
||||
memberId: this.walletIncreaseForm.memberId,
|
||||
rechargeMoney: this.walletIncreaseForm.rechargeMoney,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("充值成功");
|
||||
this.walletIncreaseFlag = false;
|
||||
this.getData();
|
||||
} else {
|
||||
ElMessage.error((res && res.message) || "充值失败");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.walletIncreaseLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
openMemberPoint(row) {
|
||||
this.memberPointLoading = false;
|
||||
this.memberPointForm = { memberId: row.id, point: null, type: "INCREASE" };
|
||||
this.memberPointFlag = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.memberPointForm && this.$refs.memberPointForm.resetFields();
|
||||
});
|
||||
},
|
||||
submitMemberPoint() {
|
||||
this.$refs.memberPointForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.memberPointLoading = true;
|
||||
API_Member.updateMemberPoint({
|
||||
memberId: this.memberPointForm.memberId,
|
||||
point: this.memberPointForm.point,
|
||||
type: this.memberPointForm.type,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
this.memberPointFlag = false;
|
||||
this.getData();
|
||||
} else {
|
||||
ElMessage.error((res && res.message) || "修改失败");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.memberPointLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleSubmitModal() {
|
||||
const { nickName, sex, username, face, newPassword, id, regionId, region } = this.form;
|
||||
let time = new Date(this.form.birthday);
|
||||
let birthday =
|
||||
this.form.birthday === undefined
|
||||
? ""
|
||||
: time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let submit = {
|
||||
regionId,
|
||||
region,
|
||||
nickName,
|
||||
sex,
|
||||
birthday,
|
||||
face,
|
||||
id,
|
||||
};
|
||||
if (newPassword) {
|
||||
submit.password = this.md5(newPassword);
|
||||
}
|
||||
API_Member.updateMember(submit).then((res) => {
|
||||
if (res.result) {
|
||||
ElMessage.success("修改成功!");
|
||||
this.descFlag = false;
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
this.loadMemberGroupList();
|
||||
this.loadMemberGradeList();
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
function handleSubmitModal() {
|
||||
const { nickName, sex, username, face, newPassword, id, regionId, region } = form.value;
|
||||
let time = new Date(form.value.birthday);
|
||||
let birthday =
|
||||
form.value.birthday === undefined
|
||||
? ""
|
||||
: time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let submit = {
|
||||
regionId,
|
||||
region,
|
||||
nickName,
|
||||
sex,
|
||||
birthday,
|
||||
face,
|
||||
id,
|
||||
};
|
||||
if (newPassword) {
|
||||
submit.password = md5(newPassword);
|
||||
}
|
||||
API_Member.updateMember(submit).then((res) => {
|
||||
if (res.result) {
|
||||
ElMessage.success("修改成功!");
|
||||
descFlag.value = false;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
loadMemberGroupList();
|
||||
loadMemberGradeList();
|
||||
});
|
||||
|
||||
// 外部通过 ref 调用(promotions/coupon-activity/coupon-publish.vue 的 memberLayoutRef.getSelection())
|
||||
defineExpose({ getSelection });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.face {
|
||||
|
||||
@@ -379,7 +379,7 @@
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="addressForm" :model="addressForm" label-width="100px" :rules="addressFormValidate">
|
||||
<el-form ref="addressFormRef" :model="addressForm" label-width="100px" :rules="addressFormValidate">
|
||||
<el-form-item label="收货人姓名" prop="name">
|
||||
<el-input v-model="addressForm.name" maxlength="8" clearable style="width: 80%" />
|
||||
</el-form-item>
|
||||
@@ -388,7 +388,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="收货人地址" prop="consigneeAddressPath">
|
||||
<span>{{ addressForm.consigneeAddressPath || "暂无地址" }}</span>
|
||||
<el-button style="margin-left: 10px" @click="$refs.map.open()">选择</el-button>
|
||||
<el-button style="margin-left: 10px" @click="map.open()">选择</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="详细地址" prop="detail">
|
||||
<el-input v-model="addressForm.detail" maxlength="35" clearable style="width: 80%" />
|
||||
@@ -412,7 +412,9 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import multipleMap from "@/components/map/multiple-map";
|
||||
@@ -420,374 +422,373 @@ import * as RegExp from "@/libs/RegExp.js";
|
||||
import * as API_Order from "@/api/order.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "memberDetail",
|
||||
components: {
|
||||
ossManage,
|
||||
multipleMap,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: "",
|
||||
activeTab: "point",
|
||||
loading: true,
|
||||
addressLoading: false,
|
||||
memberInfo: {},
|
||||
memberWalletInfo: {},
|
||||
addressModalTitle: "",
|
||||
addressModalVisible: false,
|
||||
addressForm: {
|
||||
id: "",
|
||||
isDefault: 0,
|
||||
consigneeAddressPath: "",
|
||||
consigneeAddressIdPath: "",
|
||||
},
|
||||
selectDate: null,
|
||||
submitLoading: false,
|
||||
addressFormValidate: {
|
||||
name: [{ required: true, message: "收货人姓名不能为空" }],
|
||||
mobile: [
|
||||
{ required: true, message: "请输入收货人手机号码" },
|
||||
{
|
||||
pattern: RegExp.mobile,
|
||||
message: "请输入正确的手机号",
|
||||
},
|
||||
],
|
||||
consigneeAddressPath: [{ required: true, message: "收货人地址不能为空" }],
|
||||
detail: [{ required: true, message: "收货人详细地址不能为空" }],
|
||||
},
|
||||
pointData: [],
|
||||
pointTotal: 0,
|
||||
pointSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
orderData: [],
|
||||
orderTotal: 0,
|
||||
orderSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
payStatus: "",
|
||||
orderSn: "",
|
||||
orderType: "",
|
||||
},
|
||||
addressData: [],
|
||||
addressTotal: 0,
|
||||
addressSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
walletSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
walletData: [],
|
||||
walletTotal: 0,
|
||||
receiptRecordSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
receiptRecordData: [],
|
||||
receiptRecordTotal: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
orderTypeText(v) {
|
||||
const map = {
|
||||
NORMAL: "普通订单",
|
||||
VIRTUAL: "虚拟订单",
|
||||
GIFT: "赠品订单",
|
||||
PINTUAN: "拼团订单",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
clientTypeText(v) {
|
||||
const map = {
|
||||
H5: "移动端",
|
||||
PC: "PC端",
|
||||
WECHAT_MP: "小程序端",
|
||||
APP: "移动应用端",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
orderStatusText(v) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
UNDELIVERED: "待发货",
|
||||
DELIVERED: "已发货",
|
||||
COMPLETED: "已完成",
|
||||
TAKE: "待核验",
|
||||
CANCELLED: "已关闭",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
payStatusText(v) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
groupAfterSaleStatusText(v) {
|
||||
const map = {
|
||||
NEW: "未申请",
|
||||
NOT_APPLIED: "未申请",
|
||||
ALREADY_APPLIED: "已申请",
|
||||
EXPIRED: "已失效",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
groupComplainStatusText(v) {
|
||||
const map = {
|
||||
NEW: "未申请",
|
||||
NO_APPLY: "未申请",
|
||||
APPLYING: "申请中",
|
||||
COMPLETE: "已完成",
|
||||
EXPIRED: "已失效",
|
||||
CANCEL: "取消投诉",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
},
|
||||
walletServiceTypeText(type) {
|
||||
if (type === "WALLET_WITHDRAWAL") return "余额提现";
|
||||
if (type === "WALLET_PAY") return "余额支付";
|
||||
if (type === "WALLET_REFUND") return "余额退款";
|
||||
if (type === "WALLET_RECHARGE") return "余额充值";
|
||||
return "佣金提成";
|
||||
},
|
||||
init() {
|
||||
this.getMemberInfo();
|
||||
this.getPointData();
|
||||
},
|
||||
memberInfoChange(v) {
|
||||
if (v == "point") {
|
||||
this.getPointData();
|
||||
}
|
||||
if (v == "address") {
|
||||
this.$nextTick(() => {
|
||||
this.getAddressData();
|
||||
});
|
||||
}
|
||||
if (v == "order") {
|
||||
this.getOrderData();
|
||||
}
|
||||
if (v == "wallet") {
|
||||
this.getMemberWalletData();
|
||||
this.getDepositLogData();
|
||||
}
|
||||
if (v == "receipt") {
|
||||
this.getReceiptRecordData();
|
||||
}
|
||||
},
|
||||
getMemberInfo() {
|
||||
API_Member.getMemberInfoData(this.id).then((res) => {
|
||||
this.memberInfo = res.result;
|
||||
});
|
||||
},
|
||||
memberStatusChange(v) {
|
||||
let params = {
|
||||
memberIds: [this.id],
|
||||
disabled: v,
|
||||
};
|
||||
API_Member.updateMemberStatus(params).then((res) => {});
|
||||
},
|
||||
getMemberWalletData() {
|
||||
this.loading = true;
|
||||
let params = {
|
||||
memberId: this.id,
|
||||
};
|
||||
API_Member.getMemberWallet(params).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.memberWalletInfo = res.result;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
getDepositLogData() {
|
||||
this.loading = true;
|
||||
this.walletSearchForm.memberId = this.id;
|
||||
API_Member.getUserWallet(this.walletSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.walletData = res.result.records;
|
||||
this.walletTotal = res.result.total;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
getReceiptRecordData() {
|
||||
this.loading = true;
|
||||
this.receiptRecordSearchForm.pageNumber = 1;
|
||||
this.receiptRecordSearchForm.pageSize = 20;
|
||||
this.receiptRecordSearchForm.memberId = this.id;
|
||||
API_Order.getReceiptPage(this.receiptRecordSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.receiptRecordData = res.result.records;
|
||||
this.receiptRecordTotal = res.result.total;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
getOrderData() {
|
||||
this.loading = true;
|
||||
this.orderSearchForm.pageNumber = 1;
|
||||
this.orderSearchForm.pageSize = 20;
|
||||
this.orderSearchForm.memberId = this.id;
|
||||
API_Order.getOrderList(this.orderSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.orderData = res.result.records;
|
||||
this.orderTotal = res.result.total;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
orderDetail(v) {
|
||||
this.$router.push({
|
||||
name: "order-detail",
|
||||
query: { sn: v },
|
||||
});
|
||||
},
|
||||
getPointData() {
|
||||
this.loading = true;
|
||||
this.pointSearchForm.memberId = this.id;
|
||||
API_Member.getHistoryPointData(this.pointSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.pointData = res.result.records;
|
||||
this.pointTotal = res.result.total;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
addressSubmit() {
|
||||
this.addressForm.memberId = this.id;
|
||||
this.$refs.addressForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
let submit = JSON.parse(JSON.stringify(this.addressForm));
|
||||
submit.isDefault ? (submit.isDefault = true) : (submit.isDefault = false);
|
||||
if (submit.id != "") {
|
||||
API_Member.editMemberAddress(submit).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
this.addressModalVisible = false;
|
||||
this.getAddressData();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
API_Member.addMemberAddress(submit).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
this.addressModalVisible = false;
|
||||
this.getAddressData();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getAddress(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
defineOptions({ name: "memberDetail" });
|
||||
|
||||
this.addressForm.consigneeAddressPath = paths;
|
||||
this.addressForm.consigneeAddressIdPath = ids;
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const coord = val.data[val.data.length - 1].center.split(",");
|
||||
this.addressForm.lat = coord[1];
|
||||
this.addressForm.lon = coord[0];
|
||||
} else {
|
||||
this.addressForm.consigneeAddressPath = val.data.addr;
|
||||
this.addressForm.consigneeAddressIdPath = val.data.addrId;
|
||||
this.addressForm.lat = val.data.position.lat;
|
||||
this.addressForm.lon = val.data.position.lng;
|
||||
}
|
||||
// 模板 el-form 的 ref(原 ref="addressForm",与 data 同名会互相覆盖,改名为 addressFormRef)
|
||||
const addressFormRef = ref(null);
|
||||
// 模板 multipleMap 的 ref(ref="map")
|
||||
const map = ref(null);
|
||||
|
||||
const id = ref("");
|
||||
const activeTab = ref("point");
|
||||
const loading = ref(true);
|
||||
const addressLoading = ref(false);
|
||||
const memberInfo = ref({});
|
||||
const memberWalletInfo = ref({});
|
||||
const addressModalTitle = ref("");
|
||||
const addressModalVisible = ref(false);
|
||||
const addressForm = reactive({
|
||||
id: "",
|
||||
isDefault: 0,
|
||||
consigneeAddressPath: "",
|
||||
consigneeAddressIdPath: "",
|
||||
});
|
||||
const selectDate = ref(null);
|
||||
const submitLoading = ref(false);
|
||||
const addressFormValidate = reactive({
|
||||
name: [{ required: true, message: "收货人姓名不能为空" }],
|
||||
mobile: [
|
||||
{ required: true, message: "请输入收货人手机号码" },
|
||||
{
|
||||
pattern: RegExp.mobile,
|
||||
message: "请输入正确的手机号",
|
||||
},
|
||||
memberAddressRemove(v) {
|
||||
ElMessageBox.confirm("确定要删除此收货地址?", "删除", { type: "warning" }).then(() => {
|
||||
API_Member.removeMemberAddress(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getAddressData();
|
||||
],
|
||||
consigneeAddressPath: [{ required: true, message: "收货人地址不能为空" }],
|
||||
detail: [{ required: true, message: "收货人详细地址不能为空" }],
|
||||
});
|
||||
const pointData = ref([]);
|
||||
const pointTotal = ref(0);
|
||||
const pointSearchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const orderData = ref([]);
|
||||
const orderTotal = ref(0);
|
||||
const orderSearchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
payStatus: "",
|
||||
orderSn: "",
|
||||
orderType: "",
|
||||
});
|
||||
const addressData = ref([]);
|
||||
const addressTotal = ref(0);
|
||||
const addressSearchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const walletSearchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
});
|
||||
const walletData = ref([]);
|
||||
const walletTotal = ref(0);
|
||||
const receiptRecordSearchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
});
|
||||
const receiptRecordData = ref([]);
|
||||
const receiptRecordTotal = ref(0);
|
||||
|
||||
function orderTypeText(v) {
|
||||
const map = {
|
||||
NORMAL: "普通订单",
|
||||
VIRTUAL: "虚拟订单",
|
||||
GIFT: "赠品订单",
|
||||
PINTUAN: "拼团订单",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function clientTypeText(v) {
|
||||
const map = {
|
||||
H5: "移动端",
|
||||
PC: "PC端",
|
||||
WECHAT_MP: "小程序端",
|
||||
APP: "移动应用端",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function orderStatusText(v) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
UNDELIVERED: "待发货",
|
||||
DELIVERED: "已发货",
|
||||
COMPLETED: "已完成",
|
||||
TAKE: "待核验",
|
||||
CANCELLED: "已关闭",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function payStatusText(v) {
|
||||
const map = {
|
||||
UNPAID: "未付款",
|
||||
PAID: "已付款",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function groupAfterSaleStatusText(v) {
|
||||
const map = {
|
||||
NEW: "未申请",
|
||||
NOT_APPLIED: "未申请",
|
||||
ALREADY_APPLIED: "已申请",
|
||||
EXPIRED: "已失效",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function groupComplainStatusText(v) {
|
||||
const map = {
|
||||
NEW: "未申请",
|
||||
NO_APPLY: "未申请",
|
||||
APPLYING: "申请中",
|
||||
COMPLETE: "已完成",
|
||||
EXPIRED: "已失效",
|
||||
CANCEL: "取消投诉",
|
||||
};
|
||||
return map[v] || v || "";
|
||||
}
|
||||
function walletServiceTypeText(type) {
|
||||
if (type === "WALLET_WITHDRAWAL") return "余额提现";
|
||||
if (type === "WALLET_PAY") return "余额支付";
|
||||
if (type === "WALLET_REFUND") return "余额退款";
|
||||
if (type === "WALLET_RECHARGE") return "余额充值";
|
||||
return "佣金提成";
|
||||
}
|
||||
function init() {
|
||||
getMemberInfo();
|
||||
getPointData();
|
||||
}
|
||||
function memberInfoChange(v) {
|
||||
if (v == "point") {
|
||||
getPointData();
|
||||
}
|
||||
if (v == "address") {
|
||||
nextTick(() => {
|
||||
getAddressData();
|
||||
});
|
||||
}
|
||||
if (v == "order") {
|
||||
getOrderData();
|
||||
}
|
||||
if (v == "wallet") {
|
||||
getMemberWalletData();
|
||||
getDepositLogData();
|
||||
}
|
||||
if (v == "receipt") {
|
||||
getReceiptRecordData();
|
||||
}
|
||||
}
|
||||
function getMemberInfo() {
|
||||
API_Member.getMemberInfoData(id.value).then((res) => {
|
||||
memberInfo.value = res.result;
|
||||
});
|
||||
}
|
||||
function memberStatusChange(v) {
|
||||
let params = {
|
||||
memberIds: [id.value],
|
||||
disabled: v,
|
||||
};
|
||||
API_Member.updateMemberStatus(params).then((res) => {});
|
||||
}
|
||||
function getMemberWalletData() {
|
||||
loading.value = true;
|
||||
let params = {
|
||||
memberId: id.value,
|
||||
};
|
||||
API_Member.getMemberWallet(params).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
memberWalletInfo.value = res.result;
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
function getDepositLogData() {
|
||||
loading.value = true;
|
||||
walletSearchForm.value.memberId = id.value;
|
||||
API_Member.getUserWallet(walletSearchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
walletData.value = res.result.records;
|
||||
walletTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
function getReceiptRecordData() {
|
||||
loading.value = true;
|
||||
receiptRecordSearchForm.value.pageNumber = 1;
|
||||
receiptRecordSearchForm.value.pageSize = 20;
|
||||
receiptRecordSearchForm.value.memberId = id.value;
|
||||
API_Order.getReceiptPage(receiptRecordSearchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
receiptRecordData.value = res.result.records;
|
||||
receiptRecordTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
function getOrderData() {
|
||||
loading.value = true;
|
||||
orderSearchForm.value.pageNumber = 1;
|
||||
orderSearchForm.value.pageSize = 20;
|
||||
orderSearchForm.value.memberId = id.value;
|
||||
API_Order.getOrderList(orderSearchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
orderData.value = res.result.records;
|
||||
orderTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
function orderDetail(v) {
|
||||
router.push({
|
||||
name: "order-detail",
|
||||
query: { sn: v },
|
||||
});
|
||||
}
|
||||
function getPointData() {
|
||||
loading.value = true;
|
||||
pointSearchForm.value.memberId = id.value;
|
||||
API_Member.getHistoryPointData(pointSearchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
pointData.value = res.result.records;
|
||||
pointTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
function addressSubmit() {
|
||||
addressForm.memberId = id.value;
|
||||
addressFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
let submit = JSON.parse(JSON.stringify(addressForm));
|
||||
submit.isDefault ? (submit.isDefault = true) : (submit.isDefault = false);
|
||||
if (submit.id != "") {
|
||||
API_Member.editMemberAddress(submit).then((res) => {
|
||||
submitLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("修改成功");
|
||||
addressModalVisible.value = false;
|
||||
getAddressData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
getAddressData() {
|
||||
this.addressLoading = true;
|
||||
API_Member.getMemberAddressData(this.id, this.addressSearchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.addressData = res.result.records;
|
||||
this.addressTotal = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.addressLoading = false;
|
||||
});
|
||||
},
|
||||
pointChangePage(v) {
|
||||
this.pointSearchForm.pageNumber = v;
|
||||
this.getPointData();
|
||||
},
|
||||
pointChangePageSize(v) {
|
||||
this.pointSearchForm.pageNumber = 1;
|
||||
this.pointSearchForm.pageSize = v;
|
||||
this.getPointData();
|
||||
},
|
||||
addressChangePage(v) {
|
||||
this.addressSearchForm.pageNumber = v;
|
||||
this.getAddressData();
|
||||
},
|
||||
addressChangePageSize(v) {
|
||||
this.addressSearchForm.pageNumber = 1;
|
||||
this.addressSearchForm.pageSize = v;
|
||||
this.getAddressData();
|
||||
},
|
||||
walletChangePage(v) {
|
||||
this.walletSearchForm.pageNumber = v;
|
||||
this.getDepositLogData();
|
||||
},
|
||||
walletChangePageSize(v) {
|
||||
this.walletSearchForm.pageNumber = 1;
|
||||
this.walletSearchForm.pageSize = v;
|
||||
this.getDepositLogData();
|
||||
},
|
||||
orderChangePage(v) {
|
||||
this.orderSearchForm.pageNumber = v;
|
||||
this.getOrderData();
|
||||
},
|
||||
orderChangePageSize(v) {
|
||||
this.orderSearchForm.pageNumber = 1;
|
||||
this.orderSearchForm.pageSize = v;
|
||||
this.getOrderData();
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
this.orderSearchForm.startDate = v[0];
|
||||
this.orderSearchForm.endDate = v[1];
|
||||
} else {
|
||||
delete this.orderSearchForm.startDate;
|
||||
delete this.orderSearchForm.endDate;
|
||||
API_Member.addMemberAddress(submit).then((res) => {
|
||||
submitLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("添加成功");
|
||||
addressModalVisible.value = false;
|
||||
getAddressData();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.id = this.$route.query.id;
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
function getAddress(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
|
||||
addressForm.consigneeAddressPath = paths;
|
||||
addressForm.consigneeAddressIdPath = ids;
|
||||
|
||||
const coord = val.data[val.data.length - 1].center.split(",");
|
||||
addressForm.lat = coord[1];
|
||||
addressForm.lon = coord[0];
|
||||
} else {
|
||||
addressForm.consigneeAddressPath = val.data.addr;
|
||||
addressForm.consigneeAddressIdPath = val.data.addrId;
|
||||
addressForm.lat = val.data.position.lat;
|
||||
addressForm.lon = val.data.position.lng;
|
||||
}
|
||||
}
|
||||
function memberAddressRemove(v) {
|
||||
ElMessageBox.confirm("确定要删除此收货地址?", "删除", { type: "warning" }).then(() => {
|
||||
API_Member.removeMemberAddress(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
getAddressData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
function getAddressData() {
|
||||
addressLoading.value = true;
|
||||
API_Member.getMemberAddressData(id.value, addressSearchForm.value)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
addressData.value = res.result.records;
|
||||
addressTotal.value = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
addressLoading.value = false;
|
||||
});
|
||||
}
|
||||
function pointChangePage(v) {
|
||||
pointSearchForm.value.pageNumber = v;
|
||||
getPointData();
|
||||
}
|
||||
function pointChangePageSize(v) {
|
||||
pointSearchForm.value.pageNumber = 1;
|
||||
pointSearchForm.value.pageSize = v;
|
||||
getPointData();
|
||||
}
|
||||
function addressChangePage(v) {
|
||||
addressSearchForm.value.pageNumber = v;
|
||||
getAddressData();
|
||||
}
|
||||
function addressChangePageSize(v) {
|
||||
addressSearchForm.value.pageNumber = 1;
|
||||
addressSearchForm.value.pageSize = v;
|
||||
getAddressData();
|
||||
}
|
||||
function walletChangePage(v) {
|
||||
walletSearchForm.value.pageNumber = v;
|
||||
getDepositLogData();
|
||||
}
|
||||
function walletChangePageSize(v) {
|
||||
walletSearchForm.value.pageNumber = 1;
|
||||
walletSearchForm.value.pageSize = v;
|
||||
getDepositLogData();
|
||||
}
|
||||
function orderChangePage(v) {
|
||||
orderSearchForm.value.pageNumber = v;
|
||||
getOrderData();
|
||||
}
|
||||
function orderChangePageSize(v) {
|
||||
orderSearchForm.value.pageNumber = 1;
|
||||
orderSearchForm.value.pageSize = v;
|
||||
getOrderData();
|
||||
}
|
||||
function selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
orderSearchForm.value.startDate = v[0];
|
||||
orderSearchForm.value.endDate = v[1];
|
||||
} else {
|
||||
delete orderSearchForm.value.startDate;
|
||||
delete orderSearchForm.value.endDate;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
id.value = route.query.id;
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "memberDetail.scss";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -96,7 +96,7 @@
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="descFlag" :title="descTitle" width="500px" destroy-on-close>
|
||||
<el-form ref="formValidate" :model="formValidate" :rules="ruleValidate" label-width="80px">
|
||||
<el-form ref="formValidateRef" :model="formValidate" :rules="ruleValidate" label-width="80px">
|
||||
<el-form-item label="头像">
|
||||
<img :src="formValidate.face" class="face" />
|
||||
<el-button
|
||||
@@ -143,7 +143,7 @@
|
||||
|
||||
<el-dialog v-model="picModelFlag" width="1200px">
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
ref="ossManageRef"
|
||||
@callback="callbackSelected"
|
||||
:isComponent="true"
|
||||
:initialize="picModelFlag"
|
||||
@@ -153,152 +153,156 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, nextTick, onMounted } from "vue";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import multipleMap from "@/components/map/multiple-map";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { customRouterPush } from "@/utils/filters";
|
||||
import { md5 } from "@/utils/md5.js";
|
||||
|
||||
export default {
|
||||
name: "memberRecycle",
|
||||
components: {
|
||||
ossManage,
|
||||
multipleMap,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedMember: false,
|
||||
descTitle: "",
|
||||
descFlag: false,
|
||||
openSearch: true,
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
order: "desc",
|
||||
id: "",
|
||||
username: "",
|
||||
mobile: "",
|
||||
disabled: "CLOSE",
|
||||
},
|
||||
picModelFlag: false,
|
||||
formValidate: {},
|
||||
ruleValidate: {},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
callback(val) {
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
init() {
|
||||
this.getData();
|
||||
},
|
||||
changePage() {
|
||||
this.getData();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getData();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
editPerm(val) {
|
||||
this.descTitle = `查看用户 ${val.username}`;
|
||||
this.descFlag = true;
|
||||
this.getMemberInfo(val.id);
|
||||
},
|
||||
getMemberInfo(id) {
|
||||
API_Member.getMemberInfoData(id).then((res) => {
|
||||
if (res.result) {
|
||||
this.formValidate = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
openPicSelector() {
|
||||
this.picModelFlag = true;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.ossManage) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.formValidate.face = val.url;
|
||||
},
|
||||
selectedRegion(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
this.formValidate.region = paths;
|
||||
this.formValidate.regionId = ids;
|
||||
} else {
|
||||
this.formValidate.region = val.data.addr;
|
||||
this.formValidate.regionId = val.data.addrId;
|
||||
defineOptions({ name: "memberRecycle" });
|
||||
|
||||
const emit = defineEmits(["callback"]);
|
||||
|
||||
// 模板 el-form 的 ref(原 ref="searchForm",与 data 同名会互相覆盖,改名为 searchFormRef)
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
// 模板编辑弹窗 el-form 的 ref(原 ref="formValidate",与 data 同名会互相覆盖,改名为 formValidateRef)
|
||||
const formValidateRef = ref(null);
|
||||
// 模板 ossManage 组件的 ref(原 ref="ossManage",与组件 import 同名会冲突,改名为 ossManageRef)
|
||||
const ossManageRef = ref(null);
|
||||
|
||||
const selectedMember = ref(false);
|
||||
const descTitle = ref("");
|
||||
const descFlag = ref(false);
|
||||
const openSearch = ref(true);
|
||||
const loading = ref(true);
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
order: "desc",
|
||||
id: "",
|
||||
username: "",
|
||||
mobile: "",
|
||||
disabled: "CLOSE",
|
||||
});
|
||||
const picModelFlag = ref(false);
|
||||
const formValidate = ref({});
|
||||
const ruleValidate = ref({});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
function callback(val) {
|
||||
emit("callback", val);
|
||||
}
|
||||
function init() {
|
||||
getData();
|
||||
}
|
||||
function changePage() {
|
||||
getData();
|
||||
}
|
||||
function changePageSize() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
getData();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.pageSize = 20;
|
||||
getData();
|
||||
}
|
||||
function editPerm(val) {
|
||||
descTitle.value = `查看用户 ${val.username}`;
|
||||
descFlag.value = true;
|
||||
getMemberInfo(val.id);
|
||||
}
|
||||
function getMemberInfo(id) {
|
||||
API_Member.getMemberInfoData(id).then((res) => {
|
||||
if (res.result) {
|
||||
formValidate.value = res.result;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
API_Member.getMemberListData(searchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
function openPicSelector() {
|
||||
picModelFlag.value = true;
|
||||
nextTick(() => {
|
||||
if (ossManageRef.value) {
|
||||
ossManageRef.value.selectImage = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
function callbackSelected(val) {
|
||||
picModelFlag.value = false;
|
||||
formValidate.value.face = val.url;
|
||||
}
|
||||
function selectedRegion(val) {
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
formValidate.value.region = paths;
|
||||
formValidate.value.regionId = ids;
|
||||
} else {
|
||||
formValidate.value.region = val.data.addr;
|
||||
formValidate.value.regionId = val.data.addrId;
|
||||
}
|
||||
}
|
||||
function detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
}
|
||||
function enable(v) {
|
||||
let params = {
|
||||
memberIds: [v.id],
|
||||
disabled: true,
|
||||
};
|
||||
ElMessageBox.confirm("确定启用此会员?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.updateMemberStatus(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("启用成功");
|
||||
getData();
|
||||
}
|
||||
},
|
||||
detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
enable(v) {
|
||||
let params = {
|
||||
memberIds: [v.id],
|
||||
disabled: true,
|
||||
};
|
||||
ElMessageBox.confirm("确定启用此会员?", "提示", { type: "warning" }).then(() => {
|
||||
API_Member.updateMemberStatus(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("启用成功");
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
handleSubmitModal() {
|
||||
const { nickName, sex, username, face, newPassword, id, regionId, region } = this.formValidate;
|
||||
let time = new Date(this.formValidate.birthday);
|
||||
let birthday = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let submit = {
|
||||
regionId: regionId,
|
||||
region: region,
|
||||
nickName,
|
||||
sex,
|
||||
birthday,
|
||||
face: face || "",
|
||||
id,
|
||||
};
|
||||
if (newPassword) {
|
||||
submit.password = this.md5(newPassword);
|
||||
}
|
||||
API_Member.updateMember(submit).then((res) => {
|
||||
if (res.result) {
|
||||
ElMessage.success("修改成功!");
|
||||
this.descFlag = false;
|
||||
this.init();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
function handleSubmitModal() {
|
||||
const { nickName, sex, username, face, newPassword, id, regionId, region } = formValidate.value;
|
||||
let time = new Date(formValidate.value.birthday);
|
||||
let birthday = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let submit = {
|
||||
regionId: regionId,
|
||||
region: region,
|
||||
nickName,
|
||||
sex,
|
||||
birthday,
|
||||
face: face || "",
|
||||
id,
|
||||
};
|
||||
if (newPassword) {
|
||||
// 原 this.md5 为 main.js 注册的全局属性,改为具名导入(同 login.vue / userManage.vue)
|
||||
submit.password = md5(newPassword);
|
||||
}
|
||||
API_Member.updateMember(submit).then((res) => {
|
||||
if (res.result) {
|
||||
ElMessage.success("修改成功!");
|
||||
descFlag.value = false;
|
||||
init();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.face {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog v-model="wechatModal" title="微信设置" width="530px">
|
||||
<el-form ref="wechatFormData" :model="wechatFormData" label-width="100px">
|
||||
<el-form ref="wechatFormRef" :model="wechatFormData" label-width="100px">
|
||||
<el-form-item v-if="tab === 'WECHAT'" label="模板名称">
|
||||
<el-input v-model="wechatFormData.name" maxlength="9" disabled />
|
||||
</el-form-item>
|
||||
@@ -105,171 +105,169 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import {
|
||||
wechatMessageSync,
|
||||
getWechatMessagePage,
|
||||
getWechatMessagePage as fetchWechatMessagePage,
|
||||
editWechatMessageTemplate,
|
||||
delWechatMessageTemplate,
|
||||
wechatMPMessageSync,
|
||||
getWechatMPMessagePage,
|
||||
getWechatMPMessagePage as fetchWechatMPMessagePage,
|
||||
editWechatMPMessageTemplate,
|
||||
delWechatMPMessageTemplate,
|
||||
} from "@/api/setting";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
export default {
|
||||
title: "wechat-message-manage",
|
||||
data() {
|
||||
return {
|
||||
wechatModal: false,
|
||||
wechatFormData: {},
|
||||
wechatMPFormData: {},
|
||||
tab: "WECHAT",
|
||||
searchForm: { type: "WECHAT" },
|
||||
loading: true,
|
||||
id: "",
|
||||
weChatSearchForm: { pageNumber: 1, pageSize: 20 },
|
||||
weChatMPSearchForm: { pageNumber: 1, pageSize: 20 },
|
||||
weChatData: [],
|
||||
weChatMPData: [],
|
||||
weChatTotal: 0,
|
||||
weChatMPTotal: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.type = this.tab;
|
||||
if (this.tab === "WECHAT") {
|
||||
this.weChatSearchForm.pageNumber = v;
|
||||
this.getWechatMessagePage();
|
||||
} else {
|
||||
this.weChatMPSearchForm.pageNumber = v;
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.type = this.tab;
|
||||
if (this.tab === "WECHAT") {
|
||||
this.weChatSearchForm.pageSize = v;
|
||||
this.getWechatMessagePage();
|
||||
} else {
|
||||
this.weChatMPSearchForm.pageSize = v;
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
},
|
||||
wechatSettingAlert(v) {
|
||||
this.wechatFormData = v;
|
||||
this.id = v.id;
|
||||
this.wechatModal = true;
|
||||
},
|
||||
weChatSync(mp) {
|
||||
ElMessageBox.confirm("确认要初始化微信小程序消息订阅?", "提示", { type: "warning" }).then(() => {
|
||||
if (mp === "mp") {
|
||||
wechatMPMessageSync().then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信小程序消息订阅初始化");
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
wechatMessageSync().then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信消息模板初始化成功");
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
wechatFormDataEdit() {
|
||||
this.$refs.wechatFormData.validate((valid) => {
|
||||
if (valid) {
|
||||
if (!this.wechatFormData.updateTime) {
|
||||
this.wechatFormData.updateTime = "";
|
||||
}
|
||||
editWechatMessageTemplate(this.id, this.wechatFormData).then((res) => {
|
||||
if (res.message === "success") {
|
||||
ElMessage.success("微信模板修改成功");
|
||||
this.wechatModal = false;
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
wechatMPFormDataEdit() {
|
||||
this.$refs.wechatFormData.validate((valid) => {
|
||||
if (valid) {
|
||||
editWechatMPMessageTemplate(this.id, this.wechatMPFormData).then((res) => {
|
||||
if (res.message === "success") {
|
||||
ElMessage.success("微信消息订阅模板修改成功");
|
||||
this.wechatModal = false;
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
delWeChat(v) {
|
||||
ElMessageBox.confirm("确定删除此模板?", "提示", { type: "warning" }).then(() => {
|
||||
if (this.tab === "WECHAT") {
|
||||
delWechatMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信模板删除成功");
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delWechatMPMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信消息订阅删除成功");
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
getDataList() {
|
||||
this.getWechatMessagePage();
|
||||
},
|
||||
getWechatMessagePage() {
|
||||
this.loading = true;
|
||||
getWechatMessagePage(this.weChatSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
defineOptions({ title: "wechat-message-manage" });
|
||||
|
||||
const wechatFormRef = ref(null);
|
||||
|
||||
const wechatModal = ref(false);
|
||||
const wechatFormData = ref({});
|
||||
const wechatMPFormData = ref({});
|
||||
const tab = ref("WECHAT");
|
||||
const searchForm = reactive({ type: "WECHAT" });
|
||||
const loading = ref(true);
|
||||
const id = ref("");
|
||||
const weChatSearchForm = reactive({ pageNumber: 1, pageSize: 20 });
|
||||
const weChatMPSearchForm = reactive({ pageNumber: 1, pageSize: 20 });
|
||||
const weChatData = ref([]);
|
||||
const weChatMPData = ref([]);
|
||||
const weChatTotal = ref(0);
|
||||
const weChatMPTotal = ref(0);
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.type = tab.value;
|
||||
if (tab.value === "WECHAT") {
|
||||
weChatSearchForm.pageNumber = v;
|
||||
getWechatMessagePage();
|
||||
} else {
|
||||
weChatMPSearchForm.pageNumber = v;
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.type = tab.value;
|
||||
if (tab.value === "WECHAT") {
|
||||
weChatSearchForm.pageSize = v;
|
||||
getWechatMessagePage();
|
||||
} else {
|
||||
weChatMPSearchForm.pageSize = v;
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
}
|
||||
function wechatSettingAlert(v) {
|
||||
wechatFormData.value = v;
|
||||
id.value = v.id;
|
||||
wechatModal.value = true;
|
||||
}
|
||||
function weChatSync(mp) {
|
||||
ElMessageBox.confirm("确认要初始化微信小程序消息订阅?", "提示", { type: "warning" }).then(() => {
|
||||
if (mp === "mp") {
|
||||
wechatMPMessageSync().then((res) => {
|
||||
if (res.success) {
|
||||
this.weChatData = res.result.records;
|
||||
this.weChatTotal = res.result.total;
|
||||
ElMessage.success("微信小程序消息订阅初始化");
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
},
|
||||
getWechatMPMessagePage() {
|
||||
this.loading = true;
|
||||
getWechatMPMessagePage(this.weChatMPSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
} else {
|
||||
wechatMessageSync().then((res) => {
|
||||
if (res.success) {
|
||||
this.weChatMPData = res.result.records;
|
||||
this.weChatMPTotal = res.result.total;
|
||||
ElMessage.success("微信消息模板初始化成功");
|
||||
getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
},
|
||||
tabPaneChange(tab) {
|
||||
const v = tab.paneName || this.tab;
|
||||
this.searchForm.type = v;
|
||||
if (v === "WECHAT") {
|
||||
this.getWechatMessagePage();
|
||||
} else if (v === "WECHATMP") {
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
}).catch(() => {});
|
||||
}
|
||||
function wechatFormDataEdit() {
|
||||
wechatFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
if (!wechatFormData.value.updateTime) {
|
||||
wechatFormData.value.updateTime = "";
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
editWechatMessageTemplate(id.value, wechatFormData.value).then((res) => {
|
||||
if (res.message === "success") {
|
||||
ElMessage.success("微信模板修改成功");
|
||||
wechatModal.value = false;
|
||||
getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function wechatMPFormDataEdit() {
|
||||
wechatFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
editWechatMPMessageTemplate(id.value, wechatMPFormData.value).then((res) => {
|
||||
if (res.message === "success") {
|
||||
ElMessage.success("微信消息订阅模板修改成功");
|
||||
wechatModal.value = false;
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function delWeChat(v) {
|
||||
ElMessageBox.confirm("确定删除此模板?", "提示", { type: "warning" }).then(() => {
|
||||
if (tab.value === "WECHAT") {
|
||||
delWechatMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信模板删除成功");
|
||||
getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delWechatMPMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("微信消息订阅删除成功");
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
}
|
||||
function getDataList() {
|
||||
getWechatMessagePage();
|
||||
}
|
||||
function getWechatMessagePage() {
|
||||
loading.value = true;
|
||||
fetchWechatMessagePage(weChatSearchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
weChatData.value = res.result.records;
|
||||
weChatTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getWechatMPMessagePage() {
|
||||
loading.value = true;
|
||||
fetchWechatMPMessagePage(weChatMPSearchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
weChatMPData.value = res.result.records;
|
||||
weChatMPTotal.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
function tabPaneChange(tabPane) {
|
||||
const v = tabPane.paneName || tab.value;
|
||||
searchForm.type = v;
|
||||
if (v === "WECHAT") {
|
||||
getWechatMessagePage();
|
||||
} else if (v === "WECHATMP") {
|
||||
getWechatMPMessagePage();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.link-text {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<el-tab-pane label="积分列表" name="pointList">
|
||||
<el-card class="point-content-card">
|
||||
<el-form
|
||||
ref="memberSearchForm"
|
||||
ref="memberSearchFormRef"
|
||||
:model="memberSearchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -131,7 +131,7 @@
|
||||
<el-tab-pane label="积分增减记录" name="pointChangeRecord">
|
||||
<el-card class="point-content-card">
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -203,132 +203,135 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import { customRouterPush } from "@/utils/filters";
|
||||
|
||||
export default {
|
||||
name: "point",
|
||||
data() {
|
||||
return {
|
||||
activeTab: "pointList",
|
||||
loading: true,
|
||||
memberLoading: false,
|
||||
pointsStatistics: {
|
||||
totalPoint: 0,
|
||||
unUsedPoint: 0,
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
memberSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
nickName: "",
|
||||
username: "",
|
||||
disabled: "",
|
||||
minPoint: null,
|
||||
maxPoint: null,
|
||||
},
|
||||
data: [],
|
||||
memberData: [],
|
||||
memberTotal: 0,
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
callback(val) {
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
init() {
|
||||
this.getStatistics();
|
||||
this.getMemberList();
|
||||
this.getData();
|
||||
},
|
||||
getStatistics() {
|
||||
API_Member.queryMemberPointsStatistics().then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.pointsStatistics = {
|
||||
totalPoint: res.result.totalPoint || 0,
|
||||
unUsedPoint: res.result.unUsedPoint || 0,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
formatNumber(value) {
|
||||
const numericValue = Number(value || 0);
|
||||
if (!Number.isFinite(numericValue)) return "0";
|
||||
return numericValue.toLocaleString();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
handleMemberSearch() {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPage(v) {
|
||||
this.memberSearchForm.pageNumber = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPageSize(v) {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.memberSearchForm.pageSize = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
getMemberList() {
|
||||
this.memberLoading = true;
|
||||
const params = {
|
||||
pageNumber: this.memberSearchForm.pageNumber,
|
||||
pageSize: this.memberSearchForm.pageSize,
|
||||
nickName: this.memberSearchForm.nickName || undefined,
|
||||
username: this.memberSearchForm.username || undefined,
|
||||
disabled: this.memberSearchForm.disabled || undefined,
|
||||
minPoint: this.memberSearchForm.minPoint,
|
||||
maxPoint: this.memberSearchForm.maxPoint,
|
||||
defineOptions({ name: "point" });
|
||||
|
||||
const emit = defineEmits(["callback"]);
|
||||
|
||||
// 模板 ref,script 内未使用
|
||||
const memberSearchFormRef = ref(null);
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
|
||||
const activeTab = ref("pointList");
|
||||
const loading = ref(true);
|
||||
const memberLoading = ref(false);
|
||||
const pointsStatistics = ref({
|
||||
totalPoint: 0,
|
||||
unUsedPoint: 0,
|
||||
});
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const memberSearchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
nickName: "",
|
||||
username: "",
|
||||
disabled: "",
|
||||
minPoint: null,
|
||||
maxPoint: null,
|
||||
});
|
||||
const data = ref([]);
|
||||
const memberData = ref([]);
|
||||
const memberTotal = ref(0);
|
||||
const total = ref(0);
|
||||
|
||||
function callback(val) {
|
||||
emit("callback", val);
|
||||
}
|
||||
function detail(row) {
|
||||
customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
}
|
||||
function init() {
|
||||
getStatistics();
|
||||
getMemberList();
|
||||
getData();
|
||||
}
|
||||
function getStatistics() {
|
||||
API_Member.queryMemberPointsStatistics().then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
pointsStatistics.value = {
|
||||
totalPoint: res.result.totalPoint || 0,
|
||||
unUsedPoint: res.result.unUsedPoint || 0,
|
||||
};
|
||||
API_Member.getMemberListData(params)
|
||||
.then((res) => {
|
||||
this.memberLoading = false;
|
||||
if (res && res.success && res.result && res.result.records) {
|
||||
this.memberData = res.result.records;
|
||||
this.memberTotal = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.memberLoading = false;
|
||||
});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getHistoryPointData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
function formatNumber(value) {
|
||||
const numericValue = Number(value || 0);
|
||||
if (!Number.isFinite(numericValue)) return "0";
|
||||
return numericValue.toLocaleString();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getData();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = v;
|
||||
getData();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getData();
|
||||
}
|
||||
function handleMemberSearch() {
|
||||
memberSearchForm.pageNumber = 1;
|
||||
getMemberList();
|
||||
}
|
||||
function changeMemberPage(v) {
|
||||
memberSearchForm.pageNumber = v;
|
||||
getMemberList();
|
||||
}
|
||||
function changeMemberPageSize(v) {
|
||||
memberSearchForm.pageNumber = 1;
|
||||
memberSearchForm.pageSize = v;
|
||||
getMemberList();
|
||||
}
|
||||
function getMemberList() {
|
||||
memberLoading.value = true;
|
||||
const params = {
|
||||
pageNumber: memberSearchForm.pageNumber,
|
||||
pageSize: memberSearchForm.pageSize,
|
||||
nickName: memberSearchForm.nickName || undefined,
|
||||
username: memberSearchForm.username || undefined,
|
||||
disabled: memberSearchForm.disabled || undefined,
|
||||
minPoint: memberSearchForm.minPoint,
|
||||
maxPoint: memberSearchForm.maxPoint,
|
||||
};
|
||||
API_Member.getMemberListData(params)
|
||||
.then((res) => {
|
||||
memberLoading.value = false;
|
||||
if (res && res.success && res.result && res.result.records) {
|
||||
memberData.value = res.result.records;
|
||||
memberTotal.value = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
memberLoading.value = false;
|
||||
});
|
||||
}
|
||||
function getData() {
|
||||
loading.value = true;
|
||||
API_Member.getHistoryPointData(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.points-statistics-card {
|
||||
|
||||
Reference in New Issue
Block a user