Merge remote-tracking branch 'yudao/dev' into dev

pull/137/head
jason 2025-06-10 22:37:54 +08:00
commit 6e3ffb61ef
218 changed files with 986 additions and 688 deletions

View File

@ -1,34 +0,0 @@
<script lang="ts" setup>
import { isDocAlertEnable } from '@vben/hooks';
import { openWindow } from '@vben/utils';
import { Alert, Typography } from 'ant-design-vue';
export interface DocAlertProps {
/**
* 文档标题
*/
title: string;
/**
* 文档 URL 地址
*/
url: string;
}
const props = defineProps<DocAlertProps>();
/** 跳转 URL 链接 */
const goToUrl = () => {
openWindow(props.url);
};
</script>
<template>
<Alert v-if="isDocAlertEnable()" type="info" show-icon class="mb-2 rounded">
<template #message>
<Typography.Link @click="goToUrl">
{{ title }}文档地址{{ url }}
</Typography.Link>
</template>
</Alert>
</template>

View File

@ -1 +0,0 @@
export { default as DocAlert } from './doc-alert.vue';

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 对话聊天" url="https://doc.iocoder.cn/ai/chat/" />
<template #doc>
<DocAlert title="AI 对话聊天" url="https://doc.iocoder.cn/ai/chat/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
<template #doc>
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 知识库" url="https://doc.iocoder.cn/ai/knowledge/" />
<template #doc>
<DocAlert title="AI 知识库" url="https://doc.iocoder.cn/ai/knowledge/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 思维导图" url="https://doc.iocoder.cn/ai/mindmap/" />
<template #doc>
<DocAlert title="AI 思维导图" url="https://doc.iocoder.cn/ai/mindmap/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 手册" url="https://doc.iocoder.cn/ai/build/" />
<template #doc>
<DocAlert title="AI 手册" url="https://doc.iocoder.cn/ai/build/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 对话聊天" url="https://doc.iocoder.cn/ai/chat/" />
<template #doc>
<DocAlert title="AI 对话聊天" url="https://doc.iocoder.cn/ai/chat/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 手册" url="https://doc.iocoder.cn/ai/build/" />
<template #doc>
<DocAlert title="AI 手册" url="https://doc.iocoder.cn/ai/build/" />
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="AI 工具调用function calling"
url="https://doc.iocoder.cn/ai/tool/"
/>
<template #doc>
<DocAlert
title="AI 工具调用function calling"
url="https://doc.iocoder.cn/ai/tool/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 音乐创作" url="https://doc.iocoder.cn/ai/music/" />
<template #doc>
<DocAlert title="AI 音乐创作" url="https://doc.iocoder.cn/ai/music/" />
</template>
<Button
danger
type="link"

View File

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
<template #doc>
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
</template>
<Button
danger
type="link"

View File

@ -2,13 +2,12 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmCategoryApi } from '#/api/bpm/category';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteCategory, getCategoryPage } from '#/api/bpm/category';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,14 +5,13 @@ import type { BpmFormApi } from '#/api/bpm/form';
import { watch } from 'vue';
import { useRoute } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteForm, getFormPage } from '#/api/bpm/form';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,14 +5,13 @@ import type { SystemUserApi } from '#/api/system/user';
import { onMounted, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message, Tag } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteUserGroup, getUserGroupPage } from '#/api/bpm/userGroup';
import { getSimpleUserList } from '#/api/system/user';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,14 +4,13 @@ import type { BpmOALeaveApi } from '#/api/bpm/oa/leave';
import { h } from 'vue';
import { Page, prompt } from '@vben/common-ui';
import { DocAlert, Page, prompt } from '@vben/common-ui';
import { message, Textarea } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getLeavePage } from '#/api/bpm/oa/leave';
import { cancelProcessInstanceByStartUser } from '#/api/bpm/processInstance';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { GridFormSchema, useGridColumns } from './data';

View File

