{{ activeConversation?.title ? activeConversation?.title : '对话' }}
diff --git a/apps/web-ele/src/views/ai/chat/index/modules/conversation/list.vue b/apps/web-ele/src/views/ai/chat/index/modules/conversation/list.vue
index 17340f446..1b864dd66 100644
--- a/apps/web-ele/src/views/ai/chat/index/modules/conversation/list.vue
+++ b/apps/web-ele/src/views/ai/chat/index/modules/conversation/list.vue
@@ -97,7 +97,7 @@ async function getChatConversationList() {
// 1.1 获取 对话数据
conversationList.value = await getChatConversationMyList();
// 1.2 排序
- conversationList.value.sort((a, b) => {
+ conversationList.value.toSorted((a, b) => {
return Number(b.createTime) - Number(a.createTime);
});
// 1.3 没有任何对话情况
diff --git a/apps/web-ele/src/views/ai/chat/index/modules/message/file-upload.vue b/apps/web-ele/src/views/ai/chat/index/modules/message/file-upload.vue
index 6d6b69179..a4c52db77 100644
--- a/apps/web-ele/src/views/ai/chat/index/modules/message/file-upload.vue
+++ b/apps/web-ele/src/views/ai/chat/index/modules/message/file-upload.vue
@@ -138,14 +138,14 @@ async function uploadFile(fileItem: FileItem) {
fileItem.progress = 100;
// 调试日志
- console.log('上传响应:', response);
+ console.warn('上传响应:', response);
// 兼容不同的返回格式:{ url: '...' } 或 { data: '...' } 或直接是字符串
const fileUrl =
(response as any)?.url || (response as any)?.data || response;
fileItem.url = fileUrl;
- console.log('提取的文件 URL:', fileUrl);
+ console.warn('提取的文件 URL:', fileUrl);
// 只有当 URL 有效时才添加到列表
if (fileUrl && typeof fileUrl === 'string') {
diff --git a/apps/web-ele/src/views/ai/image/index/modules/list.vue b/apps/web-ele/src/views/ai/image/index/modules/list.vue
index d958cf464..646622b52 100644
--- a/apps/web-ele/src/views/ai/image/index/modules/list.vue
+++ b/apps/web-ele/src/views/ai/image/index/modules/list.vue
@@ -144,7 +144,7 @@ async function handleImageMidjourneyButtonClick(
const data = {
id: imageDetail.id,
customId: button.customId,
- } as AiImageApi.ImageMidjourneyActionVO;
+ } as AiImageApi.ImageMidjourneyAction;
// 2. 发送 action
await midjourneyAction(data);
// 3. 刷新列表
diff --git a/apps/web-ele/src/views/ai/model/chatRole/modules/form.vue b/apps/web-ele/src/views/ai/model/chatRole/modules/form.vue
index 11b9e0eb9..35c44d2aa 100644
--- a/apps/web-ele/src/views/ai/model/chatRole/modules/form.vue
+++ b/apps/web-ele/src/views/ai/model/chatRole/modules/form.vue
@@ -13,7 +13,6 @@ import {
getChatRole,
updateChatRole,
} from '#/api/ai/model/chatRole';
-import {} from '#/api/bpm/model';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
diff --git a/apps/web-ele/src/views/ai/model/model/modules/form.vue b/apps/web-ele/src/views/ai/model/model/modules/form.vue
index 14a1bdc43..10727a642 100644
--- a/apps/web-ele/src/views/ai/model/model/modules/form.vue
+++ b/apps/web-ele/src/views/ai/model/model/modules/form.vue
@@ -9,7 +9,6 @@ import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import { createModel, getModel, updateModel } from '#/api/ai/model/model';
-import {} from '#/api/bpm/model';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
diff --git a/apps/web-ele/src/views/ai/music/index/list/index.vue b/apps/web-ele/src/views/ai/music/index/list/index.vue
index 50dbf3385..1e0dde387 100644
--- a/apps/web-ele/src/views/ai/music/index/list/index.vue
+++ b/apps/web-ele/src/views/ai/music/index/list/index.vue
@@ -17,7 +17,7 @@ const currentSong = ref({}); // 当前音乐
const mySongList = ref
[]>([]);
const squareSongList = ref[]>([]);
-function generateMusic(formData: Recordable) {
+function generateMusic(_formData: Recordable) {
loading.value = true;
setTimeout(() => {
mySongList.value = Array.from({ length: 20 }, (_, index) => {
diff --git a/apps/web-ele/src/views/ai/write/index/modules/tag.vue b/apps/web-ele/src/views/ai/write/index/modules/tag.vue
index f199a8dd1..f68df2641 100644
--- a/apps/web-ele/src/views/ai/write/index/modules/tag.vue
+++ b/apps/web-ele/src/views/ai/write/index/modules/tag.vue
@@ -21,7 +21,7 @@ const emits = defineEmits<{
{
{ name: '定制', value: 310 },
{ name: '技术支持', value: 274 },
{ name: '远程', value: 400 },
- ].sort((a, b) => {
+ ].toSorted((a, b) => {
return a.value - b.value;
}),
name: '商业占比',
diff --git a/apps/web-ele/src/views/erp/finance/payment/modules/item-form.vue b/apps/web-ele/src/views/erp/finance/payment/modules/item-form.vue
index dcd93d79b..604b8e3da 100644
--- a/apps/web-ele/src/views/erp/finance/payment/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/finance/payment/modules/item-form.vue
@@ -128,6 +128,7 @@ const handleOpenPurchaseIn = () => {
const handleAddPurchaseIn = (rows: ErpPurchaseInApi.PurchaseIn[]) => {
rows.forEach((row) => {
+ // TODO @芋艿
const newItem: ErpFinancePaymentApi.FinancePaymentItem = {
bizId: row.id,
bizType: ErpBizType.PURCHASE_IN,
diff --git a/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue b/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue
index 311e1c576..73e5f5cc5 100644
--- a/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue
@@ -127,6 +127,7 @@ function handleOpenSaleOut() {
}
function handleAddSaleOut(rows: ErpSaleOutApi.SaleOut[]) {
+ // TODO @芋艿
rows.forEach((row) => {
const newItem: ErpFinanceReceiptApi.FinanceReceiptItem = {
bizId: row.id,
diff --git a/apps/web-ele/src/views/erp/purchase/in/modules/item-form.vue b/apps/web-ele/src/views/erp/purchase/in/modules/item-form.vue
index 492618675..9dc903b2e 100644
--- a/apps/web-ele/src/views/erp/purchase/in/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/purchase/in/modules/item-form.vue
@@ -131,6 +131,7 @@ watch(
/** 处理删除 */
function handleDelete(row: ErpPurchaseInApi.PurchaseInItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/purchase/order/modules/item-form.vue b/apps/web-ele/src/views/erp/purchase/order/modules/item-form.vue
index d32daafae..7a0fa87c8 100644
--- a/apps/web-ele/src/views/erp/purchase/order/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/purchase/order/modules/item-form.vue
@@ -142,6 +142,7 @@ function handleAdd() {
/** 处理删除 */
function handleDelete(row: ErpPurchaseOrderApi.PurchaseOrderItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
@@ -169,6 +170,7 @@ async function handleProductChange(productId: any, row: any) {
/** 处理行数据变更 */
function handleRowChange(row: any) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index === -1) {
tableData.value.push(row);
diff --git a/apps/web-ele/src/views/erp/purchase/return/modules/item-form.vue b/apps/web-ele/src/views/erp/purchase/return/modules/item-form.vue
index 2010c5cb0..8974fe052 100644
--- a/apps/web-ele/src/views/erp/purchase/return/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/purchase/return/modules/item-form.vue
@@ -131,6 +131,7 @@ watch(
/** 处理删除 */
function handleDelete(row: ErpPurchaseReturnApi.PurchaseReturnItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue
index 84a698cf9..7ea01a887 100644
--- a/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue
@@ -142,6 +142,7 @@ function handleAdd() {
/** 处理删除 */
function handleDelete(row: ErpSaleOrderApi.SaleOrderItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue
index 85122ebe0..32c835e2e 100644
--- a/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue
@@ -131,6 +131,7 @@ watch(
/** 处理删除 */
function handleDelete(row: ErpSaleOutApi.SaleOutItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue
index 442baf663..75009be28 100644
--- a/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue
@@ -131,6 +131,7 @@ watch(
/** 处理删除 */
function handleDelete(row: ErpSaleReturnApi.SaleReturnItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue
index 19f78cf7c..6fb1f9d98 100644
--- a/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue
@@ -106,6 +106,7 @@ function handleAdd() {
/** 处理删除 */
function handleDelete(row: ErpStockCheckApi.StockCheckItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue
index 21145e370..24456de71 100644
--- a/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue
@@ -86,6 +86,7 @@ watch(
/** 处理新增 */
function handleAdd() {
+ // TODO @芋艿
const newRow = {
id: undefined,
warehouseId: undefined,
diff --git a/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue
index 4a0610bf2..07e120944 100644
--- a/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue
+++ b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue
@@ -105,6 +105,7 @@ function handleAdd() {
/** 处理删除 */
function handleDelete(row: ErpStockOutApi.StockOutItem) {
+ // TODO @芋艿
const index = tableData.value.findIndex((item) => item.seq === row.seq);
if (index !== -1) {
tableData.value.splice(index, 1);
diff --git a/apps/web-ele/src/views/infra/webSocket/index.vue b/apps/web-ele/src/views/infra/webSocket/index.vue
index 8f493bc7a..ac364c565 100644
--- a/apps/web-ele/src/views/infra/webSocket/index.vue
+++ b/apps/web-ele/src/views/infra/webSocket/index.vue
@@ -47,7 +47,7 @@ const { status, data, send, close, open } = useWebSocket(server.value, {
const messageList = ref(
[] as { text: string; time: number; type?: string; userId?: string }[],
); // 消息列表
-const messageReverseList = computed(() => [...messageList.value].reverse());
+const messageReverseList = computed(() => [...messageList.value].toReversed());
watchEffect(() => {
if (!data.value) {
return;
diff --git a/apps/web-ele/src/views/mall/promotion/combination/components/showcase.vue b/apps/web-ele/src/views/mall/promotion/combination/components/showcase.vue
index 748db18b8..679a21826 100644
--- a/apps/web-ele/src/views/mall/promotion/combination/components/showcase.vue
+++ b/apps/web-ele/src/views/mall/promotion/combination/components/showcase.vue
@@ -111,6 +111,7 @@ function emitActivityChange() {
>
+
{
// 使用展开运算符创建新数组,避免直接修改原数组
- return [...messageList.value].sort(
+ return [...messageList.value].toSorted(
(a: any, b: any) => a.createTime - b.createTime,
);
});
diff --git a/apps/web-ele/src/views/mall/promotion/seckill/components/showcase.vue b/apps/web-ele/src/views/mall/promotion/seckill/components/showcase.vue
index 6143063c8..608b1c804 100644
--- a/apps/web-ele/src/views/mall/promotion/seckill/components/showcase.vue
+++ b/apps/web-ele/src/views/mall/promotion/seckill/components/showcase.vue
@@ -110,6 +110,7 @@ function emitActivityChange() {
>
+
(accountList = data));
+
+/** 搜索表单配置 */
+export function useGridFormSchema(): VbenFormSchema[] {
+ return [
+ {
+ fieldName: 'accountId',
+ label: '公众号',
+ component: 'Select',
+ componentProps: {
+ options: accountList.map((item) => ({
+ label: item.name,
+ value: item.id,
+ })),
+ placeholder: '请选择公众号',
+ clearable: true,
+ },
+ },
+ ];
+}
+
+/** 表格列配置 */
+export function useGridColumns(): VxeGridPropTypes.Columns {
+ return [
+ {
+ field: 'cover',
+ title: '图片',
+ width: 360,
+ slots: { default: 'cover' },
+ },
+ {
+ field: 'title',
+ title: '标题',
+ slots: { default: 'title' },
+ },
+ {
+ field: 'updateTime',
+ title: '修改时间',
+ formatter: ({ row }) => {
+ return formatDateTime(row.updateTime * 1000);
+ },
+ },
+ {
+ title: '操作',
+ width: 120,
+ fixed: 'right',
+ slots: { default: 'actions' },
+ },
+ ];
+}
diff --git a/apps/web-ele/src/views/mp/freePublish/index.vue b/apps/web-ele/src/views/mp/freePublish/index.vue
new file mode 100644
index 000000000..c126c7f01
--- /dev/null
+++ b/apps/web-ele/src/views/mp/freePublish/index.vue
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+ {{ item.title }}
+
+
+
+ -
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-ele/src/views/mp/menu/index.vue b/apps/web-ele/src/views/mp/menu/index.vue
index 097ea52ad..688b1f268 100644
--- a/apps/web-ele/src/views/mp/menu/index.vue
+++ b/apps/web-ele/src/views/mp/menu/index.vue
@@ -134,20 +134,20 @@ function menuListToFrontend(list: any[]) {
list.forEach((item: RawMenu) => {
const menu: any = {
...item,
- };
- menu.reply = {
- type: item.replyMessageType,
- accountId: item.accountId,
- content: item.replyContent,
- mediaId: item.replyMediaId,
- url: item.replyMediaUrl,
- title: item.replyTitle,
- description: item.replyDescription,
- thumbMediaId: item.replyThumbMediaId,
- thumbMediaUrl: item.replyThumbMediaUrl,
- articles: item.replyArticles,
- musicUrl: item.replyMusicUrl,
- hqMusicUrl: item.replyHqMusicUrl,
+ reply: {
+ type: item.replyMessageType,
+ accountId: item.accountId,
+ content: item.replyContent,
+ mediaId: item.replyMediaId,
+ url: item.replyMediaUrl,
+ title: item.replyTitle,
+ description: item.replyDescription,
+ thumbMediaId: item.replyThumbMediaId,
+ thumbMediaUrl: item.replyThumbMediaUrl,
+ articles: item.replyArticles,
+ musicUrl: item.replyMusicUrl,
+ hqMusicUrl: item.replyHqMusicUrl,
+ },
};
result.push(menu as RawMenu);
});
@@ -277,18 +277,18 @@ function menuToBackend(menu: any) {
...menu,
children: undefined, // 不处理子节点
reply: undefined, // 稍后复制
+ replyMessageType: menu.reply.type,
+ replyContent: menu.reply.content,
+ replyMediaId: menu.reply.mediaId,
+ replyMediaUrl: menu.reply.url,
+ replyTitle: menu.reply.title,
+ replyDescription: menu.reply.description,
+ replyThumbMediaId: menu.reply.thumbMediaId,
+ replyThumbMediaUrl: menu.reply.thumbMediaUrl,
+ replyArticles: menu.reply.articles,
+ replyMusicUrl: menu.reply.musicUrl,
+ replyHqMusicUrl: menu.reply.hqMusicUrl,
};
- result.replyMessageType = menu.reply.type;
- result.replyContent = menu.reply.content;
- result.replyMediaId = menu.reply.mediaId;
- result.replyMediaUrl = menu.reply.url;
- result.replyTitle = menu.reply.title;
- result.replyDescription = menu.reply.description;
- result.replyThumbMediaId = menu.reply.thumbMediaId;
- result.replyThumbMediaUrl = menu.reply.thumbMediaUrl;
- result.replyArticles = menu.reply.articles;
- result.replyMusicUrl = menu.reply.musicUrl;
- result.replyHqMusicUrl = menu.reply.hqMusicUrl;
return result;
}
diff --git a/apps/web-ele/src/views/pay/app/data.ts b/apps/web-ele/src/views/pay/app/data.ts
index 9204bac98..8ee19190c 100644
--- a/apps/web-ele/src/views/pay/app/data.ts
+++ b/apps/web-ele/src/views/pay/app/data.ts
@@ -256,9 +256,7 @@ export function useAppFormSchema(): VbenFormSchema[] {
/** 渠道新增/修改的表单 */
export function useChannelFormSchema(formType: string = ''): VbenFormSchema[] {
- const schema: VbenFormSchema[] = [];
- // 添加通用字段
- schema.push(
+ const schema: VbenFormSchema[] = [
{
component: 'Input',
fieldName: 'id',
@@ -307,7 +305,8 @@ export function useChannelFormSchema(formType: string = ''): VbenFormSchema[] {
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
},
},
- );
+ ];
+ // 添加通用字段
// 根据类型添加特定字段
if (formType.includes('alipay_')) {
schema.push(
@@ -402,7 +401,10 @@ export function useChannelFormSchema(formType: string = ''): VbenFormSchema[] {
fieldName: 'config.appCertContent',
component: h(InputUpload, {
inputType: 'textarea',
- textareaProps: { rows: 3, placeholder: '请上传商户公钥应用证书' },
+ textareaProps: {
+ rows: 3,
+ placeholder: '请上传商户公钥应用证书',
+ },
fileUploadProps: {
accept: ['crt'],
},
diff --git a/apps/web-ele/src/views/system/user/modules/import-form.vue b/apps/web-ele/src/views/system/user/modules/import-form.vue
index 0004b04ce..6222bf437 100644
--- a/apps/web-ele/src/views/system/user/modules/import-form.vue
+++ b/apps/web-ele/src/views/system/user/modules/import-form.vue
@@ -1,6 +1,4 @@
+
+
+
diff --git a/apps/web-naive/src/views/_core/profile/index.vue b/apps/web-naive/src/views/_core/profile/index.vue
new file mode 100644
index 000000000..8740894e3
--- /dev/null
+++ b/apps/web-naive/src/views/_core/profile/index.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-naive/src/views/_core/profile/notification-setting.vue b/apps/web-naive/src/views/_core/profile/notification-setting.vue
new file mode 100644
index 000000000..324a4b393
--- /dev/null
+++ b/apps/web-naive/src/views/_core/profile/notification-setting.vue
@@ -0,0 +1,31 @@
+
+
+
+
diff --git a/apps/web-naive/src/views/_core/profile/password-setting.vue b/apps/web-naive/src/views/_core/profile/password-setting.vue
new file mode 100644
index 000000000..1132a51fb
--- /dev/null
+++ b/apps/web-naive/src/views/_core/profile/password-setting.vue
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/apps/web-naive/src/views/_core/profile/security-setting.vue b/apps/web-naive/src/views/_core/profile/security-setting.vue
new file mode 100644
index 000000000..be30db58e
--- /dev/null
+++ b/apps/web-naive/src/views/_core/profile/security-setting.vue
@@ -0,0 +1,43 @@
+
+
+
+
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
index 02f509123..6ff52086f 100644
--- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue
+++ b/apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue
@@ -24,7 +24,7 @@ onMounted(() => {
{ name: '定制', value: 310 },
{ name: '技术支持', value: 274 },
{ name: '远程', value: 400 },
- ].sort((a, b) => {
+ ].toSorted((a, b) => {
return a.value - b.value;
}),
name: '商业占比',
diff --git a/apps/web-naive/src/views/infra/webSocket/index.vue b/apps/web-naive/src/views/infra/webSocket/index.vue
index e76f502f9..e8728a79a 100644
--- a/apps/web-naive/src/views/infra/webSocket/index.vue
+++ b/apps/web-naive/src/views/infra/webSocket/index.vue
@@ -48,7 +48,7 @@ const { status, data, send, close, open } = useWebSocket(server.value, {
const messageList = ref(
[] as { text: string; time: number; type?: string; userId?: string }[],
); // 消息列表
-const messageReverseList = computed(() => [...messageList.value].reverse());
+const messageReverseList = computed(() => [...messageList.value].toReversed());
watchEffect(() => {
if (!data.value) {
return;
diff --git a/apps/web-tdesign/package.json b/apps/web-tdesign/package.json
index 6386cce56..c84b35a10 100644
--- a/apps/web-tdesign/package.json
+++ b/apps/web-tdesign/package.json
@@ -44,14 +44,11 @@
"@vueuse/core": "catalog:",
"cropperjs": "catalog:",
"dayjs": "catalog:",
- "lodash-es": "^4.17.21",
+ "es-toolkit": "catalog:",
"pinia": "catalog:",
- "tdesign-vue-next": "^1.17.1",
+ "tdesign-vue-next": "catalog:",
"tinymce": "catalog:",
"vue": "catalog:",
"vue-router": "catalog:"
- },
- "devDependencies": {
- "@types/lodash-es": "^4.17.12"
}
}
diff --git a/apps/web-tdesign/src/app.vue b/apps/web-tdesign/src/app.vue
index 57d5951cc..f37688b67 100644
--- a/apps/web-tdesign/src/app.vue
+++ b/apps/web-tdesign/src/app.vue
@@ -5,7 +5,7 @@ import { onMounted } from 'vue';
import { usePreferences } from '@vben/preferences';
-import { merge } from 'lodash-es';
+import { merge } from 'es-toolkit/compat';
import { ConfigProvider } from 'tdesign-vue-next';
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN';
diff --git a/apps/web-tdesign/src/bootstrap.ts b/apps/web-tdesign/src/bootstrap.ts
index edcccea4c..732030e1a 100644
--- a/apps/web-tdesign/src/bootstrap.ts
+++ b/apps/web-tdesign/src/bootstrap.ts
@@ -5,7 +5,6 @@ import { registerLoadingDirective } from '@vben/common-ui/es/loading';
import { preferences } from '@vben/preferences';
import { initStores } from '@vben/stores';
import '@vben/styles';
-import '@vben/styles/antd';
import { useTitle } from '@vueuse/core';
@@ -16,7 +15,9 @@ import { initSetupVbenForm } from './adapter/form';
import App from './app.vue';
import { router } from './router';
+// import '@vben/styles/antd';
// 引入组件库的少量全局样式变量
+import 'tdesign-vue-next/es/style/index.css';
async function bootstrap(namespace: string) {
// 初始化组件适配器
diff --git a/apps/web-tdesign/src/layouts/basic.vue b/apps/web-tdesign/src/layouts/basic.vue
index 805b8a73d..2226c68a2 100644
--- a/apps/web-tdesign/src/layouts/basic.vue
+++ b/apps/web-tdesign/src/layouts/basic.vue
@@ -2,6 +2,7 @@
import type { NotificationItem } from '@vben/layouts';
import { computed, ref, watch } from 'vue';
+import { useRouter } from 'vue-router';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
@@ -23,6 +24,7 @@ import LoginForm from '#/views/_core/authentication/login.vue';
const notifications = ref([
{
+ id: 1,
avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB',
date: '3小时前',
isRead: true,
@@ -30,6 +32,7 @@ const notifications = ref([
title: '收到了 14 份新周报',
},
{
+ id: 2,
avatar: 'https://avatar.vercel.sh/1',
date: '刚刚',
isRead: false,
@@ -37,6 +40,7 @@ const notifications = ref([
title: '朱偏右 回复了你',
},
{
+ id: 3,
avatar: 'https://avatar.vercel.sh/1',
date: '2024-01-01',
isRead: false,
@@ -44,14 +48,34 @@ const notifications = ref([
title: '曲丽丽 评论了你',
},
{
+ id: 4,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '代办提醒',
},
+ {
+ id: 5,
+ avatar: 'https://avatar.vercel.sh/satori',
+ date: '1天前',
+ isRead: false,
+ message: '描述信息描述信息描述信息',
+ title: '跳转Workspace示例',
+ link: '/workspace',
+ },
+ {
+ id: 6,
+ avatar: 'https://avatar.vercel.sh/satori',
+ date: '1天前',
+ isRead: false,
+ message: '描述信息描述信息描述信息',
+ title: '跳转外部链接示例',
+ link: 'https://doc.vben.pro',
+ },
]);
+const router = useRouter();
const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
@@ -61,6 +85,13 @@ const showDot = computed(() =>
);
const menus = computed(() => [
+ {
+ handler: () => {
+ router.push({ name: 'Profile' });
+ },
+ icon: 'lucide:user',
+ text: $t('page.auth.profile'),
+ },
{
handler: () => {
openWindow(VBEN_DOC_URL, {
@@ -102,6 +133,17 @@ function handleNoticeClear() {
notifications.value = [];
}
+function markRead(id: number | string) {
+ const item = notifications.value.find((item) => item.id === id);
+ if (item) {
+ item.isRead = true;
+ }
+}
+
+function remove(id: number | string) {
+ notifications.value = notifications.value.filter((item) => item.id !== id);
+}
+
function handleMakeAll() {
notifications.value.forEach((item) => (item.isRead = true));
}
@@ -144,6 +186,8 @@ watch(
:dot="showDot"
:notifications="notifications"
@clear="handleNoticeClear"
+ @read="(item) => item.id && markRead(item.id)"
+ @remove="(item) => item.id && remove(item.id)"
@make-all="handleMakeAll"
/>
diff --git a/apps/web-tdesign/src/locales/langs/en-US/page.json b/apps/web-tdesign/src/locales/langs/en-US/page.json
index 00a8c90b2..130cb88ac 100644
--- a/apps/web-tdesign/src/locales/langs/en-US/page.json
+++ b/apps/web-tdesign/src/locales/langs/en-US/page.json
@@ -4,7 +4,8 @@
"register": "Register",
"codeLogin": "Code Login",
"qrcodeLogin": "Qr Code Login",
- "forgetPassword": "Forget Password"
+ "forgetPassword": "Forget Password",
+ "profile": "Profile"
},
"dashboard": {
"title": "Dashboard",
diff --git a/apps/web-tdesign/src/locales/langs/zh-CN/page.json b/apps/web-tdesign/src/locales/langs/zh-CN/page.json
index eefc4924b..d2af3b1eb 100644
--- a/apps/web-tdesign/src/locales/langs/zh-CN/page.json
+++ b/apps/web-tdesign/src/locales/langs/zh-CN/page.json
@@ -4,7 +4,8 @@
"register": "注册",
"codeLogin": "验证码登录",
"qrcodeLogin": "二维码登录",
- "forgetPassword": "忘记密码"
+ "forgetPassword": "忘记密码",
+ "profile": "个人中心"
},
"dashboard": {
"title": "概览",
diff --git a/apps/web-tdesign/src/views/_core/profile/base-setting.vue b/apps/web-tdesign/src/views/_core/profile/base-setting.vue
new file mode 100644
index 000000000..aa8a4c260
--- /dev/null
+++ b/apps/web-tdesign/src/views/_core/profile/base-setting.vue
@@ -0,0 +1,65 @@
+
+
+
+
diff --git a/apps/web-tdesign/src/views/_core/profile/notification-setting.vue b/apps/web-tdesign/src/views/_core/profile/notification-setting.vue
new file mode 100644
index 000000000..324a4b393
--- /dev/null
+++ b/apps/web-tdesign/src/views/_core/profile/notification-setting.vue
@@ -0,0 +1,31 @@
+
+
+
+
diff --git a/apps/web-tdesign/src/views/_core/profile/password-setting.vue b/apps/web-tdesign/src/views/_core/profile/password-setting.vue
new file mode 100644
index 000000000..7e1c0f082
--- /dev/null
+++ b/apps/web-tdesign/src/views/_core/profile/password-setting.vue
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/apps/web-tdesign/src/views/_core/profile/security-setting.vue b/apps/web-tdesign/src/views/_core/profile/security-setting.vue
new file mode 100644
index 000000000..be30db58e
--- /dev/null
+++ b/apps/web-tdesign/src/views/_core/profile/security-setting.vue
@@ -0,0 +1,43 @@
+
+
+
+
diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue
index 02f509123..6ff52086f 100644
--- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue
+++ b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue
@@ -24,7 +24,7 @@ onMounted(() => {
{ name: '定制', value: 310 },
{ name: '技术支持', value: 274 },
{ name: '远程', value: 400 },
- ].sort((a, b) => {
+ ].toSorted((a, b) => {
return a.value - b.value;
}),
name: '商业占比',
diff --git a/apps/web-tdesign/src/views/infra/webSocket/index.vue b/apps/web-tdesign/src/views/infra/webSocket/index.vue
index c4fd5fa54..466939377 100644
--- a/apps/web-tdesign/src/views/infra/webSocket/index.vue
+++ b/apps/web-tdesign/src/views/infra/webSocket/index.vue
@@ -47,7 +47,7 @@ const { status, data, send, close, open } = useWebSocket(server.value, {
const messageList = ref(
[] as { text: string; time: number; type?: string; userId?: string }[],
); // 消息列表
-const messageReverseList = computed(() => [...messageList.value].reverse());
+const messageReverseList = computed(() => [...messageList.value].toReversed());
watchEffect(() => {
if (!data.value) {
return;
diff --git a/cspell.json b/cspell.json
index ce570510f..9bacfa30e 100644
--- a/cspell.json
+++ b/cspell.json
@@ -54,6 +54,7 @@
"styl",
"taze",
"Tinymce",
+ "tdesign",
"ui-kit",
"uicons",
"unplugin",
diff --git a/docs/.vitepress/components/preview-group.vue b/docs/.vitepress/components/preview-group.vue
index 2fb02d3fd..660a6f2f4 100644
--- a/docs/.vitepress/components/preview-group.vue
+++ b/docs/.vitepress/components/preview-group.vue
@@ -48,7 +48,7 @@ const toggleOpen = () => {
diff --git a/docs/.vitepress/config/plugins/demo-preview.ts b/docs/.vitepress/config/plugins/demo-preview.ts
index 03b1698ca..ba3863b0b 100644
--- a/docs/.vitepress/config/plugins/demo-preview.ts
+++ b/docs/.vitepress/config/plugins/demo-preview.ts
@@ -84,7 +84,7 @@ export const demoPreviewPlugin = (md: MarkdownRenderer) => {
return '';
}
const firstString = 'index.vue';
- childFiles = childFiles.sort((a, b) => {
+ childFiles = childFiles.toSorted((a, b) => {
if (a === firstString) return -1;
if (b === firstString) return 1;
return a.localeCompare(b, 'en', { sensitivity: 'base' });
diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md
index 48772bfac..30cbec448 100644
--- a/docs/src/components/common-ui/vben-form.md
+++ b/docs/src/components/common-ui/vben-form.md
@@ -335,6 +335,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
| handleReset | 表单重置回调 | `(values: Record
,) => Promise \| void` | - |
| handleSubmit | 表单提交回调 | `(values: Record,) => Promise \| void` | - |
| handleValuesChange | 表单值变化回调 | `(values: Record, fieldsChanged: string[]) => void` | - |
+| handleCollapsedChange | 表单收起展开状态变化回调 | `(collapsed: boolean) => void` | - |
| actionButtonsReverse | 调换操作按钮位置 | `boolean` | `false` |
| resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - |
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |
diff --git a/docs/src/demos/vben-drawer/auto-height/drawer.vue b/docs/src/demos/vben-drawer/auto-height/drawer.vue
index 9ab433ccb..a0bf60a0e 100644
--- a/docs/src/demos/vben-drawer/auto-height/drawer.vue
+++ b/docs/src/demos/vben-drawer/auto-height/drawer.vue
@@ -32,7 +32,7 @@ function handleUpdate(len: number) {
{{ item }}
diff --git a/docs/src/demos/vben-modal/auto-height/modal.vue b/docs/src/demos/vben-modal/auto-height/modal.vue
index 8757d5ef0..e3bec0db3 100644
--- a/docs/src/demos/vben-modal/auto-height/modal.vue
+++ b/docs/src/demos/vben-modal/auto-height/modal.vue
@@ -32,7 +32,7 @@ function handleUpdate(len: number) {
{{ item }}
diff --git a/internal/lint-configs/commitlint-config/index.mjs b/internal/lint-configs/commitlint-config/index.mjs
index 3d854399f..36c3b09ac 100644
--- a/internal/lint-configs/commitlint-config/index.mjs
+++ b/internal/lint-configs/commitlint-config/index.mjs
@@ -21,7 +21,7 @@ const scopeComplete = execSync('git status --porcelain || true')
.trim()
.split('\n')
.find((r) => ~r.indexOf('M src'))
- ?.replace(/(\/)/g, '%%')
+ ?.replaceAll(/(\/)/g, '%%')
?.match(/src%%((\w|-)*)/)?.[1]
?.replace(/s$/, '');
diff --git a/internal/lint-configs/eslint-config/src/configs/command.ts b/internal/lint-configs/eslint-config/src/configs/command.ts
index 67651b233..d0c902de2 100644
--- a/internal/lint-configs/eslint-config/src/configs/command.ts
+++ b/internal/lint-configs/eslint-config/src/configs/command.ts
@@ -3,7 +3,6 @@ import createCommand from 'eslint-plugin-command/config';
export async function command() {
return [
{
- // @ts-expect-error - no types
...createCommand(),
},
];
diff --git a/internal/lint-configs/eslint-config/src/configs/node.ts b/internal/lint-configs/eslint-config/src/configs/node.ts
index fa960d85e..f8f266436 100644
--- a/internal/lint-configs/eslint-config/src/configs/node.ts
+++ b/internal/lint-configs/eslint-config/src/configs/node.ts
@@ -35,7 +35,7 @@ export async function node(): Promise {
'error',
{
ignores: [],
- version: '>=18.0.0',
+ version: '>=20.12.0',
},
],
'n/prefer-global/buffer': ['error', 'never'],
diff --git a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
index 136bfa332..4a7d12fe9 100644
--- a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
+++ b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
@@ -4,7 +4,6 @@ import { interopDefault } from '../util';
export async function perfectionist(): Promise {
const perfectionistPlugin = await interopDefault(
- // @ts-expect-error - no types
import('eslint-plugin-perfectionist'),
);
diff --git a/internal/lint-configs/eslint-config/src/configs/turbo.ts b/internal/lint-configs/eslint-config/src/configs/turbo.ts
index 9f6bf75be..bcc27eb69 100644
--- a/internal/lint-configs/eslint-config/src/configs/turbo.ts
+++ b/internal/lint-configs/eslint-config/src/configs/turbo.ts
@@ -4,7 +4,6 @@ import { interopDefault } from '../util';
export async function turbo(): Promise {
const [pluginTurbo] = await Promise.all([
- // @ts-expect-error - no types
interopDefault(import('eslint-config-turbo')),
] as const);
diff --git a/internal/lint-configs/eslint-config/src/configs/typescript.ts b/internal/lint-configs/eslint-config/src/configs/typescript.ts
index cff9aa4bc..2f6f97650 100644
--- a/internal/lint-configs/eslint-config/src/configs/typescript.ts
+++ b/internal/lint-configs/eslint-config/src/configs/typescript.ts
@@ -5,7 +5,6 @@ import { interopDefault } from '../util';
export async function typescript(): Promise {
const [pluginTs, parserTs] = await Promise.all([
interopDefault(import('@typescript-eslint/eslint-plugin')),
- // @ts-expect-error missing types
interopDefault(import('@typescript-eslint/parser')),
] as const);
@@ -27,11 +26,11 @@ export async function typescript(): Promise {
},
},
plugins: {
- '@typescript-eslint': pluginTs,
+ '@typescript-eslint': pluginTs as any,
},
rules: {
- ...pluginTs.configs['eslint-recommended'].overrides?.[0].rules,
- ...pluginTs.configs.strict.rules,
+ ...pluginTs.configs['eslint-recommended']?.overrides?.[0]?.rules,
+ ...pluginTs.configs.strict?.rules,
'@typescript-eslint/ban-ts-comment': [
'error',
{
diff --git a/internal/lint-configs/eslint-config/src/configs/vue.ts b/internal/lint-configs/eslint-config/src/configs/vue.ts
index a64c55aff..5db72992d 100644
--- a/internal/lint-configs/eslint-config/src/configs/vue.ts
+++ b/internal/lint-configs/eslint-config/src/configs/vue.ts
@@ -6,7 +6,6 @@ export async function vue(): Promise {
const [pluginVue, parserVue, parserTs] = await Promise.all([
interopDefault(import('eslint-plugin-vue')),
interopDefault(import('vue-eslint-parser')),
- // @ts-expect-error missing types
interopDefault(import('@typescript-eslint/parser')),
] as const);
diff --git a/internal/lint-configs/eslint-config/tsconfig.json b/internal/lint-configs/eslint-config/tsconfig.json
index b2ec3b61e..dbd3bcc8d 100644
--- a/internal/lint-configs/eslint-config/tsconfig.json
+++ b/internal/lint-configs/eslint-config/tsconfig.json
@@ -1,6 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/node.json",
+ "compilerOptions": {
+ "moduleResolution": "bundler"
+ },
"include": ["src"],
"exclude": ["node_modules"]
}
diff --git a/internal/tailwind-config/package.json b/internal/tailwind-config/package.json
index 07b26be4f..269558cdd 100644
--- a/internal/tailwind-config/package.json
+++ b/internal/tailwind-config/package.json
@@ -53,6 +53,7 @@
"@tailwindcss/typography": "catalog:",
"autoprefixer": "catalog:",
"cssnano": "catalog:",
+ "jiti": "catalog:",
"postcss": "catalog:",
"postcss-antd-fixes": "catalog:",
"postcss-import": "catalog:",
diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts
index 8b3a4fcc6..298cea070 100644
--- a/internal/vite-config/src/config/application.ts
+++ b/internal/vite-config/src/config/application.ts
@@ -114,7 +114,7 @@ function createCssOptions(injectGlobalScss = true): CSSOptions {
}
return content;
},
- api: 'modern',
+ // api: 'modern',
importers: [new NodePackageImporter()],
},
}
diff --git a/package.json b/package.json
index 8229c713f..cb63ee096 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,7 @@
"node": ">=20.12.0",
"pnpm": ">=10.14.0"
},
- "packageManager": "pnpm@10.14.0",
+ "packageManager": "pnpm@10.22.0",
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
@@ -110,6 +110,7 @@
"@ctrl/tinycolor": "catalog:",
"clsx": "catalog:",
"esbuild": "0.25.3",
+ "jiti": "catalog:",
"pinia": "catalog:",
"vue": "catalog:"
},
diff --git a/packages/@core/base/design/src/design-tokens/index.ts b/packages/@core/base/design/src/design-tokens/index.ts
index 2d031d81f..4bf1467d3 100644
--- a/packages/@core/base/design/src/design-tokens/index.ts
+++ b/packages/@core/base/design/src/design-tokens/index.ts
@@ -1,4 +1,2 @@
import './default.css';
import './dark.css';
-
-export {};
diff --git a/packages/@core/base/design/src/index.ts b/packages/@core/base/design/src/index.ts
index d7c05340c..952caef7a 100644
--- a/packages/@core/base/design/src/index.ts
+++ b/packages/@core/base/design/src/index.ts
@@ -4,5 +4,3 @@ import './css/global.css';
import './css/transition.css';
import './css/nprogress.css';
import './css/ui.css';
-
-export {};
diff --git a/packages/@core/base/shared/package.json b/packages/@core/base/shared/package.json
index 495de4519..4a1c77dc4 100644
--- a/packages/@core/base/shared/package.json
+++ b/packages/@core/base/shared/package.json
@@ -86,11 +86,9 @@
"crypto-js": "catalog:",
"dayjs": "catalog:",
"defu": "catalog:",
+ "es-toolkit": "catalog:",
"jsencrypt": "catalog:",
"lodash.clonedeep": "catalog:",
- "lodash.get": "catalog:",
- "lodash.isequal": "catalog:",
- "lodash.set": "catalog:",
"nprogress": "catalog:",
"tailwind-merge": "catalog:",
"theme-colors": "catalog:"
diff --git a/packages/@core/base/shared/src/utils/index.ts b/packages/@core/base/shared/src/utils/index.ts
index 2a545447d..60554745b 100644
--- a/packages/@core/base/shared/src/utils/index.ts
+++ b/packages/@core/base/shared/src/utils/index.ts
@@ -20,7 +20,6 @@ export * from './upload';
export * from './util';
export * from './uuid'; // add by 芋艿:从 vben2.0 复制
export * from './window';
+export { get, isEqual, set } from 'es-toolkit/compat';
+// export { cloneDeep } from 'es-toolkit/object';
export { default as cloneDeep } from 'lodash.clonedeep';
-export { default as get } from 'lodash.get';
-export { default as isEqual } from 'lodash.isequal';
-export { default as set } from 'lodash.set';
diff --git a/packages/@core/preferences/src/preferences.ts b/packages/@core/preferences/src/preferences.ts
index 23c5f8bef..9ac8fb054 100644
--- a/packages/@core/preferences/src/preferences.ts
+++ b/packages/@core/preferences/src/preferences.ts
@@ -221,12 +221,8 @@ class PreferenceManager {
const dom = document.documentElement;
const COLOR_WEAK = 'invert-mode';
const COLOR_GRAY = 'grayscale-mode';
- colorWeakMode
- ? dom.classList.add(COLOR_WEAK)
- : dom.classList.remove(COLOR_WEAK);
- colorGrayMode
- ? dom.classList.add(COLOR_GRAY)
- : dom.classList.remove(COLOR_GRAY);
+ dom.classList.toggle(COLOR_WEAK, colorWeakMode);
+ dom.classList.toggle(COLOR_GRAY, colorGrayMode);
}
}
}
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 42101c124..36b1caa0c 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
@@ -47,7 +47,7 @@ async function handleSubmit(e: Event) {
return;
}
- const values = toRaw(await props.formApi.getValues());
+ const values = toRaw(await props.formApi.getValues()) ?? {};
await props.handleSubmit?.(values);
}
@@ -56,7 +56,7 @@ async function handleReset(e: Event) {
e?.stopPropagation();
const props = unref(rootProps);
- const values = toRaw(await props.formApi?.getValues());
+ const values = toRaw(await props.formApi?.getValues()) ?? {};
if (isFunction(props.handleReset)) {
await props.handleReset?.(values);
diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts
index f7f01be8f..40b9bd46e 100644
--- a/packages/@core/ui-kit/form-ui/src/form-api.ts
+++ b/packages/@core/ui-kit/form-ui/src/form-api.ts
@@ -36,6 +36,7 @@ function getDefaultState(): VbenFormProps {
handleReset: undefined,
handleSubmit: undefined,
handleValuesChange: undefined,
+ handleCollapsedChange: undefined,
layout: 'horizontal',
resetButtonOptions: {},
schema: [],
diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
index b308b251e..ef7a46a00 100644
--- a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
+++ b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
@@ -341,7 +341,7 @@ onUnmounted(() => {
:is="FieldComponent"
ref="fieldComponentRef"
:class="{
- 'border-destructive focus:border-destructive hover:border-destructive/80 focus:shadow-[0_0_0_2px_rgba(255,38,5,0.06)]':
+ 'border-destructive hover:border-destructive/80 focus:border-destructive focus:shadow-[0_0_0_2px_rgba(255,38,5,0.06)]':
isInValid,
}"
v-bind="createComponentProps(slotProps)"
diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts
index fd80c9e72..8cfcaa4bb 100644
--- a/packages/@core/ui-kit/form-ui/src/types.ts
+++ b/packages/@core/ui-kit/form-ui/src/types.ts
@@ -381,6 +381,10 @@ export interface VbenFormProps<
* 表单字段映射
*/
fieldMappingTime?: FieldMappingTime;
+ /**
+ * 表单收起展开状态变化回调
+ */
+ handleCollapsedChange?: (collapsed: boolean) => void;
/**
* 表单重置回调
*/
diff --git a/packages/@core/ui-kit/form-ui/src/use-form-context.ts b/packages/@core/ui-kit/form-ui/src/use-form-context.ts
index 4ef182edf..e95c87b96 100644
--- a/packages/@core/ui-kit/form-ui/src/use-form-context.ts
+++ b/packages/@core/ui-kit/form-ui/src/use-form-context.ts
@@ -13,7 +13,7 @@ import { useForm } from 'vee-validate';
import { object, ZodIntersection, ZodNumber, ZodObject, ZodString } from 'zod';
import { getDefaultsForSchema } from 'zod-defaults';
-type ExtendFormProps = VbenFormProps & { formApi: ExtendedFormApi };
+type ExtendFormProps = VbenFormProps & { formApi?: ExtendedFormApi };
export const [injectFormProps, provideFormProps] =
createContext<[ComputedRef | ExtendFormProps, FormActions]>(
diff --git a/packages/@core/ui-kit/form-ui/src/vben-form.vue b/packages/@core/ui-kit/form-ui/src/vben-form.vue
index 260e75cdb..f3ba37f07 100644
--- a/packages/@core/ui-kit/form-ui/src/vben-form.vue
+++ b/packages/@core/ui-kit/form-ui/src/vben-form.vue
@@ -40,7 +40,9 @@ const { delegatedSlots, form } = useFormInitial(props);
provideFormProps([props, form]);
const handleUpdateCollapsed = (value: boolean) => {
- currentCollapsed.value = !!value;
+ currentCollapsed.value = value;
+ // 触发收起展开状态变化回调
+ props.handleCollapsedChange?.(value);
};
watchEffect(() => {
diff --git a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
index 3e7b00b6c..e93867257 100644
--- a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
+++ b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
@@ -25,7 +25,7 @@ import {
} from './use-form-context';
// 通过 extends 会导致热更新卡死,所以重复写了一遍
interface Props extends VbenFormProps {
- formApi: ExtendedFormApi;
+ formApi?: ExtendedFormApi;
}
const props = defineProps();
@@ -44,11 +44,13 @@ provideComponentRefMap(componentRefMap);
props.formApi?.mount?.(form, componentRefMap);
const handleUpdateCollapsed = (value: boolean) => {
- props.formApi?.setState({ collapsed: !!value });
+ props.formApi?.setState({ collapsed: value });
+ // 触发收起展开状态变化回调
+ forward.value.handleCollapsedChange?.(value);
};
function handleKeyDownEnter(event: KeyboardEvent) {
- if (!state.value.submitOnEnter || !forward.value.formApi?.isMounted) {
+ if (!state?.value.submitOnEnter || !forward.value.formApi?.isMounted) {
return;
}
// 如果是 textarea 不阻止默认行为,否则会导致无法换行。
@@ -58,11 +60,11 @@ function handleKeyDownEnter(event: KeyboardEvent) {
}
event.preventDefault();
- forward.value.formApi.validateAndSubmitForm();
+ forward.value.formApi?.validateAndSubmitForm();
}
const handleValuesChangeDebounced = useDebounceFn(async () => {
- state.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm();
+ state?.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm();
}, 300);
const valuesCache: Recordable = {};
@@ -74,7 +76,7 @@ onMounted(async () => {
() => form.values,
async (newVal) => {
if (forward.value.handleValuesChange) {
- const fields = state.value.schema?.map((item) => {
+ const fields = state?.value.schema?.map((item) => {
return item.fieldName;
});
@@ -91,8 +93,9 @@ onMounted(async () => {
if (changedFields.length > 0) {
// 调用handleValuesChange回调,传入所有表单值的深拷贝和变更的字段列表
+ const values = await forward.value.formApi?.getValues();
forward.value.handleValuesChange(
- cloneDeep(await forward.value.formApi.getValues()),
+ cloneDeep(values ?? {}) as Record,
changedFields,
);
}
@@ -109,7 +112,7 @@ onMounted(async () => {