feat: 添加rwa产品
Reviewed-on: http://192.168.1.35:3000/Riwa/riwa-admin/pulls/1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# backend service base url, test environment
|
# backend service base url, test environment
|
||||||
VITE_SERVICE_BASE_URL=http://192.168.1.33:9528
|
VITE_SERVICE_BASE_URL=http://192.168.1.27:9528
|
||||||
|
|
||||||
# other backend service base url, test environment
|
# other backend service base url, test environment
|
||||||
VITE_OTHER_SERVICE_BASE_URL= `{}`
|
VITE_OTHER_SERVICE_BASE_URL= `{}`
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ defineExpose({
|
|||||||
</TableHeaderOperation>
|
</TableHeaderOperation>
|
||||||
|
|
||||||
<NDataTable
|
<NDataTable
|
||||||
|
:row-key="row => row.id"
|
||||||
:scroll-x="2000"
|
:scroll-x="2000"
|
||||||
:columns="dataTableColumns"
|
:columns="dataTableColumns"
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
|
|||||||
@@ -10,3 +10,9 @@ export enum DepositTypeEnum {
|
|||||||
crypto = '链上充值',
|
crypto = '链上充值',
|
||||||
fiat = '法币充值'
|
fiat = '法币充值'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum RwaStatusEnum {
|
||||||
|
pending = '待审核',
|
||||||
|
approved = '已通过',
|
||||||
|
rejected = '已拒绝'
|
||||||
|
}
|
||||||
|
|||||||
@@ -232,7 +232,15 @@ const local: App.I18n.Schema = {
|
|||||||
deposit: 'Deposit',
|
deposit: 'Deposit',
|
||||||
deposit_fiat: 'Fiat Deposit',
|
deposit_fiat: 'Fiat Deposit',
|
||||||
withdraw: 'Withdraw',
|
withdraw: 'Withdraw',
|
||||||
withdraw_fiat: 'Fiat Withdraw'
|
withdraw_fiat: 'Fiat Withdraw',
|
||||||
|
rwa_producttype: 'Product Type',
|
||||||
|
rwa: 'RWA Management',
|
||||||
|
rwa_product: 'RWA Product',
|
||||||
|
user: 'User Management',
|
||||||
|
user_bank: 'User Bank',
|
||||||
|
user_bankcard: 'User Bank Card',
|
||||||
|
user_list: 'User List',
|
||||||
|
user_transfer: 'User Transfer'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
|||||||
deposit_fiat: () => import("@/views/deposit/fiat/index.vue"),
|
deposit_fiat: () => import("@/views/deposit/fiat/index.vue"),
|
||||||
home: () => import("@/views/home/index.vue"),
|
home: () => import("@/views/home/index.vue"),
|
||||||
rwa_product: () => import("@/views/rwa/product/index.vue"),
|
rwa_product: () => import("@/views/rwa/product/index.vue"),
|
||||||
rwa_producttype: () => import("@/views/rwa/producttype/index.vue"),
|
rwa_producttype: () => import("@/views/rwa/productType/index.vue"),
|
||||||
user_bank: () => import("@/views/user/bank/index.vue"),
|
user_bank: () => import("@/views/user/bank/index.vue"),
|
||||||
user_bankcard: () => import("@/views/user/bankcard/index.vue"),
|
user_bankcard: () => import("@/views/user/bankcard/index.vue"),
|
||||||
user_list: () => import("@/views/user/list/index.vue"),
|
user_list: () => import("@/views/user/list/index.vue"),
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { ref } from 'vue';
|
import type { Ref, WatchSource } from 'vue';
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
import { treaty } from '@elysiajs/eden';
|
import { treaty } from '@elysiajs/eden';
|
||||||
import type { App } from '@riwa/api-types';
|
import type { App } from '@riwa/api-types';
|
||||||
import { getServiceBaseURL } from '@/utils/service';
|
import { getServiceBaseURL } from '@/utils/service';
|
||||||
import { localStg } from '@/utils/storage';
|
import { localStg } from '@/utils/storage';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
|
||||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||||
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
||||||
@@ -14,37 +16,104 @@ const client = treaty<App>(baseURL, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function safeClient<T, E>(
|
export interface SafeClientOptions {
|
||||||
requestFactory: () => Promise<{ data: T; error: E }>,
|
silent?: boolean;
|
||||||
options: { silent?: boolean; immediate?: boolean } = {}
|
immediate?: boolean;
|
||||||
) {
|
watchSource?: WatchSource; // 用于监听的响应式数据源
|
||||||
const { immediate = true } = options;
|
}
|
||||||
const data = ref<T>();
|
|
||||||
const error = ref<E>();
|
|
||||||
|
|
||||||
const executeRequest = async () => {
|
export interface SafeClientReturn<T, E> {
|
||||||
const res = await requestFactory();
|
data: Ref<T | null>;
|
||||||
|
error: Ref<E | null>;
|
||||||
|
isPending: Ref<boolean>;
|
||||||
|
execute: () => Promise<void>;
|
||||||
|
onFetchResponse: (callback: (data: T, error: E) => void) => void;
|
||||||
|
stopWatching?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
if (res.error) {
|
export type RequestPromise<T, E> = Promise<{ data: T; error: E; status?: number; response?: Response }>;
|
||||||
|
|
||||||
|
export function safeClient<T, E>(
|
||||||
|
requestPromise: (() => RequestPromise<T, E>) | RequestPromise<T, E>,
|
||||||
|
options: SafeClientOptions = {}
|
||||||
|
): SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>> {
|
||||||
|
const { immediate = true, watchSource } = options;
|
||||||
|
const data = ref<T | null>(null);
|
||||||
|
const error = ref<E | null>(null);
|
||||||
|
const isPending = ref(false);
|
||||||
|
let responseCallback: ((data: T, error: E) => void) | null = null;
|
||||||
|
let stopWatcher: (() => void) | undefined;
|
||||||
|
|
||||||
|
const execute = async () => {
|
||||||
|
isPending.value = true;
|
||||||
|
let request: () => RequestPromise<T, E>;
|
||||||
|
if (typeof requestPromise !== 'function') {
|
||||||
|
request = () => Promise.resolve(requestPromise);
|
||||||
|
} else {
|
||||||
|
request = requestPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await request().finally(() => {
|
||||||
|
isPending.value = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.error && res.status === 418) {
|
||||||
if (!options.silent) {
|
if (!options.silent) {
|
||||||
window.$message?.error('An error occurred while processing your request.');
|
const msg = $t((res.error as any).value.code, {
|
||||||
|
...(res.error as any).value.context
|
||||||
|
});
|
||||||
|
window.$message?.create(msg, {
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
throw res.error;
|
throw res.error;
|
||||||
}
|
}
|
||||||
data.value = res.data;
|
data.value = res.data;
|
||||||
error.value = res.error;
|
error.value = res.error;
|
||||||
|
|
||||||
|
// 调用注册的回调函数
|
||||||
|
if (responseCallback) {
|
||||||
|
responseCallback(res.data, res.error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (immediate) {
|
function onFetchResponse(callback: (data: T, error: E) => void) {
|
||||||
await executeRequest();
|
responseCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
function stopWatching() {
|
||||||
data,
|
if (stopWatcher) {
|
||||||
error,
|
stopWatcher();
|
||||||
refresh: executeRequest
|
stopWatcher = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果提供了 watchSource,则监听其变化
|
||||||
|
if (watchSource) {
|
||||||
|
stopWatcher = watch(
|
||||||
|
watchSource,
|
||||||
|
() => {
|
||||||
|
execute();
|
||||||
|
},
|
||||||
|
{ immediate: false } // 不立即执行,避免与 immediate 选项冲突
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: SafeClientReturn<T, E> = {
|
||||||
|
data: data as Ref<T | null>,
|
||||||
|
error: error as Ref<E | null>,
|
||||||
|
isPending,
|
||||||
|
execute,
|
||||||
|
onFetchResponse,
|
||||||
|
stopWatching
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const promise = immediate ? execute().then(() => result) : Promise.resolve(result);
|
||||||
|
|
||||||
|
Object.assign(promise, result);
|
||||||
|
|
||||||
|
return promise as SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { client, safeClient };
|
export { client };
|
||||||
|
|||||||
2
src/typings/common.d.ts
vendored
2
src/typings/common.d.ts
vendored
@@ -22,4 +22,6 @@ declare namespace CommonType {
|
|||||||
type RecordNullable<T> = {
|
type RecordNullable<T> = {
|
||||||
[K in keyof T]?: T[K] | null;
|
[K in keyof T]?: T[K] | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type TreatyBody<T> = T extends (...args: any[]) => any ? NonNullable<Parameters<T>[0]> : never;
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/typings/components.d.ts
vendored
6
src/typings/components.d.ts
vendored
@@ -47,6 +47,7 @@ declare module 'vue' {
|
|||||||
NButton: typeof import('naive-ui')['NButton']
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
|
NCol: typeof import('naive-ui')['NCol']
|
||||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||||
NDataTable: typeof import('naive-ui')['NDataTable']
|
NDataTable: typeof import('naive-ui')['NDataTable']
|
||||||
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
||||||
@@ -71,6 +72,7 @@ declare module 'vue' {
|
|||||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||||
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
||||||
NPopover: typeof import('naive-ui')['NPopover']
|
NPopover: typeof import('naive-ui')['NPopover']
|
||||||
|
NRow: typeof import('naive-ui')['NRow']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSelect: typeof import('naive-ui')['NSelect']
|
NSelect: typeof import('naive-ui')['NSelect']
|
||||||
NSpace: typeof import('naive-ui')['NSpace']
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
@@ -81,6 +83,7 @@ declare module 'vue' {
|
|||||||
NTabs: typeof import('naive-ui')['NTabs']
|
NTabs: typeof import('naive-ui')['NTabs']
|
||||||
NThing: typeof import('naive-ui')['NThing']
|
NThing: typeof import('naive-ui')['NThing']
|
||||||
NTooltip: typeof import('naive-ui')['NTooltip']
|
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||||
|
NUpload: typeof import('naive-ui')['NUpload']
|
||||||
NWatermark: typeof import('naive-ui')['NWatermark']
|
NWatermark: typeof import('naive-ui')['NWatermark']
|
||||||
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||||
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||||
@@ -135,6 +138,7 @@ declare global {
|
|||||||
const NButton: typeof import('naive-ui')['NButton']
|
const NButton: typeof import('naive-ui')['NButton']
|
||||||
const NCard: typeof import('naive-ui')['NCard']
|
const NCard: typeof import('naive-ui')['NCard']
|
||||||
const NCheckbox: typeof import('naive-ui')['NCheckbox']
|
const NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
|
const NCol: typeof import('naive-ui')['NCol']
|
||||||
const NColorPicker: typeof import('naive-ui')['NColorPicker']
|
const NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||||
const NDataTable: typeof import('naive-ui')['NDataTable']
|
const NDataTable: typeof import('naive-ui')['NDataTable']
|
||||||
const NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
const NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
||||||
@@ -159,6 +163,7 @@ declare global {
|
|||||||
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||||
const NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
const NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
||||||
const NPopover: typeof import('naive-ui')['NPopover']
|
const NPopover: typeof import('naive-ui')['NPopover']
|
||||||
|
const NRow: typeof import('naive-ui')['NRow']
|
||||||
const NScrollbar: typeof import('naive-ui')['NScrollbar']
|
const NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
const NSelect: typeof import('naive-ui')['NSelect']
|
const NSelect: typeof import('naive-ui')['NSelect']
|
||||||
const NSpace: typeof import('naive-ui')['NSpace']
|
const NSpace: typeof import('naive-ui')['NSpace']
|
||||||
@@ -169,6 +174,7 @@ declare global {
|
|||||||
const NTabs: typeof import('naive-ui')['NTabs']
|
const NTabs: typeof import('naive-ui')['NTabs']
|
||||||
const NThing: typeof import('naive-ui')['NThing']
|
const NThing: typeof import('naive-ui')['NThing']
|
||||||
const NTooltip: typeof import('naive-ui')['NTooltip']
|
const NTooltip: typeof import('naive-ui')['NTooltip']
|
||||||
|
const NUpload: typeof import('naive-ui')['NUpload']
|
||||||
const NWatermark: typeof import('naive-ui')['NWatermark']
|
const NWatermark: typeof import('naive-ui')['NWatermark']
|
||||||
const PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
const PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||||
const ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
const ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||||
|
|||||||
103
src/views/rwa/product/components/add.vue
Normal file
103
src/views/rwa/product/components/add.vue
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, useTemplateRef } from 'vue';
|
||||||
|
import type { FormInst, FormRules } from 'naive-ui';
|
||||||
|
import { client, safeClient } from '@/service/api';
|
||||||
|
|
||||||
|
defineOptions({ name: 'RwaProductAdd' });
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'close'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
type Body = CommonType.TreatyBody<typeof client.api.admin.rwa.issuance.products.post>;
|
||||||
|
|
||||||
|
const formInst = useTemplateRef<FormInst>('formInst');
|
||||||
|
const { data } = safeClient(
|
||||||
|
client.api.admin.rwa.category.categories.get({
|
||||||
|
query: {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 9999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const form = ref<Body>({
|
||||||
|
name: '',
|
||||||
|
code: '',
|
||||||
|
categoryId: '',
|
||||||
|
description: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules: FormRules = {
|
||||||
|
name: [{ required: true, message: '请输入产品名称', trigger: ['blur', 'input'] }],
|
||||||
|
code: [{ required: true, message: '请输入产品编号', trigger: ['blur', 'input'] }],
|
||||||
|
categoryId: [{ required: true, message: '请输入产品类型', trigger: ['blur', 'input'] }],
|
||||||
|
estimatedValue: [{ required: true, message: '请输入产品估值', trigger: ['blur', 'input'] }],
|
||||||
|
totalSupplyLimit: [{ required: true, message: '请输入总发行量', trigger: ['blur', 'input'] }]
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
formInst.value?.validate(async errors => {
|
||||||
|
if (!errors) {
|
||||||
|
await safeClient(
|
||||||
|
client.api.admin.rwa.issuance.products.post({
|
||||||
|
...form.value
|
||||||
|
})
|
||||||
|
);
|
||||||
|
emit('close');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="my-10">
|
||||||
|
<NForm
|
||||||
|
ref="formInst"
|
||||||
|
:model="form"
|
||||||
|
label-width="auto"
|
||||||
|
label-placement="left"
|
||||||
|
:rules="rules"
|
||||||
|
require-mark-placement="left"
|
||||||
|
>
|
||||||
|
<NFormItem path="name" label="产品名称">
|
||||||
|
<NInput v-model:value="form.name" />
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="code" label="产品编号">
|
||||||
|
<NInput v-model:value="form.code" />
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="categoryId" label="产品类型">
|
||||||
|
<NSelect
|
||||||
|
:value="form.categoryId || null"
|
||||||
|
:options="data?.data?.map(item => ({ label: item.name, value: item.id }))"
|
||||||
|
@update:value="val => (form.categoryId = val as string)"
|
||||||
|
/>
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="estimatedValue" label="产品估值">
|
||||||
|
<NInput v-model:value="form.estimatedValue" />
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="totalSupplyLimit" label="总发行量">
|
||||||
|
<NInput v-model:value="form.totalSupplyLimit" />
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="description" label="产品描述">
|
||||||
|
<NInput v-model:value="form.description" type="textarea" />
|
||||||
|
</NFormItem>
|
||||||
|
<NFormItem path="proofDocuments" label="资产证明 ">
|
||||||
|
<NUpload
|
||||||
|
action="https://naive-upload.free.beeceptor.com/"
|
||||||
|
:headers="{ 'naive-info': 'hello!' }"
|
||||||
|
:data="{
|
||||||
|
'naive-data': 'cool! naive!'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<NButton>上传文件</NButton>
|
||||||
|
</NUpload>
|
||||||
|
</NFormItem>
|
||||||
|
<NSpace justify="end">
|
||||||
|
<NButton @click="$emit('close')">取 消</NButton>
|
||||||
|
<NButton type="primary" @click="handleSubmit">确 认</NButton>
|
||||||
|
</NSpace>
|
||||||
|
</NForm>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTemplateRef } from 'vue';
|
import { h, useTemplateRef } from 'vue';
|
||||||
|
import { useDateFormat } from '@vueuse/core';
|
||||||
import { NDatePicker, useDialog, useMessage } from 'naive-ui';
|
import { NDatePicker, useDialog, useMessage } from 'naive-ui';
|
||||||
import { client, safeClient } from '@/service/api';
|
import { client, safeClient } from '@/service/api';
|
||||||
import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
|
import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
|
||||||
|
import { RwaStatusEnum } from '@/enum';
|
||||||
|
import Add from './components/add.vue';
|
||||||
|
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
@@ -21,8 +24,10 @@ const fetchData: TableFetchData = ({ pagination, filter }) => {
|
|||||||
|
|
||||||
const columns: TableBaseColumns = [
|
const columns: TableBaseColumns = [
|
||||||
{
|
{
|
||||||
title: 'ID',
|
key: 'selection',
|
||||||
key: 'id'
|
title: '序号',
|
||||||
|
type: 'selection',
|
||||||
|
width: 60
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '产品代码',
|
title: '产品代码',
|
||||||
@@ -48,12 +53,15 @@ const columns: TableBaseColumns = [
|
|||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
key: 'createdAt',
|
key: 'createdAt',
|
||||||
render: (row: any) => {
|
render: (row: any) => {
|
||||||
return new Date(row.createdAt).toLocaleDateString();
|
return useDateFormat(row.createdAt, 'YYYY-MM-DD HH:mm').value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
key: 'status'
|
key: 'status',
|
||||||
|
render: row => {
|
||||||
|
return RwaStatusEnum[row.status as keyof typeof RwaStatusEnum];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '描述',
|
title: '描述',
|
||||||
@@ -119,6 +127,25 @@ const filterColumns: TableFilterColumns = [
|
|||||||
component: NDatePicker
|
component: NDatePicker
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
const dialogInstance = dialog.create({
|
||||||
|
title: '添加产品',
|
||||||
|
content: () =>
|
||||||
|
h(Add, {
|
||||||
|
onClose: () => {
|
||||||
|
dialogInstance.destroy();
|
||||||
|
tableInst.value?.reload();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
style: { width: '600px' },
|
||||||
|
showIcon: false,
|
||||||
|
onPositiveClick: () => {
|
||||||
|
message.success('添加成功');
|
||||||
|
tableInst.value?.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -128,6 +155,7 @@ const filterColumns: TableFilterColumns = [
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:filter-columns="filterColumns"
|
:filter-columns="filterColumns"
|
||||||
:fetch-data="fetchData"
|
:fetch-data="fetchData"
|
||||||
|
@add="handleAdd"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user