@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmProcessExpressionApi } from '#/api/bpm/processExpression';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@ -11,7 +11,6 @@ import {
deleteProcessExpression,
getProcessExpressionPage,
} from '#/api/bpm/processExpression';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,7 +4,7 @@ import type { BpmTaskApi } from '#/api/bpm/task';
import { h } from 'vue';
import { Page, prompt } from '@vben/common-ui';
import { DocAlert, Page, prompt } from '@vben/common-ui';
import { Button, message, Textarea } from 'ant-design-vue';
@ -14,7 +14,6 @@ import {
getProcessInstanceMyPage,
} from '#/api/bpm/processInstance';
import { DictTag } from '#/components/dict-tag';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { BpmProcessInstanceStatus, DICT_TYPE } from '#/utils';

View File

@ -4,7 +4,7 @@ import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
import { h } from 'vue';
import { Page, prompt } from '@vben/common-ui';
import { DocAlert, Page, prompt } from '@vben/common-ui';
import { message, Textarea } from 'ant-design-vue';
@ -13,7 +13,6 @@ import {
cancelProcessInstanceByAdmin,
getProcessInstanceManagerPage,
} from '#/api/bpm/processInstance';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { router } from '#/router';
import { BpmProcessInstanceStatus } from '#/utils';

View File

@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmProcessListenerApi } from '#/api/bpm/processListener';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@ -11,7 +11,6 @@ import {
deleteProcessListener,
getProcessListenerPage,
} from '#/api/bpm/processListener';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -2,11 +2,10 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getProcessInstanceCopyPage } from '#/api/bpm/processInstance';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { router } from '#/router';

View File

@ -2,11 +2,10 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmTaskApi } from '#/api/bpm/task';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getTaskDonePage } from '#/api/bpm/task';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -2,11 +2,10 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmTaskApi } from '#/api/bpm/task';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getTaskManagerPage } from '#/api/bpm/task';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -2,11 +2,10 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { BpmTaskApi } from '#/api/bpm/task';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getTaskTodoPage } from '#/api/bpm/task';
import { DocAlert } from '#/components/doc-alert';
import { router } from '#/router';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,7 +4,7 @@ import type { CrmBusinessApi } from '#/api/crm/business';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue';
@ -15,7 +15,6 @@ import {
exportBusiness,
getBusinessPage,
} from '#/api/crm/business';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { CrmBusinessStatusApi } from '#/api/crm/business/status';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@ -11,7 +11,6 @@ import {
deleteBusinessStatus,
getBusinessStatusPage,
} from '#/api/crm/business/status';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns } from './data';

View File

@ -4,14 +4,13 @@ import type { CrmClueApi } from '#/api/crm/clue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteClue, exportClue, getCluePage } from '#/api/crm/clue';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,7 +5,7 @@ import type { CrmContactApi } from '#/api/crm/contact';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Tabs } from 'ant-design-vue';
@ -16,7 +16,6 @@ import {
exportContact,
getContactPage,
} from '#/api/crm/contact';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,7 +5,7 @@ import type { CrmContractApi } from '#/api/crm/contract';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Tabs } from 'ant-design-vue';
@ -17,7 +17,6 @@ import {
getContractPage,
submitContract,
} from '#/api/crm/contract';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,7 +5,7 @@ import type { CrmCustomerApi } from '#/api/crm/customer';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Tabs } from 'ant-design-vue';
@ -16,7 +16,6 @@ import {
exportCustomer,
getCustomerPage,
} from '#/api/crm/customer';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,7 +4,7 @@ import type { CrmCustomerLimitConfigApi } from '#/api/crm/customer/limitConfig';
import { ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message, Tabs } from 'ant-design-vue';
@ -14,7 +14,6 @@ import {
getCustomerLimitConfigPage,
LimitConfType,
} from '#/api/crm/customer/limitConfig';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns } from './data';

View File

