- 新增 apiTokenUpdatePost 接口支持修改 Token 信息 - 扩展 Token 数据结构,增加充值金额限制和次数限制相关字段 - 调整新增/编辑 Token 弹窗,支持编辑模式下的充值限制显示和输入 - 新增绑定记录卡片视图与表格视图切换功能 - 绑定记录视图显示总记录数和总金额统计信息 - 卡片视图改进绑定记录样式和交互,支持复制卡号和卡密 - 弹窗样式和分页控件优化,提升用户体验 - 修复并完善 Api 文档,补充修改 Token 接口说明和示例代码
255 lines
6.8 KiB
Vue
255 lines
6.8 KiB
Vue
<template>
|
|
<a-modal
|
|
v-model:visible="modalVisible"
|
|
:title="isEditMode ? '编辑Token' : '新增Token'"
|
|
width="600px"
|
|
@cancel="handleCancel"
|
|
@before-ok="handleBeforeOk"
|
|
>
|
|
<a-form
|
|
ref="formRef"
|
|
:model="formModel"
|
|
:rules="rules"
|
|
:label-col-props="{ span: 6 }"
|
|
:wrapper-col-props="{ span: 18 }"
|
|
label-align="left"
|
|
>
|
|
<a-form-item field="tokenName" label="Token名称" required>
|
|
<a-input
|
|
v-model="formModel.tokenName"
|
|
placeholder="请输入Token名称"
|
|
:max-length="100"
|
|
show-word-limit
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item
|
|
v-if="!isEditMode"
|
|
field="tokenValue"
|
|
label="Token值"
|
|
required
|
|
>
|
|
<a-textarea
|
|
v-model="formModel.tokenValue"
|
|
placeholder="请输入Token值"
|
|
:max-length="1000"
|
|
:auto-size="{ minRows: 3, maxRows: 6 }"
|
|
show-word-limit
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="phone" label="绑定手机号" required>
|
|
<a-input
|
|
v-model="formModel.phone"
|
|
placeholder="请输入绑定的手机号"
|
|
:max-length="11"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="remark" label="备注">
|
|
<a-textarea
|
|
v-model="formModel.remark"
|
|
placeholder="请输入备注信息"
|
|
:max-length="500"
|
|
:auto-size="{ minRows: 2, maxRows: 4 }"
|
|
show-word-limit
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="rechargeLimitAmount" label="充值金额限制" required>
|
|
<a-input-number
|
|
v-model="formModel.rechargeLimitAmount"
|
|
placeholder="请输入充值金额限制"
|
|
:min="0"
|
|
:precision="2"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="rechargeLimitCount" label="充值次数限制" required>
|
|
<a-input-number
|
|
v-model="formModel.rechargeLimitCount"
|
|
placeholder="请输入充值次数限制"
|
|
:min="0"
|
|
:precision="0"
|
|
style="width: 100%"
|
|
/>
|
|
</a-form-item>
|
|
</a-form>
|
|
</a-modal>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, reactive, computed, watch } from 'vue';
|
|
import { Notification, FormInstance } from '@arco-design/web-vue';
|
|
import { KamiApiCamelOilV1TokenInfo } from '@/api/generated/index.ts';
|
|
import { jdV2TokenClient } from '@/api/index.ts';
|
|
|
|
interface Props {
|
|
visible: boolean;
|
|
editData?: KamiApiCamelOilV1TokenInfo;
|
|
}
|
|
|
|
interface Emits {
|
|
(e: 'update:visible', value: boolean): void;
|
|
(e: 'success'): void;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const emit = defineEmits<Emits>();
|
|
|
|
const modalVisible = computed({
|
|
get: () => props.visible,
|
|
set: value => emit('update:visible', value)
|
|
});
|
|
|
|
const isEditMode = computed(() => !!props.editData);
|
|
|
|
const formRef = ref<FormInstance>();
|
|
|
|
const generateFormModel = () => {
|
|
return {
|
|
tokenId: 0,
|
|
tokenName: '',
|
|
tokenValue: '',
|
|
phone: '',
|
|
remark: '',
|
|
rechargeLimitAmount: 0,
|
|
rechargeLimitCount: 0
|
|
};
|
|
};
|
|
|
|
const formModel = reactive(generateFormModel());
|
|
|
|
const rules = computed(() => ({
|
|
tokenName: [
|
|
{ required: true, message: '请输入Token名称' },
|
|
{ min: 1, max: 100, message: 'Token名称长度为1-100个字符' }
|
|
],
|
|
tokenValue: [
|
|
{ required: !isEditMode.value, message: '请输入Token值' },
|
|
{ min: 1, max: 1000, message: 'Token值长度为1-1000个字符' }
|
|
],
|
|
phone: [
|
|
{ required: true, message: '请输入绑定手机号' },
|
|
{ match: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }
|
|
],
|
|
remark: [{ max: 500, message: '备注长度不能超过500个字符' }],
|
|
rechargeLimitAmount: [
|
|
{ required: true, message: '请输入充值金额限制' },
|
|
{ type: 'number', min: 0, message: '充值金额限制不能小于0' }
|
|
],
|
|
rechargeLimitCount: [
|
|
{ required: true, message: '请输入充值次数限制' },
|
|
{ type: 'number', min: 0, message: '充值次数限制不能小于0' }
|
|
]
|
|
}));
|
|
|
|
// 监听弹窗显示状态和编辑数据,更新表单
|
|
watch(
|
|
[() => props.visible, () => props.editData],
|
|
([visible, editData]) => {
|
|
if (visible) {
|
|
if (editData && isEditMode.value) {
|
|
// 编辑模式,填充现有数据
|
|
Object.assign(formModel, {
|
|
tokenName: editData.tokenName || '',
|
|
tokenValue: editData.tokenValue || '',
|
|
phone: editData.phone || '',
|
|
remark: editData.remark || '',
|
|
rechargeLimitAmount: editData.rechargeLimitAmount || 0,
|
|
rechargeLimitCount: editData.rechargeLimitCount || 0,
|
|
tokenId: editData.id || 0
|
|
});
|
|
} else {
|
|
// 新增模式,重置表单
|
|
Object.assign(formModel, generateFormModel());
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
const handleCancel = () => {
|
|
emit('update:visible', false);
|
|
};
|
|
|
|
const handleBeforeOk = async () => {
|
|
try {
|
|
const valid = await formRef.value?.validate();
|
|
if (!valid) {
|
|
return false;
|
|
}
|
|
|
|
if (isEditMode.value) {
|
|
// 编辑Token
|
|
await jdV2TokenClient.apiTokenUpdatePost({
|
|
kamiApiCamelOilV1UpdateTokenReq: {
|
|
tokenId: formModel.tokenId,
|
|
tokenName: formModel.tokenName,
|
|
phone: formModel.phone,
|
|
remark: formModel.remark,
|
|
rechargeLimitAmount: formModel.rechargeLimitAmount,
|
|
rechargeLimitCount: formModel.rechargeLimitCount
|
|
}
|
|
});
|
|
|
|
Notification.success({
|
|
content: '编辑Token成功',
|
|
closable: true
|
|
});
|
|
} else {
|
|
// 新增Token
|
|
await jdV2TokenClient.apiTokenCreatePost({
|
|
kamiApiCamelOilV1CreateTokenReq: {
|
|
tokenName: formModel.tokenName,
|
|
tokenValue: formModel.tokenValue,
|
|
phone: formModel.phone,
|
|
remark: formModel.remark,
|
|
rechargeLimitAmount: formModel.rechargeLimitAmount,
|
|
rechargeLimitCount: formModel.rechargeLimitCount
|
|
}
|
|
});
|
|
|
|
Notification.success({
|
|
content: '新增Token成功',
|
|
closable: true
|
|
});
|
|
}
|
|
|
|
emit('success');
|
|
emit('update:visible', false);
|
|
return true;
|
|
} catch (err) {
|
|
const action = isEditMode.value ? '编辑' : '新增';
|
|
console.error(`${action}Token失败:`, err);
|
|
Notification.error({
|
|
content: `${action}Token失败`,
|
|
closable: true
|
|
});
|
|
return false;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 使用 Arco Design 的原生样式,确保主题兼容性 */
|
|
:deep(.arco-modal-body) {
|
|
max-height: 60vh;
|
|
overflow-y: auto;
|
|
|
|
/* 确保滚动条样式跟随主题 */
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--color-border-3) transparent;
|
|
}
|
|
|
|
:deep(.arco-modal-body::-webkit-scrollbar) {
|
|
width: 6px;
|
|
}
|
|
|
|
:deep(.arco-modal-body::-webkit-scrollbar-thumb) {
|
|
background-color: var(--color-border-3);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
:deep(.arco-modal-body::-webkit-scrollbar-track) {
|
|
background-color: transparent;
|
|
}
|
|
</style>
|