perf(trade): 优化商品购买页面的规格展示和折扣计算,支持订单取消

This commit is contained in:
xiaojunnuo
2026-05-29 00:56:30 +08:00
parent c7a9363422
commit 6624769032
16 changed files with 452 additions and 240 deletions
@@ -72,6 +72,7 @@ export default function (): CreateCrudOptionsRet {
title: "升级金额",
type: "number",
form: {
show: compute(({ form }) => form.levelType !== "exclusive"),
component: { name: PriceInput, vModel: "modelValue", edit: true },
rules: [{ required: true, message: "请输入升级金额" }],
},
@@ -100,7 +101,7 @@ export default function (): CreateCrudOptionsRet {
}),
form: {
value: "normal",
helper: "专属等级可由管理员手动指定,不参与普通用户自动升级。",
helper: "专属等级可由管理员手动指定,不参与普通用户自动升级。专属等级不会在普通用户端展示。",
},
column: { width: 120, align: "center" },
},
@@ -23,7 +23,6 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
initialForm: {
userId: row.userId,
levelId: row.levelId,
levelLocked: row.levelLocked === true,
},
columns: {
levelId: {
@@ -33,20 +32,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
form: {
col: { span: 24 },
rules: [{ required: true, message: "请选择推广等级" }],
},
},
levelLocked: {
title: "锁定等级",
type: "dict-switch",
dict: dict({
data: [
{ label: "自动升级", value: false, color: "success" },
{ label: "锁定", value: true, color: "warning" },
],
}),
form: {
col: { span: 24 },
helper: "专属等级会自动锁定,不参与自动升级。",
helper: "专属等级将锁定为当前等级,普通等级将按累计推广金额自动升级。",
},
},
},
@@ -80,8 +66,17 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
columns: {
userId: { title: "用户ID", type: "number", search: { show: true }, column: { width: 100 } },
username: { title: "用户名", type: "text", search: { show: true }, column: { width: 160 } },
userDisplay: { title: "显示名称", type: "text", column: { width: 160 } },
username: {
title: "用户名",
type: "text",
search: { show: true },
column: {
width: 180,
cellRender({ row }) {
return row.simpleUser?.displayName || row.userDisplay || row.username || row.userId;
},
},
},
enabled: {
title: "开通状态",
type: "dict-switch",
@@ -33,7 +33,8 @@
</div>
<div class="level-rate-label">佣金比例</div>
<div class="level-rate">{{ item.commissionRate || 0 }}%</div>
<div class="level-threshold">累计推广 {{ amountToYuan(item.minAmount) }} </div>
<div v-if="item.levelType === 'exclusive'" class="level-threshold exclusive-threshold">平台指定专属等级</div>
<div v-else class="level-threshold">累计推广 {{ amountToYuan(item.minAmount) }} </div>
<div class="level-meta">
<a-tag :color="item.disabled ? 'default' : 'success'">{{ item.disabled ? "已禁用" : "已启用" }}</a-tag>
<span>排序 {{ item.sort || 0 }}</span>
@@ -232,6 +233,10 @@ onActivated(() => {
text-align: center;
}
.exclusive-threshold {
color: #8a5a16;
}
.level-meta {
display: flex;
align-items: center;
@@ -26,11 +26,11 @@ export async function UpdateObj(obj: any) {
});
}
export async function DelObj(id: any) {
export async function CancelObj(id: any) {
return await request({
url: apiPrefix + "/delete",
url: apiPrefix + "/cancel",
method: "post",
params: { id },
data: { id },
});
}
@@ -50,14 +50,6 @@ export async function GetDetail(id: any) {
});
}
export async function DeleteBatch(ids: any[]) {
return await request({
url: apiPrefix + "/deleteByIds",
method: "post",
data: { ids },
});
}
export async function UpdatePaid(id: any) {
return await request({
url: apiPrefix + "/updatePaid",
@@ -1,17 +1,10 @@
import * as api from "./api";
import { useI18n } from "/src/locales";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { Modal } from "ant-design-vue";
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
const { t } = useI18n();
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
@@ -20,43 +13,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const res = await api.UpdateObj(form);
return res;
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
const res = await api.AddObj(form);
return res;
};
const userStore = useUserStore();
const settingStore = useSettingStore();
const selectedRowKeys: Ref<any[]> = ref([]);
context.selectedRowKeys = selectedRowKeys;
return {
crudOptions: {
settings: {
plugins: {
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
rowSelection: {
enabled: true,
order: -99,
before: true,
// handle: (pluginProps,useCrudProps)=>CrudOptions,
props: {
multiple: true,
crossPage: true,
selectedRowKeys,
},
},
},
},
request: {
pageRequest,
addRequest,
editRequest,
delRequest,
},
actionbar: {
buttons: {
@@ -67,7 +34,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
toolbar: { show: false },
rowHandle: {
width: 320,
width: 150,
fixed: "right",
buttons: {
view: {
@@ -79,11 +46,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
edit: {
show: false,
},
remove: {
show: false,
},
syncStatus: {
show: compute(({ row }) => {
return row.status === "wait_pay";
}),
text: "同步订单状态",
title: "同步订单状态",
text: null,
tooltip: { title: "同步订单状态" },
icon: "ant-design:sync-outlined",
type: "link",
click: async ({ row }) => {
Modal.confirm({
@@ -96,11 +69,36 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
});
},
},
cancel: {
show: compute(({ row }) => {
return row.status === "wait_pay";
}),
title: "取消订单",
text: null,
tooltip: { title: "取消订单" },
icon: "ion:close-circle-outline",
type: "link",
click({ row }) {
Modal.confirm({
title: "确认取消订单?",
content: "取消后订单会关闭,已冻结的余额抵扣金额将自动退回。",
okText: "确认取消",
cancelText: "再想想",
onOk: async () => {
await api.CancelObj(row.id);
await crudExpose.doRefresh();
},
});
},
},
updatePaid: {
show: compute(({ row }) => {
return row.status === "wait_pay";
}),
text: "确认已支付",
title: "确认已支付",
text: null,
tooltip: { title: "确认已支付" },
icon: "ant-design:check-circle-outlined",
type: "link",
click({ row }) {
Modal.confirm({
@@ -175,7 +173,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
},
rebateAmount: {
title: "返利抵扣",
title: "余额抵扣",
type: "number",
column: {
width: 110,
@@ -224,7 +222,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
{ label: "支付宝", value: "alipay" },
{ label: "微信", value: "wxpay" },
{ label: "免费", value: "free" },
{ label: "返利余额", value: "rebate" },
{ label: "余额抵扣", value: "rebate" },
],
}),
column: {
@@ -6,13 +6,7 @@
<span class="sub"> </span>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #pagination-left>
<a-tooltip title="批量删除">
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
</a-tooltip>
</template>
</fs-crud>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
@@ -20,31 +14,11 @@
import { onActivated, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { message, Modal } from "ant-design-vue";
import { DeleteBatch } from "./api";
defineOptions({
name: "TradeManager",
});
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
const selectedRowKeys = context.selectedRowKeys;
const handleBatchDelete = () => {
if (selectedRowKeys.value?.length > 0) {
Modal.confirm({
title: "确认",
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
async onOk() {
await DeleteBatch(selectedRowKeys.value);
message.info("删除成功");
crudExpose.doRefresh();
selectedRowKeys.value = [];
},
});
} else {
message.error("请先勾选记录");
}
};
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
// 页面打开后获取列表数据
onMounted(() => {