@ -4,14 +4,13 @@ import type { CrmCustomerApi } from '#/api/crm/customer';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { exportCustomer, getCustomerPage } from '#/api/crm/customer';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,7 +4,7 @@ import type { CrmProductCategoryApi } from '#/api/crm/product/category';
import { ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@ -13,7 +13,6 @@ import {
deleteProductCategory,
getProductCategoryList,
} from '#/api/crm/product/category';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,7 +5,7 @@ import type { CrmReceivableApi } from '#/api/crm/receivable';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Tabs } from 'ant-design-vue';
@ -17,7 +17,6 @@ import {
getReceivablePage,
submitReceivable,
} from '#/api/crm/receivable';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -5,7 +5,7 @@ import type { CrmReceivablePlanApi } from '#/api/crm/receivable/plan';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Tabs } from 'ant-design-vue';
@ -16,7 +16,6 @@ import {
exportReceivablePlan,
getReceivablePlanPage,
} from '#/api/crm/receivable/plan';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import ReceivableForm from '../modules/form.vue';

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
<template #doc>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
<template #doc>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
<template #doc>
<DocAlert
title="【财务】采购付款、销售收款"
url="https://doc.iocoder.cn/sale/finance-payment-receipt/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="ERP 手册(功能开启)"
url="https://doc.iocoder.cn/erp/build/"
/>
<template #doc>
<DocAlert
title="ERP 手册(功能开启)"
url="https://doc.iocoder.cn/erp/build/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
<template #doc>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
<template #doc>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
<template #doc>
<DocAlert
title="【产品】产品信息、分类、单位"
url="https://doc.iocoder.cn/erp/product/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
<template #doc>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
<template #doc>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
<template #doc>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
<template #doc>
<DocAlert
title="【采购】采购订单、入库、退货"
url="https://doc.iocoder.cn/erp/purchase/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
<template #doc>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
<template #doc>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
<template #doc>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
<template #doc>
<DocAlert
title="【销售】销售订单、出库、退货"
url="https://doc.iocoder.cn/erp/sale/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【库存】库存调拨、库存盘点"
url="https://doc.iocoder.cn/erp/stock-move-check/"
/>
<template #doc>
<DocAlert
title="【库存】库存调拨、库存盘点"
url="https://doc.iocoder.cn/erp/stock-move-check/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【库存】其它入库、其它出库"
url="https://doc.iocoder.cn/erp/stock-in-out/"
/>
<template #doc>
<DocAlert
title="【库存】其它入库、其它出库"
url="https://doc.iocoder.cn/erp/stock-in-out/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【库存】库存调拨、库存盘点"
url="https://doc.iocoder.cn/erp/stock-move-check/"
/>
<template #doc>
<DocAlert
title="【库存】库存调拨、库存盘点"
url="https://doc.iocoder.cn/erp/stock-move-check/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,17 +1,17 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>
<Page>
<DocAlert
title="【库存】其它入库、其它出库"
url="https://doc.iocoder.cn/erp/stock-in-out/"
/>
<template #doc>
<DocAlert
title="【库存】其它入库、其它出库"
url="https://doc.iocoder.cn/erp/stock-in-out/"
/>
</template>
<Button
danger
type="link"

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { InfraApiAccessLogApi } from '#/api/infra/api-access-log';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
@ -10,7 +10,6 @@ import {
exportApiAccessLog,
getApiAccessLogPage,
} from '#/api/infra/api-access-log';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { InfraApiErrorLogApi } from '#/api/infra/api-error-log';
import { confirm, Page, useVbenModal } from '@vben/common-ui';
import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { message } from 'ant-design-vue';
@ -13,7 +13,6 @@ import {
getApiErrorLogPage,
updateApiErrorLogStatus,
} from '#/api/infra/api-error-log';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { InfraApiErrorLogProcessStatusEnum } from '#/utils';

View File

@ -6,7 +6,7 @@ import type { InfraDataSourceConfigApi } from '#/api/infra/data-source-config';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@ -18,7 +18,6 @@ import {
syncCodegenFromDB,
} from '#/api/infra/codegen';
import { getDataSourceConfigList } from '#/api/infra/data-source-config';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -1,10 +1,9 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { getConfigKey } from '#/api/infra/config';
import { DocAlert } from '#/components/doc-alert';
import { IFrame } from '#/components/iframe';
const loading = ref(true); //

View File

@ -4,7 +4,7 @@ import type { InfraJobApi } from '#/api/infra/job';
import { useRouter } from 'vue-router';
import { confirm, Page, useVbenModal } from '@vben/common-ui';
import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { message } from 'ant-design-vue';
@ -17,7 +17,6 @@ import {
runJob,
updateJobStatus,
} from '#/api/infra/job';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { InfraJobStatusEnum } from '#/utils';

View File

