feat(shop): 优化店铺功能模块界面和交互
- 修改提现页面状态标签文案为更准确的描述 - 在用户信息中添加ID显示并调整布局结构 - 简化支付信息显示为统一的商家转账标识 - 调整表格列配置,将用户ID改为订单号,新增收款方式列 - 修复行双击编辑功能被注释的问题 - 将礼品卡文本修正为礼品劵 - 配送员编辑页面增加用户和社区选择组件及密钥保护功能 - 身份证号显示增加掩码保护 - 配送员列表页面重新排列列顺序 - 菜单搜索组件关键词字段从keywords改为title - 开发环境配置中注释掉API地址配置
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
VITE_APP_NAME=后台管理(开发环境)
|
||||
VITE_API_URL=http://127.0.0.1:9200/api
|
||||
#VITE_API_URL=http://127.0.0.1:9200/api
|
||||
#VITE_SERVER_API_URL=http://127.0.0.1:8000/api
|
||||
|
||||
|
||||
|
||||
@@ -25,41 +25,27 @@
|
||||
>待审核</a-tag
|
||||
>
|
||||
<a-tag v-if="record.applyStatus === 20" color="success"
|
||||
>审核通过</a-tag
|
||||
>转账成功</a-tag
|
||||
>
|
||||
<a-tag v-if="record.applyStatus === 30" color="error">已驳回</a-tag>
|
||||
<a-tag v-if="record.applyStatus === 30" color="error">用户取消</a-tag>
|
||||
<a-tag v-if="record.applyStatus === 40">已打款</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'userInfo'">
|
||||
<a-space>
|
||||
<a-avatar :src="record.avatar" />
|
||||
<div class="flex flex-col">
|
||||
<span>{{ record.realName || '未实名认证' }}</span>
|
||||
<span class="text-gray-400">{{ record.phone }}</span>
|
||||
<div>
|
||||
<span>{{ record.realName || '未实名认证' }}</span>
|
||||
<span class="text-gray-400">(ID:{{ record.userId }})</span>
|
||||
</div>
|
||||
<div><span class="text-gray-400">{{ record.phone }}</span></div>
|
||||
</div>
|
||||
</a-space>
|
||||
</template>
|
||||
<template v-if="column.key === 'paymentInfo'">
|
||||
<template v-if="record.payType === 10">
|
||||
<a-space direction="vertical">
|
||||
<a-tag color="blue">微信</a-tag>
|
||||
<span>{{ record.wechatName }}</span>
|
||||
<span>{{ record.wechatName }}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
<template v-if="record.payType === 20">
|
||||
<a-space direction="vertical">
|
||||
<a-tag color="blue">支付宝</a-tag>
|
||||
<span>{{ record.alipayName }}</span>
|
||||
<span>{{ record.alipayAccount }}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
<template v-if="record.payType === 30">
|
||||
<a-space direction="vertical">
|
||||
<a-tag color="blue">银行卡</a-tag>
|
||||
<span>{{ record.bankName }}</span>
|
||||
<span>{{ record.bankAccount }}</span>
|
||||
<span>{{ record.bankCard }}</span>
|
||||
<a-tag color="blue">商家转账</a-tag>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
@@ -186,26 +172,27 @@
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: '用户ID',
|
||||
dataIndex: 'userId',
|
||||
key: 'userId',
|
||||
title: '订单号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
align: 'center',
|
||||
width: 90,
|
||||
fixed: 'left'
|
||||
},
|
||||
// {
|
||||
// title: '用户ID',
|
||||
// dataIndex: 'userId',
|
||||
// key: 'userId',
|
||||
// align: 'center',
|
||||
// width: 90,
|
||||
// fixed: 'left'
|
||||
// },
|
||||
{
|
||||
title: '提现金额',
|
||||
dataIndex: 'money',
|
||||
key: 'money',
|
||||
title: '收款方式',
|
||||
dataIndex: 'paymentInfo',
|
||||
key: 'paymentInfo',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
customRender: ({ text }) => {
|
||||
const amount = parseFloat(text || '0').toFixed(2);
|
||||
return {
|
||||
type: 'span',
|
||||
children: `¥${amount}`
|
||||
};
|
||||
}
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '用户信息',
|
||||
@@ -213,9 +200,17 @@
|
||||
key: 'userInfo'
|
||||
},
|
||||
{
|
||||
title: '收款信息',
|
||||
dataIndex: 'paymentInfo',
|
||||
key: 'paymentInfo'
|
||||
title: '转账金额',
|
||||
dataIndex: 'money',
|
||||
key: 'money',
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
const amount = parseFloat(text || '0').toFixed(2);
|
||||
return {
|
||||
type: 'span',
|
||||
children: `¥${amount}`
|
||||
};
|
||||
}
|
||||
},
|
||||
// {
|
||||
// title: '审核时间',
|
||||
@@ -247,7 +242,7 @@
|
||||
key: 'comments'
|
||||
},
|
||||
{
|
||||
title: '申请状态',
|
||||
title: '状态',
|
||||
dataIndex: 'applyStatus',
|
||||
key: 'applyStatus',
|
||||
align: 'center',
|
||||
@@ -448,7 +443,7 @@
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
// openEdit(record);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
|
||||
"
|
||||
>
|
||||
<a-form-item label="礼品卡" name="name">
|
||||
<a-form-item label="礼品劵" name="name">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入礼品卡名称"
|
||||
|
||||
@@ -20,26 +20,29 @@
|
||||
"
|
||||
>
|
||||
<a-form-item label="选择用户" name="userId">
|
||||
<!-- SelectUser 组件本身不支持 v-model,只通过 @done 回传选择结果;用 key 强制刷新回显 -->
|
||||
<SelectUser
|
||||
:key="String(form.userId ?? '') + selectedUserText"
|
||||
:value="selectedUserText"
|
||||
:placeholder="`选择用户`"
|
||||
v-model:value="form.userId"
|
||||
@done="onChooseUser"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="配送点" name="dealerId">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配送点ID(多选)"
|
||||
v-model:value="form.dealerId"
|
||||
<a-form-item label="配送点(小区)" name="dealerId">
|
||||
<SelectCommunity
|
||||
:key="String(form.dealerId ?? '') + selectedCommunityText"
|
||||
:value="selectedCommunityText"
|
||||
:placeholder="`选择小区`"
|
||||
@done="onChooseCommunity"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="骑手编号" name="riderNo">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入骑手编号(可选)"
|
||||
v-model:value="form.riderNo"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="骑手编号" name="riderNo">-->
|
||||
<!-- <a-input-->
|
||||
<!-- allow-clear-->
|
||||
<!-- placeholder="请输入骑手编号(可选)"-->
|
||||
<!-- v-model:value="form.riderNo"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="姓名" name="realName">
|
||||
<a-input
|
||||
allow-clear
|
||||
@@ -54,26 +57,20 @@
|
||||
v-model:value="form.mobile"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="头像" name="avatar">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入头像"
|
||||
v-model:value="form.avatar"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="头像" name="avatar">-->
|
||||
<!-- <a-input-->
|
||||
<!-- allow-clear-->
|
||||
<!-- placeholder="请输入头像"-->
|
||||
<!-- v-model:value="form.avatar"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="身份证号" name="idCardNo">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入身份证号"
|
||||
v-model:value="form.idCardNo"
|
||||
:value="maskedIdCardNo"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group v-model:value="form.status">
|
||||
<a-radio :value="0">正常</a-radio>
|
||||
<a-radio :value="1">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="接单状态" name="workStatus">
|
||||
<a-input
|
||||
allow-clear
|
||||
@@ -147,22 +144,34 @@
|
||||
v-model:value="form.sortNumber"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group v-model:value="form.status">
|
||||
<a-radio :value="0">正常</a-radio>
|
||||
<a-radio :value="1">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { computed, ref, reactive, watch } from 'vue';
|
||||
import { Form, message } from 'ant-design-vue';
|
||||
import { assignObject, uuid } from 'ele-admin-pro';
|
||||
import { addShopStoreRider, updateShopStoreRider } from '@/api/shop/shopStoreRider';
|
||||
import {
|
||||
addShopStoreRider,
|
||||
updateShopStoreRider
|
||||
} from '@/api/shop/shopStoreRider';
|
||||
import { ShopStoreRider } from '@/api/shop/shopStoreRider/model';
|
||||
import { getUser } from '@/api/system/user';
|
||||
import { getShopCommunity } from '@/api/shop/shopCommunity';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
||||
import { FormInstance } from 'ant-design-vue/es/form';
|
||||
import { FileRecord } from '@/api/system/file/model';
|
||||
import type { User } from '@/api/system/user/model';
|
||||
import type { ShopCommunity } from '@/api/shop/shopCommunity/model';
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
@@ -190,6 +199,8 @@
|
||||
// 表格选中数据
|
||||
const formRef = ref<FormInstance | null>(null);
|
||||
const images = ref<ItemType[]>([]);
|
||||
const selectedUserText = ref('');
|
||||
const selectedCommunityText = ref('');
|
||||
|
||||
// 用户信息
|
||||
const form = reactive<ShopStoreRider>({
|
||||
@@ -225,17 +236,33 @@
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
shopStoreRiderName: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请填写配送员名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
// userId: [
|
||||
// {
|
||||
// required: true,
|
||||
// type: 'string',
|
||||
// message: '请选择用户',
|
||||
// trigger: 'blur'
|
||||
// }
|
||||
// ],
|
||||
// dealerId: [
|
||||
// {
|
||||
// required: true,
|
||||
// type: 'string',
|
||||
// message: '请选择配送点',
|
||||
// trigger: 'blur'
|
||||
// }
|
||||
// ],
|
||||
// realName: [
|
||||
// {
|
||||
// required: true,
|
||||
// type: 'string',
|
||||
// message: '请填写姓名',
|
||||
// trigger: 'blur'
|
||||
// }
|
||||
// ],
|
||||
});
|
||||
|
||||
const chooseImage = (data: FileRecord) => {
|
||||
const _chooseImage = (data: FileRecord) => {
|
||||
images.value.push({
|
||||
uid: data.id,
|
||||
url: data.path,
|
||||
@@ -244,13 +271,26 @@
|
||||
form.avatar = data.path;
|
||||
};
|
||||
|
||||
const onDeleteItem = (index: number) => {
|
||||
const _onDeleteItem = (index: number) => {
|
||||
images.value.splice(index, 1);
|
||||
form.avatar = '';
|
||||
};
|
||||
|
||||
const maskIdCard = (value?: string) => {
|
||||
if (!value) return '';
|
||||
const s = String(value).trim();
|
||||
const startLen = Math.min(6, Math.max(0, s.length - 4));
|
||||
const endLen = Math.min(4, s.length);
|
||||
const starLen = Math.max(4, s.length - startLen - endLen);
|
||||
if (s.length <= startLen + endLen) return s;
|
||||
return `${s.slice(0, startLen)}${'*'.repeat(starLen)}${s.slice(-endLen)}`;
|
||||
};
|
||||
|
||||
const maskedIdCardNo = computed(() => maskIdCard(form.idCardNo));
|
||||
|
||||
const onChooseUser = (user?: User) => {
|
||||
if (!user) {
|
||||
selectedUserText.value = '';
|
||||
form.userId = undefined;
|
||||
return;
|
||||
}
|
||||
@@ -259,6 +299,22 @@
|
||||
form.mobile = user.phone ?? user.mobile;
|
||||
form.avatar = user.avatar ?? user.avatarUrl;
|
||||
form.idCardNo = user.idCard ?? user.idcard;
|
||||
|
||||
const name = user.realName ?? user.nickname ?? '';
|
||||
const phone = user.phone ?? user.mobile ?? '';
|
||||
selectedUserText.value = phone ? `${name}(${phone})` : name;
|
||||
};
|
||||
|
||||
const onChooseCommunity = (
|
||||
community?: ShopCommunity & { index?: number }
|
||||
) => {
|
||||
if (!community) {
|
||||
selectedCommunityText.value = '';
|
||||
form.dealerId = undefined;
|
||||
return;
|
||||
}
|
||||
form.dealerId = community.id;
|
||||
selectedCommunityText.value = community.name ?? String(community.id ?? '');
|
||||
};
|
||||
|
||||
const { resetFields } = useForm(form, rules);
|
||||
@@ -275,7 +331,9 @@
|
||||
const formData = {
|
||||
...form
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateShopStoreRider : addShopStoreRider;
|
||||
const saveOrUpdate = isUpdate.value
|
||||
? updateShopStoreRider
|
||||
: addShopStoreRider;
|
||||
saveOrUpdate(formData)
|
||||
.then((msg) => {
|
||||
loading.value = false;
|
||||
@@ -296,16 +354,47 @@
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
images.value = [];
|
||||
selectedUserText.value = '';
|
||||
selectedCommunityText.value = '';
|
||||
if (props.data) {
|
||||
assignObject(form, props.data);
|
||||
if(props.data.avatar){
|
||||
if (props.data.avatar) {
|
||||
images.value.push({
|
||||
uid: uuid(),
|
||||
url: props.data.avatar,
|
||||
status: 'done'
|
||||
})
|
||||
});
|
||||
}
|
||||
isUpdate.value = true;
|
||||
|
||||
// 回显展示文本(避免组件内部不响应 props.value 更新)
|
||||
if (form.userId) {
|
||||
const uid = form.userId;
|
||||
getUser(form.userId)
|
||||
.then((user) => {
|
||||
if (form.userId !== uid) return;
|
||||
const name = user.realName ?? user.nickname ?? '';
|
||||
const phone = user.phone ?? user.mobile ?? '';
|
||||
selectedUserText.value = phone ? `${name}(${phone})` : name;
|
||||
})
|
||||
.catch(() => {
|
||||
if (form.userId !== uid) return;
|
||||
selectedUserText.value = String(form.userId ?? '');
|
||||
});
|
||||
}
|
||||
if (form.dealerId) {
|
||||
const dealerId = form.dealerId;
|
||||
getShopCommunity(form.dealerId)
|
||||
.then((community) => {
|
||||
if (form.dealerId !== dealerId) return;
|
||||
selectedCommunityText.value =
|
||||
community.name ?? String(community.id ?? '');
|
||||
})
|
||||
.catch(() => {
|
||||
if (form.dealerId !== dealerId) return;
|
||||
selectedCommunityText.value = String(form.dealerId ?? '');
|
||||
});
|
||||
}
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
|
||||
@@ -105,16 +105,6 @@
|
||||
key: 'userId',
|
||||
width: 90
|
||||
},
|
||||
{
|
||||
title: '选择配送点',
|
||||
dataIndex: 'dealerId',
|
||||
key: 'dealerId'
|
||||
},
|
||||
{
|
||||
title: '骑手编号',
|
||||
dataIndex: 'riderNo',
|
||||
key: 'riderNo'
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'realName',
|
||||
@@ -135,6 +125,11 @@
|
||||
dataIndex: 'idCardNo',
|
||||
key: 'idCardNo'
|
||||
},
|
||||
{
|
||||
title: '选择配送点',
|
||||
dataIndex: 'dealerId',
|
||||
key: 'dealerId'
|
||||
},
|
||||
// {
|
||||
// title: '状态',
|
||||
// dataIndex: 'status',
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<a-button type="dashed" @click="openImport">恢复</a-button>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词搜索"
|
||||
placeholder="请输入菜单名称"
|
||||
style="width: 240px"
|
||||
v-model:value="where.keywords"
|
||||
v-model:value="where.title"
|
||||
@search="reload"
|
||||
/>
|
||||
<a-button type="text" @click="reset">重置</a-button>
|
||||
|
||||
Reference in New Issue
Block a user