Pre Merge pull request !339 from 芋道源码/dev

pull/339/MERGE
芋道源码 2026-04-12 13:28:23 +00:00 committed by Gitee
commit a5d6d1d543
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
12 changed files with 64 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -82,9 +82,9 @@
![功能分层](/.gitee/image/common/ruoyi-vue-pro-biz.png)
- 通用模块(必选):系统功能、基础设施
- 通用模块(可选):工作流程、支付系统、数据报表、会员中心
- 业务系统按需ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
* 通用模块(必选):系统功能、基础设施
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
* 业务系统按需ERP 系统、CRM 系统、MES 系统、商城系统、微信公众号、AI 大模型、IoT 物联网
### 系统功能
@ -219,6 +219,16 @@
![功能图](/.gitee/image/common/mall-preview.png)
### 会员中心
| | 功能 | 描述 |
|-----|------|----------------------------------|
| 🚀 | 会员管理 | 会员是 C 端的消费者,该功能用于会员的搜索与管理 |
| 🚀 | 会员标签 | 对会员的标签进行创建、查询、修改、删除等操作 |
| 🚀 | 会员等级 | 对会员的等级、成长值进行管理,可用于订单折扣等会员权益 |
| 🚀 | 会员分组 | 对会员进行分组,用于用户画像、内容推送等运营手段 |
| 🚀 | 积分签到 | 回馈给签到、消费等行为的积分,会员可订单抵现、积分兑换等途径消耗 |
### ERP 系统
演示地址:<https://doc.iocoder.cn/erp-preview/>
@ -231,6 +241,14 @@
![功能图](/.gitee/image/common/crm-feature.png)
### MES 系统
演示地址:<https://doc.iocoder.cn/mes-preview/>
![功能图](/.gitee/image/common/mes-feature.png)
![功能图](/.gitee/image/common/mes-preview.png)
### AI 大模型
演示地址:<https://doc.iocoder.cn/ai-preview/>
@ -238,3 +256,11 @@
![功能图](/.gitee/image/common/ai-feature.png)
![功能图](/.gitee/image/common/ai-preview.gif)
### IoT 物联网
演示地址:<https://doc.iocoder.cn/iot/build>
![功能图](/.gitee/image/common/iot-feature.png)
![预览图](/.gitee/image/common/iot-preview.png)

View File

@ -3,6 +3,9 @@ import type { Recordable } from '@vben/types';
export * from './rangePickerProps';
export * from './routerHelper';
// 从共享包导出 URL 工具函数
export { isUrl } from '@vben/utils';
/**
*
* @param {Array} ary
@ -27,14 +30,3 @@ export const findIndex = <T = Recordable<any>>(
});
return index;
};
/**
* URL
* @param path URL
*/
export const isUrl = (path: string): boolean => {
// fix:修复hash路由无法跳转的问题
const reg =
/(((^https?:(?:\/\/)?)(?:[-:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%#/.\w-]*)?\??[-+=&%@.\w]*(?:#\w*)?)?)$/;
return reg.test(path);
};

View File

@ -41,8 +41,8 @@ const [Modal, modalApi] = useVbenModal({
onConfirm: handleOk,
onOpenChange(isOpen) {
if (isOpen) {
// loading CropperImage loading handleReady
modalLoading(true);
// loading loading
modalLoading(!!src.value);
} else {
//
previewSource.value = '';
@ -65,10 +65,14 @@ function handleBeforeUpload(file: File) {
reader.readAsDataURL(file);
src.value = '';
previewSource.value = '';
modalLoading(true);
reader.addEventListener('load', (e) => {
src.value = (e.target?.result as string) ?? '';
filename = file.name;
});
reader.addEventListener('error', () => {
modalLoading(false);
});
return false;
}
@ -82,6 +86,10 @@ function handleReady(cropperInstance: CropperType) {
modalLoading(false);
}
function handleCropperError() {
modalLoading(false);
}
function handlerToolbar(event: string, arg?: number) {
if (event === 'scaleX') {
scaleX = arg = scaleX === -1 ? 1 : -1;
@ -133,6 +141,7 @@ async function handleOk() {
:src="src"
height="300px"
@cropend="handleCropend"
@cropend-error="handleCropperError"
@ready="handleReady"
/>
</div>

View File

@ -144,6 +144,10 @@ function getRoundedCanvas() {
context.fill();
return canvas;
}
function handleImageError() {
emit('cropendError');
}
</script>
<template>
@ -155,6 +159,7 @@ function getRoundedCanvas() {
:crossorigin="crossorigin"
:src="src"
:style="getImageStyle"
@error="handleImageError"
class="h-auto max-w-full"
/>
</div>

View File

@ -3,6 +3,9 @@ import type { Recordable } from '@vben/types';
export * from './rangePickerProps';
export * from './routerHelper';
// 从共享包导出 URL 工具函数
export { isUrl } from '@vben/utils';
/**
*
* @param {Array} ary
@ -28,14 +31,3 @@ export const findIndex = <T = Recordable<any>>(
});
return index;
};
/**
* URL
* @param path URL
*/
export const isUrl = (path: string): boolean => {
// fix:修复hash路由无法跳转的问题
const reg =
/(((^https?:(?:\/\/)?)(?:[-:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%#/.\w-]*)?\??[-+=&%@.\w]*(?:#\w*)?)?)$/;
return reg.test(path);
};

View File

@ -18,6 +18,7 @@ export * from './tree';
export * from './unique';
export * from './update-css-variables';
export * from './upload';
export * from './url';
export * from './util';
export * from './uuid'; // add by 芋艿:从 vben2.0 复制
export * from './window';

View File

@ -0,0 +1,12 @@
/**
* URL
* @param path URL
*/
export function isUrl(path: string): boolean {
try {
new URL(path);
return true;
} catch {
return false;
}
}