@ -4,12 +4,11 @@ import type { InfraJobLogApi } from '#/api/infra/job-log';
import { useRoute } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { downloadFileFromBlobPart } from '@vben/utils';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { exportJobLog, getJobLogPage } from '#/api/infra/job-log';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -3,12 +3,11 @@ import type { InfraRedisApi } from '#/api/infra/redis';
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Card } from 'ant-design-vue';
import { getRedisMonitorInfo } from '#/api/infra/redis';
import { DocAlert } from '#/components/doc-alert';
import Commands from './modules/commands.vue';
import Info from './modules/info.vue';

View File

@ -1,10 +1,9 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { getConfigKey } from '#/api/infra/config';
import { DocAlert } from '#/components/doc-alert';
import { IFrame } from '#/components/iframe';
const loading = ref(true); //

View File

@ -1,10 +1,9 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { getConfigKey } from '#/api/infra/config';
import { DocAlert } from '#/components/doc-alert';
import { IFrame } from '#/components/iframe';
const loading = ref(true); //

View File

@ -1,10 +1,9 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { getConfigKey } from '#/api/infra/config';
import { DocAlert } from '#/components/doc-alert';
import { IFrame } from '#/components/iframe';
const loading = ref(true); //

View File

@ -3,7 +3,7 @@ import type { SystemUserApi } from '#/api/system/user';
import { computed, onMounted, ref, watchEffect } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { useAccessStore } from '@vben/stores';
import { formatDate } from '@vben/utils';
@ -22,7 +22,6 @@ import {
} from 'ant-design-vue';
import { getSimpleUserList } from '#/api/system/user';
import { DocAlert } from '#/components/doc-alert';
const accessStore = useAccessStore();
const refreshToken = accessStore.refreshToken as string;

View File

@ -8,7 +8,12 @@ import type {
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { AnalysisOverview, Page, WorkbenchQuickNav } from '@vben/common-ui';
import {
AnalysisOverview,
DocAlert,
Page,
WorkbenchQuickNav,
} from '@vben/common-ui';
import {
SvgBellIcon,
SvgCakeIcon,
@ -19,7 +24,6 @@ import { isString, openWindow } from '@vben/utils';
import { getUserCountComparison } from '#/api/mall/statistics/member';
import { getOrderComparison } from '#/api/mall/statistics/trade';
import { DocAlert } from '#/components/doc-alert';
/** 商城首页 */
defineOptions({ name: 'MallHome' });

View File

@ -5,13 +5,12 @@ import type { MallCategoryApi } from '#/api/mall/product/category';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteCategory, getCategoryList } from '#/api/mall/product/category';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -4,7 +4,7 @@ import type { MallCommentApi } from '#/api/mall/product/comment';
import { h } from 'vue';
import { confirm, Page, prompt, useVbenModal } from '@vben/common-ui';
import { confirm, DocAlert, Page, prompt, useVbenModal } from '@vben/common-ui';
import { message, Textarea } from 'ant-design-vue';
@ -14,7 +14,6 @@ import {
replyComment,
updateCommentVisible,
} from '#/api/mall/product/comment';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert } from '#/components/doc-alert';
import { DocAlert, Page } from '@vben/common-ui';
import PropertyGrid from './modules/property-grid.vue';
import ValueGrid from './modules/value-grid.vue';

View File

