diff --git a/build.gradle b/build.gradle index 62ddadd9..29658d65 100644 --- a/build.gradle +++ b/build.gradle @@ -333,6 +333,7 @@ subprojects { packageJson.name =project.name; packageJson.version =project.version; packageJson.dependencies['platform-core']=platform_core_frontend_version; + packageJson.dependencies['platform-components']=platform_components_frontend_version; def json = groovy.json.JsonOutput.toJson(packageJson); file('package.json').withWriter('UTF-8') { writer -> writer.write(groovy.json.JsonOutput.prettyPrint(json)); diff --git a/gradle.properties b/gradle.properties index ea14bc66..9348a35e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,7 +38,8 @@ application_version=1.0.0 platform_group=io.sc platform_version=8.1.8 platform_plugin_version=8.1.8 -platform_core_frontend_version=8.1.12 +platform_core_frontend_version=8.1.14 +platform_components_frontend_version=8.1.2 ########################################################### # dependencies version diff --git a/io.sc.platform.app/build.gradle b/io.sc.platform.app/build.gradle index beb657de..5d020de3 100644 --- a/io.sc.platform.app/build.gradle +++ b/io.sc.platform.app/build.gradle @@ -1,15 +1,17 @@ dependencies { api( - project(":io.sc.platform.ws.cxf"), - project(":io.sc.platform.system"), - project(":io.sc.platform.security.loginform"), + project(":io.sc.platform.csv"), + project(":io.sc.platform.communication"), + //project(":io.sc.platform.flowable"), + project(":io.sc.platform.groovy"), project(":io.sc.platform.jdbc.liquibase"), project(":io.sc.platform.jdbc.schemacrawler"), project(":io.sc.platform.lcdp"), project(":io.sc.platform.lcdp.frontend"), project(":io.sc.platform.orm.mybatis"), - project(":io.sc.platform.csv"), - project(":io.sc.platform.groovy"), + project(":io.sc.platform.security.loginform"), + project(":io.sc.platform.system"), + project(":io.sc.platform.ws.cxf"), project(":org.webjars.luckysheet-2.1.13"), project(":org.webjars.tailwindcss-3.3.5"), diff --git a/io.sc.platform.communication/build.gradle b/io.sc.platform.communication/build.gradle new file mode 100644 index 00000000..3abca14d --- /dev/null +++ b/io.sc.platform.communication/build.gradle @@ -0,0 +1,7 @@ +dependencies { + api( + project(":io.sc.platform.mvc"), + + "org.springframework.boot:spring-boot-starter-mail", + ) +} diff --git a/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/MailSenderService.java b/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/MailSenderService.java new file mode 100644 index 00000000..399b7675 --- /dev/null +++ b/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/MailSenderService.java @@ -0,0 +1,45 @@ +package io.sc.platform.communication.service; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + +import org.springframework.mail.SimpleMailMessage; + +/** + * 邮件发送器服务 + */ +public interface MailSenderService { + /** + * 发送简单邮件 + * @param from 发件人 + * @param to 收件人 + * @param cc 抄送人 + * @param subject 标题 + * @param text 文本 + */ + public void sendSimpleMessage(String from,String[] to,String[] cc,String subject,String text); + + /** + * 发送简单邮件 + * @param messages 邮件消息 + */ + public void sendSimpleMessage(SimpleMailMessage... messages); + + + /** + * 发送富文本邮件 + * @param from 发件人 + * @param to 收件人 + * @param cc 抄送人 + * @param subject 标题 + * @param text 文本 + * @throws MessagingException 违例 + */ + public void sendMimeMessage(String from,String[] to,String[] cc,String subject,String text) throws MessagingException; + + /** + * 发送富文本邮件 + * @param mimeMessages 邮件消息 + */ + public void sendMimeMessage(MimeMessage... mimeMessages); +} diff --git a/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/impl/MailSenderServiceImpl.java b/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/impl/MailSenderServiceImpl.java new file mode 100644 index 00000000..c75f1b93 --- /dev/null +++ b/io.sc.platform.communication/src/main/java/io/sc/platform/communication/service/impl/MailSenderServiceImpl.java @@ -0,0 +1,66 @@ +package io.sc.platform.communication.service.impl; + +import javax.annotation.PostConstruct; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + +import io.sc.platform.communication.service.MailSenderService; +import io.sc.platform.core.util.BeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; + +@Service +public class MailSenderServiceImpl implements MailSenderService { + @Autowired private ApplicationContext applicationContext; + private JavaMailSender mailSender; + + @PostConstruct + public void initMailSenderService(){ + this.mailSender = BeanUtil.getBean(applicationContext,JavaMailSender.class); + } + + @Override + public void sendSimpleMessage(String from, String[] to, String[] cc, String subject, String text) { + if(mailSender!=null){ + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(from); + message.setTo(to); + message.setCc(cc); + message.setSubject(subject); + message.setText(text); + sendSimpleMessage(message); + } + } + + @Override + public void sendSimpleMessage(SimpleMailMessage... messages) { + if(mailSender!=null){ + mailSender.send(messages); + } + } + + @Override + public void sendMimeMessage(String from, String[] to, String[] cc, String subject, String html) throws MessagingException { + if(mailSender!=null) { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true); + helper.setFrom(from); + helper.setTo(to); + helper.setCc(cc); + helper.setSubject(subject); + helper.setText(html, true); + sendMimeMessage(message); + } + } + + @Override + public void sendMimeMessage(MimeMessage... mimeMessages) { + if(mailSender!=null) { + mailSender.send(mimeMessages); + } + } +} diff --git a/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/application-properties.json b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/application-properties.json new file mode 100644 index 00000000..e1962098 --- /dev/null +++ b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/application-properties.json @@ -0,0 +1,17 @@ +[ + { + "module" : "io.sc.platform.communication", + "order" : 4000, + "description": "email configuration", + "properties": [ + "spring.mail.host=zzz.xxx.yyy", + "spring.mail.port=25", + "spring.mail.protocol=smtp", + "spring.mail.test-connection=false", + "spring.mail.default-encoding=UTF-8", + "spring.mail.properties.mail.smtp.auth=true", + "spring.mail.username=xxx", + "spring.mail.password=yyy" + ] + } +] \ No newline at end of file diff --git a/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/components.json b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/components.json new file mode 100644 index 00000000..71c12f94 --- /dev/null +++ b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/components.json @@ -0,0 +1,5 @@ +{ + "includes":[ + "io.sc.platform.communication.service.impl" + ] +} \ No newline at end of file diff --git a/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/restart-properties.json b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/restart-properties.json new file mode 100644 index 00000000..c5313555 --- /dev/null +++ b/io.sc.platform.communication/src/main/resources/META-INF/platform/plugins/restart-properties.json @@ -0,0 +1,22 @@ +{ + "container":[ + "spring.mail.host", + "spring.mail.port", + "spring.mail.protocol", + "spring.mail.test-connection", + "spring.mail.default-encoding", + "spring.mail.properties.mail.smtp.auth", + "spring.mail.username", + "spring.mail.password" + ], + "jar": [ + "spring.mail.host", + "spring.mail.port", + "spring.mail.protocol", + "spring.mail.test-connection", + "spring.mail.default-encoding", + "spring.mail.properties.mail.smtp.auth", + "spring.mail.username", + "spring.mail.password" + ] +} \ No newline at end of file diff --git a/io.sc.platform.components.frontend/package.json b/io.sc.platform.components.frontend/package.json index 914872bf..94374ef3 100644 --- a/io.sc.platform.components.frontend/package.json +++ b/io.sc.platform.components.frontend/package.json @@ -93,12 +93,10 @@ "platform-core": "8.1.12", "platform-components": "8.1.2", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", - "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "vue-router": "4.2.5" } } diff --git a/io.sc.platform.components.frontend/src/App.vue b/io.sc.platform.components.frontend/src/App.vue index 15499133..7fcbc8cb 100644 --- a/io.sc.platform.components.frontend/src/App.vue +++ b/io.sc.platform.components.frontend/src/App.vue @@ -1,7 +1,5 @@ + diff --git a/io.sc.platform.core.frontend/src/platform/component/app/WPlatformPage.vue b/io.sc.platform.core.frontend/src/platform/components/app/WPlatformPage.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/app/WPlatformPage.vue rename to io.sc.platform.core.frontend/src/platform/components/app/WPlatformPage.vue diff --git a/io.sc.platform.core.frontend/src/platform/components/dialog/PlatformDialog.vue b/io.sc.platform.core.frontend/src/platform/components/dialog/PlatformDialog.vue new file mode 100644 index 00000000..76546814 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/dialog/PlatformDialog.vue @@ -0,0 +1,118 @@ + + + diff --git a/io.sc.platform.core.frontend/src/platform/components/dialog/WDialog.vue b/io.sc.platform.core.frontend/src/platform/components/dialog/WDialog.vue new file mode 100644 index 00000000..e0ebd6e5 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/dialog/WDialog.vue @@ -0,0 +1,107 @@ + + + diff --git a/io.sc.platform.core.frontend/src/platform/components/drawer/PlatformDrawer.vue b/io.sc.platform.core.frontend/src/platform/components/drawer/PlatformDrawer.vue new file mode 100644 index 00000000..841550a3 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/drawer/PlatformDrawer.vue @@ -0,0 +1,103 @@ + + + diff --git a/io.sc.platform.core.frontend/src/platform/components/form/PlatformForm.vue b/io.sc.platform.core.frontend/src/platform/components/form/PlatformForm.vue new file mode 100644 index 00000000..64ab2185 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/form/PlatformForm.vue @@ -0,0 +1,528 @@ + + + diff --git a/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGrid.vue b/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGrid.vue new file mode 100644 index 00000000..575b14e5 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGrid.vue @@ -0,0 +1,2322 @@ + + + + + diff --git a/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGridTdDrag.vue b/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGridTdDrag.vue new file mode 100644 index 00000000..30a64299 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/grid/PlatformGridTdDrag.vue @@ -0,0 +1,30 @@ + + + diff --git a/io.sc.platform.core.frontend/src/platform/component/icon/WIconEmpty.vue b/io.sc.platform.core.frontend/src/platform/components/icon/WIconEmpty.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/icon/WIconEmpty.vue rename to io.sc.platform.core.frontend/src/platform/components/icon/WIconEmpty.vue diff --git a/io.sc.platform.core.frontend/src/platform/component/index.ts b/io.sc.platform.core.frontend/src/platform/components/index.ts similarity index 52% rename from io.sc.platform.core.frontend/src/platform/component/index.ts rename to io.sc.platform.core.frontend/src/platform/components/index.ts index f80f8305..b14e194f 100644 --- a/io.sc.platform.core.frontend/src/platform/component/index.ts +++ b/io.sc.platform.core.frontend/src/platform/components/index.ts @@ -7,6 +7,12 @@ import WColorInput from './widget/color/WColorInput.vue'; import WColorInputPalette from './widget/color/WColorInputPalette.vue'; import WPosition from './widget/position/WPosition.vue'; +import PlatformDialog from './dialog/PlatformDialog.vue'; +import PlatformDrawer from './drawer/PlatformDrawer.vue'; +import PlatformForm from './form/PlatformForm.vue'; +import PlatformGrid from './grid/PlatformGrid.vue'; +import PlatformGridTdDrag from './grid/PlatformGridTdDrag.vue'; + export default { install: (app: App) => { app.component('WPlatformPage', WPlatformPage); @@ -16,7 +22,25 @@ export default { app.component('WColorInput', WColorInput); app.component('WColorInputPalette', WColorInputPalette); app.component('WPosition', WPosition); + + app.component('PlatformDialog', PlatformDialog); + app.component('PlatformDrawer', PlatformDrawer); + app.component('PlatformForm', PlatformForm); + app.component('PlatformGrid', PlatformGrid); + app.component('PlatformGridTdDrag', PlatformGridTdDrag); }, }; -export { WPlatformPage, WIconEmpty, WHScreenDiv, WColorInput, WColorInputPalette }; +export { + WPlatformPage, + WIconEmpty, + WHScreenDiv, + WColorInput, + WColorInputPalette, + WPosition, + PlatformDialog, + PlatformDrawer, + PlatformForm, + PlatformGrid, + PlatformGridTdDrag, +}; diff --git a/io.sc.platform.core.frontend/src/platform/component/layout/WHScreenDiv.vue b/io.sc.platform.core.frontend/src/platform/components/layout/WHScreenDiv.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/layout/WHScreenDiv.vue rename to io.sc.platform.core.frontend/src/platform/components/layout/WHScreenDiv.vue diff --git a/io.sc.platform.core.frontend/src/platform/component/layout/WVExpandDiv.vue b/io.sc.platform.core.frontend/src/platform/components/layout/WVExpandDiv.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/layout/WVExpandDiv.vue rename to io.sc.platform.core.frontend/src/platform/components/layout/WVExpandDiv.vue diff --git a/io.sc.platform.core.frontend/src/platform/components/panel/PlatformInfo.vue b/io.sc.platform.core.frontend/src/platform/components/panel/PlatformInfo.vue new file mode 100644 index 00000000..2002435b --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/panel/PlatformInfo.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/io.sc.platform.core.frontend/src/platform/component/svg/WSvgEditor.vue b/io.sc.platform.core.frontend/src/platform/components/svg/WSvgEditor.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/svg/WSvgEditor.vue rename to io.sc.platform.core.frontend/src/platform/components/svg/WSvgEditor.vue diff --git a/io.sc.platform.core.frontend/src/platform/components/utils/commUtil.ts b/io.sc.platform.core.frontend/src/platform/components/utils/commUtil.ts new file mode 100644 index 00000000..c163d1f8 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/utils/commUtil.ts @@ -0,0 +1,186 @@ +import { QVueGlobals } from 'quasar'; + +/** + * 平台icon,使用【material icons】,以下为列举的一些平台常用的图标,并不包含全部 + * 不在该枚举中时可使用自定义的图标,目的是以后方便全局替换。 + */ +export enum PlatformIconEnum { + 查询 = 'search', + 更多查询 = 'zoom_in', + 重置 = 'restart_alt', + 刷新 = 'loop', + 新增 = 'add', + 新增2 = 'add_box', + 新增3 = 'playlist_add_circle', + 编辑 = 'edit', + 删除 = 'delete', + 查看 = 'visibility', + 全屏 = 'fullscreen', + 退出全屏 = 'fullscreen_exit', + 关闭 = 'close', + 保存 = 'save', + 提交 = 'beenhere', + 字母 = 'abc', + 时钟 = 'access_time', + 上箭头 = 'arrow_upward', + 下箭头 = 'arrow_downward', + 左箭头 = 'arrow_back', + 右箭头 = 'arrow_forward', + 附件 = 'attach_file', + 否状态 = 'cancel', + 是状态 = 'check_circle', + 首页 = 'home', + 设置 = 'settings', + 设置2 = 'settings_applications', + 扳手 = 'build_circle', + 收起 = 'arrow_drop_up', + 展开 = 'arrow_drop_down', + 提示 = 'info', + 警告 = 'warning', + 日期 = 'event', + 日期范围 = 'date_range', + 文件夹 = 'folder', + 校验 = 'published_with_changes', + 下载 = 'download', + 上传 = 'upload', + 选取变量 = 'find_in_page', + 报表通用 = 'assessment', + 复制 = 'file_copy', + 发送 = 'send', +} + +/** + * 页面状态(包含:新增=add、编辑=edit、查看=view) + */ +export enum PageStatusEnum { + 新增 = 'add', + 编辑 = 'edit', + 查看 = 'view', +} + +/** + * Form元素类型枚举 + */ +export enum FormTypeEnum { + 文本框 = 'text', + 文本域 = 'textarea', + 下拉框 = 'select', + 多选下拉框 = 'selectMultiple', + 数字框 = 'number', + 日期 = 'date', + 日期时间 = 'dateTime', + 日期范围 = 'dateRange', +} + +/** + * 数据类型枚举 + */ +export enum DataTypeEnum { + 字符串 = 'String', + 整数 = 'Integer', + 小数 = 'BigDecimal', + 日期 = 'Date', + 布尔 = 'Boolean', +} + +/** + * 下拉框选项值来源枚举 + */ +export enum OptionComeFromEnum { + 数据字典 = 'dictionary', + Java接口 = 'javaApi', + 自定义数组 = 'array', +} + +/** + * 平台Form组件内置校验name枚举 + */ +export enum FormComponentValidateEnum { + 字符串不能包含空格校验 = 'noSpace', + 必须为整数校验 = 'integer', + 默认日期格式校验 = 'date', + 字符串最大长度校验 = 'maxLength', + 最大小数位数校验 = 'maxPrecision', + 数字最小值校验 = 'minValue', + 数字最大值校验 = 'maxValue', +} + +/** + * 查询操作类型枚举 + */ +export enum OperatorTypeEnum { + isBlank = 'isBlank', // value is null or value='' + notBlank = 'notBlank', // value is not null && value<>'' + + isNull = 'isNull', // value is null + notNull = 'notNull', // value is not null + + equals = 'equals', // = + notEqual = 'notEqual', // <> + + greaterThan = 'greaterThan', // > + greaterOrEqual = 'greaterOrEqual', // >= + + lessThan = 'lessThan', // < + lessOrEqual = 'lessOrEqual', // <= + + contains = 'contains', // like %xxx% + notContains = 'notContains', // not like %xxx% + + startsWith = 'startsWith', // like xxx% + notStartsWith = 'notStartsWith', // not like xxx% + + endsWith = 'endsWith', // like %xxx + notEndsWith = 'notEndsWith', // not like %xxx + + between = 'between', // min {} }], + timeout: 3000, + }); +} + +/** + * 判断是否为空(一般用于Form元素) + * @param obj 需要判断的对象 + * @returns + */ +export function isEmpty(obj) { + if (typeof obj === 'undefined' || obj === null || obj === '') { + return true; + } else { + return false; + } +} diff --git a/io.sc.platform.core.frontend/src/platform/components/utils/componentComm.ts b/io.sc.platform.core.frontend/src/platform/components/utils/componentComm.ts new file mode 100644 index 00000000..46a98ca8 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/utils/componentComm.ts @@ -0,0 +1,332 @@ +import { Tools } from '@/platform/utils'; +/** + * 抽取窗口组件属性 + * @param {Object} props 属性对象 + * @returns 窗口组件属性 + */ +export function extractDialogProps(props: any) { + if (props) { + const result: any = {}; + result.persistent = props.persistent; // 设置后,用户在对话框外单击或按 ESC 键时不再关闭对话框;此外,应用程序路由更改也不会关闭它 + result.noEscDismiss = props.noEscDismiss; // 用户不能按 ESC 键关闭对话框;如果还设置了 'persistent' 属性,则无需设置它 + result.noBackdropDismiss = props.noBackdropDismiss; // 用户不能通过单击对话框外部来关闭对话框;如果还设置了 'persistent' 属性,则无需设置它 + result.noRouteDismiss = props.noRouteDismiss; // 更改路由应用程序不会关闭对话框;如果还设置了 'persistent' 属性,则无需设置它 + result.autoClose = props.autoClose; // 对话框内的任何单击/点击都将关闭它 + result.noShake = props.noShake; // 不要晃动对话框来引起用户的注意。 + result.allowFocusOutside = props.allowFocusOutside; // 允许对话框外的元素可聚焦;出于辅助功能的原因,默认情况下 QDialog 不允许外部聚焦. + result.seamless = props.seamless; // 使对话框进入无缝模式;不使用背景,因此用户也可以与页面的其他部分进行交互 + result.position = props.position; // 将对话框附着到一侧(默认:standard、top、right、bottom、left) + result.square = props.square; // 强制内容具有方形边框 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 抽取form表单组件属性 + * @param {Object} props 属性对象 + * @returns 表单组件属性 + */ +export function extractFormProps(props: any) { + if (props) { + const result: any = {}; + result.autofocus = props.autofocus; // 在初始组件渲染时将第一个可聚焦元素聚焦 + result.greedy = props.greedy; // 验证表单中的所有字段(默认情况下,它在通过同步的验证找到第一个无效字段后停止) + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 抽取表单项组件属性 + * @param {String} type 组件类型 + * @param {Object} props 属性对象 + * @returns 表单项组件属性 + */ +export function extractFormItemComponentProps(type: string, props: any) { + if ('dateRange' === type) { + return dateRange(props); + } else if ('date' === type) { + return date(props); + } else if ('select' === type) { + return select(props); + } else if ('checkbox' === type) { + return checkbox(props); + } else if ('optionGroup' === type) { + return optionGroup(props); + } else { + return input(props); + } +} + +/** + * input组件 + * @param props + * @returns + */ +function input(props: any) { + if (props) { + const result: any = {}; + result.hint = props.hint; // 辅助(提示)文本,放在组件下面 + result.hideBottomSpace = props.hideBottomSpace ?? true; + result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本 + result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有) + result.prefix = props.prefix; // 前缀 + result.suffix = props.suffix; // 后缀 + result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空 + result.counter = props.counter; // 在右下角显示自动计数器(字符数) + result.autogrow = props.autogrow; // 使字段及其内容自动增长(内容过长时组件变高,内容换行) + result.maxlength = props.maxlength; // 指定模型的最大长度 + result.disable = props.disable; // 将组件置于禁用模式 + result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称 + result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称 + result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称 + result.filled = props.filled; // 对字段使用“填充”设计 + result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计 + result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突 + result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆 + result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间 + result.type = props.type; // 组件类型 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 日期范围组件 + * @param props + * @returns + */ +function dateRange(props: any) { + if (props) { + const result: any = {}; + result.hint = props.hint; // 辅助(提示)文本,放在组件下面 + result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本 + result.hideBottomSpace = props.hideBottomSpace ?? true; + result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有) + result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空 + result.disable = props.disable; // 将组件置于禁用模式 + result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称 + result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称 + result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称 + result.filled = props.filled; // 对字段使用“填充”设计 + result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计 + result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突 + result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆 + result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 日期组件 + * @param props + * @returns + */ +function date(props: any) { + if (props) { + const result: any = {}; + result.hint = props.hint; // 辅助(提示)文本,放在组件下面 + result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本 + result.hideBottomSpace = props.hideBottomSpace ?? true; + result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有) + result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空 + result.disable = props.disable; // 将组件置于禁用模式 + result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称 + result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称 + result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称 + result.filled = props.filled; // 对字段使用“填充”设计 + result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计 + result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突 + result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆 + result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 下拉框组件 + * @param props + * @returns + */ +function select(props: any) { + if (props) { + const result: any = {}; + result.hint = props.hint; // 辅助(提示)文本,放在组件下面 + result.hideHint = props.hideHint ?? true; // 当字段没有焦点时隐藏辅助(提示)文本 + result.hideBottomSpace = props.hideBottomSpace ?? true; + result.stackLabel = props.stackLabel; // 标签将始终显示在字段上方,而不考虑字段内容(如果有) + result.prefix = props.prefix; // 前缀 + result.suffix = props.suffix; // 后缀 + result.clearable = props.clearable; // 设置值(非 undefined 或 null )时附加可清除图标;单击时,模型将变为空 + result.counter = props.counter; // 在右下角显示自动计数器(字符数) + result.useInput = props.useInput; // 使用一个输入标签,用户可以在其中输入 + result.autogrow = props.autogrow; // 使字段及其内容自动增长(内容过长时组件变高,内容换行) + result.disable = props.disable; // 将组件置于禁用模式 + result.labelColor = props.labelColor; // 组件 label 的文字颜色,来自 Quasar 调色板的颜色名称 + result.color = props.color; // 组件颜色,来自 Quasar 调色板的颜色名称 + result.bgColor = props.bgColor; // 组件背景颜色,来自 Quasar 调色板的颜色名称 + result.filled = props.filled; // 对字段使用“填充”设计 + result.outlined = props.outlined ?? true; // 对字段使用“轮廓线”设计 + result.borderless = props.borderless; // 对字段采用“无边界”设计,与 outlined 冲突 + result.rounded = props.rounded; // 为组件应用较小标准的边框圆角,也就是边框为椭圆 + result.dense = props.dense ?? true; // 紧凑模式,占用更少的空间 + result.multiple = props.multiple; // 支持多选 + result.options = props.options; // 下拉选项集合 + result.maxValues = props.maxValues; // 允许用户可以进行的最大选择数 + result.useChips = props.useChips; // 使用QChip显示当前选择的内容 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 复选框组件 + * @param props + * @returns + */ +function checkbox(props: any) { + if (props) { + const result: any = {}; + result.keepColor = props.keepColor; // 当组件未勾选/关闭时,是否应保留颜色? + result.checkedIcon = props.checkedIcon; // 此图标将会在 model 值为 true 时被使用(代替默认的设计) + result.uncheckedIcon = props.uncheckedIcon; // 此图标将会在 model 值为 false 时被使用(代替默认的设计) + result.toggleIndeterminate = props.toggleIndeterminate ?? false; // 当用户点击组件时,除 true 和 false 外,是否还添加一个不确定(indeterminate)的状态? + result.leftLabel = props.leftLabel; // 如有标签,应显示在组件的左侧 + result.trueValue = props.trueValue; // model 为何值时被视为选中/勾选/启用? + result.falseValue = props.falseValue; // model 为何值时被视为未选中/未勾选/关闭? + result.disable = props.disable; // 将组件置于禁用模式 + result.size = props.size; // 带有 CSS 单位的尺寸大小,包括单位的名称或标准大小名称(xs | sm | md | lg | xl) + result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称 + result.dense = props.dense; // 紧凑模式,占用更少的空间 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 选项组组件 + * @param props + * @returns + */ +function optionGroup(props: any) { + if (props) { + const result: any = {}; + result.name = props.name; // 用于指定控件的名称;如果处理直接提交到 URL 的表单时很有用 + result.keepColor = props.keepColor; // 当组件未勾选/关闭时,是否应保留颜色? + result.type = props.optionGroupType; // 要使用的输入组件类型,默认radio,可选:radio、checkbox、toggle + result.leftLabel = props.leftLabel; // 如有标签,应显示在组件的左侧 + result.inline = props.inline ?? true; // 将输入组件显示为内联块,而不是每个组件都有自己的行 + result.options = props.options; //具有值、标签和禁用(可选)属性的对象数组,包含的属性:label、value、disable等 + result.disable = props.disable; // 将组件置于禁用模式下 + result.size = props.size; // 带有 CSS 单位的尺寸大小,包括单位的名称或标准大小名称(xs | sm | md | lg | xl) + result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称 + result.dense = props.dense; // 紧凑模式,占用更少的空间 + return Tools.pickNotNil(result); + } + return {}; +} + +/** + * 抽取表格组件属性 + * @param {Object} props 属性对象 + * @returns 表格组件属性 + */ +export function extractTableProps(props: any) { + if (props) { + const result: any = {}; + result.color = props.color; // 组件的颜色,来自 Quasar 调色板的颜色名称 + result.dense = props.dense; // 密恐模式; + result.dark = props.dark; // 设置组件背景为深色 + result.flat = props.flat; // 应用“平面”设计(无默认阴影) + result.bordered = props.bordered; // 将默认边框应用于组件 + result.square = props.square; // 删除边框圆角(border-radius),使边框为正方形 + return Tools.pickNotNil(result); + } + return {}; +} + +function columnStyle(item: any) { + let style = ''; + if (Object.hasOwnProperty.call(item, 'style')) { + style = item.style; + } + if (Object.hasOwnProperty.call(item, 'width')) { + item.style = `min-width: ` + item.width + `px; max-width: ` + item.width + `px;` + style; + delete item.width; + + if (Object.hasOwnProperty.call(item, 'classes')) { + item.classes = item.classes + ' truncate'; + } else { + item.classes = 'truncate'; + } + } +} +function columnChildrenHandler(item: any, gridColumns: any) { + if (item.childrenColumns && item.childrenColumns.length > 0) { + item.childrenColumns.forEach((column) => { + columnChildrenHandler(column, gridColumns); + }); + } else { + columnStyle(item); + gridColumns.push({ + ...{ align: 'left', label: item.name, field: item.name, sortable: true }, + ...item, + }); + } +} +/** + * 处理表格列属性 + */ +export function extractTableColumnsProps(props: any) { + const gridColumns = []; + if (props.tableColumns && props.tableColumns.length > 0) { + if (props.tableShowSortNo) { + gridColumns.push({ name: '_sortNo_', align: 'center', label: '序号', field: '_sortNo_' }); + } + props.tableColumns.forEach((item: any) => { + columnChildrenHandler(item, gridColumns); + }); + return gridColumns; + } + return []; +} + +const formColsScreenMap = new Map(); +formColsScreenMap.set(1, { xs: 1, sm: 1, md: 2, lg: 3, xl: 4 }); +formColsScreenMap.set(2, { xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }); +formColsScreenMap.set(3, { xs: 1, sm: 2, md: 3, lg: 4, xl: 6 }); +formColsScreenMap.set(4, { xs: 1, sm: 2, md: 4, lg: 4, xl: 6 }); +formColsScreenMap.set(5, { xs: 1, sm: 2, md: 5, lg: 6, xl: 6 }); +formColsScreenMap.set(6, { xs: 1, sm: 3, md: 6, lg: 6, xl: 6 }); +formColsScreenMap.set(7, { xs: 1, sm: 4, md: 7, lg: 7, xl: 7 }); +formColsScreenMap.set(8, { xs: 1, sm: 4, md: 8, lg: 8, xl: 8 }); +formColsScreenMap.set(9, { xs: 1, sm: 4, md: 9, lg: 9, xl: 9 }); +formColsScreenMap.set(10, { xs: 1, sm: 4, md: 10, lg: 10, xl: 10 }); +formColsScreenMap.set(11, { xs: 1, sm: 4, md: 11, lg: 11, xl: 11 }); +formColsScreenMap.set(12, { xs: 1, sm: 4, md: 12, lg: 12, xl: 12 }); +/** + * 根据设置的每列显示数、屏幕断点获取当前查询表单每行显示多少个字段 + * @param configColsNumber + * @param screen + */ +export function getQueryFormColsNumberByScreen(configColsNumber: number, screen: any) { + return formColsScreenMap.get(configColsNumber)[screen]; +} + +/** + * 集合根据传入的key转map + * @param key + * @param array + */ +export function arrayToMap(key, array) { + const map = new Map(); + array.forEach((item) => { + if (item.name !== '_sortNo_') { + map.set(item[key], item); + } + }); + return map; +} diff --git a/io.sc.platform.core.frontend/src/platform/components/utils/index.ts b/io.sc.platform.core.frontend/src/platform/components/utils/index.ts new file mode 100644 index 00000000..c5949a65 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/utils/index.ts @@ -0,0 +1,19 @@ +export { PlatformIconEnum } from './commUtil'; +export { PageStatusEnum } from './commUtil'; +export { FormTypeEnum } from './commUtil'; +export { DataTypeEnum } from './commUtil'; +export { OptionComeFromEnum } from './commUtil'; +export { FormComponentValidateEnum } from './commUtil'; +export { OperatorTypeEnum } from './commUtil'; +export type { CriteriaType } from './commUtil'; +export { PlatformNotifyTypeEnum } from './commUtil'; +export { platformNotify } from './commUtil'; +export { isEmpty } from './commUtil'; + +export { extractDialogProps } from './componentComm'; +export { extractFormProps } from './componentComm'; +export { extractFormItemComponentProps } from './componentComm'; +export { extractTableProps } from './componentComm'; +export { extractTableColumnsProps } from './componentComm'; +export { getQueryFormColsNumberByScreen } from './componentComm'; +export { arrayToMap } from './componentComm'; diff --git a/io.sc.platform.core.frontend/src/platform/component/widget/color/WColorInput.vue b/io.sc.platform.core.frontend/src/platform/components/widget/color/WColorInput.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/widget/color/WColorInput.vue rename to io.sc.platform.core.frontend/src/platform/components/widget/color/WColorInput.vue diff --git a/io.sc.platform.core.frontend/src/platform/component/widget/color/WColorInputPalette.vue b/io.sc.platform.core.frontend/src/platform/components/widget/color/WColorInputPalette.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/widget/color/WColorInputPalette.vue rename to io.sc.platform.core.frontend/src/platform/components/widget/color/WColorInputPalette.vue diff --git a/io.sc.platform.core.frontend/src/platform/component/widget/position/WPosition.vue b/io.sc.platform.core.frontend/src/platform/components/widget/position/WPosition.vue similarity index 100% rename from io.sc.platform.core.frontend/src/platform/component/widget/position/WPosition.vue rename to io.sc.platform.core.frontend/src/platform/components/widget/position/WPosition.vue diff --git a/io.sc.platform.core.frontend/src/platform/enums/IconEnum.ts b/io.sc.platform.core.frontend/src/platform/enums/IconEnum.ts new file mode 100644 index 00000000..15aff17c --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/enums/IconEnum.ts @@ -0,0 +1,48 @@ +/** + * 平台icon,使用【material icons】,以下为列举的一些平台常用的图标,并不包含全部 + * 不在该枚举中时可使用自定义的图标,目的是以后方便全局替换。 + */ +export enum IconEnum { + 查询 = 'search', + 更多查询 = 'zoom_in', + 重置 = 'restart_alt', + 刷新 = 'loop', + 新增 = 'add', + 新增2 = 'add_box', + 新增3 = 'playlist_add_circle', + 编辑 = 'edit', + 删除 = 'delete', + 查看 = 'visibility', + 全屏 = 'fullscreen', + 退出全屏 = 'fullscreen_exit', + 关闭 = 'close', + 保存 = 'save', + 提交 = 'beenhere', + 字母 = 'abc', + 时钟 = 'access_time', + 上箭头 = 'arrow_upward', + 下箭头 = 'arrow_downward', + 左箭头 = 'arrow_back', + 右箭头 = 'arrow_forward', + 附件 = 'attach_file', + 否状态 = 'cancel', + 是状态 = 'check_circle', + 首页 = 'home', + 设置 = 'settings', + 设置2 = 'settings_applications', + 扳手 = 'build_circle', + 收起 = 'arrow_drop_up', + 展开 = 'arrow_drop_down', + 提示 = 'info', + 警告 = 'warning', + 日期 = 'event', + 日期范围 = 'date_range', + 文件夹 = 'folder', + 校验 = 'published_with_changes', + 下载 = 'download', + 上传 = 'upload', + 选取变量 = 'find_in_page', + 报表通用 = 'assessment', + 复制 = 'file_copy', + 发送 = 'send', +} diff --git a/io.sc.platform.core.frontend/src/platform/enums/index.ts b/io.sc.platform.core.frontend/src/platform/enums/index.ts new file mode 100644 index 00000000..16841e2d --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/enums/index.ts @@ -0,0 +1 @@ +export { IconEnum } from './IconEnum'; diff --git a/io.sc.platform.core.frontend/src/platform/index.ts b/io.sc.platform.core.frontend/src/platform/index.ts index 064dec53..a6595fa9 100644 --- a/io.sc.platform.core.frontend/src/platform/index.ts +++ b/io.sc.platform.core.frontend/src/platform/index.ts @@ -2,7 +2,7 @@ import { App } from 'vue'; import PlatformPlugin from './plugin'; import QuasarPlugin from './plugin/quasar'; -import ComponentPlugin from './component'; +import ComponentPlugin from './components'; import DirectivePlugin from './directive'; import VueDOMPurifyHTML from 'vue-dompurify-html'; @@ -52,13 +52,28 @@ export type { UserType, } from './types'; +/** + * 导出常量 + */ export { PConst } from './PConst'; + +/** + * 导出枚举 + */ +export { IconEnum } from './enums'; + +/** + * 导出插件 + */ export { axios } from './plugin'; export { eventBus } from './plugin'; export { i18n } from './plugin'; export { usePlatformStore } from './plugin'; export { router } from './plugin'; +/** + * 导出管理器 + */ export { Environment } from './plugin'; export { ApplicationInitializer } from './plugin'; export { ComponentManager } from './plugin'; @@ -71,10 +86,27 @@ export { RouterManager } from './plugin'; export { SessionManager } from './plugin'; export { TagViewManager } from './plugin'; +/** + * 导出工具 + */ export { Tools } from './utils'; export { QuasarTools } from './utils'; export { JavascriptLoader } from './utils'; export { TreeBuilder } from './utils'; -// 导出平台 UI 组件 -export { WColorInput, WColorInputPalette, WHScreenDiv, WIconEmpty, WPlatformPage } from './component'; +/** + * 导出 UI 组件 + */ +export { + WPlatformPage, + WIconEmpty, + WHScreenDiv, + WColorInput, + WColorInputPalette, + WPosition, + PlatformDialog, + PlatformDrawer, + PlatformForm, + PlatformGrid, + PlatformGridTdDrag, +} from './components'; diff --git a/io.sc.platform.core.frontend/src/platform/mock/api/system/user/appConfigure.json b/io.sc.platform.core.frontend/src/platform/mock/api/lcdp/configure/getActiveConfigure.json similarity index 83% rename from io.sc.platform.core.frontend/src/platform/mock/api/system/user/appConfigure.json rename to io.sc.platform.core.frontend/src/platform/mock/api/lcdp/configure/getActiveConfigure.json index 257725db..dfa10e31 100644 --- a/io.sc.platform.core.frontend/src/platform/mock/api/system/user/appConfigure.json +++ b/io.sc.platform.core.frontend/src/platform/mock/api/lcdp/configure/getActiveConfigure.json @@ -1,30 +1,15 @@ { "enable": true, - "url": "/api/system/user/appConfigure", + "url": "/api/lcdp/configure/getActiveConfigure", "method": "get", "response": { "code" : 200, "messageI18nKey" : "success", "message" : "success", "data" : { - "i18nMessages" : { - "en" : { - "application.copyright" : "Copyright © 2019–2022", - "application.title" : "Developer Platform" - }, - "zh_CN" : { - "application.copyright" : "Copyright © 2019–2022", - "application.title" : "应用开发平台" - }, - "tw_CN" : { - "application.copyright" : "Copyright © 2019–2022", - "application.title" : "應用開發平台" - } - }, "setting" : { "routerHistoryMode" : "hash", - "logoutConfirm" : true, - "notifyTimeout" : 1000, + "homePage" : "/home", "i18n" : { "availableLocales" : [ "en", "zh_CN", "tw_CN" ], "locale" : "zh_CN", @@ -32,8 +17,7 @@ "fallbackWarn" : false, "missingWarn" : false, "changeNotify" : true - }, - "homePage" : "/home" + } }, "theme" : { "dark" : false, @@ -116,14 +100,15 @@ "containerBgColor" : "#EEEEEE" }, "footer" : { - "show" : true, + "show" : false, "height" : 40, "color" : "#ffffff", "bgColor" : "#14234a" }, "login" : { "bgImage" : "login-bg.jpg", - "encodePassword" : true + "encodePassword" : true, + "logoutConfirm" : true }, "scroller" : { "enable" : true, @@ -137,6 +122,11 @@ "notifier" : { "position" : "top", "timeout" : 2000 + }, + "grid" : { + "headBgColor" : "#f5f7fa", + "stickyBgColor" : "#ffffff", + "borderColor" : "rgba(0, 0, 0, 0.12)" } } } diff --git a/io.sc.platform.core.frontend/src/platform/mock/index.ts b/io.sc.platform.core.frontend/src/platform/mock/index.ts index 20bd2514..1717049d 100644 --- a/io.sc.platform.core.frontend/src/platform/mock/index.ts +++ b/io.sc.platform.core.frontend/src/platform/mock/index.ts @@ -1,7 +1,7 @@ import login from './api/login.json'; import session from './api/system/user/session.json'; -import appConfigure from './api/system/user/appConfigure.json'; +import activeConfigure from './api/lcdp/configure/getActiveConfigure.json'; -const PLATFORM_MOCKS = [login, session, appConfigure]; +const PLATFORM_MOCKS = [login, session, activeConfigure]; export default PLATFORM_MOCKS; diff --git a/io.sc.platform.core.frontend/src/platform/utils/Tools.ts b/io.sc.platform.core.frontend/src/platform/utils/Tools.ts index bc0abd5f..9767a119 100644 --- a/io.sc.platform.core.frontend/src/platform/utils/Tools.ts +++ b/io.sc.platform.core.frontend/src/platform/utils/Tools.ts @@ -722,6 +722,26 @@ class Tools { } return true; } + + /** + * 仅保留对象字段非空值 + * @param object 对象 + */ + public static pickNotNil(object: object): object { + if (object) { + for (const property in object) { + const value = object[property]; + if (Tools.isObject(value) && !Tools.isArray(value)) { + Tools.pickNotNil(value); + } else { + if (Tools.isUndefinedOrNull(value)) { + delete object[property]; + } + } + } + } + return object; + } } export { Tools }; diff --git a/io.sc.platform.core.frontend/src/views/View1.vue b/io.sc.platform.core.frontend/src/views/View1.vue index 57942253..d500a864 100644 --- a/io.sc.platform.core.frontend/src/views/View1.vue +++ b/io.sc.platform.core.frontend/src/views/View1.vue @@ -1,9 +1,39 @@ diff --git a/io.sc.platform.core.frontend/template-project/package.json b/io.sc.platform.core.frontend/template-project/package.json index 80cd7f7f..f6765a92 100644 --- a/io.sc.platform.core.frontend/template-project/package.json +++ b/io.sc.platform.core.frontend/template-project/package.json @@ -1,6 +1,6 @@ { "name": "platform-core", - "version": "8.1.13", + "version": "8.1.15", "description": "前端核心包,用于快速构建前端的脚手架", "private": false, "keywords": [], @@ -77,14 +77,12 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.13", + "platform-core": "8.1.15", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", - "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "vue-router": "4.2.5" } } \ No newline at end of file diff --git a/io.sc.platform.core.frontend/template-project/src/App.vue b/io.sc.platform.core.frontend/template-project/src/App.vue index 15499133..698133d2 100644 --- a/io.sc.platform.core.frontend/template-project/src/App.vue +++ b/io.sc.platform.core.frontend/template-project/src/App.vue @@ -1,10 +1,7 @@ diff --git a/io.sc.platform.core.frontend/template-project/src/views/View1.vue b/io.sc.platform.core.frontend/template-project/src/views/View1.vue index 0d689abf..40ddb498 100644 --- a/io.sc.platform.core.frontend/template-project/src/views/View1.vue +++ b/io.sc.platform.core.frontend/template-project/src/views/View1.vue @@ -1,9 +1,39 @@ diff --git a/io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs b/io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs index af4586f7..38e5cb76 100644 --- a/io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs +++ b/io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.core.frontend/webpack.config.mf.cjs b/io.sc.platform.core.frontend/webpack.config.mf.cjs index af4586f7..38e5cb76 100644 --- a/io.sc.platform.core.frontend/webpack.config.mf.cjs +++ b/io.sc.platform.core.frontend/webpack.config.mf.cjs @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java b/io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java index 9fc3e677..caebb341 100644 --- a/io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java +++ b/io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java @@ -19,6 +19,9 @@ public class PlatformResourceBundleMessageSource extends ResourceBundleMessageSo @Override public Map> getMessages(String... messageKeys) { + if(messageKeys==null || messageKeys.length<=0){ + return Collections.emptyMap(); + } Map> messageMap =PlatformMessageSourceLoader.getInstance().getMessages(this.getBasenameSet()); if(messageMap.isEmpty()){ return Collections.emptyMap(); diff --git a/io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/RuntimeServiceImpl.java b/io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/RuntimeServiceImpl.java index b38a746a..a2ba236c 100644 --- a/io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/RuntimeServiceImpl.java +++ b/io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/RuntimeServiceImpl.java @@ -58,7 +58,7 @@ public class RuntimeServiceImpl implements RuntimeService { @Override public boolean isInstallerReady() { - Object bean =BeanUtil.getBeanByClassName(applicationContext,INSTALLER_SERVICE_CLASS); + Object bean =BeanUtil.getBean(applicationContext,INSTALLER_SERVICE_CLASS); if(bean!=null){ try { Object value = BeanUtil.invoke(bean, "isEnabled"); @@ -80,7 +80,7 @@ public class RuntimeServiceImpl implements RuntimeService { @Override public boolean isDatabaseUpdaterReady() { - Object bean =BeanUtil.getBeanByClassName(applicationContext,LIQUIBASE_SERVICE_CLASS); + Object bean =BeanUtil.getBean(applicationContext,LIQUIBASE_SERVICE_CLASS); if(bean!=null){ try { Object value = BeanUtil.invoke(bean, "isEnabled"); diff --git a/io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java b/io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java index 73f69a84..f5d52052 100644 --- a/io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java +++ b/io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java @@ -2,6 +2,7 @@ package io.sc.platform.core.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import java.lang.reflect.InvocationTargetException; @@ -10,14 +11,28 @@ import java.lang.reflect.Method; public class BeanUtil { private static final Logger log = LoggerFactory.getLogger(BeanUtil.class); private BeanUtil(){} - public static Object getBeanByClassName(ApplicationContext applicationContext, String beanClassName){ + + public static T getBean(ApplicationContext applicationContext, Class beanClass){ try { - Class beanClass = Class.forName(beanClassName); return applicationContext.getBean(beanClass); + } catch (BeansException e) { + return null; + } + } + + public static Object getBean(ApplicationContext applicationContext, String beanClassName){ + Class beanClass = null; + try { + beanClass = Class.forName(beanClassName); } catch (ClassNotFoundException e) { log.error("",e); return null; } + try { + return applicationContext.getBean(beanClass); + } catch (BeansException e) { + return null; + } } public static Object invoke(Object bean,String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { diff --git a/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker-compose/docker-compose.adoc b/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker-compose/docker-compose.adoc index 225dceb2..461cb8da 100644 --- a/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker-compose/docker-compose.adoc +++ b/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker-compose/docker-compose.adoc @@ -10,6 +10,7 @@ Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器 这时候就需要一个工具能够管理一组相关联的的应用容器,这就是 Docker Compose。 Compose有2个重要的概念: + * 项目(Project): 由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。 * 服务(Service): 一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 diff --git a/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker/mysql/mysql.adoc b/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker/mysql/mysql.adoc index cb7d21cb..404a3199 100644 --- a/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker/mysql/mysql.adoc +++ b/io.sc.platform.developer.doc/asciidoc/9999-appendix/docker/mysql/mysql.adoc @@ -1,4 +1,6 @@ == Mysql 8 +=== docker-compose.yml + === 安装 [source,bash] ---- diff --git a/io.sc.platform.developer.frontend/package.json b/io.sc.platform.developer.frontend/package.json index e6c39a45..6d7dcea6 100644 --- a/io.sc.platform.developer.frontend/package.json +++ b/io.sc.platform.developer.frontend/package.json @@ -79,14 +79,13 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.12", + "platform-core": "8.1.14", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "platform-components": "8.1.2" } } \ No newline at end of file diff --git a/io.sc.platform.developer.frontend/webpack.config.mf.cjs b/io.sc.platform.developer.frontend/webpack.config.mf.cjs index af4586f7..38e5cb76 100644 --- a/io.sc.platform.developer.frontend/webpack.config.mf.cjs +++ b/io.sc.platform.developer.frontend/webpack.config.mf.cjs @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.flowable/build.gradle b/io.sc.platform.flowable/build.gradle index fe31da1c..90053cca 100644 --- a/io.sc.platform.flowable/build.gradle +++ b/io.sc.platform.flowable/build.gradle @@ -1,5 +1,6 @@ dependencies { api( + project(":io.sc.platform.communication"), project(":io.sc.platform.system"), "org.flowable:flowable-spring-boot-starter-process:${flowable_version}", diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java index c77e77d0..68e3680b 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java @@ -5,6 +5,7 @@ import io.sc.platform.flowable.jpa.repository.AgentRepository; import io.sc.platform.flowable.service.AgentService; import io.sc.platform.mvc.controller.support.RestCrudController; import io.sc.platform.security.util.SecurityUtil; +import io.sc.platform.system.api.user.User; import io.sc.platform.system.user.jpa.entity.UserEntity; import io.sc.platform.system.user.jpa.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.util.List; import java.util.Map; @Controller diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java index 4a699d7e..d54be46a 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java @@ -4,6 +4,16 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import io.sc.platform.core.Environment; +import io.sc.platform.core.util.LocaleUtil; +import io.sc.platform.flowable.service.FlowableModelerService; +import io.sc.platform.flowable.support.BpmnModelWrapper; +import io.sc.platform.flowable.support.FlowableGroupList; +import io.sc.platform.flowable.support.FlowableUser; +import io.sc.platform.flowable.support.FlowableUserList; +import io.sc.platform.orm.service.support.QueryParameter; +import io.sc.platform.system.role.service.RoleService; +import io.sc.platform.system.user.service.UserService; import org.apache.commons.io.IOUtils; import org.flowable.bpmn.model.BpmnModel; import org.flowable.editor.language.json.converter.BpmnJsonConverter; @@ -21,18 +31,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import org.wsp.framework.core.Environment; -import org.wsp.framework.core.util.LocaleUtil; -import org.wsp.framework.flowable.service.FlowableModelerService; -import org.wsp.framework.flowable.support.BpmnModelWrapper; -import org.wsp.framework.flowable.support.FlowableGroupList; -import org.wsp.framework.flowable.support.FlowableUser; -import org.wsp.framework.flowable.support.FlowableUserList; -import org.wsp.framework.jpa.service.support.protocol.QueryParameter; -import org.wsp.framework.jpa.service.support.protocol.criteria.TextMatchStyle; -import org.wsp.framework.system.role.service.RoleService; -import org.wsp.framework.system.user.entity.User; -import org.wsp.framework.system.user.service.UserService; import com.fasterxml.jackson.databind.JsonNode; @@ -74,7 +72,7 @@ public class FlowableModelerEditorWebController { @RequestMapping(value = "app/rest/stencil-sets/editor", method = RequestMethod.GET) @ResponseBody public String stencilsets(Locale locale) throws Exception{ - String[] candidateCodes =LocaleUtil.getCandidateCode(locale); + String[] candidateCodes = LocaleUtil.getCandidateCode(locale); Resource rs =null; for(String candidateCode : candidateCodes){ rs =new DefaultResourceLoader().getResource("classpath:/org/wsp/framework/flowable/controller/stencilsets_" + candidateCode + ".json"); @@ -85,7 +83,7 @@ public class FlowableModelerEditorWebController { if(!rs.exists()) { rs =new DefaultResourceLoader().getResource("classpath:/org/wsp/framework/flowable/controller/stencilsets.json"); } - return IOUtils.toString(rs.getInputStream(),Environment.DEFAULT_ENCODING); + return IOUtils.toString(rs.getInputStream(), Environment.DEFAULT_CHARSET_NAME); } /** @@ -138,7 +136,6 @@ public class FlowableModelerEditorWebController { User queryExampleEntity =new User(); queryExampleEntity.setLoginName(filter); QueryParameter queryParameter =new QueryParameter(); - queryParameter.setTextMatchStyle(TextMatchStyle.substring); return FlowableUserList.fromUsers(userService.query(queryExampleEntity, queryParameter)); } diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java index d4afbba7..157f3607 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java @@ -1,20 +1,20 @@ package io.sc.platform.flowable.controller; +import io.sc.platform.flowable.jpa.entity.ProcessEntity; +import io.sc.platform.flowable.jpa.repository.ProcessEntityRepository; +import io.sc.platform.flowable.service.ProcessEntityService; +import io.sc.platform.mvc.controller.support.RestCrudController; +import io.sc.platform.security.util.SecurityUtil; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; -import org.wsp.framework.flowable.entity.ProcessEntity; -import org.wsp.framework.flowable.repository.ProcessEntityRepository; -import org.wsp.framework.flowable.service.ProcessEntityService; -import org.wsp.framework.mvc.controller.support.SmartClientRestfulCrudController; -import org.wsp.framework.security.util.SecurityUtil; @Controller @RequestMapping("/api/system/process") -public class ProcessEntityWebController extends SmartClientRestfulCrudController{ +public class ProcessEntityWebController extends RestCrudController { //========================================================================================================= // 菜单入口 //========================================================================================================= diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessOperationWebController.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessOperationWebController.java index 6b91210c..81c574e1 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessOperationWebController.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessOperationWebController.java @@ -1,12 +1,12 @@ package io.sc.platform.flowable.controller; +import io.sc.platform.flowable.controller.support.ProcessProperties; +import io.sc.platform.flowable.service.ProcessOperationService; +import io.sc.platform.flowable.support.CompleteTaskException; +import io.sc.platform.flowable.support.CompleteTaskResponse; +import io.sc.platform.flowable.support.Goback; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import org.wsp.framework.flowable.controller.support.ProcessProperties; -import org.wsp.framework.flowable.service.ProcessOperationService; -import org.wsp.framework.flowable.support.CompleteTaskException; -import org.wsp.framework.flowable.support.CompleteTaskResponse; -import org.wsp.framework.flowable.support.Goback; import java.util.List; import java.util.Map; diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java index 52e03d3e..ed58a84d 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java @@ -1,14 +1,10 @@ package io.sc.platform.flowable.controller; +import io.sc.platform.flowable.service.ProcessQueryService; +import io.sc.platform.flowable.support.*; +import io.sc.platform.mvc.support.FileDownloader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import org.wsp.framework.flowable.entity.ProcessEntity; -import org.wsp.framework.flowable.service.ProcessQueryService; -import org.wsp.framework.flowable.support.*; -import org.wsp.framework.jpa.service.support.protocol.QueryParameter; -import org.wsp.framework.mvc.protocol.response.ResponseWrapper; -import org.wsp.framework.mvc.protocol.response.support.ResponseWrapperBuilder; -import org.wsp.framework.mvc.support.FileDownloader; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -41,7 +37,7 @@ public class ProcessQueryWebController { @RequestMapping(value="instance/isc/fetch", method=RequestMethod.GET) @ResponseBody - public ResponseWrapper processInstanceQuery(@RequestParam(name="businessKey",required=false)String businessKey,ProcessEntity queryExampleEntity, QueryParameter queryParameter) throws Exception{ + public ResponseWrapper processInstanceQuery(@RequestParam(name="businessKey",required=false)String businessKey, ProcessEntity queryExampleEntity, QueryParameter queryParameter) throws Exception{ return ResponseWrapperBuilder.query(service.queryProcessInstances(businessKey,queryExampleEntity,queryParameter)); } diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java index 52c921d4..e17708de 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java @@ -2,9 +2,9 @@ package io.sc.platform.flowable.controller.support; import java.util.Map; -import org.wsp.framework.core.util.JacksonObjectMapper; import com.fasterxml.jackson.core.JsonProcessingException; +import io.sc.platform.core.util.ObjectMapper4Json; public class ProcessProperties { private String bussinessKey; @@ -40,7 +40,7 @@ public class ProcessProperties { @Override public String toString() { try { - return JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(this); + return ObjectMapper4Json.getMapper().writeValueAsString(this); } catch (JsonProcessingException e) { return super.toString(); } diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/VariableSetterListener.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/VariableSetterListener.java index 1310bbab..542c5792 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/VariableSetterListener.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/VariableSetterListener.java @@ -2,6 +2,7 @@ package io.sc.platform.flowable.extension.listener; import java.util.Map; +import io.sc.platform.core.util.ObjectMapper4Json; import org.flowable.common.engine.api.delegate.Expression; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.ExecutionListener; @@ -10,7 +11,6 @@ import org.flowable.task.service.delegate.DelegateTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; -import org.wsp.framework.core.util.JacksonObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; @@ -35,7 +35,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(variables!=null){ String variablesText =variables.getExpressionText(); if(StringUtils.hasText(variablesText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(variablesText, new TypeReference>(){}); + Map map = ObjectMapper4Json.getMapper().readValue(variablesText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ execution.setVariable(key, map.get(key)); @@ -47,7 +47,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(variablesLocal!=null){ String variablesLocalText =variablesLocal.getExpressionText(); if(StringUtils.hasText(variablesLocalText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(variablesLocalText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(variablesLocalText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ execution.setVariableLocal(key, map.get(key)); @@ -59,7 +59,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(transientVariables!=null){ String transientVariablesText =transientVariables.getExpressionText(); if(StringUtils.hasText(transientVariablesText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(transientVariablesText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(transientVariablesText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ execution.setTransientVariable(key, map.get(key)); @@ -71,7 +71,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(transientVariablesLocal!=null){ String transientVariablesLocalText =transientVariablesLocal.getExpressionText(); if(StringUtils.hasText(transientVariablesLocalText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(transientVariablesLocalText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(transientVariablesLocalText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ execution.setTransientVariableLocal(key, map.get(key)); @@ -91,7 +91,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(variables!=null){ String variablesText =variables.getExpressionText(); if(StringUtils.hasText(variablesText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(variablesText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(variablesText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ delegateTask.setVariable(key, map.get(key)); @@ -103,7 +103,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(variablesLocal!=null){ String variablesLocalText =variablesLocal.getExpressionText(); if(StringUtils.hasText(variablesLocalText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(variablesLocalText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(variablesLocalText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ delegateTask.setVariableLocal(key, map.get(key)); @@ -115,7 +115,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(transientVariables!=null){ String transientVariablesText =transientVariables.getExpressionText(); if(StringUtils.hasText(transientVariablesText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(transientVariablesText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(transientVariablesText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ delegateTask.setTransientVariable(key, map.get(key)); @@ -127,7 +127,7 @@ public class VariableSetterListener implements ExecutionListener, TaskListener{ if(transientVariablesLocal!=null){ String transientVariablesLocalText =transientVariablesLocal.getExpressionText(); if(StringUtils.hasText(transientVariablesLocalText)){ - Map map =JacksonObjectMapper.getDefaultObjectMapper().readValue(transientVariablesLocalText, new TypeReference>(){}); + Map map =ObjectMapper4Json.getMapper().readValue(transientVariablesLocalText, new TypeReference>(){}); if(map!=null && map.size()>0){ for(String key : map.keySet()){ delegateTask.setTransientVariableLocal(key, map.get(key)); diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/task/SendMailListener.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/task/SendMailListener.java index 18ef39d1..5c859fec 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/task/SendMailListener.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/task/SendMailListener.java @@ -1,5 +1,8 @@ package io.sc.platform.flowable.extension.listener.task; +import io.sc.platform.communication.service.MailSenderService; +import io.sc.platform.system.user.jpa.entity.UserEntity; +import io.sc.platform.system.user.service.UserService; import org.flowable.common.engine.api.delegate.Expression; import org.flowable.engine.delegate.TaskListener; import org.flowable.task.service.delegate.DelegateTask; @@ -9,9 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import org.wsp.framework.communication.mail.service.MailSenderService; -import org.wsp.framework.system.user.entity.User; -import org.wsp.framework.system.user.service.UserService; @Component("flowableSendMailListener") public class SendMailListener implements TaskListener{ @@ -42,10 +42,10 @@ public class SendMailListener implements TaskListener{ String assignee =delegateTask.getAssignee(); if(StringUtils.hasText(assignee)) { - User user =userService.getRepository().findByLoginName(assignee); - if(user!=null) { - String userName =user.getNickName(); - String to =user.getEmail(); + UserEntity userEntity =userService.getRepository().findByLoginName(assignee); + if(userEntity!=null) { + String userName =userEntity.getUserName(); + String to =userEntity.getEmail(); if(StringUtils.hasText(to)) { mailSenderService.sendSimpleMessage( "wangshaoping@gbicc.net", diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/Agent.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/Agent.java index 3b93ff48..b67a449a 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/Agent.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/Agent.java @@ -17,11 +17,9 @@ import org.hibernate.annotations.GenericGenerator; /** * 代理人实体类 - * @author wangshaoping - * */ @Entity -@Table(name="FR_SYS_AGENT") +@Table(name="SYS_AGENT") public class Agent extends AuditorEntity implements Serializable{ private static final long serialVersionUID = 2228732422179849265L; @@ -29,50 +27,50 @@ public class Agent extends AuditorEntity implements Serializable{ @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid2") - @Column(name="FD_ID") + @Column(name="_ID") @Size(max=36) private String id; //被代理人登录名 - @Column(name="FD_LOGINNAME") + @Column(name="_LOGINNAME") @Size(max=255) private String loginName; //被代理人用户名 - @Column(name="FD_USERNAME") + @Column(name="_USERNAME") @Size(max=255) private String userName; //代理人登录名 - @Column(name="FD_AGENT_LOGINNAME") + @Column(name="_AGENT_LOGINNAME") @Size(max=255) private String agentLoginName; //代理人用户名 - @Column(name="FD_AGENT_USERNAME") + @Column(name="_AGENT_USERNAME") @Size(max=255) private String agentUserName; //开始日期 - @Column(name="FD_START_DATE") + @Column(name="_START_DATE") private Date startDate; //结束日期 - @Column(name="FD_END_DATE") + @Column(name="_END_DATE") private Date endDate; //代理原因 - @Column(name="FD_REASONS") + @Column(name="_REASONS") @Size(max=255) private String reasons; //是否生效 - @Column(name="FD_EFFECTIVE") + @Column(name="_EFFECTIVE") @Convert(converter= NumericBooleanConverter.class) private Boolean effective; //意见(主要用于记录审批意见) - @Column(name="FD_COMMENTS") + @Column(name="_COMMENTS") @Size(max=1024) private String comments; diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java index 21a3fa67..2397ac0e 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java @@ -12,18 +12,16 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.Size; +import io.sc.platform.flowable.support.ProcessStatus; import io.sc.platform.orm.converter.NumericBooleanConverter; import io.sc.platform.orm.entity.AuditorEntity; import org.hibernate.annotations.GenericGenerator; -import org.wsp.framework.flowable.support.ProcessStatus; /** * 流程定义实体类 - * @author wangshaoping - * */ @Entity -@Table(name="FR_SYS_PROCESS") +@Table(name="SYS_PROCESS") public class ProcessEntity extends AuditorEntity implements Serializable{ private static final long serialVersionUID = 2056614495312244260L; @@ -31,50 +29,50 @@ public class ProcessEntity extends AuditorEntity implements Serializable{ @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid2") - @Column(name="FD_ID") + @Column(name="_ID") @Size(max=36) private String id; //流程分类 - @Column(name="FD_CATEGORY") + @Column(name="_CATEGORY") @Size(max=255) private String category; //代码 - @Column(name="FD_KEY") + @Column(name="_KEY") @Size(max=255) private String key; //名称 - @Column(name="FD_NAME") + @Column(name="_NAME") @Size(max=255) private String name; //描述 - @Column(name="FD_DESCRIPTION") + @Column(name="_DESCRIPTION") @Size(max=255) private String description; //流程引擎中的发布ID - @Column(name="FD_DEPLOYED_ID") + @Column(name="_DEPLOYED_ID") @Size(max=255) private String deployedId; //版本 - @Column(name="FD_VERSION") + @Column(name="_VERSION") private Integer version; //Flowable 流程定义 xml - @Column(name="FD_XML") + @Column(name="_XML") private String xml; //流程定义状态 - @Column(name="FD_STATUS", length=10) + @Column(name="_STATUS", length=10) @Enumerated(EnumType.STRING) private ProcessStatus status; //是否可以自行领取任务 - @Column(name="FD_CAN_CLAIM_TASK") + @Column(name="_CAN_CLAIM_TASK") @Convert(converter= NumericBooleanConverter.class) private Boolean canClaimTask; diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java index ee6d1ee3..499c2d64 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java @@ -1,6 +1,7 @@ package io.sc.platform.flowable.jpa.repository; import io.sc.platform.flowable.jpa.entity.ProcessEntity; +import io.sc.platform.flowable.support.ProcessStatus; import io.sc.platform.orm.repository.DaoRepository; import java.util.List; @@ -20,7 +21,7 @@ public interface ProcessEntityRepository extends DaoRepository implements ProcessEntityService{ +public class ProcessEntityServiceImpl extends DaoServiceImpl implements ProcessEntityService { @Autowired private RepositoryService repositoryService; @@ -34,7 +36,7 @@ public class ProcessEntityServiceImpl extends DaoServiceImpl { private String modelId; private String name; private String key; @@ -59,4 +64,19 @@ public class BpmnModelWrapper { public void setModel(BpmnModel model) { this.model = model; } + + @Override + public void serialize(BpmnModelWrapper value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); + gen.writeStartObject(); + gen.writeObjectField("modelId", value.getModelId()); + gen.writeObjectField("name", value.getName()); + gen.writeObjectField("key", value.getKey()); + gen.writeObjectField("description", value.getDescription()); + gen.writeObjectField("lastUpdated", value.getLastUpdated()); + gen.writeObjectField("lastUpdatedBy", value.getLastUpdatedBy()); + + gen.writeObjectField("model", jsonConverter.convertToJson(value.getModel())); + gen.writeEndObject(); + } } diff --git a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/CompleteTaskResponse.java b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/CompleteTaskResponse.java index eb3eadb0..d657a40c 100644 --- a/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/CompleteTaskResponse.java +++ b/io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/CompleteTaskResponse.java @@ -1,17 +1,14 @@ package io.sc.platform.flowable.support; -import java.util.ArrayList; -import java.util.List; - +import com.fasterxml.jackson.core.type.TypeReference; import io.sc.platform.core.util.ObjectMapper4Json; -import org.wsp.framework.core.util.JacksonObjectMapper; -import com.fasterxml.jackson.core.type.TypeReference; +import java.util.ArrayList; +import java.util.List; /** * 完成任务响应 * 当客户端提交并完成任务时,服务器进行处理并返回该类的对象 - * @author wangshaoping * */ public class CompleteTaskResponse { diff --git a/io.sc.platform.lcdp.frontend/package.json b/io.sc.platform.lcdp.frontend/package.json index c9977081..2c76c0b0 100644 --- a/io.sc.platform.lcdp.frontend/package.json +++ b/io.sc.platform.lcdp.frontend/package.json @@ -79,14 +79,13 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.12", + "platform-core": "8.1.14", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "platform-components": "8.1.2" } } \ No newline at end of file diff --git a/io.sc.platform.lcdp.frontend/src/App.vue b/io.sc.platform.lcdp.frontend/src/App.vue index 15499133..9eec9c4b 100644 --- a/io.sc.platform.lcdp.frontend/src/App.vue +++ b/io.sc.platform.lcdp.frontend/src/App.vue @@ -1,10 +1,5 @@ - + diff --git a/io.sc.platform.lcdp.frontend/webpack.config.mf.cjs b/io.sc.platform.lcdp.frontend/webpack.config.mf.cjs index af4586f7..0b3d7c1a 100644 --- a/io.sc.platform.lcdp.frontend/webpack.config.mf.cjs +++ b/io.sc.platform.lcdp.frontend/webpack.config.mf.cjs @@ -2,7 +2,7 @@ * webpack module federation 配置 */ const fs = require('fs'); // 文件读取 -const Json5 =require('json5'); // json5 +const Json5 =require('json5'); // json5 const { ModuleFederationPlugin } = require('webpack').container; // webpack 模块联邦插件 const packageJson = require('./package.json'); // package.json const projectName =packageJson.name; // 项目名称 @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.mvc.frontend/package.json b/io.sc.platform.mvc.frontend/package.json index a3b85267..5024f9c6 100644 --- a/io.sc.platform.mvc.frontend/package.json +++ b/io.sc.platform.mvc.frontend/package.json @@ -79,14 +79,13 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.12", + "platform-core": "8.1.14", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "platform-components": "8.1.2" } } \ No newline at end of file diff --git a/io.sc.platform.mvc.frontend/src/App.vue b/io.sc.platform.mvc.frontend/src/App.vue index 15499133..9eec9c4b 100644 --- a/io.sc.platform.mvc.frontend/src/App.vue +++ b/io.sc.platform.mvc.frontend/src/App.vue @@ -1,10 +1,5 @@ - + diff --git a/io.sc.platform.mvc.frontend/webpack.config.mf.cjs b/io.sc.platform.mvc.frontend/webpack.config.mf.cjs index af4586f7..0b3d7c1a 100644 --- a/io.sc.platform.mvc.frontend/webpack.config.mf.cjs +++ b/io.sc.platform.mvc.frontend/webpack.config.mf.cjs @@ -2,7 +2,7 @@ * webpack module federation 配置 */ const fs = require('fs'); // 文件读取 -const Json5 =require('json5'); // json5 +const Json5 =require('json5'); // json5 const { ModuleFederationPlugin } = require('webpack').container; // webpack 模块联邦插件 const packageJson = require('./package.json'); // package.json const projectName =packageJson.name; // 项目名称 @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/I18nMessageController.java b/io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/I18nMessageController.java index 5b79e377..e37fef56 100644 --- a/io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/I18nMessageController.java +++ b/io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/I18nMessageController.java @@ -3,10 +3,7 @@ package io.sc.platform.mvc.controller; import io.sc.platform.core.enums.Language; import io.sc.platform.core.service.MessageSourceService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.Map; @@ -19,4 +16,9 @@ public class I18nMessageController { public Map getI18nMessages(@PathVariable(name = "lang",required = false) Language language) throws Exception{ return messageSourceService.getMessages(language==null? Language.getDefault():language); } + + @GetMapping("getI18nMessagesByKeys") + public Map> getI18nMessages(@RequestParam(name="key",required=false) String[] keys) throws Exception{ + return messageSourceService.getMessages(keys); + } } diff --git a/io.sc.platform.mvc/src/main/resources/META-INF/platform/plugins/security.json b/io.sc.platform.mvc/src/main/resources/META-INF/platform/plugins/security.json index d1367e2d..64bf3d2e 100644 --- a/io.sc.platform.mvc/src/main/resources/META-INF/platform/plugins/security.json +++ b/io.sc.platform.mvc/src/main/resources/META-INF/platform/plugins/security.json @@ -2,6 +2,7 @@ "permitPatterns":[ "/api/mvc/frontend/regist", "/api/mvc/i18n/getI18nMessages", - "/api/mvc/i18n/getI18nMessages/**/*" + "/api/mvc/i18n/getI18nMessages/**/*", + "/api/mvc/i18n/getI18nMessagesByKeys" ] } \ No newline at end of file diff --git a/io.sc.platform.security.frontend/package.json b/io.sc.platform.security.frontend/package.json index d8ac5872..31e5b7c5 100644 --- a/io.sc.platform.security.frontend/package.json +++ b/io.sc.platform.security.frontend/package.json @@ -79,14 +79,13 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.12", + "platform-core": "8.1.14", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "platform-components": "8.1.2" } } \ No newline at end of file diff --git a/io.sc.platform.security.frontend/src/plugin.ts b/io.sc.platform.security.frontend/src/plugin.ts index 4a4bf514..d297d32b 100644 --- a/io.sc.platform.security.frontend/src/plugin.ts +++ b/io.sc.platform.security.frontend/src/plugin.ts @@ -17,29 +17,34 @@ class Initializer { gc.webContextPath = window['webContextPath']; gc.loginError = window['loginError'] === 'true' ? true : false; - for (const key in gc.i18nMessages['en']) { - en[key] = gc.i18nMessages['en'][key]; - } - for (const key in gc.i18nMessages['zh_CN']) { - zh_CN[key] = gc.i18nMessages['zh_CN'][key]; - } - for (const key in gc.i18nMessages['tw_CN']) { - tw_CN[key] = gc.i18nMessages['tw_CN'][key]; - } - i18n = createI18n({ - legacy: false, - availableLocales: gc.setting.i18n.availableLocales, - locale: gc.setting.i18n.locale, - fallbackLocale: gc.setting.i18n.fallbackLocale, - missingWarn: gc.setting.i18n.missingWarn, - fallbackWarn: gc.setting.i18n.fallbackWarn, - messages: { - en: en, - zh_CN: zh_CN, - tw_CN: tw_CN, - }, - }); - callback(); + fetch(window['webContextPath'] + 'api/mvc/i18n/getI18nMessagesByKeys?key=application.title&key=application.copyright') + .then((response) => response.json()) + .then((data) => { + const i18nMessages = data.data; + for (const key in i18nMessages['en']) { + en[key] = i18nMessages['en'][key]; + } + for (const key in i18nMessages['zh_CN']) { + zh_CN[key] = i18nMessages['zh_CN'][key]; + } + for (const key in i18nMessages['tw_CN']) { + tw_CN[key] = i18nMessages['tw_CN'][key]; + } + i18n = createI18n({ + legacy: false, + availableLocales: gc.setting.i18n.availableLocales, + locale: gc.setting.i18n.locale, + fallbackLocale: gc.setting.i18n.fallbackLocale, + missingWarn: gc.setting.i18n.missingWarn, + fallbackWarn: gc.setting.i18n.fallbackWarn, + messages: { + en: en, + zh_CN: zh_CN, + tw_CN: tw_CN, + }, + }); + callback(); + }); }); } } diff --git a/io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java b/io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java index 009aa477..ad3ffd43 100644 --- a/io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java +++ b/io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java @@ -73,7 +73,7 @@ public class UserDetailsServiceImpl implements UserDetailsService{ ); user.setUserId(u.getId()); user.setLoginName(u.getLoginName()); - user.setNickName(u.getNickName()); + user.setUserName(u.getUserName()); //---------------------------------------------------------------------------------- //设置默认角色 @@ -213,7 +213,7 @@ public class UserDetailsServiceImpl implements UserDetailsService{ sb.append("{").append("\n"); sb.append(" ").append("id : ").append(user.getUserId()).append(",\n"); sb.append(" ").append("loginName : ").append(user.getLoginName()).append(",\n"); - sb.append(" ").append("nickName : ").append(user.getNickName()).append(",\n"); + sb.append(" ").append("userName : ").append(user.getUserName()).append(",\n"); sb.append("\n"); sb.append(" ").append("enabled : ").append(user.isEnabled()).append(",\n"); sb.append(" ").append("accountNonExpired : ").append(user.isAccountNonExpired()).append(",\n"); diff --git a/io.sc.platform.security/src/main/java/io/sc/platform/security/service/support/User.java b/io.sc.platform.security/src/main/java/io/sc/platform/security/service/support/User.java index 1906eafa..f2df32a9 100644 --- a/io.sc.platform.security/src/main/java/io/sc/platform/security/service/support/User.java +++ b/io.sc.platform.security/src/main/java/io/sc/platform/security/service/support/User.java @@ -10,7 +10,7 @@ import java.sql.SQLException; public class User { private String id; private String loginName; - private String nickName; + private String userName; private String password; private String description; private Boolean enable; @@ -53,7 +53,7 @@ public class User { User user = new User(); user.setId(rs.getString("_ID")); user.setLoginName(rs.getString("_LOGINNAME")); - user.setNickName(rs.getString("_USERNAME")); + user.setUserName(rs.getString("_USERNAME")); user.setPassword(rs.getString("_PASSWORD")); user.setEnable(1 == rs.getInt("_ENABLE") ? true : false); user.setAccountExpired(1 == rs.getInt("_IS_ACCOUNT_EXPIRED") ? true : false); @@ -85,12 +85,12 @@ public class User { this.loginName = loginName; } - public String getNickName() { - return nickName; + public String getUserName() { + return userName; } - public void setNickName(String nickName) { - this.nickName = nickName; + public void setUserName(String userName) { + this.userName = userName; } public String getPassword() { diff --git a/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityClaimNames.java b/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityClaimNames.java index 71eb2103..bcefeec4 100644 --- a/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityClaimNames.java +++ b/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityClaimNames.java @@ -4,7 +4,7 @@ public class SecurityClaimNames { public static final class User { public static final String USER_ID = "userId"; //用户ID public static final String LOGIN_NAME = "loginName"; //用户登录名 - public static final String NICK_NAME = "userName"; //用户别名 + public static final String USER_NAME = "userName"; //用户别名 public static final String DEFAULT_APP_ID = "defaultAppId"; //默认应用ID public static final String DEFAULT_APP_CODE = "defaultAppCode"; //默认应用代码 diff --git a/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java b/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java index 5223592d..20691bee 100644 --- a/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java +++ b/io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java @@ -25,7 +25,7 @@ public class SecurityUser extends User{ //扩展属性 private String userId; //用户ID private String loginName; //用户登录名 - private String nickName; //用户别名 + private String userName; //用户名 private String defaultAppId; //默认应用ID private String defaultAppCode; //默认应用代码 @@ -70,11 +70,11 @@ public class SecurityUser extends User{ public void setLoginName(String loginName) { this.loginName = loginName; } - public String getNickName() { - return nickName; + public String getUserName() { + return userName; } - public void setNickName(String nickName) { - this.nickName = nickName; + public void setUserName(String userName) { + this.userName = userName; } public String getDefaultAppId() { return defaultAppId; @@ -184,7 +184,7 @@ public class SecurityUser extends User{ return "SecurityUser{" + "userId='" + userId + '\'' + ", loginName='" + loginName + '\'' + - ", nickName='" + nickName + '\'' + + ", userName='" + userName + '\'' + ", defaultAppId='" + this.defaultAppId + '\'' + ", defaultAppCode='" + this.defaultAppCode + '\'' + ", defaultAppName='" + this.defaultAppName + '\'' + diff --git a/io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java b/io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java index ca4345c1..d86bf959 100644 --- a/io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java +++ b/io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java @@ -29,7 +29,7 @@ public class SecurityUtil { if(user!=null){ put(map,SecurityClaimNames.User.USER_ID,user.getUserId()); //用户ID put(map,SecurityClaimNames.User.LOGIN_NAME,user.getLoginName()); //用户登录名 - put(map,SecurityClaimNames.User.NICK_NAME,user.getNickName()); //用户别名 + put(map,SecurityClaimNames.User.USER_NAME,user.getUserName()); //用户名 put(map,SecurityClaimNames.User.DEFAULT_APP_ID,user.getDefaultAppId()); //默认应用ID put(map,SecurityClaimNames.User.DEFAULT_APP_CODE,user.getDefaultAppCode()); //默认应用代码 @@ -65,7 +65,7 @@ public class SecurityUtil { SecurityUser user =new SecurityUser(userId,"******",authorities); user.setUserId(StringUtil.toString(map.get(SecurityClaimNames.User.USER_ID))); user.setLoginName(StringUtil.toString(map.get(SecurityClaimNames.User.LOGIN_NAME))); - user.setNickName(StringUtil.toString(map.get(SecurityClaimNames.User.NICK_NAME))); + user.setUserName(StringUtil.toString(map.get(SecurityClaimNames.User.USER_NAME))); user.setDefaultAppId(StringUtil.toString(map.get(SecurityClaimNames.User.DEFAULT_APP_ID))); user.setDefaultAppCode(StringUtil.toString(map.get(SecurityClaimNames.User.DEFAULT_APP_CODE))); @@ -125,10 +125,10 @@ public class SecurityUtil { * 获取当前登录用户的用户名(通常是中文名) * @return 当前登录用户的用户名(通常是中文名) */ - public static String getNickName(){ + public static String getUserName(){ SecurityUser user =getSecurityUser(); if(user!=null){ - return user.getNickName(); + return user.getUserName(); } return null; } diff --git a/io.sc.platform.security/src/main/resources/META-INF/platform/plugins/application-properties.json b/io.sc.platform.security/src/main/resources/META-INF/platform/plugins/application-properties.json new file mode 100644 index 00000000..87a24f43 --- /dev/null +++ b/io.sc.platform.security/src/main/resources/META-INF/platform/plugins/application-properties.json @@ -0,0 +1,11 @@ +[ + { + "module" : "io.sc.platform.security", + "order" : 153, + "description" : "", + "properties": [ + "# - io.sc.platform.security", + "application.default-password = password" + ] + } +] \ No newline at end of file diff --git a/io.sc.platform.system.frontend/package.json b/io.sc.platform.system.frontend/package.json index 5fe15e67..53d9c38e 100644 --- a/io.sc.platform.system.frontend/package.json +++ b/io.sc.platform.system.frontend/package.json @@ -79,14 +79,13 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.12", + "platform-core": "8.1.14", "quasar": "2.13.0", - "react-dnd-html5-backend": "16.0.1", "tailwindcss": "3.3.5", "vue": "3.3.7", "vue-dompurify-html": "4.1.4", "vue-i18n": "9.6.0", "vue-router": "4.2.5", - "vue3-dnd": "2.0.2" + "platform-components": "8.1.2" } } \ No newline at end of file diff --git a/io.sc.platform.system.frontend/webpack.config.mf.cjs b/io.sc.platform.system.frontend/webpack.config.mf.cjs index af4586f7..38e5cb76 100644 --- a/io.sc.platform.system.frontend/webpack.config.mf.cjs +++ b/io.sc.platform.system.frontend/webpack.config.mf.cjs @@ -42,12 +42,10 @@ module.exports = { 'pinia': { requiredVersion: deps['pinia'], singleton: true }, 'platform-core': { requiredVersion: deps['platform-core'], singleton: true }, 'quasar': { requiredVersion: deps['quasar'], singleton: true }, - 'react-dnd-html5-backend':{ requiredVersion: deps['react-dnd-html5-backend'], singleton: true }, 'vue': { requiredVersion: deps['vue'], singleton: true }, 'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true }, 'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true }, 'vue-router': { requiredVersion: deps['vue-router'], singleton: true }, - 'vue3-dnd':{ requiredVersion: deps['vue3-dnd'], singleton: true }, } }), ] diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/MessageSourceAutoConfiguration.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/MessageSourceAutoConfiguration.java index 452c4f96..2168b5a5 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/MessageSourceAutoConfiguration.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/MessageSourceAutoConfiguration.java @@ -2,6 +2,7 @@ package io.sc.platform.system.autoconfigure; import io.sc.platform.core.i18n.MessageSourceBaseName; import io.sc.platform.core.i18n.PlatformResourceBundleMessageSource; +import io.sc.platform.core.service.RuntimeService; import io.sc.platform.system.autoconfigure.support.CompositeMessageSource; import io.sc.platform.system.autoconfigure.support.DatabaseMessageSource; import io.sc.platform.system.i18n.jpa.repository.I18nRepository; @@ -12,6 +13,7 @@ import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.context.MessageSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -30,6 +32,7 @@ import java.time.Duration; @AutoConfigureBefore(io.sc.platform.core.autoconfigure.MessageSourceAutoConfiguration.class) @EnableConfigurationProperties public class MessageSourceAutoConfiguration { + @Autowired private RuntimeService runtimeService; @Autowired private I18nRepository repository; @Bean @@ -41,6 +44,17 @@ public class MessageSourceAutoConfiguration { @Bean @ConditionalOnMissingBean public MessageSource messageSource(MessageSourceProperties messageSourceProperties){ + //组合消息源(先从数据库消息源中查找,如果不存在,再从资源包消息源中查找) + CompositeMessageSource compositeMessageSource =new CompositeMessageSource(); + + //数据库消息源 + if(runtimeService.isReady()) { + DatabaseMessageSource databaseMessageSource = new DatabaseMessageSource(repository); + databaseMessageSource.reload(); + compositeMessageSource.addMessageSource(databaseMessageSource); + } + + // 资源包消息源 PlatformResourceBundleMessageSource resourceBundleMessageSource = new PlatformResourceBundleMessageSource(); resourceBundleMessageSource.setBasenames(MessageSourceBaseName.getBaseNames(messageSourceProperties.getBasename())); if (messageSourceProperties.getEncoding() != null) { @@ -53,15 +67,8 @@ public class MessageSourceAutoConfiguration { if (cacheDuration != null) { resourceBundleMessageSource.setCacheMillis(cacheDuration.toMillis()); } - - //数据库消息源 - DatabaseMessageSource databaseMessageSource =new DatabaseMessageSource(repository); - databaseMessageSource.reload(); - - //组合消息源(先从数据库消息源中查找,如果不存在,再从资源包消息源中查找) - CompositeMessageSource compositeMessageSource =new CompositeMessageSource(); - compositeMessageSource.addMessageSource(databaseMessageSource); compositeMessageSource.addMessageSource(resourceBundleMessageSource); + return compositeMessageSource; } } diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/CompositeMessageSource.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/CompositeMessageSource.java index 7034a57f..bf153e32 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/CompositeMessageSource.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/CompositeMessageSource.java @@ -64,6 +64,9 @@ public class CompositeMessageSource implements MessageSource, PlatformMessageSou @Override public Map> getMessages(String... messageKeys) { + if(messageKeys==null || messageKeys.length<=0){ + return Collections.emptyMap(); + } Map> messageMap = getMessages(); if(messageMap.isEmpty()){ return Collections.emptyMap(); diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/DatabaseMessageSource.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/DatabaseMessageSource.java index f93ae9f6..d4733b15 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/DatabaseMessageSource.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/autoconfigure/support/DatabaseMessageSource.java @@ -3,10 +3,12 @@ package io.sc.platform.system.autoconfigure.support; import io.sc.platform.core.Environment; import io.sc.platform.core.enums.Language; import io.sc.platform.core.i18n.PlatformMessageSource; +import io.sc.platform.core.service.RuntimeService; import io.sc.platform.core.util.LocaleUtil; import io.sc.platform.system.api.i18n.I18nLanguage; import io.sc.platform.system.i18n.jpa.entity.I18nEntity; import io.sc.platform.system.i18n.jpa.repository.I18nRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; @@ -33,7 +35,7 @@ public class DatabaseMessageSource implements MessageSource, PlatformMessageSour */ public void reload() { messages.clear(); - messages =load(); + messages = load(); } @Override @@ -46,6 +48,9 @@ public class DatabaseMessageSource implements MessageSource, PlatformMessageSour @Override public Map> getMessages(String... messageKeys) { + if(messageKeys==null || messageKeys.length<=0){ + return Collections.emptyMap(); + } Map> messageMap = getMessages(); if(messageMap.isEmpty()){ return Collections.emptyMap(); diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserController.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserController.java index 05948bb2..bcc92703 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserController.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserController.java @@ -5,11 +5,10 @@ import io.sc.platform.system.user.jpa.entity.UserEntity; import io.sc.platform.system.user.jpa.repository.UserRepository; import io.sc.platform.system.user.service.UserService; import io.sc.platform.system.user.service.support.UserSession; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import java.util.List; @RestController @RequestMapping("/api/system/user") @@ -18,4 +17,14 @@ public class UserController extends RestCrudController loginNames) throws Exception{ + service.resetPassword(loginNames); + } } diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/jpa/repository/UserRepository.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/jpa/repository/UserRepository.java index 1d97c2e4..b82e949c 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/jpa/repository/UserRepository.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/jpa/repository/UserRepository.java @@ -2,7 +2,24 @@ package io.sc.platform.system.user.jpa.repository; import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.system.user.jpa.entity.UserEntity; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface UserRepository extends DaoRepository { + /** + * 通过登录名查询用户实体,采用 left join fetch 查找,可一次性找出用户及其所属的所有角色 + * @param loginName 登录名 + * @return 用户实体 + */ + @Query("select user from UserEntity as user left join fetch user.roles where user.loginName=:loginName") + public UserEntity findByLoginName(@Param("loginName") String loginName); + /** + * 通过登录名查询用户实体 + * @param loginNames 登录名集合 + * @return 用户实体列表 + */ + public List findByLoginNameIn(List loginNames); } diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/UserService.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/UserService.java index fccf2fc9..b657cc21 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/UserService.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/UserService.java @@ -7,7 +7,15 @@ import io.sc.platform.system.user.jpa.repository.UserRepository; import io.sc.platform.system.user.service.support.UserSession; import javax.servlet.http.HttpServletRequest; +import java.util.List; public interface UserService extends DaoService { public UserSession getUserSession(HttpServletRequest request); + + /** + * 重置用户密码 + * @param userIds 用户ID集合 + * @throws Exception 违例 + */ + public void resetPassword(List userIds) throws Exception; } diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java index a4dca7c1..5b511904 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java @@ -16,17 +16,22 @@ import io.sc.platform.system.user.jpa.repository.UserRepository; import io.sc.platform.system.user.service.UserService; import io.sc.platform.system.user.service.support.UserSession; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; @Service public class UserServiceImpl extends DaoServiceImpl implements UserService { + @Autowired private Environment environment; @Autowired private MenuService menuService; @Autowired private FrontEndService frontEndService; @Autowired private I18nService i18nService; + @Autowired private PasswordEncoder passwordEncoder; @Override public UserSession getUserSession(HttpServletRequest request) { @@ -39,6 +44,20 @@ public class UserServiceImpl extends DaoServiceImpl userIds) throws Exception{ + if(userIds!=null && !userIds.isEmpty()){ + List entities =repository.findAllById(userIds); + if(entities!=null && !entities.isEmpty()){ + for(UserEntity entity : entities){ + entity.setPassword(passwordEncoder.encode(environment.getProperty("application.default-password",""))); + } + repository.saveAll(entities); + } + } + } + private List getFrontEndRoutes(List menus){ List result =new ArrayList<>(); addFrontEndRoutes(result,menus); diff --git a/settings.gradle b/settings.gradle index 08dfc170..c4d28dd3 100755 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ include ':app.platform' include ':io.sc.example' include ':io.sc.platform.app' include ':io.sc.platform.app-nacos' +include ':io.sc.platform.communication' include ':io.sc.platform.core' include ':io.sc.platform.core.frontend' include ':io.sc.platform.components.frontend' @@ -11,7 +12,7 @@ include ':io.sc.platform.csv' include ':io.sc.platform.developer' include ':io.sc.platform.developer.frontend' include ':io.sc.platform.developer.doc' -//include ':io.sc.platform.flowable' +include ':io.sc.platform.flowable' include ':io.sc.platform.gradle' include ':io.sc.platform.groovy' include ':io.sc.platform.installer'