-
-
-
疯狂的牛子Li
+
+
+ {{ info.nodeName }}
+
+
+ {{ info.createTime }}
+
+
+
+
+
+
+
+ {{ info.createByName }}
+
+
+
+
+
+
+ {{ diffUpdateTimeString }}前更新
+
+
-
处理时间: 2022-01-01
diff --git a/apps/web-antd/src/views/workflow/components/approval-content.vue b/apps/web-antd/src/views/workflow/components/approval-content.vue
new file mode 100644
index 00000000..8db040d0
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/approval-content.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/approval-modal.vue b/apps/web-antd/src/views/workflow/components/approval-modal.vue
new file mode 100644
index 00000000..b9177e12
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/approval-modal.vue
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/approval-panel.vue b/apps/web-antd/src/views/workflow/components/approval-panel.vue
new file mode 100644
index 00000000..da4c29f5
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/approval-panel.vue
@@ -0,0 +1,520 @@
+
+
+
+
+
+
+
+
+ handleLoadInfo(task)">
+
+
+
+
+
+
+
+
+
{{ task.flowName }}
+
+
+
+
+
+
+
{{ task.createByName }}
+
+
+
+ 流程分类: {{ task.categoryName }}
+
+
+
+
+ 提交时间: {{ task.createTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 撤销申请
+
+
+ 重新编辑
+
+
+ 删除
+
+
+
+ 通过
+
+ 终止
+
+
+ 驳回
+
+
+
+
+
+ 其他
+
+
+
+
+
+
+
+
+
+ 流程干预
+ updateAssigneeModalApi.open()">
+ 修改办理人
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/approval-rejection-modal.vue b/apps/web-antd/src/views/workflow/components/approval-rejection-modal.vue
new file mode 100644
index 00000000..c7b6855a
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/approval-rejection-modal.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/approval-timeline-item.vue b/apps/web-antd/src/views/workflow/components/approval-timeline-item.vue
new file mode 100644
index 00000000..f6b26f7f
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/approval-timeline-item.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.nodeName }}
+
+
+
{{ item.approveName }}
+
{{ item.updateTime }}
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/approval-timeline.vue b/apps/web-antd/src/views/workflow/components/approval-timeline.vue
index 68f34f34..0e344fcc 100644
--- a/apps/web-antd/src/views/workflow/components/approval-timeline.vue
+++ b/apps/web-antd/src/views/workflow/components/approval-timeline.vue
@@ -1,50 +1,21 @@
-
-
-
-
-
-
-
发起人
-
疯狂的牛子Li
-
2022-01-01 12:00:00
-
- 这里是备注信息
-
-
-
+
+
diff --git a/apps/web-antd/src/views/workflow/components/copy-component.vue b/apps/web-antd/src/views/workflow/components/copy-component.vue
new file mode 100644
index 00000000..6b95687a
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/copy-component.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +{{ userListModel.length - props.ellipseNumber }}
+
+
+
+
选择人员
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/flow-designer.vue b/apps/web-antd/src/views/workflow/components/flow-designer.vue
new file mode 100644
index 00000000..1f678f4c
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/flow-designer.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/flow-info-modal.vue b/apps/web-antd/src/views/workflow/components/flow-info-modal.vue
new file mode 100644
index 00000000..034d1565
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/flow-info-modal.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/flow-interfere-modal.vue b/apps/web-antd/src/views/workflow/components/flow-interfere-modal.vue
new file mode 100644
index 00000000..38b6d66c
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/flow-interfere-modal.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+ {{ taskInfo.nodeName }}
+
+
+ {{ taskInfo.nodeCode }}
+
+
+ {{ taskInfo.createTime }}
+
+
+ {{ taskInfo.instanceId }}
+
+
+ {{ taskInfo.version }}
+
+
+ {{ taskInfo.businessId }}
+
+
+
+
+
+
+
+ addSignatureModalApi.open()">加签
+ reductionSignatureModalApi.open()">
+ 减签
+
+
+ transferModalApi.open()">转办
+ 终止
+
+
+
diff --git a/apps/web-antd/src/views/workflow/components/helper.tsx b/apps/web-antd/src/views/workflow/components/helper.tsx
new file mode 100644
index 00000000..a4ec7a41
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/helper.tsx
@@ -0,0 +1,60 @@
+import { defineComponent, h, ref } from 'vue';
+
+import { Modal } from 'ant-design-vue';
+import dayjs from 'dayjs';
+import duration from 'dayjs/plugin/duration';
+import relativeTime from 'dayjs/plugin/relativeTime';
+
+import ApprovalContent from './approval-content.vue';
+
+export interface ApproveWithReasonModalProps {
+ title: string;
+ description: string;
+ onOk: (reason: string) => void;
+}
+
+/**
+ * 带审批意见的confirm
+ * @param props props
+ */
+export function approveWithReasonModal(props: ApproveWithReasonModalProps) {
+ const { onOk, title, description } = props;
+ const content = ref('');
+ Modal.confirm({
+ title,
+ content: h(
+ defineComponent({
+ setup() {
+ return () =>
+ h(ApprovalContent, {
+ description,
+ value: content.value,
+ 'onUpdate:value': (v) => (content.value = v),
+ });
+ },
+ }),
+ ),
+ centered: true,
+ okButtonProps: { danger: true },
+ onOk: () => onOk(content.value),
+ });
+}
+
+dayjs.extend(duration);
+dayjs.extend(relativeTime);
+/**
+ * 计算相差的时间
+ * @param dateTime 时间字符串
+ * @returns 相差的时间
+ */
+export function getDiffTimeString(dateTime: string) {
+ // 计算相差秒数
+ const diffSeconds = dayjs().diff(dayjs(dateTime), 'second');
+ /**
+ * 转为时间显示(x月 x天)
+ * https://dayjs.fenxianglu.cn/category/duration.html#%E4%BA%BA%E6%80%A7%E5%8C%96
+ *
+ */
+ const diffText = dayjs.duration(diffSeconds, 'seconds').humanize();
+ return diffText;
+}
diff --git a/apps/web-antd/src/views/workflow/components/index.ts b/apps/web-antd/src/views/workflow/components/index.ts
index c1694380..4155011d 100644
--- a/apps/web-antd/src/views/workflow/components/index.ts
+++ b/apps/web-antd/src/views/workflow/components/index.ts
@@ -1,2 +1,30 @@
+export { default as applyModal } from './apply-modal.vue';
export { default as ApprovalCard } from './approval-card.vue';
+/**
+ * 审批同意
+ */
+export { default as approvalModal } from './approval-modal.vue';
+export { default as ApprovalPanel } from './approval-panel.vue';
+/**
+ * 审批驳回
+ */
+export { default as approvalRejectionModal } from './approval-rejection-modal.vue';
export { default as ApprovalTimeline } from './approval-timeline.vue';
+/**
+ * 选择抄送人
+ */
+export { default as CopyComponent } from './copy-component.vue';
+
+/**
+ * 详情信息 modal
+ */
+export { default as flowInfoModal } from './flow-info-modal.vue';
+/**
+ * 流程干预 modal
+ */
+export { default as flowInterfereModal } from './flow-interfere-modal.vue';
+
+/**
+ * 选人 支持单选/多选
+ */
+export { default as userSelectModal } from './user-select-modal.vue';
diff --git a/apps/web-antd/src/views/workflow/components/rejection.png b/apps/web-antd/src/views/workflow/components/rejection.png
deleted file mode 100644
index 7ed92204..00000000
Binary files a/apps/web-antd/src/views/workflow/components/rejection.png and /dev/null differ
diff --git a/apps/web-antd/src/views/workflow/components/user-select-modal.vue b/apps/web-antd/src/views/workflow/components/user-select-modal.vue
new file mode 100644
index 00000000..d9a0d144
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/components/user-select-modal.vue
@@ -0,0 +1,365 @@
+
+
+
+
+
+
+
tableApi.reload()"
+ @select="handleDeptQuery"
+ />
+
+
+
+
+
+
+
{{ row.nickName }}
+
+ {{ row.phonenumber || '暂无手机号' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.nickName }}
+
+
+ {{ row.phonenumber || '暂无手机号' }}
+
+
+
+
+
+
+ 移除
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/formManage/index.vue b/apps/web-antd/src/views/workflow/formManage/index.vue
deleted file mode 100644
index 06372a15..00000000
--- a/apps/web-antd/src/views/workflow/formManage/index.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/apps/web-antd/src/views/workflow/leave/api/index.ts b/apps/web-antd/src/views/workflow/leave/api/index.ts
new file mode 100644
index 00000000..20b87efc
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/leave/api/index.ts
@@ -0,0 +1,62 @@
+import type { LeaveForm, LeaveQuery, LeaveVO } from './model';
+
+import type { ID, IDS, PageResult } from '#/api/common';
+
+import { commonExport } from '#/api/helper';
+import { requestClient } from '#/api/request';
+
+/**
+ * 查询请假申请列表
+ * @param params
+ * @returns 请假申请列表
+ */
+export function leaveList(params?: LeaveQuery) {
+ return requestClient.get
>('/workflow/leave/list', {
+ params,
+ });
+}
+
+/**
+ * 导出请假申请列表
+ * @param params
+ * @returns 请假申请列表
+ */
+export function leaveExport(params?: LeaveQuery) {
+ return commonExport('/workflow/leave/export', params ?? {});
+}
+
+/**
+ * 查询请假申请详情
+ * @param id id
+ * @returns 请假申请详情
+ */
+export function leaveInfo(id: ID) {
+ return requestClient.get(`/workflow/leave/${id}`);
+}
+
+/**
+ * 新增请假申请
+ * @param data
+ * @returns void
+ */
+export function leaveAdd(data: LeaveForm) {
+ return requestClient.postWithMsg('/workflow/leave', data);
+}
+
+/**
+ * 更新请假申请
+ * @param data
+ * @returns void
+ */
+export function leaveUpdate(data: LeaveForm) {
+ return requestClient.putWithMsg('/workflow/leave', data);
+}
+
+/**
+ * 删除请假申请
+ * @param id id
+ * @returns void
+ */
+export function leaveRemove(id: ID | IDS) {
+ return requestClient.deleteWithMsg(`/workflow/leave/${id}`);
+}
diff --git a/apps/web-antd/src/views/workflow/leave/api/model.d.ts b/apps/web-antd/src/views/workflow/leave/api/model.d.ts
new file mode 100644
index 00000000..c1b0dbf7
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/leave/api/model.d.ts
@@ -0,0 +1,107 @@
+import type { BaseEntity, PageQuery } from '#/api/common';
+
+export interface LeaveVO {
+ /**
+ * 主键
+ */
+ id: number | string;
+
+ /**
+ * 请假类型
+ */
+ leaveType: string;
+
+ /**
+ * 开始时间
+ */
+ startDate: string;
+
+ /**
+ * 结束时间
+ */
+ endDate: string;
+
+ /**
+ * 请假天数
+ */
+ leaveDays: number;
+
+ /**
+ * 请假原因
+ */
+ remark: string;
+
+ /**
+ *
+ */
+ status: string;
+}
+
+export interface LeaveForm extends BaseEntity {
+ /**
+ * 主键
+ */
+ id?: number | string;
+
+ /**
+ * 请假类型
+ */
+ leaveType?: string;
+
+ /**
+ * 开始时间
+ */
+ startDate?: string;
+
+ /**
+ * 结束时间
+ */
+ endDate?: string;
+
+ /**
+ * 请假天数
+ */
+ leaveDays?: number;
+
+ /**
+ * 请假原因
+ */
+ remark?: string;
+
+ /**
+ *
+ */
+ status?: string;
+}
+
+export interface LeaveQuery extends PageQuery {
+ /**
+ * 请假类型
+ */
+ leaveType?: string;
+
+ /**
+ * 开始时间
+ */
+ startDate?: string;
+
+ /**
+ * 结束时间
+ */
+ endDate?: string;
+
+ /**
+ * 请假天数
+ */
+ leaveDays?: number;
+
+ /**
+ *
+ */
+ status?: string;
+
+ /**
+ * 日期范围参数
+ */
+ params?: any;
+}
diff --git a/apps/web-antd/src/views/workflow/leave/data.tsx b/apps/web-antd/src/views/workflow/leave/data.tsx
new file mode 100644
index 00000000..159bcc71
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/leave/data.tsx
@@ -0,0 +1,173 @@
+import type { FormSchemaGetter, VbenFormSchema } from '#/adapter/form';
+import type { VxeGridProps } from '#/adapter/vxe-table';
+
+import { DictEnum } from '@vben/constants';
+import { getPopupContainer } from '@vben/utils';
+
+import dayjs from 'dayjs';
+
+import { OptionsTag } from '#/components/table';
+import { renderDict } from '#/utils/render';
+
+export const leaveTypeOptions = [
+ { label: '病假', value: '1' },
+ { label: '事假', value: '2' },
+ { label: '年假', value: '3' },
+ { label: '婚假', value: '4' },
+ { label: '产假', value: '5' },
+ { label: '其他', value: '7' },
+];
+
+export const leaveFlowOptions = [
+ { label: '请假流程-普通', value: 'leave1' },
+ { label: '请假流程-排他网关', value: 'leave2' },
+ { label: '请假流程-并行网关', value: 'leave3' },
+ { label: '请假流程-会签', value: 'leave4' },
+ { label: '请假申请-并行会签网关', value: 'leave5' },
+];
+
+export const querySchema: FormSchemaGetter = () => [
+ {
+ component: 'InputNumber',
+ componentProps: {
+ min: 1,
+ },
+ fieldName: 'startLeaveDays',
+ label: '请假天数',
+ },
+ {
+ component: 'InputNumber',
+ componentProps: {
+ min: 1,
+ },
+ fieldName: 'endLeaveDays',
+ label: '至',
+ labelClass: 'justify-center',
+ },
+];
+
+export const columns: VxeGridProps['columns'] = [
+ { type: 'checkbox', width: 60 },
+ {
+ title: '请假类型',
+ field: 'leaveType',
+ slots: {
+ default: ({ row }) => {
+ return ;
+ },
+ },
+ },
+ {
+ title: '开始时间',
+ field: 'startDate',
+ formatter: ({ cellValue }) => dayjs(cellValue).format('YYYY-MM-DD'),
+ },
+ {
+ title: '结束时间',
+ field: 'endDate',
+ formatter: ({ cellValue }) => dayjs(cellValue).format('YYYY-MM-DD'),
+ },
+ {
+ title: '请假天数',
+ field: 'leaveDays',
+ formatter: ({ cellValue }) => `${cellValue}天`,
+ },
+ {
+ title: '请假原因',
+ field: 'remark',
+ },
+ {
+ title: '流程状态',
+ field: 'status',
+ slots: {
+ default: ({ row }) => {
+ return renderDict(row.status, DictEnum.WF_BUSINESS_STATUS);
+ },
+ },
+ },
+ {
+ field: 'action',
+ fixed: 'right',
+ slots: { default: 'action' },
+ title: '操作',
+ width: 210,
+ },
+];
+
+export const modalSchema: (isEdit: boolean) => VbenFormSchema[] = (
+ isEdit: boolean,
+) => [
+ {
+ label: '主键',
+ fieldName: 'id',
+ component: 'Input',
+ dependencies: {
+ show: () => false,
+ triggerFields: [''],
+ },
+ },
+ {
+ label: '流程类型',
+ fieldName: 'flowType',
+ component: 'Select',
+ help: '这里仅仅为了发起流程方便, 实际不应该包含此字段',
+ componentProps: {
+ options: leaveFlowOptions,
+ getPopupContainer,
+ },
+ defaultValue: 'leave1',
+ rules: 'selectRequired',
+ dependencies: {
+ show: () => isEdit,
+ triggerFields: [''],
+ },
+ },
+ {
+ label: '请假类型',
+ fieldName: 'leaveType',
+ component: 'Select',
+ componentProps: {
+ options: leaveTypeOptions,
+ getPopupContainer,
+ },
+ rules: 'selectRequired',
+ formItemClass: 'col-span-1',
+ },
+ {
+ label: '开始时间',
+ fieldName: 'dateRange',
+ component: 'RangePicker',
+ componentProps(model) {
+ return {
+ format: 'YYYY-MM-DD',
+ valueFormat: 'YYYY-MM-DD HH:mm:ss',
+ onChange: (dates: [string, string]) => {
+ if (!dates) {
+ model.leaveDays = null;
+ return;
+ }
+ const [start, end] = dates;
+ const leaveDays = dayjs(end).diff(dayjs(start), 'day') + 1;
+ model.leaveDays = leaveDays;
+ },
+ };
+ },
+ rules: 'required',
+ formItemClass: 'col-span-1',
+ },
+ {
+ label: '请假天数',
+ fieldName: 'leaveDays',
+ component: 'Input',
+ componentProps: {
+ disabled: true,
+ },
+ rules: 'required',
+ },
+ {
+ label: '请假原因',
+ fieldName: 'remark',
+ component: 'Textarea',
+ formItemClass: 'items-baseline',
+ },
+];
diff --git a/apps/web-antd/src/views/workflow/leave/index.vue b/apps/web-antd/src/views/workflow/leave/index.vue
index 06372a15..db1cfd1e 100644
--- a/apps/web-antd/src/views/workflow/leave/index.vue
+++ b/apps/web-antd/src/views/workflow/leave/index.vue
@@ -1,9 +1,198 @@
-
-
-
+
+
+
+
+
+ {{ $t('pages.common.export') }}
+
+
+ {{ $t('pages.common.delete') }}
+
+
+ {{ $t('pages.common.add') }}
+
+
+
+
+
+
+ {{ $t('pages.common.edit') }}
+
+
+
+ 撤销
+
+
+ 详情
+
+
+ {{ $t('pages.common.delete') }}
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/leave/leave-description.vue b/apps/web-antd/src/views/workflow/leave/leave-description.vue
new file mode 100644
index 00000000..d81ef9b8
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/leave/leave-description.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ {{ leaveType }}
+
+
+ {{ formatDate(data.startDate) }} - {{ formatDate(data.endDate) }}
+
+
+ {{ data.leaveDays }}天
+
+
+ {{ data.remark || '无' }}
+
+
+
diff --git a/apps/web-antd/src/views/workflow/leave/leave-form.vue b/apps/web-antd/src/views/workflow/leave/leave-form.vue
new file mode 100644
index 00000000..883dbcf4
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/leave/leave-form.vue
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/model/index.vue b/apps/web-antd/src/views/workflow/model/index.vue
deleted file mode 100644
index 06372a15..00000000
--- a/apps/web-antd/src/views/workflow/model/index.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue b/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue
new file mode 100644
index 00000000..6912c256
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processDefinition/category-tree.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ label.substring(0, label.indexOf(searchValue)) }}
+ {{ searchValue }}
+ {{
+ label.substring(
+ label.indexOf(searchValue) + searchValue.length,
+ )
+ }}
+
+ {{ label }}
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processDefinition/constant.ts b/apps/web-antd/src/views/workflow/processDefinition/constant.ts
new file mode 100644
index 00000000..e24dfc7f
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processDefinition/constant.ts
@@ -0,0 +1,36 @@
+import { optionsToEnum } from '@vben/utils';
+
+export const activityStatusOptions = [
+ {
+ label: '激活',
+ value: 1,
+ color: 'success',
+ enumName: 'Active',
+ },
+ {
+ label: '挂起',
+ value: 0,
+ color: 'error',
+ enumName: 'Suspended',
+ },
+] as const;
+
+export const ActivityStatusEnum = optionsToEnum(activityStatusOptions);
+
+export const publishStatusOptions = [
+ {
+ label: '已发布',
+ value: 1,
+ color: 'success',
+ },
+ {
+ label: '未发布',
+ value: 0,
+ color: 'warning',
+ },
+ {
+ label: '失效',
+ value: 9,
+ color: 'error',
+ },
+];
diff --git a/apps/web-antd/src/views/workflow/processDefinition/data.tsx b/apps/web-antd/src/views/workflow/processDefinition/data.tsx
new file mode 100644
index 00000000..ecaffdf0
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processDefinition/data.tsx
@@ -0,0 +1,103 @@
+import type { FormSchemaGetter } from '#/adapter/form';
+import type { VxeGridProps } from '#/adapter/vxe-table';
+
+import { OptionsTag } from '#/components/table';
+
+import { publishStatusOptions } from './constant';
+
+export const querySchema: FormSchemaGetter = () => [
+ {
+ component: 'Input',
+ fieldName: 'flowName',
+ label: '流程名称',
+ },
+ {
+ component: 'Input',
+ fieldName: 'flowCode',
+ label: '流程code',
+ },
+];
+
+export const columns: VxeGridProps['columns'] = [
+ { type: 'checkbox', width: 60 },
+ {
+ field: 'flowName',
+ title: '流程名称',
+ minWidth: 150,
+ },
+ {
+ field: 'flowCode',
+ title: '流程code',
+ minWidth: 150,
+ },
+ {
+ field: 'version',
+ title: '版本号',
+ minWidth: 80,
+ formatter: ({ cellValue }) => `V${cellValue}.0`,
+ },
+ {
+ field: 'activityStatus',
+ title: '激活状态',
+ minWidth: 100,
+ slots: {
+ default: 'activityStatus',
+ },
+ },
+ {
+ field: 'isPublish',
+ title: '发布状态',
+ minWidth: 100,
+ slots: {
+ default: ({ row }) => {
+ const cellValue = row.isPublish;
+ return (
+
+ );
+ },
+ },
+ },
+ {
+ field: 'action',
+ fixed: 'right',
+ slots: { default: 'action' },
+ title: '操作',
+ resizable: false,
+ width: 200,
+ },
+];
+
+export const modalSchema: FormSchemaGetter = () => [
+ {
+ component: 'Input',
+ dependencies: {
+ show: () => false,
+ triggerFields: [''],
+ },
+ fieldName: 'id',
+ },
+ {
+ component: 'TreeSelect',
+ fieldName: 'category',
+ label: '流程分类',
+ rules: 'selectRequired',
+ },
+ {
+ component: 'Input',
+ fieldName: 'flowCode',
+ label: '流程code',
+ rules: 'required',
+ },
+ {
+ component: 'Input',
+ fieldName: 'flowName',
+ label: '流程名称',
+ rules: 'required',
+ },
+ {
+ component: 'Input',
+ fieldName: 'formPath',
+ label: '表单路径',
+ rules: 'required',
+ },
+];
diff --git a/apps/web-antd/src/views/workflow/processDefinition/index.vue b/apps/web-antd/src/views/workflow/processDefinition/index.vue
index 06372a15..1a51fddc 100644
--- a/apps/web-antd/src/views/workflow/processDefinition/index.vue
+++ b/apps/web-antd/src/views/workflow/processDefinition/index.vue
@@ -1,9 +1,373 @@
+
-
-
-
+
+
+
tableApi.reload()"
+ @select="() => tableApi.reload()"
+ />
+
+
+
+
+
+
+
+ {{ $t('pages.common.delete') }}
+
+
+ 部署
+
+
+ {{ $t('pages.common.add') }}
+
+
+
+
+ handleActive(row, status)"
+ />
+
+
+
+
+
+ 编辑信息
+
+
+
+ 删除流程
+
+
+
+
+
+ {{ row.isPublish ? '查看流程' : '设计流程' }}
+
+
+
+ 发布流程
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processDefinition/process-definition-deploy-modal.vue b/apps/web-antd/src/views/workflow/processDefinition/process-definition-deploy-modal.vue
new file mode 100644
index 00000000..760dcbc5
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processDefinition/process-definition-deploy-modal.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+ 点击或者拖拽到此处上传[json]文件
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processDefinition/process-definition-modal.vue b/apps/web-antd/src/views/workflow/processDefinition/process-definition-modal.vue
new file mode 100644
index 00000000..22997090
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processDefinition/process-definition-modal.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processInstance/data.tsx b/apps/web-antd/src/views/workflow/processInstance/data.tsx
new file mode 100644
index 00000000..6e7e711d
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processInstance/data.tsx
@@ -0,0 +1,91 @@
+import type { FormSchemaGetter } from '#/adapter/form';
+import type { VxeGridProps } from '#/adapter/vxe-table';
+
+import { DictEnum } from '@vben/constants';
+
+import { OptionsTag } from '#/components/table';
+import { renderDict } from '#/utils/render';
+
+import { activityStatusOptions } from '../processDefinition/constant';
+
+export const querySchema: FormSchemaGetter = () => [
+ {
+ component: 'Input',
+ label: '任务名称',
+ fieldName: 'nodeName',
+ },
+ {
+ component: 'Input',
+ label: '流程名称',
+ fieldName: 'flowName',
+ },
+ {
+ component: 'Input',
+ label: '流程编码',
+ fieldName: 'flowCode',
+ },
+];
+
+export const columns: VxeGridProps['columns'] = [
+ { type: 'checkbox', width: 60 },
+ {
+ field: 'flowName',
+ title: '流程名称',
+ minWidth: 150,
+ },
+ {
+ field: 'nodeName',
+ title: '任务名称',
+ minWidth: 150,
+ },
+ {
+ field: 'flowCode',
+ title: '流程编码',
+ minWidth: 150,
+ },
+ {
+ field: 'createByName',
+ title: '申请人',
+ minWidth: 150,
+ },
+ {
+ field: 'version',
+ title: '版本号',
+ minWidth: 150,
+ formatter: ({ cellValue }) => `V${cellValue}.0`,
+ },
+ {
+ field: 'activityStatus',
+ title: '状态',
+ minWidth: 100,
+ slots: {
+ default: ({ row }) => {
+ const cellValue = row.activityStatus;
+ return (
+
+ );
+ },
+ },
+ },
+ {
+ field: 'flowStatus',
+ title: '流程状态',
+ minWidth: 100,
+ slots: {
+ default: ({ row }) => {
+ return renderDict(row.flowStatus, DictEnum.WF_BUSINESS_STATUS);
+ },
+ },
+ },
+ {
+ field: 'action',
+ fixed: 'right',
+ slots: { default: 'action' },
+ title: '操作',
+ resizable: false,
+ width: 200,
+ },
+];
diff --git a/apps/web-antd/src/views/workflow/processInstance/index.vue b/apps/web-antd/src/views/workflow/processInstance/index.vue
index 06372a15..4ce21bb5 100644
--- a/apps/web-antd/src/views/workflow/processInstance/index.vue
+++ b/apps/web-antd/src/views/workflow/processInstance/index.vue
@@ -1,9 +1,235 @@
-
-
-
+
+
+
tableApi.reload()"
+ @select="() => tableApi.reload()"
+ />
+
+
+
+
+
+
+
+ {{ $t('pages.common.delete') }}
+
+
+
+
+
+
+
+ 作废流程
+
+
+
+ 删除流程
+
+
+
+
+
+
+
+
+ tableApi.reload()" />
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processInstance/instance-invalid-modal.vue b/apps/web-antd/src/views/workflow/processInstance/instance-invalid-modal.vue
new file mode 100644
index 00000000..58727b2b
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processInstance/instance-invalid-modal.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/processInstance/instance-variable-modal.vue b/apps/web-antd/src/views/workflow/processInstance/instance-variable-modal.vue
new file mode 100644
index 00000000..420a9d0c
--- /dev/null
+++ b/apps/web-antd/src/views/workflow/processInstance/instance-variable-modal.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/task/allTaskWaiting.vue b/apps/web-antd/src/views/workflow/task/allTaskWaiting.vue
index 06372a15..d1843616 100644
--- a/apps/web-antd/src/views/workflow/task/allTaskWaiting.vue
+++ b/apps/web-antd/src/views/workflow/task/allTaskWaiting.vue
@@ -1,9 +1,357 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 共 {{ taskTotal }} 条记录
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/task/myDocument.vue b/apps/web-antd/src/views/workflow/task/myDocument.vue
index 06372a15..cb6123bd 100644
--- a/apps/web-antd/src/views/workflow/task/myDocument.vue
+++ b/apps/web-antd/src/views/workflow/task/myDocument.vue
@@ -1,9 +1,256 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 共 {{ taskTotal }} 条记录
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/task/taskCopyList.vue b/apps/web-antd/src/views/workflow/task/taskCopyList.vue
index 06372a15..403488a6 100644
--- a/apps/web-antd/src/views/workflow/task/taskCopyList.vue
+++ b/apps/web-antd/src/views/workflow/task/taskCopyList.vue
@@ -1,9 +1,298 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 共 {{ taskTotal }} 条记录
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/task/taskFinish.vue b/apps/web-antd/src/views/workflow/task/taskFinish.vue
index 06372a15..0a56df40 100644
--- a/apps/web-antd/src/views/workflow/task/taskFinish.vue
+++ b/apps/web-antd/src/views/workflow/task/taskFinish.vue
@@ -1,9 +1,298 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 共 {{ taskTotal }} 条记录
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/workflow/task/taskWaiting.vue b/apps/web-antd/src/views/workflow/task/taskWaiting.vue
index e8d75ad0..664c601e 100644
--- a/apps/web-antd/src/views/workflow/task/taskWaiting.vue
+++ b/apps/web-antd/src/views/workflow/task/taskWaiting.vue
@@ -1,25 +1,97 @@
+
-
+
-
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
- 共 {{ data.length }} 条记录
+ 共 {{ taskTotal }} 条记录
-
-
-
-
-
-
-
疯狂的牛子Li
-
-
XXXX有限公司
-
-
提交于: 2022-01-01 12:00:00
-
-
-
-
-
![]()
-
-
-
-
-
-
- 审批记录
- 全文评论
-
-
-
-
-
+
diff --git a/apps/web-antd/src/views/演示使用自行删除/README.md b/apps/web-antd/src/views/演示使用自行删除/README.md
new file mode 100644
index 00000000..064135fc
--- /dev/null
+++ b/apps/web-antd/src/views/演示使用自行删除/README.md
@@ -0,0 +1 @@
+演示站专用目录 可直接删除该目录
diff --git a/apps/web-antd/src/views/演示使用自行删除/menu/index.vue b/apps/web-antd/src/views/演示使用自行删除/menu/index.vue
new file mode 100644
index 00000000..7b7b2b5a
--- /dev/null
+++ b/apps/web-antd/src/views/演示使用自行删除/menu/index.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/演示使用自行删除/upload/index.vue b/apps/web-antd/src/views/演示使用自行删除/upload/index.vue
index c5556660..aa2971a6 100644
--- a/apps/web-antd/src/views/演示使用自行删除/upload/index.vue
+++ b/apps/web-antd/src/views/演示使用自行删除/upload/index.vue
@@ -1,11 +1,8 @@
@@ -27,7 +24,11 @@ const signleImage = ref('');
:show-icon="true"
message="新特性: 设置max-number为1时, 会被绑定为string而非string[]类型 省去手动转换"
/>
-
+
diff --git a/apps/web-antd/src/views/演示使用自行删除/vxe/edit-table.vue b/apps/web-antd/src/views/演示使用自行删除/vxe/edit-table.vue
new file mode 100644
index 00000000..42355990
--- /dev/null
+++ b/apps/web-antd/src/views/演示使用自行删除/vxe/edit-table.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+ 获取表格数据
+ 校验
+ 删除勾选
+
+ {{ $t('pages.common.add') }}
+
+
+
+
+
diff --git a/apps/web-antd/src/views/演示使用自行删除/vxe/index.vue b/apps/web-antd/src/views/演示使用自行删除/vxe/index.vue
new file mode 100644
index 00000000..6da7f702
--- /dev/null
+++ b/apps/web-antd/src/views/演示使用自行删除/vxe/index.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/演示使用自行删除/wechat/index.vue b/apps/web-antd/src/views/演示使用自行删除/wechat/index.vue
index 72675125..7e55d09a 100644
--- a/apps/web-antd/src/views/演示使用自行删除/wechat/index.vue
+++ b/apps/web-antd/src/views/演示使用自行删除/wechat/index.vue
@@ -1,18 +1,13 @@
@@ -25,12 +20,7 @@ onMounted(async () => {
type="info"
/>
-
+
diff --git a/apps/web-antd/vite.config.mts b/apps/web-antd/vite.config.mts
index ed01d813..7e884500 100644
--- a/apps/web-antd/vite.config.mts
+++ b/apps/web-antd/vite.config.mts
@@ -8,12 +8,6 @@ export default defineConfig(async () => {
return {
application: {},
vite: {
- optimizeDeps: {
- include: [
- 'ant-design-vue/es/locale/zh_CN',
- 'ant-design-vue/es/locale/en_US',
- ],
- },
plugins: [
// Components({
// dirs: [], // 默认会导入src/components目录下所有组件 不需要
@@ -37,9 +31,6 @@ export default defineConfig(async () => {
ws: true,
},
},
- warmup: {
- clientFiles: ['./index.html', './src/{views,components}/*'],
- },
},
},
};
diff --git a/apps/web-ele/.env b/apps/web-ele/.env
deleted file mode 100644
index 87cb3df1..00000000
--- a/apps/web-ele/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-# 应用标题
-VITE_APP_TITLE=Vben Admin Ele
-
-# 应用命名空间,用于缓存、store等功能的前缀,确保隔离
-VITE_APP_NAMESPACE=vben-web-ele
diff --git a/apps/web-ele/.env.analyze b/apps/web-ele/.env.analyze
deleted file mode 100644
index ffafa8dd..00000000
--- a/apps/web-ele/.env.analyze
+++ /dev/null
@@ -1,7 +0,0 @@
-# public path
-VITE_BASE=/
-
-# Basic interface address SPA
-VITE_GLOB_API_URL=/api
-
-VITE_VISUALIZER=true
diff --git a/apps/web-ele/.env.development b/apps/web-ele/.env.development
deleted file mode 100644
index 8bcb432e..00000000
--- a/apps/web-ele/.env.development
+++ /dev/null
@@ -1,16 +0,0 @@
-# 端口号
-VITE_PORT=5777
-
-VITE_BASE=/
-
-# 接口地址
-VITE_GLOB_API_URL=/api
-
-# 是否开启 Nitro Mock服务,true 为开启,false 为关闭
-VITE_NITRO_MOCK=true
-
-# 是否打开 devtools,true 为打开,false 为关闭
-VITE_DEVTOOLS=false
-
-# 是否注入全局loading
-VITE_INJECT_APP_LOADING=true
diff --git a/apps/web-ele/.env.production b/apps/web-ele/.env.production
deleted file mode 100644
index 5375847a..00000000
--- a/apps/web-ele/.env.production
+++ /dev/null
@@ -1,19 +0,0 @@
-VITE_BASE=/
-
-# 接口地址
-VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
-
-# 是否开启压缩,可以设置为 none, brotli, gzip
-VITE_COMPRESS=none
-
-# 是否开启 PWA
-VITE_PWA=false
-
-# vue-router 的模式
-VITE_ROUTER_HISTORY=hash
-
-# 是否注入全局loading
-VITE_INJECT_APP_LOADING=true
-
-# 打包后是否生成dist.zip
-VITE_ARCHIVER=true
diff --git a/apps/web-ele/index.html b/apps/web-ele/index.html
deleted file mode 100644
index 2b59b8d7..00000000
--- a/apps/web-ele/index.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- <%= VITE_APP_TITLE %>
-
-
-
-
-
-
-
-
diff --git a/apps/web-ele/package.json b/apps/web-ele/package.json
deleted file mode 100644
index 9828c52f..00000000
--- a/apps/web-ele/package.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "name": "@vben/web-ele",
- "version": "5.5.0",
- "homepage": "https://vben.pro",
- "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/vbenjs/vue-vben-admin.git",
- "directory": "apps/web-ele"
- },
- "license": "MIT",
- "author": {
- "name": "vben",
- "email": "ann.vben@gmail.com",
- "url": "https://github.com/anncwb"
- },
- "type": "module",
- "scripts": {
- "build": "pnpm vite build --mode production",
- "build:analyze": "pnpm vite build --mode analyze",
- "dev": "pnpm vite --mode development",
- "preview": "vite preview",
- "typecheck": "vue-tsc --noEmit --skipLibCheck"
- },
- "imports": {
- "#/*": "./src/*"
- },
- "dependencies": {
- "@vben/access": "workspace:*",
- "@vben/common-ui": "workspace:*",
- "@vben/constants": "workspace:*",
- "@vben/hooks": "workspace:*",
- "@vben/icons": "workspace:*",
- "@vben/layouts": "workspace:*",
- "@vben/locales": "workspace:*",
- "@vben/plugins": "workspace:*",
- "@vben/preferences": "workspace:*",
- "@vben/request": "workspace:*",
- "@vben/stores": "workspace:*",
- "@vben/styles": "workspace:*",
- "@vben/types": "workspace:*",
- "@vben/utils": "workspace:*",
- "@vueuse/core": "catalog:",
- "dayjs": "catalog:",
- "element-plus": "catalog:",
- "pinia": "catalog:",
- "vue": "catalog:",
- "vue-router": "catalog:"
- },
- "devDependencies": {
- "unplugin-element-plus": "catalog:"
- }
-}
diff --git a/apps/web-ele/postcss.config.mjs b/apps/web-ele/postcss.config.mjs
deleted file mode 100644
index 3d807045..00000000
--- a/apps/web-ele/postcss.config.mjs
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@vben/tailwind-config/postcss';
diff --git a/apps/web-ele/public/favicon.ico b/apps/web-ele/public/favicon.ico
deleted file mode 100644
index fcf9818e..00000000
Binary files a/apps/web-ele/public/favicon.ico and /dev/null differ
diff --git a/apps/web-ele/src/adapter/component/index.ts b/apps/web-ele/src/adapter/component/index.ts
deleted file mode 100644
index 818c8c4e..00000000
--- a/apps/web-ele/src/adapter/component/index.ts
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用
- * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
- */
-
-import type { BaseFormComponentType } from '@vben/common-ui';
-import type { Recordable } from '@vben/types';
-
-import type { Component, SetupContext } from 'vue';
-import { h } from 'vue';
-
-import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
-import { $t } from '@vben/locales';
-
-import {
- ElButton,
- ElCheckbox,
- ElCheckboxButton,
- ElCheckboxGroup,
- ElDatePicker,
- ElDivider,
- ElInput,
- ElInputNumber,
- ElNotification,
- ElRadio,
- ElRadioButton,
- ElRadioGroup,
- ElSelectV2,
- ElSpace,
- ElSwitch,
- ElTimePicker,
- ElTreeSelect,
- ElUpload,
-} from 'element-plus';
-
-const withDefaultPlaceholder = (
- component: T,
- type: 'input' | 'select',
-) => {
- return (props: any, { attrs, slots }: Omit) => {
- const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
- return h(component, { ...props, ...attrs, placeholder }, slots);
- };
-};
-
-// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
-export type ComponentType =
- | 'ApiSelect'
- | 'ApiTreeSelect'
- | 'Checkbox'
- | 'CheckboxGroup'
- | 'DatePicker'
- | 'Divider'
- | 'IconPicker'
- | 'Input'
- | 'InputNumber'
- | 'RadioGroup'
- | 'Select'
- | 'Space'
- | 'Switch'
- | 'TimePicker'
- | 'TreeSelect'
- | 'Upload'
- | BaseFormComponentType;
-
-async function initComponentAdapter() {
- const components: Partial> = {
- // 如果你的组件体积比较大,可以使用异步加载
- // Button: () =>
- // import('xxx').then((res) => res.Button),
- ApiSelect: (props, { attrs, slots }) => {
- return h(
- ApiComponent,
- {
- placeholder: $t('ui.placeholder.select'),
- ...props,
- ...attrs,
- component: ElSelectV2,
- loadingSlot: 'loading',
- visibleEvent: 'onVisibleChange',
- },
- slots,
- );
- },
- ApiTreeSelect: (props, { attrs, slots }) => {
- return h(
- ApiComponent,
- {
- placeholder: $t('ui.placeholder.select'),
- ...props,
- ...attrs,
- component: ElTreeSelect,
- props: { label: 'label', children: 'children' },
- nodeKey: 'value',
- loadingSlot: 'loading',
- optionsPropName: 'data',
- visibleEvent: 'onVisibleChange',
- },
- slots,
- );
- },
- Checkbox: ElCheckbox,
- CheckboxGroup: (props, { attrs, slots }) => {
- let defaultSlot;
- if (Reflect.has(slots, 'default')) {
- defaultSlot = slots.default;
- } else {
- const { options, isButton } = attrs;
- if (Array.isArray(options)) {
- defaultSlot = () =>
- options.map((option) =>
- h(isButton ? ElCheckboxButton : ElCheckbox, option),
- );
- }
- }
- return h(
- ElCheckboxGroup,
- { ...props, ...attrs },
- { ...slots, default: defaultSlot },
- );
- },
- // 自定义默认按钮
- DefaultButton: (props, { attrs, slots }) => {
- return h(ElButton, { ...props, attrs, type: 'info' }, slots);
- },
- // 自定义主要按钮
- PrimaryButton: (props, { attrs, slots }) => {
- return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
- },
- Divider: ElDivider,
- IconPicker: (props, { attrs, slots }) => {
- return h(
- IconPicker,
- {
- iconSlot: 'append',
- modelValueProp: 'model-value',
- inputComponent: ElInput,
- ...props,
- ...attrs,
- },
- slots,
- );
- },
- Input: withDefaultPlaceholder(ElInput, 'input'),
- InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
- RadioGroup: (props, { attrs, slots }) => {
- let defaultSlot;
- if (Reflect.has(slots, 'default')) {
- defaultSlot = slots.default;
- } else {
- const { options } = attrs;
- if (Array.isArray(options)) {
- defaultSlot = () =>
- options.map((option) =>
- h(attrs.isButton ? ElRadioButton : ElRadio, option),
- );
- }
- }
- return h(
- ElRadioGroup,
- { ...props, ...attrs },
- { ...slots, default: defaultSlot },
- );
- },
- Select: (props, { attrs, slots }) => {
- return h(ElSelectV2, { ...props, attrs }, slots);
- },
- Space: ElSpace,
- Switch: ElSwitch,
- TimePicker: (props, { attrs, slots }) => {
- const { name, id, isRange } = props;
- const extraProps: Recordable = {};
- if (isRange) {
- if (name && !Array.isArray(name)) {
- extraProps.name = [name, `${name}_end`];
- }
- if (id && !Array.isArray(id)) {
- extraProps.id = [id, `${id}_end`];
- }
- }
- return h(
- ElTimePicker,
- {
- ...props,
- ...attrs,
- ...extraProps,
- },
- slots,
- );
- },
- DatePicker: (props, { attrs, slots }) => {
- const { name, id, type } = props;
- const extraProps: Recordable = {};
- if (type && type.includes('range')) {
- if (name && !Array.isArray(name)) {
- extraProps.name = [name, `${name}_end`];
- }
- if (id && !Array.isArray(id)) {
- extraProps.id = [id, `${id}_end`];
- }
- }
- return h(
- ElDatePicker,
- {
- ...props,
- ...attrs,
- ...extraProps,
- },
- slots,
- );
- },
- TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
- Upload: ElUpload,
- };
-
- // 将组件注册到全局共享状态中
- globalShareState.setComponents(components);
-
- // 定义全局共享状态中的消息提示
- globalShareState.defineMessage({
- // 复制成功消息提示
- copyPreferencesSuccess: (title, content) => {
- ElNotification({
- title,
- message: content,
- position: 'bottom-right',
- duration: 0,
- type: 'success',
- });
- },
- });
-}
-
-export { initComponentAdapter };
diff --git a/apps/web-ele/src/adapter/form.ts b/apps/web-ele/src/adapter/form.ts
deleted file mode 100644
index 13ae9c42..00000000
--- a/apps/web-ele/src/adapter/form.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import type {
- VbenFormSchema as FormSchema,
- VbenFormProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
-import { $t } from '@vben/locales';
-
-setupVbenForm({
- config: {
- modelPropNameMap: {
- Upload: 'fileList',
- CheckboxGroup: 'model-value',
- },
- },
- defineRules: {
- required: (value, _params, ctx) => {
- if (value === undefined || value === null || value.length === 0) {
- return $t('ui.formRules.required', [ctx.label]);
- }
- return true;
- },
- selectRequired: (value, _params, ctx) => {
- if (value === undefined || value === null) {
- return $t('ui.formRules.selectRequired', [ctx.label]);
- }
- return true;
- },
- },
-});
-
-const useVbenForm = useForm;
-
-export { useVbenForm, z };
-
-export type VbenFormSchema = FormSchema;
-export type { VbenFormProps };
diff --git a/apps/web-ele/src/adapter/vxe-table.ts b/apps/web-ele/src/adapter/vxe-table.ts
deleted file mode 100644
index 44b31eae..00000000
--- a/apps/web-ele/src/adapter/vxe-table.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { h } from 'vue';
-
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
-
-import { ElButton, ElImage } from 'element-plus';
-
-import { useVbenForm } from './form';
-
-setupVbenVxeTable({
- configVxeTable: (vxeUI) => {
- vxeUI.setConfig({
- grid: {
- align: 'center',
- border: false,
- columnConfig: {
- resizable: true,
- },
- minHeight: 180,
- formConfig: {
- // 全局禁用vxe-table的表单配置,使用formOptions
- enabled: false,
- },
- proxyConfig: {
- autoLoad: true,
- response: {
- result: 'items',
- total: 'total',
- list: 'items',
- },
- showActiveMsg: true,
- showResponseMsg: false,
- },
- round: true,
- showOverflow: true,
- size: 'small',
- },
- });
-
- // 表格配置项可以用 cellRender: { name: 'CellImage' },
- vxeUI.renderer.add('CellImage', {
- renderTableDefault(_renderOpts, params) {
- const { column, row } = params;
- const src = row[column.field];
- return h(ElImage, { src, previewSrcList: [src] });
- },
- });
-
- // 表格配置项可以用 cellRender: { name: 'CellLink' },
- vxeUI.renderer.add('CellLink', {
- renderTableDefault(renderOpts) {
- const { props } = renderOpts;
- return h(
- ElButton,
- { size: 'small', link: true },
- { default: () => props?.text },
- );
- },
- });
-
- // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
- // vxeUI.formats.add
- },
- useVbenForm,
-});
-
-export { useVbenVxeGrid };
-
-export type * from '@vben/plugins/vxe-table';
diff --git a/apps/web-ele/src/api/core/auth.ts b/apps/web-ele/src/api/core/auth.ts
deleted file mode 100644
index 71d9f994..00000000
--- a/apps/web-ele/src/api/core/auth.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { baseRequestClient, requestClient } from '#/api/request';
-
-export namespace AuthApi {
- /** 登录接口参数 */
- export interface LoginParams {
- password?: string;
- username?: string;
- }
-
- /** 登录接口返回值 */
- export interface LoginResult {
- accessToken: string;
- }
-
- export interface RefreshTokenResult {
- data: string;
- status: number;
- }
-}
-
-/**
- * 登录
- */
-export async function loginApi(data: AuthApi.LoginParams) {
- return requestClient.post('/auth/login', data);
-}
-
-/**
- * 刷新accessToken
- */
-export async function refreshTokenApi() {
- return baseRequestClient.post('/auth/refresh', {
- withCredentials: true,
- });
-}
-
-/**
- * 退出登录
- */
-export async function logoutApi() {
- return baseRequestClient.post('/auth/logout', {
- withCredentials: true,
- });
-}
-
-/**
- * 获取用户权限码
- */
-export async function getAccessCodesApi() {
- return requestClient.get('/auth/codes');
-}
diff --git a/apps/web-ele/src/api/core/index.ts b/apps/web-ele/src/api/core/index.ts
deleted file mode 100644
index 28a5aef4..00000000
--- a/apps/web-ele/src/api/core/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './auth';
-export * from './menu';
-export * from './user';
diff --git a/apps/web-ele/src/api/core/menu.ts b/apps/web-ele/src/api/core/menu.ts
deleted file mode 100644
index 9ef60b11..00000000
--- a/apps/web-ele/src/api/core/menu.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { RouteRecordStringComponent } from '@vben/types';
-
-import { requestClient } from '#/api/request';
-
-/**
- * 获取用户所有菜单
- */
-export async function getAllMenusApi() {
- return requestClient.get('/menu/all');
-}
diff --git a/apps/web-ele/src/api/core/user.ts b/apps/web-ele/src/api/core/user.ts
deleted file mode 100644
index 7e28ea84..00000000
--- a/apps/web-ele/src/api/core/user.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { UserInfo } from '@vben/types';
-
-import { requestClient } from '#/api/request';
-
-/**
- * 获取用户信息
- */
-export async function getUserInfoApi() {
- return requestClient.get('/user/info');
-}
diff --git a/apps/web-ele/src/api/index.ts b/apps/web-ele/src/api/index.ts
deleted file mode 100644
index 4b0e0413..00000000
--- a/apps/web-ele/src/api/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './core';
diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts
deleted file mode 100644
index a9514c81..00000000
--- a/apps/web-ele/src/api/request.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * 该文件可自行根据业务逻辑进行调整
- */
-import type { HttpResponse } from '@vben/request';
-
-import { useAppConfig } from '@vben/hooks';
-import { preferences } from '@vben/preferences';
-import {
- authenticateResponseInterceptor,
- errorMessageResponseInterceptor,
- RequestClient,
-} from '@vben/request';
-import { useAccessStore } from '@vben/stores';
-
-import { ElMessage } from 'element-plus';
-
-import { useAuthStore } from '#/store';
-
-import { refreshTokenApi } from './core';
-
-const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
-
-function createRequestClient(baseURL: string) {
- const client = new RequestClient({
- baseURL,
- });
-
- /**
- * 重新认证逻辑
- */
- async function doReAuthenticate() {
- console.warn('Access token or refresh token is invalid or expired. ');
- const accessStore = useAccessStore();
- const authStore = useAuthStore();
- accessStore.setAccessToken(null);
- if (
- preferences.app.loginExpiredMode === 'modal' &&
- accessStore.isAccessChecked
- ) {
- accessStore.setLoginExpired(true);
- } else {
- await authStore.logout();
- }
- }
-
- /**
- * 刷新token逻辑
- */
- async function doRefreshToken() {
- const accessStore = useAccessStore();
- const resp = await refreshTokenApi();
- const newToken = resp.data;
- accessStore.setAccessToken(newToken);
- return newToken;
- }
-
- function formatToken(token: null | string) {
- return token ? `Bearer ${token}` : null;
- }
-
- // 请求头处理
- client.addRequestInterceptor({
- fulfilled: async (config) => {
- const accessStore = useAccessStore();
-
- config.headers.Authorization = formatToken(accessStore.accessToken);
- config.headers['Accept-Language'] = preferences.app.locale;
- return config;
- },
- });
-
- // response数据解构
- client.addResponseInterceptor({
- fulfilled: (response) => {
- const { data: responseData, status } = response;
-
- const { code, data } = responseData;
- if (status >= 200 && status < 400 && code === 0) {
- return data;
- }
- throw Object.assign({}, response, { response });
- },
- });
-
- // token过期的处理
- client.addResponseInterceptor(
- authenticateResponseInterceptor({
- client,
- doReAuthenticate,
- doRefreshToken,
- enableRefreshToken: preferences.app.enableRefreshToken,
- formatToken,
- }),
- );
-
- // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
- client.addResponseInterceptor(
- errorMessageResponseInterceptor((msg: string, error) => {
- // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
- // 当前mock接口返回的错误字段是 error 或者 message
- const responseData = error?.response?.data ?? {};
- const errorMessage = responseData?.error ?? responseData?.message ?? '';
- // 如果没有错误信息,则会根据状态码进行提示
- ElMessage.error(errorMessage || msg);
- }),
- );
-
- return client;
-}
-
-export const requestClient = createRequestClient(apiURL);
-
-export const baseRequestClient = new RequestClient({ baseURL: apiURL });
diff --git a/apps/web-ele/src/app.vue b/apps/web-ele/src/app.vue
deleted file mode 100644
index 1217658d..00000000
--- a/apps/web-ele/src/app.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
diff --git a/apps/web-ele/src/bootstrap.ts b/apps/web-ele/src/bootstrap.ts
deleted file mode 100644
index ad1dce0f..00000000
--- a/apps/web-ele/src/bootstrap.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { createApp, watchEffect } from 'vue';
-
-import { registerAccessDirective } from '@vben/access';
-import { preferences } from '@vben/preferences';
-import { initStores } from '@vben/stores';
-import '@vben/styles';
-import '@vben/styles/ele';
-
-import { useTitle } from '@vueuse/core';
-import { ElLoading } from 'element-plus';
-
-import { $t, setupI18n } from '#/locales';
-
-import { initComponentAdapter } from './adapter/component';
-import App from './app.vue';
-import { router } from './router';
-
-async function bootstrap(namespace: string) {
- // 初始化组件适配器
- await initComponentAdapter();
- const app = createApp(App);
-
- // 注册Element Plus提供的v-loading指令
- app.directive('loading', ElLoading.directive);
-
- // 国际化 i18n 配置
- await setupI18n(app);
-
- // 配置 pinia-tore
- await initStores(app, { namespace });
-
- // 安装权限指令
- registerAccessDirective(app);
-
- // 配置路由及路由守卫
- app.use(router);
-
- // 动态更新标题
- watchEffect(() => {
- if (preferences.app.dynamicTitle) {
- const routeTitle = router.currentRoute.value.meta?.title;
- const pageTitle =
- (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name;
- useTitle(pageTitle);
- }
- });
-
- app.mount('#app');
-}
-
-export { bootstrap };
diff --git a/apps/web-ele/src/layouts/auth.vue b/apps/web-ele/src/layouts/auth.vue
deleted file mode 100644
index 18d415bc..00000000
--- a/apps/web-ele/src/layouts/auth.vue
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/apps/web-ele/src/layouts/basic.vue b/apps/web-ele/src/layouts/basic.vue
deleted file mode 100644
index 51412956..00000000
--- a/apps/web-ele/src/layouts/basic.vue
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/web-ele/src/layouts/index.ts b/apps/web-ele/src/layouts/index.ts
deleted file mode 100644
index a4320780..00000000
--- a/apps/web-ele/src/layouts/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-const BasicLayout = () => import('./basic.vue');
-const AuthPageLayout = () => import('./auth.vue');
-
-const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
-
-export { AuthPageLayout, BasicLayout, IFrameView };
diff --git a/apps/web-ele/src/locales/README.md b/apps/web-ele/src/locales/README.md
deleted file mode 100644
index 7b451032..00000000
--- a/apps/web-ele/src/locales/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# locale
-
-每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。
diff --git a/apps/web-ele/src/locales/index.ts b/apps/web-ele/src/locales/index.ts
deleted file mode 100644
index 1f3e22c9..00000000
--- a/apps/web-ele/src/locales/index.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
-import type { Language } from 'element-plus/es/locale';
-
-import type { App } from 'vue';
-import { ref } from 'vue';
-
-import {
- $t,
- setupI18n as coreSetup,
- loadLocalesMapFromDir,
-} from '@vben/locales';
-import { preferences } from '@vben/preferences';
-
-import dayjs from 'dayjs';
-import enLocale from 'element-plus/es/locale/lang/en';
-import defaultLocale from 'element-plus/es/locale/lang/zh-cn';
-
-const elementLocale = ref(defaultLocale);
-
-const modules = import.meta.glob('./langs/**/*.json');
-
-const localesMap = loadLocalesMapFromDir(
- /\.\/langs\/([^/]+)\/(.*)\.json$/,
- modules,
-);
-/**
- * 加载应用特有的语言包
- * 这里也可以改造为从服务端获取翻译数据
- * @param lang
- */
-async function loadMessages(lang: SupportedLanguagesType) {
- const [appLocaleMessages] = await Promise.all([
- localesMap[lang]?.(),
- loadThirdPartyMessage(lang),
- ]);
- return appLocaleMessages?.default;
-}
-
-/**
- * 加载第三方组件库的语言包
- * @param lang
- */
-async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
- await Promise.all([loadElementLocale(lang), loadDayjsLocale(lang)]);
-}
-
-/**
- * 加载dayjs的语言包
- * @param lang
- */
-async function loadDayjsLocale(lang: SupportedLanguagesType) {
- let locale;
- switch (lang) {
- case 'en-US': {
- locale = await import('dayjs/locale/en');
- break;
- }
- case 'zh-CN': {
- locale = await import('dayjs/locale/zh-cn');
- break;
- }
- // 默认使用英语
- default: {
- locale = await import('dayjs/locale/en');
- }
- }
- if (locale) {
- dayjs.locale(locale);
- } else {
- console.error(`Failed to load dayjs locale for ${lang}`);
- }
-}
-
-/**
- * 加载element-plus的语言包
- * @param lang
- */
-async function loadElementLocale(lang: SupportedLanguagesType) {
- switch (lang) {
- case 'en-US': {
- elementLocale.value = enLocale;
- break;
- }
- case 'zh-CN': {
- elementLocale.value = defaultLocale;
- break;
- }
- }
-}
-
-async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
- await coreSetup(app, {
- defaultLocale: preferences.app.locale,
- loadMessages,
- missingWarn: !import.meta.env.PROD,
- ...options,
- });
-}
-
-export { $t, elementLocale, setupI18n };
diff --git a/apps/web-ele/src/locales/langs/en-US/demos.json b/apps/web-ele/src/locales/langs/en-US/demos.json
deleted file mode 100644
index 6eddebb5..00000000
--- a/apps/web-ele/src/locales/langs/en-US/demos.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "title": "Demos",
- "elementPlus": "Element Plus",
- "form": "Form",
- "vben": {
- "title": "Project",
- "about": "About",
- "document": "Document",
- "antdv": "Ant Design Vue Version",
- "naive-ui": "Naive UI Version",
- "element-plus": "Element Plus Version"
- }
-}
diff --git a/apps/web-ele/src/locales/langs/en-US/page.json b/apps/web-ele/src/locales/langs/en-US/page.json
deleted file mode 100644
index 618a258c..00000000
--- a/apps/web-ele/src/locales/langs/en-US/page.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "auth": {
- "login": "Login",
- "register": "Register",
- "codeLogin": "Code Login",
- "qrcodeLogin": "Qr Code Login",
- "forgetPassword": "Forget Password"
- },
- "dashboard": {
- "title": "Dashboard",
- "analytics": "Analytics",
- "workspace": "Workspace"
- }
-}
diff --git a/apps/web-ele/src/locales/langs/zh-CN/demos.json b/apps/web-ele/src/locales/langs/zh-CN/demos.json
deleted file mode 100644
index ba6d6ccd..00000000
--- a/apps/web-ele/src/locales/langs/zh-CN/demos.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "title": "演示",
- "elementPlus": "Element Plus",
- "form": "表单演示",
- "vben": {
- "title": "项目",
- "about": "关于",
- "document": "文档",
- "antdv": "Ant Design Vue 版本",
- "naive-ui": "Naive UI 版本",
- "element-plus": "Element Plus 版本"
- }
-}
diff --git a/apps/web-ele/src/locales/langs/zh-CN/page.json b/apps/web-ele/src/locales/langs/zh-CN/page.json
deleted file mode 100644
index 4cb67081..00000000
--- a/apps/web-ele/src/locales/langs/zh-CN/page.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "auth": {
- "login": "登录",
- "register": "注册",
- "codeLogin": "验证码登录",
- "qrcodeLogin": "二维码登录",
- "forgetPassword": "忘记密码"
- },
- "dashboard": {
- "title": "概览",
- "analytics": "分析页",
- "workspace": "工作台"
- }
-}
diff --git a/apps/web-ele/src/main.ts b/apps/web-ele/src/main.ts
deleted file mode 100644
index 5d728a02..00000000
--- a/apps/web-ele/src/main.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { initPreferences } from '@vben/preferences';
-import { unmountGlobalLoading } from '@vben/utils';
-
-import { overridesPreferences } from './preferences';
-
-/**
- * 应用初始化完成之后再进行页面加载渲染
- */
-async function initApplication() {
- // name用于指定项目唯一标识
- // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据
- const env = import.meta.env.PROD ? 'prod' : 'dev';
- const appVersion = import.meta.env.VITE_APP_VERSION;
- const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;
-
- // app偏好设置初始化
- await initPreferences({
- namespace,
- overrides: overridesPreferences,
- });
-
- // 启动应用并挂载
- // vue应用主要逻辑及视图
- const { bootstrap } = await import('./bootstrap');
- await bootstrap(namespace);
-
- // 移除并销毁loading
- unmountGlobalLoading();
-}
-
-initApplication();
diff --git a/apps/web-ele/src/preferences.ts b/apps/web-ele/src/preferences.ts
deleted file mode 100644
index b2e9ace4..00000000
--- a/apps/web-ele/src/preferences.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { defineOverridesPreferences } from '@vben/preferences';
-
-/**
- * @description 项目配置文件
- * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置
- * !!! 更改配置后请清空缓存,否则可能不生效
- */
-export const overridesPreferences = defineOverridesPreferences({
- // overrides
- app: {
- name: import.meta.env.VITE_APP_TITLE,
- },
-});
diff --git a/apps/web-ele/src/router/access.ts b/apps/web-ele/src/router/access.ts
deleted file mode 100644
index 2d07c892..00000000
--- a/apps/web-ele/src/router/access.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import type {
- ComponentRecordType,
- GenerateMenuAndRoutesOptions,
-} from '@vben/types';
-
-import { generateAccessible } from '@vben/access';
-import { preferences } from '@vben/preferences';
-
-import { ElMessage } from 'element-plus';
-
-import { getAllMenusApi } from '#/api';
-import { BasicLayout, IFrameView } from '#/layouts';
-import { $t } from '#/locales';
-
-const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
-
-async function generateAccess(options: GenerateMenuAndRoutesOptions) {
- const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
-
- const layoutMap: ComponentRecordType = {
- BasicLayout,
- IFrameView,
- };
-
- return await generateAccessible(preferences.app.accessMode, {
- ...options,
- fetchMenuListAsync: async () => {
- ElMessage({
- duration: 1500,
- message: `${$t('common.loadingMenu')}...`,
- });
- return await getAllMenusApi();
- },
- // 可以指定没有权限跳转403页面
- forbiddenComponent,
- // 如果 route.meta.menuVisibleWithForbidden = true
- layoutMap,
- pageMap,
- });
-}
-
-export { generateAccess };
diff --git a/apps/web-ele/src/router/guard.ts b/apps/web-ele/src/router/guard.ts
deleted file mode 100644
index fce5a892..00000000
--- a/apps/web-ele/src/router/guard.ts
+++ /dev/null
@@ -1,125 +0,0 @@
-import type { Router } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-import { preferences } from '@vben/preferences';
-import { useAccessStore, useUserStore } from '@vben/stores';
-import { startProgress, stopProgress } from '@vben/utils';
-
-import { accessRoutes, coreRouteNames } from '#/router/routes';
-import { useAuthStore } from '#/store';
-
-import { generateAccess } from './access';
-
-/**
- * 通用守卫配置
- * @param router
- */
-function setupCommonGuard(router: Router) {
- // 记录已经加载的页面
- const loadedPaths = new Set();
-
- router.beforeEach(async (to) => {
- to.meta.loaded = loadedPaths.has(to.path);
-
- // 页面加载进度条
- if (!to.meta.loaded && preferences.transition.progress) {
- startProgress();
- }
- return true;
- });
-
- router.afterEach((to) => {
- // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
-
- loadedPaths.add(to.path);
-
- // 关闭页面加载进度条
- if (preferences.transition.progress) {
- stopProgress();
- }
- });
-}
-
-/**
- * 权限访问守卫配置
- * @param router
- */
-function setupAccessGuard(router: Router) {
- router.beforeEach(async (to, from) => {
- const accessStore = useAccessStore();
- const userStore = useUserStore();
- const authStore = useAuthStore();
-
- // 基本路由,这些路由不需要进入权限拦截
- if (coreRouteNames.includes(to.name as string)) {
- if (to.path === LOGIN_PATH && accessStore.accessToken) {
- return decodeURIComponent(
- (to.query?.redirect as string) || DEFAULT_HOME_PATH,
- );
- }
- return true;
- }
-
- // accessToken 检查
- if (!accessStore.accessToken) {
- // 明确声明忽略权限访问权限,则可以访问
- if (to.meta.ignoreAccess) {
- return true;
- }
-
- // 没有访问权限,跳转登录页面
- if (to.fullPath !== LOGIN_PATH) {
- return {
- path: LOGIN_PATH,
- // 如不需要,直接删除 query
- query: { redirect: encodeURIComponent(to.fullPath) },
- // 携带当前跳转的页面,登录后重新跳转该页面
- replace: true,
- };
- }
- return to;
- }
-
- // 是否已经生成过动态路由
- if (accessStore.isAccessChecked) {
- return true;
- }
-
- // 生成路由表
- // 当前登录用户拥有的角色标识列表
- const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
- const userRoles = userInfo.roles ?? [];
-
- // 生成菜单和路由
- const { accessibleMenus, accessibleRoutes } = await generateAccess({
- roles: userRoles,
- router,
- // 则会在菜单中显示,但是访问会被重定向到403
- routes: accessRoutes,
- });
-
- // 保存菜单信息和路由信息
- accessStore.setAccessMenus(accessibleMenus);
- accessStore.setAccessRoutes(accessibleRoutes);
- accessStore.setIsAccessChecked(true);
- const redirectPath = (from.query.redirect ?? to.fullPath) as string;
-
- return {
- ...router.resolve(decodeURIComponent(redirectPath)),
- replace: true,
- };
- });
-}
-
-/**
- * 项目守卫配置
- * @param router
- */
-function createRouterGuard(router: Router) {
- /** 通用 */
- setupCommonGuard(router);
- /** 权限访问 */
- setupAccessGuard(router);
-}
-
-export { createRouterGuard };
diff --git a/apps/web-ele/src/router/index.ts b/apps/web-ele/src/router/index.ts
deleted file mode 100644
index 48402303..00000000
--- a/apps/web-ele/src/router/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
- createRouter,
- createWebHashHistory,
- createWebHistory,
-} from 'vue-router';
-
-import { resetStaticRoutes } from '@vben/utils';
-
-import { createRouterGuard } from './guard';
-import { routes } from './routes';
-
-/**
- * @zh_CN 创建vue-router实例
- */
-const router = createRouter({
- history:
- import.meta.env.VITE_ROUTER_HISTORY === 'hash'
- ? createWebHashHistory(import.meta.env.VITE_BASE)
- : createWebHistory(import.meta.env.VITE_BASE),
- // 应该添加到路由的初始路由列表。
- routes,
- scrollBehavior: (to, _from, savedPosition) => {
- if (savedPosition) {
- return savedPosition;
- }
- return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 };
- },
- // 是否应该禁止尾部斜杠。
- // strict: true,
-});
-
-const resetRoutes = () => resetStaticRoutes(router, routes);
-
-// 创建路由守卫
-createRouterGuard(router);
-
-export { resetRoutes, router };
diff --git a/apps/web-ele/src/router/routes/core.ts b/apps/web-ele/src/router/routes/core.ts
deleted file mode 100644
index fe030a9a..00000000
--- a/apps/web-ele/src/router/routes/core.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-
-import { AuthPageLayout } from '#/layouts';
-import { $t } from '#/locales';
-import Login from '#/views/_core/authentication/login.vue';
-
-/** 全局404页面 */
-const fallbackNotFoundRoute: RouteRecordRaw = {
- component: () => import('#/views/_core/fallback/not-found.vue'),
- meta: {
- hideInBreadcrumb: true,
- hideInMenu: true,
- hideInTab: true,
- title: '404',
- },
- name: 'FallbackNotFound',
- path: '/:path(.*)*',
-};
-
-/** 基本路由,这些路由是必须存在的 */
-const coreRoutes: RouteRecordRaw[] = [
- {
- meta: {
- title: 'Root',
- },
- name: 'Root',
- path: '/',
- redirect: DEFAULT_HOME_PATH,
- },
- {
- component: AuthPageLayout,
- meta: {
- hideInTab: true,
- title: 'Authentication',
- },
- name: 'Authentication',
- path: '/auth',
- redirect: LOGIN_PATH,
- children: [
- {
- name: 'Login',
- path: 'login',
- component: Login,
- meta: {
- title: $t('page.auth.login'),
- },
- },
- {
- name: 'CodeLogin',
- path: 'code-login',
- component: () => import('#/views/_core/authentication/code-login.vue'),
- meta: {
- title: $t('page.auth.codeLogin'),
- },
- },
- {
- name: 'QrCodeLogin',
- path: 'qrcode-login',
- component: () =>
- import('#/views/_core/authentication/qrcode-login.vue'),
- meta: {
- title: $t('page.auth.qrcodeLogin'),
- },
- },
- {
- name: 'ForgetPassword',
- path: 'forget-password',
- component: () =>
- import('#/views/_core/authentication/forget-password.vue'),
- meta: {
- title: $t('page.auth.forgetPassword'),
- },
- },
- {
- name: 'Register',
- path: 'register',
- component: () => import('#/views/_core/authentication/register.vue'),
- meta: {
- title: $t('page.auth.register'),
- },
- },
- ],
- },
-];
-
-export { coreRoutes, fallbackNotFoundRoute };
diff --git a/apps/web-ele/src/router/routes/index.ts b/apps/web-ele/src/router/routes/index.ts
deleted file mode 100644
index e6fb1440..00000000
--- a/apps/web-ele/src/router/routes/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { mergeRouteModules, traverseTreeValues } from '@vben/utils';
-
-import { coreRoutes, fallbackNotFoundRoute } from './core';
-
-const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', {
- eager: true,
-});
-
-// 有需要可以自行打开注释,并创建文件夹
-// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true });
-// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true });
-
-/** 动态路由 */
-const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles);
-
-/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */
-// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles);
-// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles);
-const staticRoutes: RouteRecordRaw[] = [];
-const externalRoutes: RouteRecordRaw[] = [];
-
-/** 路由列表,由基本路由、外部路由和404兜底路由组成
- * 无需走权限验证(会一直显示在菜单中) */
-const routes: RouteRecordRaw[] = [
- ...coreRoutes,
- ...externalRoutes,
- fallbackNotFoundRoute,
-];
-
-/** 基本路由列表,这些路由不需要进入权限拦截 */
-const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);
-
-/** 有权限校验的路由列表,包含动态路由和静态路由 */
-const accessRoutes = [...dynamicRoutes, ...staticRoutes];
-export { accessRoutes, coreRouteNames, routes };
diff --git a/apps/web-ele/src/router/routes/modules/dashboard.ts b/apps/web-ele/src/router/routes/modules/dashboard.ts
deleted file mode 100644
index 1bddab9d..00000000
--- a/apps/web-ele/src/router/routes/modules/dashboard.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { BasicLayout } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- icon: 'lucide:layout-dashboard',
- order: -1,
- title: $t('page.dashboard.title'),
- },
- name: 'Dashboard',
- path: '/',
- children: [
- {
- name: 'Analytics',
- path: '/analytics',
- component: () => import('#/views/dashboard/analytics/index.vue'),
- meta: {
- affixTab: true,
- icon: 'lucide:area-chart',
- title: $t('page.dashboard.analytics'),
- },
- },
- {
- name: 'Workspace',
- path: '/workspace',
- component: () => import('#/views/dashboard/workspace/index.vue'),
- meta: {
- icon: 'carbon:workspace',
- title: $t('page.dashboard.workspace'),
- },
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-ele/src/router/routes/modules/demos.ts b/apps/web-ele/src/router/routes/modules/demos.ts
deleted file mode 100644
index 90cc2f11..00000000
--- a/apps/web-ele/src/router/routes/modules/demos.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { BasicLayout } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- icon: 'ic:baseline-view-in-ar',
- keepAlive: true,
- order: 1000,
- title: $t('demos.title'),
- },
- name: 'Demos',
- path: '/demos',
- children: [
- {
- meta: {
- title: $t('demos.elementPlus'),
- },
- name: 'NaiveDemos',
- path: '/demos/element',
- component: () => import('#/views/demos/element/index.vue'),
- },
- {
- meta: {
- title: $t('demos.form'),
- },
- name: 'BasicForm',
- path: '/demos/form',
- component: () => import('#/views/demos/form/basic.vue'),
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-ele/src/router/routes/modules/vben.ts b/apps/web-ele/src/router/routes/modules/vben.ts
deleted file mode 100644
index 2cfef549..00000000
--- a/apps/web-ele/src/router/routes/modules/vben.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import {
- VBEN_ANT_PREVIEW_URL,
- VBEN_DOC_URL,
- VBEN_GITHUB_URL,
- VBEN_LOGO_URL,
- VBEN_NAIVE_PREVIEW_URL,
-} from '@vben/constants';
-import { SvgAntdvLogoIcon } from '@vben/icons';
-
-import { BasicLayout, IFrameView } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- badgeType: 'dot',
- icon: VBEN_LOGO_URL,
- order: 9999,
- title: $t('demos.vben.title'),
- },
- name: 'VbenProject',
- path: '/vben-admin',
- children: [
- {
- name: 'VbenAbout',
- path: '/vben-admin/about',
- component: () => import('#/views/_core/about/index.vue'),
- meta: {
- icon: 'lucide:copyright',
- title: $t('demos.vben.about'),
- },
- },
- {
- name: 'VbenDocument',
- path: '/vben-admin/document',
- component: IFrameView,
- meta: {
- icon: 'lucide:book-open-text',
- link: VBEN_DOC_URL,
- title: $t('demos.vben.document'),
- },
- },
- {
- name: 'VbenGithub',
- path: '/vben-admin/github',
- component: IFrameView,
- meta: {
- icon: 'mdi:github',
- link: VBEN_GITHUB_URL,
- title: 'Github',
- },
- },
- {
- name: 'VbenNaive',
- path: '/vben-admin/naive',
- component: IFrameView,
- meta: {
- badgeType: 'dot',
- icon: 'logos:naiveui',
- link: VBEN_NAIVE_PREVIEW_URL,
- title: $t('demos.vben.naive-ui'),
- },
- },
- {
- name: 'VbenAntd',
- path: '/vben-admin/antd',
- component: IFrameView,
- meta: {
- badgeType: 'dot',
- icon: SvgAntdvLogoIcon,
- link: VBEN_ANT_PREVIEW_URL,
- title: $t('demos.vben.antdv'),
- },
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-ele/src/store/auth.ts b/apps/web-ele/src/store/auth.ts
deleted file mode 100644
index 639fb037..00000000
--- a/apps/web-ele/src/store/auth.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import type { Recordable, UserInfo } from '@vben/types';
-
-import { ref } from 'vue';
-import { useRouter } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
-
-import { ElNotification } from 'element-plus';
-import { defineStore } from 'pinia';
-
-import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
-import { $t } from '#/locales';
-
-export const useAuthStore = defineStore('auth', () => {
- const accessStore = useAccessStore();
- const userStore = useUserStore();
- const router = useRouter();
-
- const loginLoading = ref(false);
-
- /**
- * 异步处理登录操作
- * Asynchronously handle the login process
- * @param params 登录表单数据
- */
- async function authLogin(
- params: Recordable,
- onSuccess?: () => Promise | void,
- ) {
- // 异步处理用户登录操作并获取 accessToken
- let userInfo: null | UserInfo = null;
- try {
- loginLoading.value = true;
- const { accessToken } = await loginApi(params);
-
- // 如果成功获取到 accessToken
- if (accessToken) {
- // 将 accessToken 存储到 accessStore 中
- accessStore.setAccessToken(accessToken);
-
- // 获取用户信息并存储到 accessStore 中
- const [fetchUserInfoResult, accessCodes] = await Promise.all([
- fetchUserInfo(),
- getAccessCodesApi(),
- ]);
-
- userInfo = fetchUserInfoResult;
-
- userStore.setUserInfo(userInfo);
- accessStore.setAccessCodes(accessCodes);
-
- if (accessStore.loginExpired) {
- accessStore.setLoginExpired(false);
- } else {
- onSuccess
- ? await onSuccess?.()
- : await router.push(userInfo.homePath || DEFAULT_HOME_PATH);
- }
-
- if (userInfo?.realName) {
- ElNotification({
- message: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
- title: $t('authentication.loginSuccess'),
- type: 'success',
- });
- }
- }
- } finally {
- loginLoading.value = false;
- }
-
- return {
- userInfo,
- };
- }
-
- async function logout(redirect: boolean = true) {
- try {
- await logoutApi();
- } catch {
- // 不做任何处理
- }
- resetAllStores();
- accessStore.setLoginExpired(false);
-
- // 回登录页带上当前路由地址
- await router.replace({
- path: LOGIN_PATH,
- query: redirect
- ? {
- redirect: encodeURIComponent(router.currentRoute.value.fullPath),
- }
- : {},
- });
- }
-
- async function fetchUserInfo() {
- let userInfo: null | UserInfo = null;
- userInfo = await getUserInfoApi();
- userStore.setUserInfo(userInfo);
- return userInfo;
- }
-
- function $reset() {
- loginLoading.value = false;
- }
-
- return {
- $reset,
- authLogin,
- fetchUserInfo,
- loginLoading,
- logout,
- };
-});
diff --git a/apps/web-ele/src/store/index.ts b/apps/web-ele/src/store/index.ts
deleted file mode 100644
index 269586ee..00000000
--- a/apps/web-ele/src/store/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './auth';
diff --git a/apps/web-ele/src/views/_core/README.md b/apps/web-ele/src/views/_core/README.md
deleted file mode 100644
index 8248afe6..00000000
--- a/apps/web-ele/src/views/_core/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# \_core
-
-此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。
diff --git a/apps/web-ele/src/views/_core/about/index.vue b/apps/web-ele/src/views/_core/about/index.vue
deleted file mode 100644
index 0ee52433..00000000
--- a/apps/web-ele/src/views/_core/about/index.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/authentication/code-login.vue b/apps/web-ele/src/views/_core/authentication/code-login.vue
deleted file mode 100644
index 1fc15e14..00000000
--- a/apps/web-ele/src/views/_core/authentication/code-login.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/authentication/forget-password.vue b/apps/web-ele/src/views/_core/authentication/forget-password.vue
deleted file mode 100644
index 0958e89b..00000000
--- a/apps/web-ele/src/views/_core/authentication/forget-password.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/authentication/login.vue b/apps/web-ele/src/views/_core/authentication/login.vue
deleted file mode 100644
index 099e4c8c..00000000
--- a/apps/web-ele/src/views/_core/authentication/login.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/authentication/qrcode-login.vue b/apps/web-ele/src/views/_core/authentication/qrcode-login.vue
deleted file mode 100644
index 23f5f2da..00000000
--- a/apps/web-ele/src/views/_core/authentication/qrcode-login.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/authentication/register.vue b/apps/web-ele/src/views/_core/authentication/register.vue
deleted file mode 100644
index f264c467..00000000
--- a/apps/web-ele/src/views/_core/authentication/register.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/fallback/coming-soon.vue b/apps/web-ele/src/views/_core/fallback/coming-soon.vue
deleted file mode 100644
index f394930f..00000000
--- a/apps/web-ele/src/views/_core/fallback/coming-soon.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/fallback/forbidden.vue b/apps/web-ele/src/views/_core/fallback/forbidden.vue
deleted file mode 100644
index 8ea65fed..00000000
--- a/apps/web-ele/src/views/_core/fallback/forbidden.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/fallback/internal-error.vue b/apps/web-ele/src/views/_core/fallback/internal-error.vue
deleted file mode 100644
index 819a47d5..00000000
--- a/apps/web-ele/src/views/_core/fallback/internal-error.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/fallback/not-found.vue b/apps/web-ele/src/views/_core/fallback/not-found.vue
deleted file mode 100644
index 4d178e9c..00000000
--- a/apps/web-ele/src/views/_core/fallback/not-found.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/_core/fallback/offline.vue b/apps/web-ele/src/views/_core/fallback/offline.vue
deleted file mode 100644
index 5de4a88d..00000000
--- a/apps/web-ele/src/views/_core/fallback/offline.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue
deleted file mode 100644
index fadfc917..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue
deleted file mode 100644
index 30c4265d..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue
deleted file mode 100644
index 260520b8..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue
deleted file mode 100644
index e0d0aab5..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue
deleted file mode 100644
index 7e1f14ee..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/analytics/index.vue b/apps/web-ele/src/views/dashboard/analytics/index.vue
deleted file mode 100644
index 00b34df1..00000000
--- a/apps/web-ele/src/views/dashboard/analytics/index.vue
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-ele/src/views/dashboard/workspace/index.vue b/apps/web-ele/src/views/dashboard/workspace/index.vue
deleted file mode 100644
index b95d6138..00000000
--- a/apps/web-ele/src/views/dashboard/workspace/index.vue
+++ /dev/null
@@ -1,266 +0,0 @@
-
-
-
-
-
-
- 早安, {{ userStore.userInfo?.realName }}, 开始您一天的工作吧!
-
- 今日晴,20℃ - 32℃!
-
-
-
-
-
diff --git a/apps/web-ele/src/views/demos/element/index.vue b/apps/web-ele/src/views/demos/element/index.vue
deleted file mode 100644
index 0a7012d6..00000000
--- a/apps/web-ele/src/views/demos/element/index.vue
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
-
-
-
-
- 按钮
-
- Text
- Default
- Primary
- Info
- Success
- Warning
- Error
-
-
-
- Message
-
- 信息
- 错误
- 警告
- 成功
-
-
-
- Notification
-
- 信息
- 错误
- 警告
- 成功
-
-
-
- Segmented
-
-
-
- V-Loading
-
- 一些演示的内容
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/web-ele/src/views/demos/form/basic.vue b/apps/web-ele/src/views/demos/form/basic.vue
deleted file mode 100644
index 90aaccef..00000000
--- a/apps/web-ele/src/views/demos/form/basic.vue
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
-
-
-
- 基础表单演示
- 设置表单值
-
-
-
-
-
-
diff --git a/apps/web-ele/tailwind.config.mjs b/apps/web-ele/tailwind.config.mjs
deleted file mode 100644
index f17f556f..00000000
--- a/apps/web-ele/tailwind.config.mjs
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@vben/tailwind-config';
diff --git a/apps/web-ele/tsconfig.json b/apps/web-ele/tsconfig.json
deleted file mode 100644
index 02c287fe..00000000
--- a/apps/web-ele/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "extends": "@vben/tsconfig/web-app.json",
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "#/*": ["./src/*"]
- }
- },
- "references": [{ "path": "./tsconfig.node.json" }],
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
-}
diff --git a/apps/web-ele/tsconfig.node.json b/apps/web-ele/tsconfig.node.json
deleted file mode 100644
index c2f0d86c..00000000
--- a/apps/web-ele/tsconfig.node.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "extends": "@vben/tsconfig/node.json",
- "compilerOptions": {
- "composite": true,
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
- "noEmit": false
- },
- "include": ["vite.config.mts"]
-}
diff --git a/apps/web-ele/vite.config.mts b/apps/web-ele/vite.config.mts
deleted file mode 100644
index 9f1e7235..00000000
--- a/apps/web-ele/vite.config.mts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { defineConfig } from '@vben/vite-config';
-
-import ElementPlus from 'unplugin-element-plus/vite';
-
-export default defineConfig(async () => {
- return {
- application: {},
- vite: {
- plugins: [
- ElementPlus({
- format: 'esm',
- }),
- ],
- server: {
- proxy: {
- '/api': {
- changeOrigin: true,
- rewrite: (path) => path.replace(/^\/api/, ''),
- // mock代理目标地址
- target: 'http://localhost:5320/api',
- ws: true,
- },
- },
- },
- },
- };
-});
diff --git a/apps/web-naive/.env b/apps/web-naive/.env
deleted file mode 100644
index 350660c0..00000000
--- a/apps/web-naive/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-# 应用标题
-VITE_APP_TITLE=Vben Admin Naive
-
-# 应用命名空间,用于缓存、store等功能的前缀,确保隔离
-VITE_APP_NAMESPACE=vben-web-naive
diff --git a/apps/web-naive/.env.analyze b/apps/web-naive/.env.analyze
deleted file mode 100644
index ffafa8dd..00000000
--- a/apps/web-naive/.env.analyze
+++ /dev/null
@@ -1,7 +0,0 @@
-# public path
-VITE_BASE=/
-
-# Basic interface address SPA
-VITE_GLOB_API_URL=/api
-
-VITE_VISUALIZER=true
diff --git a/apps/web-naive/.env.development b/apps/web-naive/.env.development
deleted file mode 100644
index 11c5254a..00000000
--- a/apps/web-naive/.env.development
+++ /dev/null
@@ -1,16 +0,0 @@
-# 端口号
-VITE_PORT=5888
-
-VITE_BASE=/
-
-# 接口地址
-VITE_GLOB_API_URL=/api
-
-# 是否开启 Nitro Mock服务,true 为开启,false 为关闭
-VITE_NITRO_MOCK=true
-
-# 是否打开 devtools,true 为打开,false 为关闭
-VITE_DEVTOOLS=false
-
-# 是否注入全局loading
-VITE_INJECT_APP_LOADING=true
diff --git a/apps/web-naive/.env.production b/apps/web-naive/.env.production
deleted file mode 100644
index 5375847a..00000000
--- a/apps/web-naive/.env.production
+++ /dev/null
@@ -1,19 +0,0 @@
-VITE_BASE=/
-
-# 接口地址
-VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
-
-# 是否开启压缩,可以设置为 none, brotli, gzip
-VITE_COMPRESS=none
-
-# 是否开启 PWA
-VITE_PWA=false
-
-# vue-router 的模式
-VITE_ROUTER_HISTORY=hash
-
-# 是否注入全局loading
-VITE_INJECT_APP_LOADING=true
-
-# 打包后是否生成dist.zip
-VITE_ARCHIVER=true
diff --git a/apps/web-naive/index.html b/apps/web-naive/index.html
deleted file mode 100644
index 7ea63841..00000000
--- a/apps/web-naive/index.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- <%= VITE_APP_TITLE %>
-
-
-
-
-
-
-
-
diff --git a/apps/web-naive/package.json b/apps/web-naive/package.json
deleted file mode 100644
index 180b5692..00000000
--- a/apps/web-naive/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "@vben/web-naive",
- "version": "5.5.0",
- "homepage": "https://vben.pro",
- "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/vbenjs/vue-vben-admin.git",
- "directory": "apps/web-naive"
- },
- "license": "MIT",
- "author": {
- "name": "vben",
- "email": "ann.vben@gmail.com",
- "url": "https://github.com/anncwb"
- },
- "type": "module",
- "scripts": {
- "build": "pnpm vite build --mode production",
- "build:analyze": "pnpm vite build --mode analyze",
- "dev": "pnpm vite --mode development",
- "preview": "vite preview",
- "typecheck": "vue-tsc --noEmit --skipLibCheck"
- },
- "imports": {
- "#/*": "./src/*"
- },
- "dependencies": {
- "@vben/access": "workspace:*",
- "@vben/common-ui": "workspace:*",
- "@vben/constants": "workspace:*",
- "@vben/hooks": "workspace:*",
- "@vben/icons": "workspace:*",
- "@vben/layouts": "workspace:*",
- "@vben/locales": "workspace:*",
- "@vben/plugins": "workspace:*",
- "@vben/preferences": "workspace:*",
- "@vben/request": "workspace:*",
- "@vben/stores": "workspace:*",
- "@vben/styles": "workspace:*",
- "@vben/types": "workspace:*",
- "@vben/utils": "workspace:*",
- "@vueuse/core": "catalog:",
- "naive-ui": "catalog:",
- "pinia": "catalog:",
- "vue": "catalog:",
- "vue-router": "catalog:"
- }
-}
diff --git a/apps/web-naive/postcss.config.mjs b/apps/web-naive/postcss.config.mjs
deleted file mode 100644
index 3d807045..00000000
--- a/apps/web-naive/postcss.config.mjs
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@vben/tailwind-config/postcss';
diff --git a/apps/web-naive/public/favicon.ico b/apps/web-naive/public/favicon.ico
deleted file mode 100644
index fcf9818e..00000000
Binary files a/apps/web-naive/public/favicon.ico and /dev/null differ
diff --git a/apps/web-naive/src/adapter/component/index.ts b/apps/web-naive/src/adapter/component/index.ts
deleted file mode 100644
index 545a6199..00000000
--- a/apps/web-naive/src/adapter/component/index.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用
- * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
- */
-
-import type { BaseFormComponentType } from '@vben/common-ui';
-
-import type { Component, SetupContext } from 'vue';
-import { h } from 'vue';
-
-import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
-import { $t } from '@vben/locales';
-
-import {
- NButton,
- NCheckbox,
- NCheckboxGroup,
- NDatePicker,
- NDivider,
- NInput,
- NInputNumber,
- NRadio,
- NRadioButton,
- NRadioGroup,
- NSelect,
- NSpace,
- NSwitch,
- NTimePicker,
- NTreeSelect,
- NUpload,
-} from 'naive-ui';
-
-import { message } from '#/adapter/naive';
-
-const withDefaultPlaceholder = (
- component: T,
- type: 'input' | 'select',
-) => {
- return (props: any, { attrs, slots }: Omit) => {
- const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
- return h(component, { ...props, ...attrs, placeholder }, slots);
- };
-};
-
-// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
-export type ComponentType =
- | 'ApiSelect'
- | 'ApiTreeSelect'
- | 'Checkbox'
- | 'CheckboxGroup'
- | 'DatePicker'
- | 'Divider'
- | 'IconPicker'
- | 'Input'
- | 'InputNumber'
- | 'RadioGroup'
- | 'Select'
- | 'Space'
- | 'Switch'
- | 'TimePicker'
- | 'TreeSelect'
- | 'Upload'
- | BaseFormComponentType;
-
-async function initComponentAdapter() {
- const components: Partial> = {
- // 如果你的组件体积比较大,可以使用异步加载
- // Button: () =>
- // import('xxx').then((res) => res.Button),
-
- ApiSelect: (props, { attrs, slots }) => {
- return h(
- ApiComponent,
- {
- placeholder: $t('ui.placeholder.select'),
- ...props,
- ...attrs,
- component: NSelect,
- modelPropName: 'value',
- },
- slots,
- );
- },
- ApiTreeSelect: (props, { attrs, slots }) => {
- return h(
- ApiComponent,
- {
- placeholder: $t('ui.placeholder.select'),
- ...props,
- ...attrs,
- component: NTreeSelect,
- nodeKey: 'value',
- loadingSlot: 'arrow',
- keyField: 'value',
- modelPropName: 'value',
- optionsPropName: 'options',
- visibleEvent: 'onVisibleChange',
- },
- slots,
- );
- },
- Checkbox: NCheckbox,
- CheckboxGroup: (props, { attrs, slots }) => {
- let defaultSlot;
- if (Reflect.has(slots, 'default')) {
- defaultSlot = slots.default;
- } else {
- const { options } = attrs;
- if (Array.isArray(options)) {
- defaultSlot = () => options.map((option) => h(NCheckbox, option));
- }
- }
- return h(
- NCheckboxGroup,
- { ...props, ...attrs },
- { default: defaultSlot },
- );
- },
- DatePicker: NDatePicker,
- // 自定义默认按钮
- DefaultButton: (props, { attrs, slots }) => {
- return h(NButton, { ...props, attrs, type: 'default' }, slots);
- },
- // 自定义主要按钮
- PrimaryButton: (props, { attrs, slots }) => {
- return h(NButton, { ...props, attrs, type: 'primary' }, slots);
- },
- Divider: NDivider,
- IconPicker: (props, { attrs, slots }) => {
- return h(
- IconPicker,
- { iconSlot: 'suffix', inputComponent: NInput, ...props, ...attrs },
- slots,
- );
- },
- Input: withDefaultPlaceholder(NInput, 'input'),
- InputNumber: withDefaultPlaceholder(NInputNumber, 'input'),
- RadioGroup: (props, { attrs, slots }) => {
- let defaultSlot;
- if (Reflect.has(slots, 'default')) {
- defaultSlot = slots.default;
- } else {
- const { options } = attrs;
- if (Array.isArray(options)) {
- defaultSlot = () =>
- options.map((option) =>
- h(attrs.isButton ? NRadioButton : NRadio, option),
- );
- }
- }
- const groupRender = h(
- NRadioGroup,
- { ...props, ...attrs },
- { default: defaultSlot },
- );
- return attrs.isButton
- ? h(NSpace, { vertical: true }, () => groupRender)
- : groupRender;
- },
- Select: withDefaultPlaceholder(NSelect, 'select'),
- Space: NSpace,
- Switch: NSwitch,
- TimePicker: NTimePicker,
- TreeSelect: withDefaultPlaceholder(NTreeSelect, 'select'),
- Upload: NUpload,
- };
-
- // 将组件注册到全局共享状态中
- globalShareState.setComponents(components);
-
- // 定义全局共享状态中的消息提示
- globalShareState.defineMessage({
- // 复制成功消息提示
- copyPreferencesSuccess: (title, content) => {
- message.success(content || title, {
- duration: 0,
- });
- },
- });
-}
-
-export { initComponentAdapter };
diff --git a/apps/web-naive/src/adapter/form.ts b/apps/web-naive/src/adapter/form.ts
deleted file mode 100644
index 2c3cee87..00000000
--- a/apps/web-naive/src/adapter/form.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import type {
- VbenFormSchema as FormSchema,
- VbenFormProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
-import { $t } from '@vben/locales';
-
-setupVbenForm({
- config: {
- // naive-ui组件不接受onChang事件,所以需要禁用
- disabledOnChangeListener: true,
- // naive-ui组件的空值为null,不能是undefined,否则重置表单时不生效
- emptyStateValue: null,
- baseModelPropName: 'value',
- modelPropNameMap: {
- Checkbox: 'checked',
- Radio: 'checked',
- Upload: 'fileList',
- },
- },
- defineRules: {
- required: (value, _params, ctx) => {
- if (value === undefined || value === null || value.length === 0) {
- return $t('ui.formRules.required', [ctx.label]);
- }
- return true;
- },
- selectRequired: (value, _params, ctx) => {
- if (value === undefined || value === null) {
- return $t('ui.formRules.selectRequired', [ctx.label]);
- }
- return true;
- },
- },
-});
-
-const useVbenForm = useForm;
-
-export { useVbenForm, z };
-
-export type VbenFormSchema = FormSchema;
-export type { VbenFormProps };
diff --git a/apps/web-naive/src/adapter/naive.ts b/apps/web-naive/src/adapter/naive.ts
deleted file mode 100644
index 1eb7b7b6..00000000
--- a/apps/web-naive/src/adapter/naive.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { computed } from 'vue';
-
-import { preferences } from '@vben/preferences';
-import '@vben/styles';
-
-import { createDiscreteApi, darkTheme, lightTheme } from 'naive-ui';
-
-const themeOverridesProviderProps = computed(() => ({
- themeOverrides: preferences.theme.mode === 'light' ? lightTheme : darkTheme,
-}));
-
-const themeProviderProps = computed(() => ({
- theme: preferences.theme.mode === 'light' ? lightTheme : darkTheme,
-}));
-
-export const { dialog, loadingBar, message, modal, notification } =
- createDiscreteApi(
- ['message', 'dialog', 'notification', 'loadingBar', 'modal'],
- {
- configProviderProps: themeProviderProps,
- loadingBarProviderProps: themeOverridesProviderProps,
- messageProviderProps: themeOverridesProviderProps,
- notificationProviderProps: themeOverridesProviderProps,
- },
- );
diff --git a/apps/web-naive/src/adapter/vxe-table.ts b/apps/web-naive/src/adapter/vxe-table.ts
deleted file mode 100644
index 081cfb29..00000000
--- a/apps/web-naive/src/adapter/vxe-table.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { h } from 'vue';
-
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
-
-import { NButton, NImage } from 'naive-ui';
-
-import { useVbenForm } from './form';
-
-setupVbenVxeTable({
- configVxeTable: (vxeUI) => {
- vxeUI.setConfig({
- grid: {
- align: 'center',
- border: false,
- columnConfig: {
- resizable: true,
- },
- minHeight: 180,
- formConfig: {
- // 全局禁用vxe-table的表单配置,使用formOptions
- enabled: false,
- },
- proxyConfig: {
- autoLoad: true,
- response: {
- result: 'items',
- total: 'total',
- list: 'items',
- },
- showActiveMsg: true,
- showResponseMsg: false,
- },
- round: true,
- showOverflow: true,
- size: 'small',
- },
- });
-
- // 表格配置项可以用 cellRender: { name: 'CellImage' },
- vxeUI.renderer.add('CellImage', {
- renderTableDefault(_renderOpts, params) {
- const { column, row } = params;
- return h(NImage, { src: row[column.field] });
- },
- });
-
- // 表格配置项可以用 cellRender: { name: 'CellLink' },
- vxeUI.renderer.add('CellLink', {
- renderTableDefault(renderOpts) {
- const { props } = renderOpts;
- return h(
- NButton,
- { size: 'small', type: 'primary', quaternary: true },
- { default: () => props?.text },
- );
- },
- });
-
- // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
- // vxeUI.formats.add
- },
- useVbenForm,
-});
-
-export { useVbenVxeGrid };
-
-export type * from '@vben/plugins/vxe-table';
diff --git a/apps/web-naive/src/api/core/auth.ts b/apps/web-naive/src/api/core/auth.ts
deleted file mode 100644
index 71d9f994..00000000
--- a/apps/web-naive/src/api/core/auth.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { baseRequestClient, requestClient } from '#/api/request';
-
-export namespace AuthApi {
- /** 登录接口参数 */
- export interface LoginParams {
- password?: string;
- username?: string;
- }
-
- /** 登录接口返回值 */
- export interface LoginResult {
- accessToken: string;
- }
-
- export interface RefreshTokenResult {
- data: string;
- status: number;
- }
-}
-
-/**
- * 登录
- */
-export async function loginApi(data: AuthApi.LoginParams) {
- return requestClient.post('/auth/login', data);
-}
-
-/**
- * 刷新accessToken
- */
-export async function refreshTokenApi() {
- return baseRequestClient.post('/auth/refresh', {
- withCredentials: true,
- });
-}
-
-/**
- * 退出登录
- */
-export async function logoutApi() {
- return baseRequestClient.post('/auth/logout', {
- withCredentials: true,
- });
-}
-
-/**
- * 获取用户权限码
- */
-export async function getAccessCodesApi() {
- return requestClient.get('/auth/codes');
-}
diff --git a/apps/web-naive/src/api/core/index.ts b/apps/web-naive/src/api/core/index.ts
deleted file mode 100644
index 28a5aef4..00000000
--- a/apps/web-naive/src/api/core/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './auth';
-export * from './menu';
-export * from './user';
diff --git a/apps/web-naive/src/api/core/menu.ts b/apps/web-naive/src/api/core/menu.ts
deleted file mode 100644
index 9ef60b11..00000000
--- a/apps/web-naive/src/api/core/menu.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { RouteRecordStringComponent } from '@vben/types';
-
-import { requestClient } from '#/api/request';
-
-/**
- * 获取用户所有菜单
- */
-export async function getAllMenusApi() {
- return requestClient.get('/menu/all');
-}
diff --git a/apps/web-naive/src/api/core/user.ts b/apps/web-naive/src/api/core/user.ts
deleted file mode 100644
index 7e28ea84..00000000
--- a/apps/web-naive/src/api/core/user.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { UserInfo } from '@vben/types';
-
-import { requestClient } from '#/api/request';
-
-/**
- * 获取用户信息
- */
-export async function getUserInfoApi() {
- return requestClient.get('/user/info');
-}
diff --git a/apps/web-naive/src/api/index.ts b/apps/web-naive/src/api/index.ts
deleted file mode 100644
index 4b0e0413..00000000
--- a/apps/web-naive/src/api/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './core';
diff --git a/apps/web-naive/src/api/request.ts b/apps/web-naive/src/api/request.ts
deleted file mode 100644
index 72056e19..00000000
--- a/apps/web-naive/src/api/request.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * 该文件可自行根据业务逻辑进行调整
- */
-import type { HttpResponse } from '@vben/request';
-
-import { useAppConfig } from '@vben/hooks';
-import { preferences } from '@vben/preferences';
-import {
- authenticateResponseInterceptor,
- errorMessageResponseInterceptor,
- RequestClient,
-} from '@vben/request';
-import { useAccessStore } from '@vben/stores';
-
-import { message } from '#/adapter/naive';
-import { useAuthStore } from '#/store';
-
-import { refreshTokenApi } from './core';
-
-const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
-
-function createRequestClient(baseURL: string) {
- const client = new RequestClient({
- baseURL,
- });
-
- /**
- * 重新认证逻辑
- */
- async function doReAuthenticate() {
- console.warn('Access token or refresh token is invalid or expired. ');
- const accessStore = useAccessStore();
- const authStore = useAuthStore();
- accessStore.setAccessToken(null);
- if (
- preferences.app.loginExpiredMode === 'modal' &&
- accessStore.isAccessChecked
- ) {
- accessStore.setLoginExpired(true);
- } else {
- await authStore.logout();
- }
- }
-
- /**
- * 刷新token逻辑
- */
- async function doRefreshToken() {
- const accessStore = useAccessStore();
- const resp = await refreshTokenApi();
- const newToken = resp.data;
- accessStore.setAccessToken(newToken);
- return newToken;
- }
-
- function formatToken(token: null | string) {
- return token ? `Bearer ${token}` : null;
- }
-
- // 请求头处理
- client.addRequestInterceptor({
- fulfilled: async (config) => {
- const accessStore = useAccessStore();
-
- config.headers.Authorization = formatToken(accessStore.accessToken);
- config.headers['Accept-Language'] = preferences.app.locale;
- return config;
- },
- });
-
- // response数据解构
- client.addResponseInterceptor({
- fulfilled: (response) => {
- const { data: responseData, status } = response;
-
- const { code, data } = responseData;
- if (status >= 200 && status < 400 && code === 0) {
- return data;
- }
- throw Object.assign({}, response, { response });
- },
- });
-
- // token过期的处理
- client.addResponseInterceptor(
- authenticateResponseInterceptor({
- client,
- doReAuthenticate,
- doRefreshToken,
- enableRefreshToken: preferences.app.enableRefreshToken,
- formatToken,
- }),
- );
-
- // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
- client.addResponseInterceptor(
- errorMessageResponseInterceptor((msg: string, error) => {
- // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
- // 当前mock接口返回的错误字段是 error 或者 message
- const responseData = error?.response?.data ?? {};
- const errorMessage = responseData?.error ?? responseData?.message ?? '';
- // 如果没有错误信息,则会根据状态码进行提示
- message.error(errorMessage || msg);
- }),
- );
-
- return client;
-}
-
-export const requestClient = createRequestClient(apiURL);
-
-export const baseRequestClient = new RequestClient({ baseURL: apiURL });
diff --git a/apps/web-naive/src/app.vue b/apps/web-naive/src/app.vue
deleted file mode 100644
index 23983c55..00000000
--- a/apps/web-naive/src/app.vue
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/web-naive/src/bootstrap.ts b/apps/web-naive/src/bootstrap.ts
deleted file mode 100644
index fc7f961d..00000000
--- a/apps/web-naive/src/bootstrap.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { createApp, watchEffect } from 'vue';
-
-import { registerAccessDirective } from '@vben/access';
-import { preferences } from '@vben/preferences';
-import { initStores } from '@vben/stores';
-import '@vben/styles';
-
-import { useTitle } from '@vueuse/core';
-
-import { $t, setupI18n } from '#/locales';
-
-import { initComponentAdapter } from './adapter/component';
-import App from './app.vue';
-import { router } from './router';
-
-async function bootstrap(namespace: string) {
- // 初始化组件适配器
- initComponentAdapter();
- const app = createApp(App);
-
- // 国际化 i18n 配置
- await setupI18n(app);
-
- // 配置 pinia-tore
- await initStores(app, { namespace });
-
- // 安装权限指令
- registerAccessDirective(app);
-
- // 配置路由及路由守卫
- app.use(router);
-
- // 动态更新标题
- watchEffect(() => {
- if (preferences.app.dynamicTitle) {
- const routeTitle = router.currentRoute.value.meta?.title;
- const pageTitle =
- (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name;
- useTitle(pageTitle);
- }
- });
-
- app.mount('#app');
-}
-
-export { bootstrap };
diff --git a/apps/web-naive/src/layouts/auth.vue b/apps/web-naive/src/layouts/auth.vue
deleted file mode 100644
index 18d415bc..00000000
--- a/apps/web-naive/src/layouts/auth.vue
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/apps/web-naive/src/layouts/basic.vue b/apps/web-naive/src/layouts/basic.vue
deleted file mode 100644
index f75b3ddc..00000000
--- a/apps/web-naive/src/layouts/basic.vue
+++ /dev/null
@@ -1,158 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/web-naive/src/layouts/index.ts b/apps/web-naive/src/layouts/index.ts
deleted file mode 100644
index a4320780..00000000
--- a/apps/web-naive/src/layouts/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-const BasicLayout = () => import('./basic.vue');
-const AuthPageLayout = () => import('./auth.vue');
-
-const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
-
-export { AuthPageLayout, BasicLayout, IFrameView };
diff --git a/apps/web-naive/src/locales/README.md b/apps/web-naive/src/locales/README.md
deleted file mode 100644
index 7b451032..00000000
--- a/apps/web-naive/src/locales/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# locale
-
-每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。
diff --git a/apps/web-naive/src/locales/index.ts b/apps/web-naive/src/locales/index.ts
deleted file mode 100644
index 3d77913a..00000000
--- a/apps/web-naive/src/locales/index.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';
-
-import type { App } from 'vue';
-
-import {
- $t,
- setupI18n as coreSetup,
- loadLocalesMapFromDir,
-} from '@vben/locales';
-import { preferences } from '@vben/preferences';
-
-const modules = import.meta.glob('./langs/**/*.json');
-
-const localesMap = loadLocalesMapFromDir(
- /\.\/langs\/([^/]+)\/(.*)\.json$/,
- modules,
-);
-
-/**
- * 加载应用特有的语言包
- * 这里也可以改造为从服务端获取翻译数据
- * @param lang
- */
-async function loadMessages(lang: SupportedLanguagesType) {
- const appLocaleMessages = await localesMap[lang]?.();
- return appLocaleMessages?.default;
-}
-
-async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
- await coreSetup(app, {
- defaultLocale: preferences.app.locale,
- loadMessages,
- missingWarn: !import.meta.env.PROD,
- ...options,
- });
-}
-
-export { $t, setupI18n };
diff --git a/apps/web-naive/src/locales/langs/en-US/demos.json b/apps/web-naive/src/locales/langs/en-US/demos.json
deleted file mode 100644
index 839fc2e6..00000000
--- a/apps/web-naive/src/locales/langs/en-US/demos.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "title": "Demos",
- "naive": "Naive UI",
- "table": "Table",
- "form": "Form",
- "vben": {
- "title": "Project",
- "about": "About",
- "document": "Document",
- "antdv": "Ant Design Vue Version",
- "naive-ui": "Naive UI Version",
- "element-plus": "Element Plus Version"
- }
-}
diff --git a/apps/web-naive/src/locales/langs/en-US/page.json b/apps/web-naive/src/locales/langs/en-US/page.json
deleted file mode 100644
index f021341a..00000000
--- a/apps/web-naive/src/locales/langs/en-US/page.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "auth": {
- "login": "Login",
- "register": "Register",
- "codeLogin": "Code Login",
- "qrcodeLogin": "Qr Code Login",
- "forgetPassword": "Forget Password",
- "oauthLogin": "OAuth Login"
- },
- "dashboard": {
- "title": "Dashboard",
- "analytics": "Analytics",
- "workspace": "Workspace"
- }
-}
diff --git a/apps/web-naive/src/locales/langs/zh-CN/demos.json b/apps/web-naive/src/locales/langs/zh-CN/demos.json
deleted file mode 100644
index e0d7e616..00000000
--- a/apps/web-naive/src/locales/langs/zh-CN/demos.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "title": "演示",
- "naive": "Naive UI",
- "table": "Table",
- "form": "表单",
- "vben": {
- "title": "项目",
- "about": "关于",
- "document": "文档",
- "antdv": "Ant Design Vue 版本",
- "naive-ui": "Naive UI 版本",
- "element-plus": "Element Plus 版本"
- }
-}
diff --git a/apps/web-naive/src/locales/langs/zh-CN/page.json b/apps/web-naive/src/locales/langs/zh-CN/page.json
deleted file mode 100644
index 6fa681ee..00000000
--- a/apps/web-naive/src/locales/langs/zh-CN/page.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "auth": {
- "login": "登录",
- "register": "注册",
- "codeLogin": "验证码登陆",
- "qrcodeLogin": "二维码登陆",
- "forgetPassword": "忘记密码",
- "oauthLogin": "第三方登录"
- },
- "dashboard": {
- "title": "概览",
- "analytics": "分析页",
- "workspace": "工作台"
- }
-}
diff --git a/apps/web-naive/src/main.ts b/apps/web-naive/src/main.ts
deleted file mode 100644
index 5d728a02..00000000
--- a/apps/web-naive/src/main.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { initPreferences } from '@vben/preferences';
-import { unmountGlobalLoading } from '@vben/utils';
-
-import { overridesPreferences } from './preferences';
-
-/**
- * 应用初始化完成之后再进行页面加载渲染
- */
-async function initApplication() {
- // name用于指定项目唯一标识
- // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据
- const env = import.meta.env.PROD ? 'prod' : 'dev';
- const appVersion = import.meta.env.VITE_APP_VERSION;
- const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;
-
- // app偏好设置初始化
- await initPreferences({
- namespace,
- overrides: overridesPreferences,
- });
-
- // 启动应用并挂载
- // vue应用主要逻辑及视图
- const { bootstrap } = await import('./bootstrap');
- await bootstrap(namespace);
-
- // 移除并销毁loading
- unmountGlobalLoading();
-}
-
-initApplication();
diff --git a/apps/web-naive/src/preferences.ts b/apps/web-naive/src/preferences.ts
deleted file mode 100644
index b2e9ace4..00000000
--- a/apps/web-naive/src/preferences.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { defineOverridesPreferences } from '@vben/preferences';
-
-/**
- * @description 项目配置文件
- * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置
- * !!! 更改配置后请清空缓存,否则可能不生效
- */
-export const overridesPreferences = defineOverridesPreferences({
- // overrides
- app: {
- name: import.meta.env.VITE_APP_TITLE,
- },
-});
diff --git a/apps/web-naive/src/router/access.ts b/apps/web-naive/src/router/access.ts
deleted file mode 100644
index 7a80bac0..00000000
--- a/apps/web-naive/src/router/access.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type {
- ComponentRecordType,
- GenerateMenuAndRoutesOptions,
-} from '@vben/types';
-
-import { generateAccessible } from '@vben/access';
-import { preferences } from '@vben/preferences';
-
-import { message } from '#/adapter/naive';
-import { getAllMenusApi } from '#/api';
-import { BasicLayout, IFrameView } from '#/layouts';
-import { $t } from '#/locales';
-
-const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
-
-async function generateAccess(options: GenerateMenuAndRoutesOptions) {
- const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
-
- const layoutMap: ComponentRecordType = {
- BasicLayout,
- IFrameView,
- };
-
- return await generateAccessible(preferences.app.accessMode, {
- ...options,
- fetchMenuListAsync: async () => {
- message.loading(`${$t('common.loadingMenu')}...`, {
- duration: 1.5,
- });
- return await getAllMenusApi();
- },
- // 可以指定没有权限跳转403页面
- forbiddenComponent,
- // 如果 route.meta.menuVisibleWithForbidden = true
- layoutMap,
- pageMap,
- });
-}
-
-export { generateAccess };
diff --git a/apps/web-naive/src/router/guard.ts b/apps/web-naive/src/router/guard.ts
deleted file mode 100644
index c95d994e..00000000
--- a/apps/web-naive/src/router/guard.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import type { Router } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-import { preferences } from '@vben/preferences';
-import { useAccessStore, useUserStore } from '@vben/stores';
-import { startProgress, stopProgress } from '@vben/utils';
-
-import { accessRoutes, coreRouteNames } from '#/router/routes';
-import { useAuthStore } from '#/store';
-
-import { generateAccess } from './access';
-
-/**
- * 通用守卫配置
- * @param router
- */
-function setupCommonGuard(router: Router) {
- // 记录已经加载的页面
- const loadedPaths = new Set();
-
- router.beforeEach(async (to) => {
- to.meta.loaded = loadedPaths.has(to.path);
-
- // 页面加载进度条
- if (!to.meta.loaded && preferences.transition.progress) {
- startProgress();
- }
- return true;
- });
-
- router.afterEach((to) => {
- // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
-
- loadedPaths.add(to.path);
-
- // 关闭页面加载进度条
- if (preferences.transition.progress) {
- stopProgress();
- }
- });
-}
-
-/**
- * 权限访问守卫配置
- * @param router
- */
-function setupAccessGuard(router: Router) {
- router.beforeEach(async (to, from) => {
- const accessStore = useAccessStore();
- const userStore = useUserStore();
- const authStore = useAuthStore();
-
- // 基本路由,这些路由不需要进入权限拦截
- if (coreRouteNames.includes(to.name as string)) {
- if (to.path === LOGIN_PATH && accessStore.accessToken) {
- return decodeURIComponent(
- (to.query?.redirect as string) || DEFAULT_HOME_PATH,
- );
- }
- return true;
- }
-
- // accessToken 检查
- if (!accessStore.accessToken) {
- // 明确声明忽略权限访问权限,则可以访问
- if (to.meta.ignoreAccess) {
- return true;
- }
-
- // 没有访问权限,跳转登录页面
- if (to.fullPath !== LOGIN_PATH) {
- return {
- path: LOGIN_PATH,
- // 如不需要,直接删除 query
- query: { redirect: encodeURIComponent(to.fullPath) },
- // 携带当前跳转的页面,登录后重新跳转该页面
- replace: true,
- };
- }
- return to;
- }
-
- // 是否已经生成过动态路由
- if (accessStore.isAccessChecked) {
- return true;
- }
- // 生成路由表
- // 当前登录用户拥有的角色标识列表
- const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
- const userRoles = userInfo.roles ?? [];
-
- // 生成菜单和路由
- const { accessibleMenus, accessibleRoutes } = await generateAccess({
- roles: userRoles,
- router,
- // 则会在菜单中显示,但是访问会被重定向到403
- routes: accessRoutes,
- });
-
- // 保存菜单信息和路由信息
- accessStore.setAccessMenus(accessibleMenus);
- accessStore.setAccessRoutes(accessibleRoutes);
- accessStore.setIsAccessChecked(true);
- const redirectPath = (from.query.redirect ?? to.fullPath) as string;
-
- return {
- ...router.resolve(decodeURIComponent(redirectPath)),
- replace: true,
- };
- });
-}
-
-/**
- * 项目守卫配置
- * @param router
- */
-function createRouterGuard(router: Router) {
- /** 通用 */
- setupCommonGuard(router);
- /** 权限访问 */
- setupAccessGuard(router);
-}
-
-export { createRouterGuard };
diff --git a/apps/web-naive/src/router/index.ts b/apps/web-naive/src/router/index.ts
deleted file mode 100644
index 48402303..00000000
--- a/apps/web-naive/src/router/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
- createRouter,
- createWebHashHistory,
- createWebHistory,
-} from 'vue-router';
-
-import { resetStaticRoutes } from '@vben/utils';
-
-import { createRouterGuard } from './guard';
-import { routes } from './routes';
-
-/**
- * @zh_CN 创建vue-router实例
- */
-const router = createRouter({
- history:
- import.meta.env.VITE_ROUTER_HISTORY === 'hash'
- ? createWebHashHistory(import.meta.env.VITE_BASE)
- : createWebHistory(import.meta.env.VITE_BASE),
- // 应该添加到路由的初始路由列表。
- routes,
- scrollBehavior: (to, _from, savedPosition) => {
- if (savedPosition) {
- return savedPosition;
- }
- return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 };
- },
- // 是否应该禁止尾部斜杠。
- // strict: true,
-});
-
-const resetRoutes = () => resetStaticRoutes(router, routes);
-
-// 创建路由守卫
-createRouterGuard(router);
-
-export { resetRoutes, router };
diff --git a/apps/web-naive/src/router/routes/core.ts b/apps/web-naive/src/router/routes/core.ts
deleted file mode 100644
index fe030a9a..00000000
--- a/apps/web-naive/src/router/routes/core.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-
-import { AuthPageLayout } from '#/layouts';
-import { $t } from '#/locales';
-import Login from '#/views/_core/authentication/login.vue';
-
-/** 全局404页面 */
-const fallbackNotFoundRoute: RouteRecordRaw = {
- component: () => import('#/views/_core/fallback/not-found.vue'),
- meta: {
- hideInBreadcrumb: true,
- hideInMenu: true,
- hideInTab: true,
- title: '404',
- },
- name: 'FallbackNotFound',
- path: '/:path(.*)*',
-};
-
-/** 基本路由,这些路由是必须存在的 */
-const coreRoutes: RouteRecordRaw[] = [
- {
- meta: {
- title: 'Root',
- },
- name: 'Root',
- path: '/',
- redirect: DEFAULT_HOME_PATH,
- },
- {
- component: AuthPageLayout,
- meta: {
- hideInTab: true,
- title: 'Authentication',
- },
- name: 'Authentication',
- path: '/auth',
- redirect: LOGIN_PATH,
- children: [
- {
- name: 'Login',
- path: 'login',
- component: Login,
- meta: {
- title: $t('page.auth.login'),
- },
- },
- {
- name: 'CodeLogin',
- path: 'code-login',
- component: () => import('#/views/_core/authentication/code-login.vue'),
- meta: {
- title: $t('page.auth.codeLogin'),
- },
- },
- {
- name: 'QrCodeLogin',
- path: 'qrcode-login',
- component: () =>
- import('#/views/_core/authentication/qrcode-login.vue'),
- meta: {
- title: $t('page.auth.qrcodeLogin'),
- },
- },
- {
- name: 'ForgetPassword',
- path: 'forget-password',
- component: () =>
- import('#/views/_core/authentication/forget-password.vue'),
- meta: {
- title: $t('page.auth.forgetPassword'),
- },
- },
- {
- name: 'Register',
- path: 'register',
- component: () => import('#/views/_core/authentication/register.vue'),
- meta: {
- title: $t('page.auth.register'),
- },
- },
- ],
- },
-];
-
-export { coreRoutes, fallbackNotFoundRoute };
diff --git a/apps/web-naive/src/router/routes/index.ts b/apps/web-naive/src/router/routes/index.ts
deleted file mode 100644
index e6fb1440..00000000
--- a/apps/web-naive/src/router/routes/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { mergeRouteModules, traverseTreeValues } from '@vben/utils';
-
-import { coreRoutes, fallbackNotFoundRoute } from './core';
-
-const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', {
- eager: true,
-});
-
-// 有需要可以自行打开注释,并创建文件夹
-// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true });
-// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true });
-
-/** 动态路由 */
-const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles);
-
-/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */
-// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles);
-// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles);
-const staticRoutes: RouteRecordRaw[] = [];
-const externalRoutes: RouteRecordRaw[] = [];
-
-/** 路由列表,由基本路由、外部路由和404兜底路由组成
- * 无需走权限验证(会一直显示在菜单中) */
-const routes: RouteRecordRaw[] = [
- ...coreRoutes,
- ...externalRoutes,
- fallbackNotFoundRoute,
-];
-
-/** 基本路由列表,这些路由不需要进入权限拦截 */
-const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);
-
-/** 有权限校验的路由列表,包含动态路由和静态路由 */
-const accessRoutes = [...dynamicRoutes, ...staticRoutes];
-export { accessRoutes, coreRouteNames, routes };
diff --git a/apps/web-naive/src/router/routes/modules/dashboard.ts b/apps/web-naive/src/router/routes/modules/dashboard.ts
deleted file mode 100644
index 1bddab9d..00000000
--- a/apps/web-naive/src/router/routes/modules/dashboard.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { BasicLayout } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- icon: 'lucide:layout-dashboard',
- order: -1,
- title: $t('page.dashboard.title'),
- },
- name: 'Dashboard',
- path: '/',
- children: [
- {
- name: 'Analytics',
- path: '/analytics',
- component: () => import('#/views/dashboard/analytics/index.vue'),
- meta: {
- affixTab: true,
- icon: 'lucide:area-chart',
- title: $t('page.dashboard.analytics'),
- },
- },
- {
- name: 'Workspace',
- path: '/workspace',
- component: () => import('#/views/dashboard/workspace/index.vue'),
- meta: {
- icon: 'carbon:workspace',
- title: $t('page.dashboard.workspace'),
- },
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-naive/src/router/routes/modules/demos.ts b/apps/web-naive/src/router/routes/modules/demos.ts
deleted file mode 100644
index d0631cb5..00000000
--- a/apps/web-naive/src/router/routes/modules/demos.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import { BasicLayout } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- icon: 'ic:baseline-view-in-ar',
- keepAlive: true,
- order: 1000,
- title: $t('demos.title'),
- },
- name: 'Demos',
- path: '/demos',
- children: [
- {
- meta: {
- title: $t('demos.naive'),
- },
- name: 'NaiveDemos',
- path: '/demos/naive',
- component: () => import('#/views/demos/naive/index.vue'),
- },
- {
- meta: {
- title: $t('demos.table'),
- },
- name: 'Table',
- path: '/demos/table',
- component: () => import('#/views/demos/table/index.vue'),
- },
- {
- meta: {
- title: $t('demos.form'),
- },
- name: 'Form',
- path: '/demos/form',
- component: () => import('#/views/demos/form/basic.vue'),
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-naive/src/router/routes/modules/vben.ts b/apps/web-naive/src/router/routes/modules/vben.ts
deleted file mode 100644
index 44461a7f..00000000
--- a/apps/web-naive/src/router/routes/modules/vben.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import type { RouteRecordRaw } from 'vue-router';
-
-import {
- VBEN_ANT_PREVIEW_URL,
- VBEN_DOC_URL,
- VBEN_ELE_PREVIEW_URL,
- VBEN_GITHUB_URL,
- VBEN_LOGO_URL,
-} from '@vben/constants';
-import { SvgAntdvLogoIcon } from '@vben/icons';
-
-import { BasicLayout, IFrameView } from '#/layouts';
-import { $t } from '#/locales';
-
-const routes: RouteRecordRaw[] = [
- {
- component: BasicLayout,
- meta: {
- badgeType: 'dot',
- icon: VBEN_LOGO_URL,
- order: 9999,
- title: $t('demos.vben.title'),
- },
- name: 'VbenProject',
- path: '/vben-admin',
- children: [
- {
- name: 'VbenAbout',
- path: '/vben-admin/about',
- component: () => import('#/views/_core/about/index.vue'),
- meta: {
- icon: 'lucide:copyright',
- title: $t('demos.vben.about'),
- },
- },
- {
- name: 'VbenDocument',
- path: '/vben-admin/document',
- component: IFrameView,
- meta: {
- icon: 'lucide:book-open-text',
- link: VBEN_DOC_URL,
- title: $t('demos.vben.document'),
- },
- },
- {
- name: 'VbenGithub',
- path: '/vben-admin/github',
- component: IFrameView,
- meta: {
- icon: 'mdi:github',
- link: VBEN_GITHUB_URL,
- title: 'Github',
- },
- },
- {
- name: 'VbenAntd',
- path: '/vben-admin/antd',
- component: IFrameView,
- meta: {
- badgeType: 'dot',
- icon: SvgAntdvLogoIcon,
- link: VBEN_ANT_PREVIEW_URL,
- title: $t('demos.vben.antdv'),
- },
- },
- {
- name: 'VbenElementPlus',
- path: '/vben-admin/ele',
- component: IFrameView,
- meta: {
- badgeType: 'dot',
- icon: 'logos:element',
- link: VBEN_ELE_PREVIEW_URL,
- title: $t('demos.vben.element-plus'),
- },
- },
- ],
- },
-];
-
-export default routes;
diff --git a/apps/web-naive/src/store/auth.ts b/apps/web-naive/src/store/auth.ts
deleted file mode 100644
index 20aac562..00000000
--- a/apps/web-naive/src/store/auth.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import type { Recordable, UserInfo } from '@vben/types';
-
-import { ref } from 'vue';
-import { useRouter } from 'vue-router';
-
-import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
-import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
-
-import { defineStore } from 'pinia';
-
-import { notification } from '#/adapter/naive';
-import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
-import { $t } from '#/locales';
-
-export const useAuthStore = defineStore('auth', () => {
- const accessStore = useAccessStore();
- const userStore = useUserStore();
- const router = useRouter();
-
- const loginLoading = ref(false);
-
- /**
- * 异步处理登录操作
- * Asynchronously handle the login process
- * @param params 登录表单数据
- */
- async function authLogin(
- params: Recordable,
- onSuccess?: () => Promise | void,
- ) {
- // 异步处理用户登录操作并获取 accessToken
- let userInfo: null | UserInfo = null;
- try {
- loginLoading.value = true;
- const { accessToken } = await loginApi(params);
-
- // 如果成功获取到 accessToken
- if (accessToken) {
- // 将 accessToken 存储到 accessStore 中
- accessStore.setAccessToken(accessToken);
-
- // 获取用户信息并存储到 accessStore 中
- const [fetchUserInfoResult, accessCodes] = await Promise.all([
- fetchUserInfo(),
- getAccessCodesApi(),
- ]);
-
- userInfo = fetchUserInfoResult;
-
- userStore.setUserInfo(userInfo);
- accessStore.setAccessCodes(accessCodes);
-
- if (accessStore.loginExpired) {
- accessStore.setLoginExpired(false);
- } else {
- onSuccess
- ? await onSuccess?.()
- : await router.push(userInfo.homePath || DEFAULT_HOME_PATH);
- }
-
- if (userInfo?.realName) {
- notification.success({
- content: $t('authentication.loginSuccess'),
- description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
- duration: 3000,
- });
- }
- }
- } finally {
- loginLoading.value = false;
- }
-
- return {
- userInfo,
- };
- }
-
- async function logout(redirect: boolean = true) {
- try {
- await logoutApi();
- } catch {
- // 不做任何处理
- }
- resetAllStores();
- accessStore.setLoginExpired(false);
-
- // 回登录页带上当前路由地址
- await router.replace({
- path: LOGIN_PATH,
- query: redirect
- ? {
- redirect: encodeURIComponent(router.currentRoute.value.fullPath),
- }
- : {},
- });
- }
-
- async function fetchUserInfo() {
- let userInfo: null | UserInfo = null;
- userInfo = await getUserInfoApi();
- userStore.setUserInfo(userInfo);
- return userInfo;
- }
-
- function $reset() {
- loginLoading.value = false;
- }
-
- return {
- $reset,
- authLogin,
- fetchUserInfo,
- loginLoading,
- logout,
- };
-});
diff --git a/apps/web-naive/src/store/index.ts b/apps/web-naive/src/store/index.ts
deleted file mode 100644
index 269586ee..00000000
--- a/apps/web-naive/src/store/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './auth';
diff --git a/apps/web-naive/src/views/_core/README.md b/apps/web-naive/src/views/_core/README.md
deleted file mode 100644
index 8248afe6..00000000
--- a/apps/web-naive/src/views/_core/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# \_core
-
-此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。
diff --git a/apps/web-naive/src/views/_core/about/index.vue b/apps/web-naive/src/views/_core/about/index.vue
deleted file mode 100644
index 0ee52433..00000000
--- a/apps/web-naive/src/views/_core/about/index.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/authentication/code-login.vue b/apps/web-naive/src/views/_core/authentication/code-login.vue
deleted file mode 100644
index 1fc15e14..00000000
--- a/apps/web-naive/src/views/_core/authentication/code-login.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/authentication/forget-password.vue b/apps/web-naive/src/views/_core/authentication/forget-password.vue
deleted file mode 100644
index 0958e89b..00000000
--- a/apps/web-naive/src/views/_core/authentication/forget-password.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/authentication/login.vue b/apps/web-naive/src/views/_core/authentication/login.vue
deleted file mode 100644
index 099e4c8c..00000000
--- a/apps/web-naive/src/views/_core/authentication/login.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/authentication/qrcode-login.vue b/apps/web-naive/src/views/_core/authentication/qrcode-login.vue
deleted file mode 100644
index 23f5f2da..00000000
--- a/apps/web-naive/src/views/_core/authentication/qrcode-login.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/authentication/register.vue b/apps/web-naive/src/views/_core/authentication/register.vue
deleted file mode 100644
index e68a88f3..00000000
--- a/apps/web-naive/src/views/_core/authentication/register.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/fallback/coming-soon.vue b/apps/web-naive/src/views/_core/fallback/coming-soon.vue
deleted file mode 100644
index f394930f..00000000
--- a/apps/web-naive/src/views/_core/fallback/coming-soon.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/fallback/forbidden.vue b/apps/web-naive/src/views/_core/fallback/forbidden.vue
deleted file mode 100644
index 8ea65fed..00000000
--- a/apps/web-naive/src/views/_core/fallback/forbidden.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/fallback/internal-error.vue b/apps/web-naive/src/views/_core/fallback/internal-error.vue
deleted file mode 100644
index 819a47d5..00000000
--- a/apps/web-naive/src/views/_core/fallback/internal-error.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/fallback/not-found.vue b/apps/web-naive/src/views/_core/fallback/not-found.vue
deleted file mode 100644
index 4d178e9c..00000000
--- a/apps/web-naive/src/views/_core/fallback/not-found.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/_core/fallback/offline.vue b/apps/web-naive/src/views/_core/fallback/offline.vue
deleted file mode 100644
index 5de4a88d..00000000
--- a/apps/web-naive/src/views/_core/fallback/offline.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue
deleted file mode 100644
index fadfc917..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-visits-data.vue
deleted file mode 100644
index 30c4265d..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-data.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue
deleted file mode 100644
index 260520b8..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-visits-source.vue
deleted file mode 100644
index e0d0aab5..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-source.vue
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue
deleted file mode 100644
index 7e1f14ee..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/analytics/index.vue b/apps/web-naive/src/views/dashboard/analytics/index.vue
deleted file mode 100644
index 00b34df1..00000000
--- a/apps/web-naive/src/views/dashboard/analytics/index.vue
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-
diff --git a/apps/web-naive/src/views/dashboard/workspace/index.vue b/apps/web-naive/src/views/dashboard/workspace/index.vue
deleted file mode 100644
index b95d6138..00000000
--- a/apps/web-naive/src/views/dashboard/workspace/index.vue
+++ /dev/null
@@ -1,266 +0,0 @@
-
-
-
-
-
-
- 早安, {{ userStore.userInfo?.realName }}, 开始您一天的工作吧!
-
- 今日晴,20℃ - 32℃!
-
-
-
-
-
diff --git a/apps/web-naive/src/views/demos/form/basic.vue b/apps/web-naive/src/views/demos/form/basic.vue
deleted file mode 100644
index 7d04ff4d..00000000
--- a/apps/web-naive/src/views/demos/form/basic.vue
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
- 设置表单值
-
-
-
-
-
diff --git a/apps/web-naive/src/views/demos/naive/index.vue b/apps/web-naive/src/views/demos/naive/index.vue
deleted file mode 100644
index 41d55109..00000000
--- a/apps/web-naive/src/views/demos/naive/index.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- Default
- Tertiary
- Primary
- Info
- Success
- Warning
- Error
-
-
-
-
-
- 错误
- 警告
- 成功
- 加载中
-
-
-
-
-
- 错误
- 警告
- 成功
- 加载中
-
-
-
-
diff --git a/apps/web-naive/src/views/demos/table/index.vue b/apps/web-naive/src/views/demos/table/index.vue
deleted file mode 100644
index ddc958bc..00000000
--- a/apps/web-naive/src/views/demos/table/index.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/apps/web-naive/tailwind.config.mjs b/apps/web-naive/tailwind.config.mjs
deleted file mode 100644
index f17f556f..00000000
--- a/apps/web-naive/tailwind.config.mjs
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@vben/tailwind-config';
diff --git a/apps/web-naive/tsconfig.json b/apps/web-naive/tsconfig.json
deleted file mode 100644
index 02c287fe..00000000
--- a/apps/web-naive/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "extends": "@vben/tsconfig/web-app.json",
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "#/*": ["./src/*"]
- }
- },
- "references": [{ "path": "./tsconfig.node.json" }],
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
-}
diff --git a/apps/web-naive/tsconfig.node.json b/apps/web-naive/tsconfig.node.json
deleted file mode 100644
index c2f0d86c..00000000
--- a/apps/web-naive/tsconfig.node.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "extends": "@vben/tsconfig/node.json",
- "compilerOptions": {
- "composite": true,
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
- "noEmit": false
- },
- "include": ["vite.config.mts"]
-}
diff --git a/apps/web-naive/vite.config.mts b/apps/web-naive/vite.config.mts
deleted file mode 100644
index b6360f1d..00000000
--- a/apps/web-naive/vite.config.mts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { defineConfig } from '@vben/vite-config';
-
-export default defineConfig(async () => {
- return {
- application: {},
- vite: {
- server: {
- proxy: {
- '/api': {
- changeOrigin: true,
- rewrite: (path) => path.replace(/^\/api/, ''),
- // mock代理目标地址
- target: 'http://localhost:5320/api',
- ws: true,
- },
- },
- },
- },
- };
-});
diff --git a/cspell.json b/cspell.json
index 2baadf89..4e6b8723 100644
--- a/cspell.json
+++ b/cspell.json
@@ -9,6 +9,7 @@
"antdv",
"astro",
"brotli",
+ "clientid",
"clsx",
"defu",
"demi",
@@ -22,6 +23,7 @@
"iconoir",
"intlify",
"ipaddr",
+ "jsencrypt",
"lockb",
"logininfor",
"lucide",
@@ -42,6 +44,7 @@
"publint",
"Qqchat",
"qrcode",
+ "ruoyi",
"shadcn",
"sonner",
"sortablejs",
diff --git a/docs/.vitepress/components/preview-group.vue b/docs/.vitepress/components/preview-group.vue
index c8c6e83c..e712157c 100644
--- a/docs/.vitepress/components/preview-group.vue
+++ b/docs/.vitepress/components/preview-group.vue
@@ -1,4 +1,6 @@
diff --git a/docs/src/demos/vben-drawer/shared-data/index.vue b/docs/src/demos/vben-drawer/shared-data/index.vue
index 04885f15..fef6cb05 100644
--- a/docs/src/demos/vben-drawer/shared-data/index.vue
+++ b/docs/src/demos/vben-drawer/shared-data/index.vue
@@ -9,11 +9,12 @@ const [Drawer, drawerApi] = useVbenDrawer({
});
function open() {
- drawerApi.setData({
- content: '外部传递的数据 content',
- payload: '外部传递的数据 payload',
- });
- drawerApi.open();
+ drawerApi
+ .setData({
+ content: '外部传递的数据 content',
+ payload: '外部传递的数据 payload',
+ })
+ .open();
}
diff --git a/docs/src/demos/vben-ellipsis-text/expand/index.vue b/docs/src/demos/vben-ellipsis-text/expand/index.vue
new file mode 100644
index 00000000..842f6b32
--- /dev/null
+++ b/docs/src/demos/vben-ellipsis-text/expand/index.vue
@@ -0,0 +1,10 @@
+
+
+ {{ text }}
+
diff --git a/docs/src/demos/vben-ellipsis-text/line/index.vue b/docs/src/demos/vben-ellipsis-text/line/index.vue
new file mode 100644
index 00000000..dfbf20ef
--- /dev/null
+++ b/docs/src/demos/vben-ellipsis-text/line/index.vue
@@ -0,0 +1,10 @@
+
+
+ {{ text }}
+
diff --git a/docs/src/demos/vben-ellipsis-text/tooltip/index.vue b/docs/src/demos/vben-ellipsis-text/tooltip/index.vue
new file mode 100644
index 00000000..e6287a12
--- /dev/null
+++ b/docs/src/demos/vben-ellipsis-text/tooltip/index.vue
@@ -0,0 +1,14 @@
+
+
+
+ 住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
+
+
+ 《秦皇岛》
住在我心里孤独的
孤独的海怪 痛苦之王
开始厌倦
+ 深海的光 停滞的海浪
+
+
+
+
diff --git a/docs/src/demos/vben-modal/dynamic/index.vue b/docs/src/demos/vben-modal/dynamic/index.vue
index 718e532b..1b025545 100644
--- a/docs/src/demos/vben-modal/dynamic/index.vue
+++ b/docs/src/demos/vben-modal/dynamic/index.vue
@@ -13,8 +13,7 @@ function openModal() {
}
function handleUpdateTitle() {
- modalApi.setState({ title: '外部动态标题' });
- modalApi.open();
+ modalApi.setState({ title: '外部动态标题' }).open();
}
diff --git a/docs/src/demos/vben-modal/shared-data/index.vue b/docs/src/demos/vben-modal/shared-data/index.vue
index 58c35e24..91afeb70 100644
--- a/docs/src/demos/vben-modal/shared-data/index.vue
+++ b/docs/src/demos/vben-modal/shared-data/index.vue
@@ -9,11 +9,12 @@ const [Modal, modalApi] = useVbenModal({
});
function openModal() {
- modalApi.setData({
- content: '外部传递的数据 content',
- payload: '外部传递的数据 payload',
- });
- modalApi.open();
+ modalApi
+ .setData({
+ content: '外部传递的数据 content',
+ payload: '外部传递的数据 payload',
+ })
+ .open();
}
diff --git a/docs/src/demos/vben-vxe-table/form/index.vue b/docs/src/demos/vben-vxe-table/form/index.vue
index b5be6c65..bcf3f5a5 100644
--- a/docs/src/demos/vben-vxe-table/form/index.vue
+++ b/docs/src/demos/vben-vxe-table/form/index.vue
@@ -110,6 +110,11 @@ const gridOptions: VxeGridProps = {
},
},
},
+ toolbarConfig: {
+ // 是否显示搜索表单控制按钮
+ // @ts-ignore 正式环境时有完整的类型声明
+ search: true,
+ },
};
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });
diff --git a/docs/src/en/guide/essentials/route.md b/docs/src/en/guide/essentials/route.md
index bef40d69..8fb0a6d1 100644
--- a/docs/src/en/guide/essentials/route.md
+++ b/docs/src/en/guide/essentials/route.md
@@ -73,7 +73,6 @@ import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
badgeType: 'dot',
badgeVariants: 'destructive',
@@ -124,7 +123,6 @@ import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
icon: 'ic:baseline-view-in-ar',
keepAlive: true,
@@ -249,7 +247,6 @@ import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
icon: 'mdi:home',
title: $t('page.home.title'),
diff --git a/docs/src/en/guide/essentials/settings.md b/docs/src/en/guide/essentials/settings.md
index 68fef3e7..a3cd579e 100644
--- a/docs/src/en/guide/essentials/settings.md
+++ b/docs/src/en/guide/essentials/settings.md
@@ -217,6 +217,7 @@ const defaultPreferences: Preferences = {
globalSearch: true,
},
sidebar: {
+ autoActivateChild: false,
collapsed: false,
collapsedShowTitle: false,
enable: true,
diff --git a/docs/src/guide/essentials/route.md b/docs/src/guide/essentials/route.md
index 0eb74aea..d8a938dd 100644
--- a/docs/src/guide/essentials/route.md
+++ b/docs/src/guide/essentials/route.md
@@ -62,12 +62,10 @@ import type { RouteRecordRaw } from 'vue-router';
import { VBEN_LOGO_URL } from '@vben/constants';
-import { BasicLayout } from '#/layouts';
import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
badgeType: 'dot',
badgeVariants: 'destructive',
@@ -103,7 +101,6 @@ export default routes;
::: tip
-- 多级路由的父级路由无需设置 `component` 属性,只需设置 `children` 属性即可。除非你真的需要在父级路由嵌套下显示内容。
- 如果没有特殊情况,父级路由的 `redirect` 属性,不需要指定,默认会指向第一个子路由。
:::
@@ -113,12 +110,10 @@ export default routes;
```ts
import type { RouteRecordRaw } from 'vue-router';
-import { BasicLayout } from '#/layouts';
import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
icon: 'ic:baseline-view-in-ar',
keepAlive: true,
@@ -238,12 +233,10 @@ import type { RouteRecordRaw } from 'vue-router';
import { VBEN_LOGO_URL } from '@vben/constants';
-import { BasicLayout } from '#/layouts';
import { $t } from '#/locales';
const routes: RouteRecordRaw[] = [
{
- component: BasicLayout,
meta: {
icon: 'mdi:home',
title: $t('page.home.title'),
@@ -400,6 +393,10 @@ interface RouteMeta {
* 菜单可以看到,但是访问会被重定向到403
*/
menuVisibleWithForbidden?: boolean;
+ /**
+ * 当前路由不使用基础布局(仅在顶级生效)
+ */
+ noBasicLayout?: boolean;
/**
* 在新窗口打开
*/
@@ -584,6 +581,13 @@ _注意:_ 排序仅针对一级菜单有效,二级菜单的排序需要在对
用于配置页面的菜单参数,会在菜单中传递给页面。
+### noBasicLayout
+
+- 类型:`boolean`
+- 默认值:`false`
+
+用于配置当前路由不使用基础布局,仅在顶级时生效。默认情况下,所有的路由都会被包裹在基础布局中(包含顶部以及侧边等导航部件),如果你的页面不需要这些部件,可以设置 `noBasicLayout` 为 `true`。
+
## 路由刷新
路由刷新方式如下:
diff --git a/docs/src/guide/essentials/settings.md b/docs/src/guide/essentials/settings.md
index e3357206..3669a771 100644
--- a/docs/src/guide/essentials/settings.md
+++ b/docs/src/guide/essentials/settings.md
@@ -240,6 +240,7 @@ const defaultPreferences: Preferences = {
globalSearch: true,
},
sidebar: {
+ autoActivateChild: false,
collapsed: false,
collapsedShowTitle: false,
enable: true,
diff --git a/docs/src/guide/in-depth/ui-framework.md b/docs/src/guide/in-depth/ui-framework.md
index ce05608f..6a7508e1 100644
--- a/docs/src/guide/in-depth/ui-framework.md
+++ b/docs/src/guide/in-depth/ui-framework.md
@@ -4,7 +4,7 @@
## 新增组件库应用
-如果你想用其他别的组件库,你只需要按一下步骤进行操作:
+如果你想用其他别的组件库,你只需要按以下步骤进行操作:
1. 在`apps`内创建一个新的文件夹,例如`apps/web-xxx`。
2. 更改`apps/web-xxx/package.json`的`name`字段为`web-xxx`。
diff --git a/docs/src/guide/introduction/quick-start.md b/docs/src/guide/introduction/quick-start.md
index 747c5248..79410895 100644
--- a/docs/src/guide/introduction/quick-start.md
+++ b/docs/src/guide/introduction/quick-start.md
@@ -67,7 +67,7 @@ pnpm install
::: tip 注意
- 项目只支持使用 `pnpm` 进行依赖安装,默认会使用 `corepack` 来安装指定版本的 `pnpm`。:
-- 如果你的网络环境无法访问npm源,你可以设置系统的环境变量`COREPACK_REGISTRY=https://registry.npmmirror.com`,然后再执行`pnpm install`。
+- 如果你的网络环境无法访问npm源,你可以设置系统的环境变量`COREPACK_NPM_REGISTRY=https://registry.npmmirror.com`,然后再执行`pnpm install`。
- 如果你不想使用`corepack`,你需要禁用`corepack`,然后使用你自己的`pnpm`进行安装。
:::
diff --git a/internal/lint-configs/commitlint-config/package.json b/internal/lint-configs/commitlint-config/package.json
index fecabea5..d7e4c518 100644
--- a/internal/lint-configs/commitlint-config/package.json
+++ b/internal/lint-configs/commitlint-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/commitlint-config",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/lint-configs/eslint-config/src/configs/import.ts b/internal/lint-configs/eslint-config/src/configs/import.ts
index 67a08fea..ce6cf65d 100644
--- a/internal/lint-configs/eslint-config/src/configs/import.ts
+++ b/internal/lint-configs/eslint-config/src/configs/import.ts
@@ -10,6 +10,7 @@ export async function importPluginConfig(): Promise {
import: pluginImport,
},
rules: {
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
'import/first': 'error',
'import/newline-after-import': 'error',
'import/no-duplicates': 'error',
diff --git a/internal/lint-configs/eslint-config/src/configs/javascript.ts b/internal/lint-configs/eslint-config/src/configs/javascript.ts
index 0d87c1ba..f6b767fe 100644
--- a/internal/lint-configs/eslint-config/src/configs/javascript.ts
+++ b/internal/lint-configs/eslint-config/src/configs/javascript.ts
@@ -1,6 +1,5 @@
import type { Linter } from 'eslint';
-// @ts-expect-error - no types
import js from '@eslint/js';
import pluginUnusedImports from 'eslint-plugin-unused-imports';
import globals from 'globals';
diff --git a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
index 1b17b30f..d4fd0bb8 100644
--- a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
+++ b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
@@ -1,8 +1,13 @@
import type { Linter } from 'eslint';
-import perfectionistPlugin from 'eslint-plugin-perfectionist';
+import { interopDefault } from '../util';
export async function perfectionist(): Promise {
+ const perfectionistPlugin = await interopDefault(
+ // @ts-expect-error - no types
+ import('eslint-plugin-perfectionist'),
+ );
+
return [
perfectionistPlugin.configs['recommended-natural'],
{
@@ -19,21 +24,28 @@ export async function perfectionist(): Promise {
{
customGroups: {
type: {
- vben: 'vben',
- vue: 'vue',
+ 'vben-core-type': ['^@vben-core/.+'],
+ 'vben-type': ['^@vben/.+'],
+ 'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'],
},
value: {
- vben: ['@vben*', '@vben/**/**', '@vben-core/**/**'],
- vue: ['vue', 'vue-*', '@vue*'],
+ vben: ['^@vben/.+'],
+ 'vben-core': ['^@vben-core/.+'],
+ vue: ['^vue$', '^vue-.+', '^@vue/.+'],
},
},
+ environment: 'node',
groups: [
['external-type', 'builtin-type', 'type'],
+ 'vue-type',
+ 'vben-type',
+ 'vben-core-type',
['parent-type', 'sibling-type', 'index-type'],
['internal-type'],
'builtin',
'vue',
'vben',
+ 'vben-core',
'external',
'internal',
['parent', 'sibling', 'index'],
@@ -43,12 +55,13 @@ export async function perfectionist(): Promise {
'object',
'unknown',
],
- internalPattern: ['#*', '#*/**'],
+ internalPattern: ['^#/.+'],
newlinesBetween: 'always',
order: 'asc',
type: 'natural',
},
],
+ 'perfectionist/sort-modules': 'off',
'perfectionist/sort-named-exports': [
'error',
{
@@ -67,42 +80,6 @@ export async function perfectionist(): Promise {
groups: ['unknown', 'items', 'list', 'children'],
ignorePattern: ['children'],
order: 'asc',
- partitionByComment: 'Part:**',
- type: 'natural',
- },
- ],
- 'perfectionist/sort-vue-attributes': [
- 'error',
- {
- // Based on: https://vuejs.org/style-guide/rules-recommended.html#element-attribute-order
- customGroups: {
- /* eslint-disable perfectionist/sort-objects */
- DEFINITION: '*(is|:is|v-is)',
- LIST_RENDERING: 'v-for',
- CONDITIONALS: 'v-*(else-if|if|else|show|cloak)',
- RENDER_MODIFIERS: 'v-*(pre|once)',
- GLOBAL: '*(:id|id)',
- UNIQUE: '*(ref|key|:ref|:key)',
- SLOT: '*(v-slot|slot)',
- TWO_WAY_BINDING: '*(v-model|v-model:*)',
- // OTHER_DIRECTIVES e.g. 'v-custom-directive'
- EVENTS: '*(v-on|@*)',
- CONTENT: 'v-*(html|text)',
- /* eslint-enable perfectionist/sort-objects */
- },
- groups: [
- 'DEFINITION',
- 'LIST_RENDERING',
- 'CONDITIONALS',
- 'RENDER_MODIFIERS',
- 'GLOBAL',
- 'UNIQUE',
- 'SLOT',
- 'TWO_WAY_BINDING',
- 'unknown',
- 'EVENTS',
- 'CONTENT',
- ],
type: 'natural',
},
],
diff --git a/internal/lint-configs/eslint-config/src/configs/vue.ts b/internal/lint-configs/eslint-config/src/configs/vue.ts
index 27cc3cf2..d1c6521c 100644
--- a/internal/lint-configs/eslint-config/src/configs/vue.ts
+++ b/internal/lint-configs/eslint-config/src/configs/vue.ts
@@ -4,7 +4,6 @@ import { interopDefault } from '../util';
export async function vue(): Promise {
const [pluginVue, parserVue, parserTs] = await Promise.all([
- // @ts-expect-error missing types
interopDefault(import('eslint-plugin-vue')),
interopDefault(import('vue-eslint-parser')),
// @ts-expect-error missing types
diff --git a/internal/lint-configs/stylelint-config/package.json b/internal/lint-configs/stylelint-config/package.json
index 514cbf77..02491dd0 100644
--- a/internal/lint-configs/stylelint-config/package.json
+++ b/internal/lint-configs/stylelint-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/stylelint-config",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/node-utils/package.json b/internal/node-utils/package.json
index 7bbf40d9..b2a60da8 100644
--- a/internal/node-utils/package.json
+++ b/internal/node-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/node-utils",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/node-utils/src/spinner.ts b/internal/node-utils/src/spinner.ts
index f07cc256..13ad6a42 100644
--- a/internal/node-utils/src/spinner.ts
+++ b/internal/node-utils/src/spinner.ts
@@ -1,4 +1,6 @@
-import ora, { type Ora } from 'ora';
+import type { Ora } from 'ora';
+
+import ora from 'ora';
interface SpinnerOptions {
failedText?: string;
diff --git a/internal/tailwind-config/package.json b/internal/tailwind-config/package.json
index 946141dd..0b64d1d5 100644
--- a/internal/tailwind-config/package.json
+++ b/internal/tailwind-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/tailwind-config",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/tsconfig/package.json b/internal/tsconfig/package.json
index e39ec49b..8ebfeebf 100644
--- a/internal/tsconfig/package.json
+++ b/internal/tsconfig/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/tsconfig",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json
index 5abdcf45..6c589a1f 100644
--- a/internal/vite-config/package.json
+++ b/internal/vite-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben/vite-config",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts
index f2276094..f9808cc7 100644
--- a/internal/vite-config/src/config/application.ts
+++ b/internal/vite-config/src/config/application.ts
@@ -1,4 +1,4 @@
-import type { UserConfig } from 'vite';
+import type { CSSOptions, UserConfig } from 'vite';
import type { DefineApplicationOptions } from '../typing';
@@ -100,7 +100,7 @@ function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
});
}
-function createCssOptions(injectGlobalScss = true) {
+function createCssOptions(injectGlobalScss = true): CSSOptions {
const root = findMonorepoRoot();
return {
preprocessorOptions: injectGlobalScss
diff --git a/internal/vite-config/src/plugins/inject-app-loading/index.ts b/internal/vite-config/src/plugins/inject-app-loading/index.ts
index 9f6e2a5c..c6a79830 100644
--- a/internal/vite-config/src/plugins/inject-app-loading/index.ts
+++ b/internal/vite-config/src/plugins/inject-app-loading/index.ts
@@ -1,3 +1,5 @@
+import type { PluginOption } from 'vite';
+
import fs from 'node:fs';
import fsp from 'node:fs/promises';
import { join } from 'node:path';
@@ -5,8 +7,6 @@ import { fileURLToPath } from 'node:url';
import { readPackageJSON } from '@vben/node-utils';
-import { type PluginOption } from 'vite';
-
/**
* 用于生成将loading样式注入到项目中
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
diff --git a/internal/vite-config/src/utils/env.ts b/internal/vite-config/src/utils/env.ts
index 3a042fe8..cfc22b52 100644
--- a/internal/vite-config/src/utils/env.ts
+++ b/internal/vite-config/src/utils/env.ts
@@ -4,7 +4,6 @@ import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { fs } from '@vben/node-utils';
-
import dotenv from 'dotenv';
const getBoolean = (value: string | undefined) => value === 'true';
diff --git a/package.json b/package.json
index 6e53d711..f7213e33 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vben-admin-monorepo",
- "version": "5.5.0",
+ "version": "5.5.2",
"private": true,
"keywords": [
"monorepo",
@@ -30,8 +30,6 @@
"build:antd": "pnpm run build --filter=@vben/web-antd",
"build:docker": "./scripts/deploy/build-local-docker-image.sh",
"build:docs": "pnpm run build --filter=@vben/docs",
- "build:ele": "pnpm run build --filter=@vben/web-ele",
- "build:naive": "pnpm run build --filter=@vben/web-naive",
"build:play": "pnpm run build --filter=@vben/playground",
"changeset": "pnpm exec changeset",
"check": "pnpm run check:circular && pnpm run check:dep && pnpm run check:type && pnpm check:cspell",
@@ -44,8 +42,6 @@
"dev": "turbo-run dev",
"dev:antd": "pnpm -F @vben/web-antd run dev",
"dev:docs": "pnpm -F @vben/docs run dev",
- "dev:ele": "pnpm -F @vben/web-ele run dev",
- "dev:naive": "pnpm -F @vben/web-naive run dev",
"dev:play": "pnpm -F @vben/playground run dev",
"format": "vsh lint --format",
"lint": "vsh lint",
@@ -99,7 +95,7 @@
"node": ">=20.10.0",
"pnpm": ">=9.12.0"
},
- "packageManager": "pnpm@9.15.0",
+ "packageManager": "pnpm@9.15.3",
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
@@ -110,6 +106,7 @@
"@ast-grep/napi": "catalog:",
"@ctrl/tinycolor": "catalog:",
"clsx": "catalog:",
+ "esbuild": "0.24.0",
"pinia": "catalog:",
"vue": "catalog:"
},
diff --git a/packages/@core/base/design/package.json b/packages/@core/base/design/package.json
index 9e564de2..1d9888ca 100644
--- a/packages/@core/base/design/package.json
+++ b/packages/@core/base/design/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/design",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/base/design/src/css/ui.css b/packages/@core/base/design/src/css/ui.css
index 3a002f2a..f7119c8b 100644
--- a/packages/@core/base/design/src/css/ui.css
+++ b/packages/@core/base/design/src/css/ui.css
@@ -81,3 +81,7 @@
transform: translateY(0);
}
}
+
+.z-popup {
+ z-index: var(--popup-z-index);
+}
diff --git a/packages/@core/base/design/src/design-tokens/dark.css b/packages/@core/base/design/src/design-tokens/dark.css
index 2a1d052f..d34541e9 100644
--- a/packages/@core/base/design/src/design-tokens/dark.css
+++ b/packages/@core/base/design/src/design-tokens/dark.css
@@ -15,7 +15,11 @@
--card-foreground: 210 40% 98%;
/* Background color for popovers such as , , */
- --popover: 222.82deg 8.43% 12.27%;
+
+ /* --popover: 222.82deg 8.43% 12.27%; */
+
+ /* 弹出层的背景色与主题区域背景色太过接近 */
+ --popover: 0 0 14.2%;
--popover-foreground: 210 40% 98%;
/* Muted backgrounds such as , and */
diff --git a/packages/@core/base/design/src/design-tokens/default.css b/packages/@core/base/design/src/design-tokens/default.css
index c81ace7e..6fb71f17 100644
--- a/packages/@core/base/design/src/design-tokens/default.css
+++ b/packages/@core/base/design/src/design-tokens/default.css
@@ -1,4 +1,6 @@
:root {
+ /** 弹出层的基础层级 **/
+ --popup-z-index: 2000;
--font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto,
'Helvetica Neue', arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
diff --git a/packages/@core/base/icons/package.json b/packages/@core/base/icons/package.json
index bb971c0c..144814a0 100644
--- a/packages/@core/base/icons/package.json
+++ b/packages/@core/base/icons/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/icons",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/base/icons/src/lucide.ts b/packages/@core/base/icons/src/lucide.ts
index 97603eb5..21a1beff 100644
--- a/packages/@core/base/icons/src/lucide.ts
+++ b/packages/@core/base/icons/src/lucide.ts
@@ -28,6 +28,7 @@ export {
Fullscreen,
Github,
Grip,
+ GripVertical,
Info,
InspectionPanel,
Languages,
diff --git a/packages/@core/base/shared/package.json b/packages/@core/base/shared/package.json
index 17fa08c7..53964a65 100644
--- a/packages/@core/base/shared/package.json
+++ b/packages/@core/base/shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/shared",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
@@ -45,7 +45,7 @@
"default": "./dist/store.mjs"
},
"./global-state": {
- "types": "./dist/global-state.d.ts",
+ "types": "./src/global-state.ts",
"development": "./src/global-state.ts",
"default": "./dist/global-state.mjs"
}
diff --git a/packages/@core/base/shared/src/constants/dict-enum.ts b/packages/@core/base/shared/src/constants/dict-enum.ts
index b0976b46..a5eb7b33 100644
--- a/packages/@core/base/shared/src/constants/dict-enum.ts
+++ b/packages/@core/base/shared/src/constants/dict-enum.ts
@@ -12,4 +12,5 @@ export enum DictEnum {
SYS_YES_NO = 'sys_yes_no', // 是否
WF_BUSINESS_STATUS = 'wf_business_status', // 业务状态
WF_FORM_TYPE = 'wf_form_type', // 表单类型
+ WF_TASK_STATUS = 'wf_task_status', // 任务状态
}
diff --git a/packages/@core/base/shared/src/utils/cn.ts b/packages/@core/base/shared/src/utils/cn.ts
index 5503cc58..3a2f9773 100644
--- a/packages/@core/base/shared/src/utils/cn.ts
+++ b/packages/@core/base/shared/src/utils/cn.ts
@@ -1,4 +1,6 @@
-import { type ClassValue, clsx } from 'clsx';
+import type { ClassValue } from 'clsx';
+
+import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
function cn(...inputs: ClassValue[]) {
diff --git a/packages/@core/base/shared/src/utils/download.ts b/packages/@core/base/shared/src/utils/download.ts
index 3e708d3c..6f38ee5b 100644
--- a/packages/@core/base/shared/src/utils/download.ts
+++ b/packages/@core/base/shared/src/utils/download.ts
@@ -31,6 +31,7 @@ export async function downloadFileFromUrl({
if (isChrome || isSafari) {
triggerDownload(source, resolveFileName(source, fileName));
+ return;
}
if (!source.includes('?')) {
source += '?download';
diff --git a/packages/@core/base/typings/package.json b/packages/@core/base/typings/package.json
index 42c5db8b..c7153939 100644
--- a/packages/@core/base/typings/package.json
+++ b/packages/@core/base/typings/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/typings",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/base/typings/src/app.d.ts b/packages/@core/base/typings/src/app.d.ts
index e49a8657..02da2466 100644
--- a/packages/@core/base/typings/src/app.d.ts
+++ b/packages/@core/base/typings/src/app.d.ts
@@ -1,6 +1,8 @@
type LayoutType =
| 'full-content'
+ | 'header-mixed-nav'
| 'header-nav'
+ | 'header-sidebar-nav'
| 'mixed-nav'
| 'sidebar-mixed-nav'
| 'sidebar-nav';
@@ -38,6 +40,7 @@ type BuiltinThemeType =
type ContentCompactType = 'compact' | 'wide';
type LayoutHeaderModeType = 'auto' | 'auto-scroll' | 'fixed' | 'static';
+type LayoutHeaderMenuAlignType = 'center' | 'end' | 'start';
/**
* 登录过期模式
@@ -95,6 +98,7 @@ export type {
BreadcrumbStyleType,
BuiltinThemeType,
ContentCompactType,
+ LayoutHeaderMenuAlignType,
LayoutHeaderModeType,
LayoutType,
LoginExpiredModeType,
diff --git a/packages/@core/base/typings/src/helper.d.ts b/packages/@core/base/typings/src/helper.d.ts
index 8a6385b4..96d4f37b 100644
--- a/packages/@core/base/typings/src/helper.d.ts
+++ b/packages/@core/base/typings/src/helper.d.ts
@@ -1,4 +1,4 @@
-import { type ComputedRef, type MaybeRef } from 'vue';
+import type { ComputedRef, MaybeRef } from 'vue';
/**
* 深层递归所有属性为可选
@@ -109,6 +109,8 @@ type MergeAll<
type EmitType = (name: Name, ...args: any[]) => void;
+type MaybePromise = Promise | T;
+
export type {
AnyFunction,
AnyNormalFunction,
@@ -118,6 +120,7 @@ export type {
EmitType,
IntervalHandle,
MaybeComputedRef,
+ MaybePromise,
MaybeReadonlyRef,
Merge,
MergeAll,
diff --git a/packages/@core/base/typings/src/menu-record.ts b/packages/@core/base/typings/src/menu-record.ts
index 9cb18dcc..abcde813 100644
--- a/packages/@core/base/typings/src/menu-record.ts
+++ b/packages/@core/base/typings/src/menu-record.ts
@@ -1,6 +1,5 @@
-import type { RouteRecordRaw } from 'vue-router';
-
import type { Component } from 'vue';
+import type { RouteRecordRaw } from 'vue-router';
/**
* 扩展路由原始对象
diff --git a/packages/@core/base/typings/src/vue-router.d.ts b/packages/@core/base/typings/src/vue-router.d.ts
index b95bb33b..099e8171 100644
--- a/packages/@core/base/typings/src/vue-router.d.ts
+++ b/packages/@core/base/typings/src/vue-router.d.ts
@@ -1,6 +1,5 @@
-import type { Router, RouteRecordRaw } from 'vue-router';
-
import type { Component } from 'vue';
+import type { Router, RouteRecordRaw } from 'vue-router';
interface RouteMeta {
/**
@@ -98,6 +97,10 @@ interface RouteMeta {
* 菜单可以看到,但是访问会被重定向到403
*/
menuVisibleWithForbidden?: boolean;
+ /**
+ * 不使用基础布局(仅在顶级生效)
+ */
+ noBasicLayout?: boolean;
/**
* 在新窗口打开
*/
@@ -117,10 +120,13 @@ interface RouteMeta {
}
// 定义递归类型以将 RouteRecordRaw 的 component 属性更改为 string
-type RouteRecordStringComponent = {
+type RouteRecordStringComponent = Omit<
+ RouteRecordRaw,
+ 'children' | 'component'
+> & {
children?: RouteRecordStringComponent[];
component: T;
-} & Omit;
+};
type ComponentRecordType = Record Promise>;
diff --git a/packages/@core/composables/package.json b/packages/@core/composables/package.json
index 9af4f1f1..49f972fe 100644
--- a/packages/@core/composables/package.json
+++ b/packages/@core/composables/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/composables",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/composables/src/use-layout-style.ts b/packages/@core/composables/src/use-layout-style.ts
index ac599c4f..eba597d0 100644
--- a/packages/@core/composables/src/use-layout-style.ts
+++ b/packages/@core/composables/src/use-layout-style.ts
@@ -1,5 +1,5 @@
+import type { VisibleDomRect } from '@vben-core/shared/utils';
import type { CSSProperties } from 'vue';
-import { computed, onMounted, onUnmounted, ref } from 'vue';
import {
CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT,
@@ -7,12 +7,9 @@ import {
CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT,
CSS_VARIABLE_LAYOUT_HEADER_HEIGHT,
} from '@vben-core/shared/constants';
-import {
- getElementVisibleRect,
- type VisibleDomRect,
-} from '@vben-core/shared/utils';
-
+import { getElementVisibleRect } from '@vben-core/shared/utils';
import { useCssVar, useDebounceFn } from '@vueuse/core';
+import { computed, onMounted, onUnmounted, ref } from 'vue';
/**
* @zh_CN content style
diff --git a/packages/@core/composables/src/use-priority-value.ts b/packages/@core/composables/src/use-priority-value.ts
index d29e894e..2c6bda13 100644
--- a/packages/@core/composables/src/use-priority-value.ts
+++ b/packages/@core/composables/src/use-priority-value.ts
@@ -1,10 +1,10 @@
import type { ComputedRef, Ref } from 'vue';
-import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
import {
getFirstNonNullOrUndefined,
kebabToCamelCase,
} from '@vben-core/shared/utils';
+import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
/**
* 依次从插槽、attrs、props、state 中获取值
diff --git a/packages/@core/composables/src/use-simple-locale/index.ts b/packages/@core/composables/src/use-simple-locale/index.ts
index 1c3015bb..e344fdf3 100644
--- a/packages/@core/composables/src/use-simple-locale/index.ts
+++ b/packages/@core/composables/src/use-simple-locale/index.ts
@@ -1,8 +1,9 @@
-import { computed, ref } from 'vue';
+import type { Locale } from './messages';
import { createSharedComposable } from '@vueuse/core';
+import { computed, ref } from 'vue';
-import { getMessages, type Locale } from './messages';
+import { getMessages } from './messages';
export const useSimpleLocale = createSharedComposable(() => {
const currentLocale = ref('zh-CN');
diff --git a/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap b/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap
index def5ff60..486bf048 100644
--- a/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap
+++ b/packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap
@@ -46,6 +46,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"header": {
"enable": true,
"hidden": false,
+ "menuAlign": "start",
"mode": "fixed",
},
"logo": {
@@ -65,11 +66,12 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"globalSearch": true,
},
"sidebar": {
+ "autoActivateChild": false,
"collapsed": false,
"collapsedShowTitle": false,
"enable": true,
"expandOnHover": true,
- "extraCollapse": true,
+ "extraCollapse": false,
"hidden": false,
"width": 224,
},
@@ -78,11 +80,13 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"enable": true,
"height": 38,
"keepAlive": true,
+ "middleClickToClose": false,
"persist": true,
"showIcon": true,
"showMaximize": true,
"showMore": true,
"styleType": "chrome",
+ "wheelable": true,
},
"theme": {
"builtinType": "default",
diff --git a/packages/@core/preferences/package.json b/packages/@core/preferences/package.json
index 1cff0998..26232bf5 100644
--- a/packages/@core/preferences/package.json
+++ b/packages/@core/preferences/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/preferences",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/preferences/src/config.ts b/packages/@core/preferences/src/config.ts
index 72b087e4..df6d69ca 100644
--- a/packages/@core/preferences/src/config.ts
+++ b/packages/@core/preferences/src/config.ts
@@ -46,6 +46,7 @@ const defaultPreferences: Preferences = {
header: {
enable: true,
hidden: false,
+ menuAlign: 'start',
mode: 'fixed',
},
logo: {
@@ -65,11 +66,12 @@ const defaultPreferences: Preferences = {
globalSearch: true,
},
sidebar: {
+ autoActivateChild: false,
collapsed: false,
collapsedShowTitle: false,
enable: true,
expandOnHover: true,
- extraCollapse: true,
+ extraCollapse: false,
hidden: false,
width: 224,
},
@@ -78,11 +80,13 @@ const defaultPreferences: Preferences = {
enable: true,
height: 38,
keepAlive: true,
+ middleClickToClose: false,
persist: true,
showIcon: true,
showMaximize: true,
showMore: true,
styleType: 'chrome',
+ wheelable: true,
},
theme: {
builtinType: 'default',
@@ -105,7 +109,7 @@ const defaultPreferences: Preferences = {
fullscreen: true,
globalSearch: true,
languageToggle: true,
- lockScreen: true,
+ lockScreen: false,
notification: true,
refresh: true,
sidebarToggle: true,
diff --git a/packages/@core/preferences/src/preferences.ts b/packages/@core/preferences/src/preferences.ts
index 7851fdbc..26f1d711 100644
--- a/packages/@core/preferences/src/preferences.ts
+++ b/packages/@core/preferences/src/preferences.ts
@@ -2,16 +2,14 @@ import type { DeepPartial } from '@vben-core/typings';
import type { InitialOptions, Preferences } from './types';
-import { markRaw, reactive, readonly, watch } from 'vue';
-
import { StorageManager } from '@vben-core/shared/cache';
import { isMacOs, merge } from '@vben-core/shared/utils';
-
import {
breakpointsTailwind,
useBreakpoints,
useDebounceFn,
} from '@vueuse/core';
+import { markRaw, reactive, readonly, watch } from 'vue';
import { defaultPreferences } from './config';
import { updateCSSVariables } from './update-css-variables';
diff --git a/packages/@core/preferences/src/types.ts b/packages/@core/preferences/src/types.ts
index 2b536b85..b554b219 100644
--- a/packages/@core/preferences/src/types.ts
+++ b/packages/@core/preferences/src/types.ts
@@ -5,6 +5,7 @@ import type {
BuiltinThemeType,
ContentCompactType,
DeepPartial,
+ LayoutHeaderMenuAlignType,
LayoutHeaderModeType,
LayoutType,
LoginExpiredModeType,
@@ -104,6 +105,8 @@ interface HeaderPreferences {
enable: boolean;
/** 顶栏是否隐藏,css-隐藏 */
hidden: boolean;
+ /** 顶栏菜单位置 */
+ menuAlign: LayoutHeaderMenuAlignType;
/** header显示模式 */
mode: LayoutHeaderModeType;
}
@@ -125,6 +128,8 @@ interface NavigationPreferences {
}
interface SidebarPreferences {
+ /** 点击目录时自动激活子菜单 */
+ autoActivateChild: boolean;
/** 侧边栏是否折叠 */
collapsed: boolean;
/** 侧边栏折叠时,是否显示title */
@@ -163,6 +168,8 @@ interface TabbarPreferences {
height: number;
/** 开启标签页缓存功能 */
keepAlive: boolean;
+ /** 是否点击中键时关闭标签 */
+ middleClickToClose: boolean;
/** 是否持久化标签 */
persist: boolean;
/** 是否开启多标签页图标 */
@@ -173,6 +180,8 @@ interface TabbarPreferences {
showMore: boolean;
/** 标签页风格 */
styleType: TabsStyleType;
+ /** 是否开启鼠标滚轮响应 */
+ wheelable: boolean;
}
interface ThemePreferences {
diff --git a/packages/@core/preferences/src/use-preferences.ts b/packages/@core/preferences/src/use-preferences.ts
index fc1e2de5..94f28bef 100644
--- a/packages/@core/preferences/src/use-preferences.ts
+++ b/packages/@core/preferences/src/use-preferences.ts
@@ -1,6 +1,5 @@
-import { computed } from 'vue';
-
import { diff } from '@vben-core/shared/utils';
+import { computed } from 'vue';
import { preferencesManager } from './preferences';
import { isDarkTheme } from './update-css-variables';
@@ -82,6 +81,20 @@ function usePreferences() {
() => appPreferences.value.layout === 'header-nav',
);
+ /**
+ * @zh_CN 是否为头部混合导航模式
+ */
+ const isHeaderMixedNav = computed(
+ () => appPreferences.value.layout === 'header-mixed-nav',
+ );
+
+ /**
+ * @zh_CN 是否为顶部通栏+侧边导航模式
+ */
+ const isHeaderSidebarNav = computed(
+ () => appPreferences.value.layout === 'header-sidebar-nav',
+ );
+
/**
* @zh_CN 是否为混合导航模式
*/
@@ -93,7 +106,13 @@ function usePreferences() {
* @zh_CN 是否包含侧边导航模式
*/
const isSideMode = computed(() => {
- return isMixedNav.value || isSideMixedNav.value || isSideNav.value;
+ return (
+ isMixedNav.value ||
+ isSideMixedNav.value ||
+ isSideNav.value ||
+ isHeaderMixedNav.value ||
+ isHeaderSidebarNav.value
+ );
});
const sidebarCollapsed = computed(() => {
@@ -214,7 +233,9 @@ function usePreferences() {
globalSearchShortcutKey,
isDark,
isFullContent,
+ isHeaderMixedNav,
isHeaderNav,
+ isHeaderSidebarNav,
isMixedNav,
isMobile,
isSideMixedNav,
diff --git a/packages/@core/ui-kit/form-ui/package.json b/packages/@core/ui-kit/form-ui/package.json
index 3b5f86e5..a3f42ded 100644
--- a/packages/@core/ui-kit/form-ui/package.json
+++ b/packages/@core/ui-kit/form-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@vben-core/form-ui",
- "version": "5.5.0",
+ "version": "5.5.2",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
diff --git a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
index ac5505d5..fb90a5e4 100644
--- a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
+++ b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
@@ -3,12 +3,7 @@ import { computed, toRaw, unref, watch } from 'vue';
import { useSimpleLocale } from '@vben-core/composables';
import { VbenExpandableArrow } from '@vben-core/shadcn-ui';
-import {
- cn,
- formatDate,
- isFunction,
- triggerWindowResize,
-} from '@vben-core/shared/utils';
+import { cn, isFunction, triggerWindowResize } from '@vben-core/shared/utils';
import { COMPONENT_MAP } from '../config';
import { injectFormProps } from '../use-form-context';
@@ -58,7 +53,7 @@ async function handleSubmit(e: Event) {
return;
}
- const values = handleRangeTimeValue(toRaw(form.values));
+ const values = toRaw(await unref(rootProps).formApi?.getValues());
await unref(rootProps).handleSubmit?.(values);
}
@@ -67,13 +62,7 @@ async function handleReset(e: Event) {
e?.stopPropagation();
const props = unref(rootProps);
- const values = toRaw(form.values);
- // 清理时间字段
- props.fieldMappingTime &&
- props.fieldMappingTime.forEach(([_, [startTimeKey, endTimeKey]]) => {
- delete values[startTimeKey];
- delete values[endTimeKey];
- });
+ const values = toRaw(props.formApi?.getValues());
if (isFunction(props.handleReset)) {
await props.handleReset?.(values);
@@ -82,44 +71,6 @@ async function handleReset(e: Event) {
}
}
-function handleRangeTimeValue(values: Record