@ -5,7 +5,7 @@ import type { MallSpuApi } from '#/api/mall/product/spu';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { confirm, Page } from '@vben/common-ui';
import { confirm, DocAlert, Page } from '@vben/common-ui';
import {
downloadFileFromBlobPart,
handleTree,
@ -23,7 +23,6 @@ import {
getTabsCount,
updateStatus,
} from '#/api/mall/product/spu';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { fenToYuan, ProductSpuStatusEnum } from '#/utils';

View File

@ -0,0 +1,213 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeGridPropTypes } from '#/adapter/vxe-table';
import { z } from '#/adapter/form';
import { getSimpleArticleCategoryList } from '#/api/mall/promotion/articleCategory';
import {
CommonStatusEnum,
DICT_TYPE,
getDictOptions,
getRangePickerDefaultProps,
} from '#/utils';
/** 新增/修改的表单 */
export function useFormSchema(): VbenFormSchema[] {
return [
{
component: 'Input',
fieldName: 'id',
dependencies: {
triggerFields: [''],
show: () => false,
},
},
{
fieldName: 'title',
label: '文章标题',
component: 'Input',
rules: 'required',
},
{
fieldName: 'categoryId',
label: '文章分类',
component: 'ApiSelect',
componentProps: {
api: getSimpleArticleCategoryList,
labelField: 'name',
valueField: 'id',
},
rules: 'required',
},
{
fieldName: 'author',
label: '文章作者',
component: 'Input',
},
{
fieldName: 'introduction',
label: '文章简介',
component: 'Input',
},
{
fieldName: 'picUrl',
label: '文章封面',
component: 'ImageUpload',
componentProps: {
maxSize: 1,
},
rules: 'required',
},
{
fieldName: 'recommendHot',
label: '是否热门',
component: 'RadioGroup',
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'),
buttonStyle: 'solid',
optionType: 'button',
},
},
{
fieldName: 'recommendBanner',
label: '是否轮播图',
component: 'RadioGroup',
componentProps: {
options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'),
buttonStyle: 'solid',
optionType: 'button',
},
},
{
// TODO: 商品关联
fieldName: 'spuId',
label: '商品关联',
component: 'Input',
},
{
fieldName: 'sort',
label: '排序',
component: 'InputNumber',
componentProps: {
min: 0,
controlsPosition: 'right',
placeholder: '请输入品牌排序',
},
rules: z.number().min(0).default(1),
},
{
fieldName: 'status',
label: '状态',
component: 'RadioGroup',
componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
buttonStyle: 'solid',
optionType: 'button',
},
rules: z.number().default(CommonStatusEnum.ENABLE),
},
{
fieldName: 'description',
label: '文章内容',
component: 'RichTextarea',
},
];
}
/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'name',
label: '文章分类',
component: 'ApiSelect',
componentProps: {
api: getSimpleArticleCategoryList,
labelField: 'name',
valueField: 'id',
},
},
{
fieldName: 'title',
label: '文章标题',
component: 'Input',
},
{
fieldName: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
},
},
{
fieldName: 'createTime',
label: '创建时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
];
}
/** 表格列配置 */
export function useGridColumns(): VxeGridPropTypes.Columns {
return [
{
field: 'id',
title: '编号',
fixed: 'left',
},
{
field: 'title',
title: '标题',
},
{
field: 'picUrl',
title: '封面',
cellRender: {
name: 'CellImage',
},
},
{
field: 'categoryId',
title: '分类',
},
{
field: 'browseCount',
title: '浏览量',
},
{
field: 'author',
title: '作者',
},
{
field: 'introduction',
title: '文章简介',
},
{
field: 'sort',
title: '排序',
},
{
field: 'status',
title: '状态',
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.COMMON_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
formatter: 'formatDateTime',
},
{
title: '操作',
width: 180,
fixed: 'right',
slots: { default: 'actions' },
},
];
}

View File

@ -1,34 +1,127 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallArticleApi } from '#/api/mall/promotion/article';
import { Button } from 'ant-design-vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { DocAlert } from '#/components/doc-alert';
import { message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteArticle, getArticlePage } from '#/api/mall/promotion/article';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: Form,
destroyOnClose: true,
});
/** 刷新表格 */
function onRefresh() {
gridApi.query();
}
/** 创建品牌 */
function handleCreate() {
formModalApi.setData(null).open();
}
/** 编辑品牌 */
function handleEdit(row: MallArticleApi.Article) {
formModalApi.setData(row).open();
}
/** 删除品牌 */
async function handleDelete(row: MallArticleApi.Article) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.title]),
key: 'action_key_msg',
});
try {
await deleteArticle(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.title]),
key: 'action_key_msg',
});
onRefresh();
} finally {
hideLoading();
}
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
},
gridOptions: {
columns: useGridColumns(),
height: 'auto',
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getArticlePage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
rowConfig: {
keyField: 'id',
},
toolbarConfig: {
refresh: { code: 'query' },
search: true,
},
} as VxeTableGridOptions<MallArticleApi.Article>,
});
</script>
<template>
<Page>
<DocAlert
title="【营销】内容管理"
url="https://doc.iocoder.cn/mall/promotion-content/"
/>
<Button
danger
type="link"
target="_blank"
href="https://github.com/yudaocode/yudao-ui-admin-vue3"
>
该功能支持 Vue3 + element-plus 版本
</Button>
<br />
<Button
type="link"
target="_blank"
href="https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/promotion/article/index"
>
可参考
https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/promotion/article/index
代码pull request 贡献给我们
</Button>
<Page auto-content-height>
<FormModal @success="onRefresh" />
<Grid table-title="">
<template #toolbar-tools>
<TableAction
:actions="[
{
label: $t('ui.actionTitle.create', ['文章']),
type: 'primary',
icon: ACTION_ICON.ADD,
auth: ['promotion:article:create'],
onClick: handleCreate,
},
]"
/>
</template>
<template #actions="{ row }">
<TableAction
:actions="[
{
label: $t('common.edit'),
type: 'link',
icon: ACTION_ICON.EDIT,
auth: ['promotion:article:update'],
onClick: handleEdit.bind(null, row),
},
{
label: $t('common.delete'),
type: 'link',
danger: true,
icon: ACTION_ICON.DELETE,
auth: ['promotion:article:delete'],
popConfirm: {
title: $t('ui.actionMessage.deleteConfirm', [row.title]),
confirm: handleDelete.bind(null, row),
},
},
]"
/>
</template>
</Grid>
</Page>
</template>

View File

@ -0,0 +1,87 @@
<script lang="ts" setup>
import type { MallArticleApi } from '#/api/mall/promotion/article';
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import {
createArticle,
getArticle,
updateArticle,
} from '#/api/mall/promotion/article';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
const emit = defineEmits(['success']);
const formData = ref<MallArticleApi.Article>();
const getTitle = computed(() => {
return formData.value?.id
? $t('ui.actionTitle.edit', ['文章'])
: $t('ui.actionTitle.create', ['文章']);
});
const [Form, formApi] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
},
formItemClass: 'col-span-2',
labelWidth: 120,
},
layout: 'horizontal',
schema: useFormSchema(),
showDefaultActions: false,
});
const [Modal, modalApi] = useVbenModal({
async onConfirm() {
const { valid } = await formApi.validate();
if (!valid) {
return;
}
modalApi.lock();
//
const data = (await formApi.getValues()) as MallArticleApi.Article;
try {
await (formData.value?.id ? updateArticle(data) : createArticle(data));
//
await modalApi.close();
emit('success');
message.success($t('ui.actionMessage.operationSuccess'));
} finally {
modalApi.unlock();
}
},
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
return;
}
//
const data = modalApi.getData<MallArticleApi.Article>();
if (!data || !data.id) {
return;
}
modalApi.lock();
try {
formData.value = await getArticle(data.id as number);
// values
await formApi.setValues(formData.value);
} finally {
modalApi.unlock();
}
},
});
</script>
<template>
<Modal class="w-[40%]" :title="getTitle">
<Form class="mx-4" />
</Modal>
</template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -5,13 +5,12 @@ import type { MallAfterSaleApi } from '#/api/mall/trade/afterSale';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button, Tabs } from 'ant-design-vue';
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getAfterSalePage } from '#/api/mall/trade/afterSale';
import { DocAlert } from '#/components/doc-alert';
import { DICT_TYPE, getDictOptions } from '#/utils';
import { useGridColumns, useGridFormSchema } from './data';

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -1,9 +1,7 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert';
</script>
<template>

View File

@ -3,13 +3,12 @@ import type { MallTradeConfigApi } from '#/api/mall/trade/config';
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { DocAlert, Page } from '@vben/common-ui';
import { Card, message, Tabs } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { getTradeConfig, saveTradeConfig } from '#/api/mall/trade/config';
import { DocAlert } from '#/components/doc-alert';
import { $t } from '#/locales';
import { useFormSchema } from './data';

View File

@ -42,7 +42,8 @@ export function useGridFormSchema(): VbenFormSchema[] {
},
dependencies: {
triggerFields: ['deliveryType'],
show: (values) => values.deliveryType === DeliveryTypeEnum.PICK_UP.type,
trigger: (values) =>
values.deliveryType === DeliveryTypeEnum.PICK_UP.type,
},
},
];

View File

@ -2,16 +2,20 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallOrderApi } from '#/api/mall/trade/order';
import { onMounted, ref } from 'vue';
import { h, onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { Page, prompt } from '@vben/common-ui';
import { Card } from 'ant-design-vue';
import { Card, Input, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getOrderPage, getOrderSummary } from '#/api/mall/trade/order';
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
getOrderByPickUpVerifyCode,
getOrderPage,
getOrderSummary,
} from '#/api/mall/trade/order';
import { SummaryCard } from '#/components/summary-card';
import { DeliveryTypeEnum, fenToYuan } from '#/utils';
import { DeliveryTypeEnum, fenToYuan, TradeOrderStatusEnum } from '#/utils';
import { useGridColumns, useGridFormSchema } from './data';
@ -24,6 +28,115 @@ async function getOrderSum() {
summary.value = res;
}
/** 核销 */
async function handlePickup(pickUpVerifyCode?: string) {
if (!pickUpVerifyCode) {
pickUpVerifyCode = await prompt({
component: () => {
return h(Input, {});
},
content: '请输入核销码',
title: '核销订单',
modelPropName: 'value',
}).then(async (val) => {
if (val) {
return val;
}
});
}
if (!pickUpVerifyCode) {
return;
}
const data = await getOrderByPickUpVerifyCode(pickUpVerifyCode);
if (data?.deliveryType !== DeliveryTypeEnum.PICK_UP.type) {
message.error('未查询到订单');
return;
}
if (data?.status !== TradeOrderStatusEnum.UNDELIVERED.status) {
message.error('订单不是待核销状态');
}
}
const port = ref('');
const ports = ref([]);
const reader = ref('');
const serialPort = ref(false); //
/** 连接扫码枪 */
async function connectToSerialPort() {
try {
//
if (
'serial' in navigator &&
navigator.serial !== null &&
typeof navigator.serial === 'object' &&
'requestPort' in navigator.serial
) {
//
port.value = await (navigator.serial as any).requestPort();
} else {
message.error('浏览器不支持扫码枪连接,请更换浏览器重试');
return;
}
// 访
ports.value = await (navigator.serial as any).getPorts();
//
await (port.value as any).open({
baudRate: 9600,
dataBits: 8,
stopBits: 2,
});
message.success('成功连接扫码枪');
serialPort.value = true;
readData();
} catch (error) {
//
console.error('Error connecting to serial port:', error);
}
}
/** 监听扫码枪输入 */
async function readData() {
reader.value = (port.value as any).readable.getReader();
let data = ''; //
//
while (true) {
const { value, done } = await (reader.value as any).read();
if (done) {
//
(reader.value as any).releaseLock();
break;
}
//
const serialData = new TextDecoder().decode(value);
data = `${data}${serialData}`;
if (serialData.includes('\r')) {
//
const codeData = data.replace('\r', '');
data = ''; //
console.warn(`二维码数据:${codeData}`);
//
handlePickup(codeData);
}
}
}
async function cutPort() {
if (port.value === '') {
message.warning('请先连接或打开扫码枪');
} else {
await (reader.value as any).cancel();
await (port.value as any).close();
port.value = '';
console.warn('断开扫码枪连接');
message.success('已成功断开扫码枪连接');
serialPort.value = false;
}
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
@ -101,6 +214,27 @@ onMounted(() => {
/>
</template>
</Card>
<Grid class="h-[80%]" table-title="" />
<Grid class="h-[80%]" table-title="">
<template #toolbar-tools>
<TableAction
:actions="[
{
label: '核销',
type: 'primary',
icon: 'lucide:circle-check-big',
auth: ['trade:order:pick-up'],
onClick: handlePickup,
},
{
label: serialPort ? '断开扫描枪' : '连接扫描枪',
type: 'primary',
icon: serialPort ? 'lucide:circle-x' : 'lucide:circle-play',
danger: serialPort,
onClick: serialPort ? cutPort : connectToSerialPort,
},
]"
/>
</template>
</Grid>
</Page>
</template>

Some files were not shown because too many files have changed in this diff Show More