├── README.md ├── common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── rekoe │ └── common │ ├── image │ ├── codec │ │ ├── Base64.java │ │ ├── BaseNCodec.java │ │ └── DecoderException.java │ ├── ex │ │ ├── EncoderException.java │ │ └── ImageParseException.java │ ├── filter │ │ ├── AbstractBufferedImageOp.java │ │ ├── Colormap.java │ │ ├── ContrastFilter.java │ │ ├── CropCircleFilter.java │ │ ├── CropFilter.java │ │ ├── EdgeFilter.java │ │ ├── GradientFilter.java │ │ ├── GrayscaleFilter.java │ │ ├── HSBAdjustFilter.java │ │ ├── ImageMath.java │ │ ├── LinearColormap.java │ │ ├── PixelUtils.java │ │ ├── PixellateFilter.java │ │ ├── PointFilter.java │ │ ├── RotateFilter.java │ │ ├── ScaleFilter.java │ │ ├── SepiaToneFilter.java │ │ ├── ThresholdFilter.java │ │ ├── TransferFilter.java │ │ ├── TransformFilter.java │ │ ├── WholeImageFilter.java │ │ └── ZipFilter.java │ ├── kit │ │ ├── IOKit.java │ │ ├── ImageKit.java │ │ ├── ImageKitUtils.java │ │ └── StringKit.java │ └── type │ │ └── ImageType.java │ ├── large │ └── excell │ │ └── to │ │ └── bean │ │ └── ta │ │ ├── bean │ │ └── ExampleBean.java │ │ ├── checkedRun │ │ └── MainApp.java │ │ ├── exceptions │ │ ├── CloseException.java │ │ ├── MissingSheetException.java │ │ ├── NotSupportedException.java │ │ ├── OpenException.java │ │ ├── ParseException.java │ │ └── ReadException.java │ │ ├── impl │ │ ├── StreamingCell.java │ │ ├── StreamingRow.java │ │ ├── StreamingSheet.java │ │ ├── StreamingSheetReader.java │ │ ├── StreamingWorkbook.java │ │ ├── StreamingWorkbookReader.java │ │ ├── StringSupplier.java │ │ └── Supplier.java │ │ ├── sst │ │ ├── BufferedStringsTable.java │ │ ├── CTRstImpl.java │ │ └── FileBackedList.java │ │ └── utilities │ │ ├── StreamingReader.java │ │ ├── XmlUtils.java │ │ ├── annotations │ │ ├── ExcelBean.java │ │ ├── ExcelColumnHeader.java │ │ └── ExcelColumnIndex.java │ │ ├── bean │ │ └── ResponseBean.java │ │ ├── enums │ │ ├── CoreMessages.java │ │ └── ExcelFactoryType.java │ │ └── factory │ │ ├── Parser.java │ │ └── Test.java │ ├── shiro │ ├── OAuth2SubjectFactory.java │ └── OAuthToken.java │ └── vo │ ├── GrantDTO.java │ ├── OperationState.java │ ├── Result.java │ └── UserLoginDto.java ├── core ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── rekoe │ │ └── core │ │ ├── bean │ │ ├── BasePojo.java │ │ ├── DataBaseEntity.java │ │ ├── acl │ │ │ ├── Permission.java │ │ │ ├── Role.java │ │ │ └── User.java │ │ ├── dingtalk │ │ │ └── DingTalkUser.java │ │ └── meal │ │ │ ├── FoodCategory.java │ │ │ ├── FoodRating.java │ │ │ ├── MealFood.java │ │ │ ├── MealOrder.java │ │ │ ├── MealOrderInfo.java │ │ │ └── MealSeller.java │ │ ├── dingtalk │ │ ├── chatbot │ │ │ ├── SendResult.java │ │ │ └── message │ │ │ │ ├── ActionButtonStyle.java │ │ │ │ ├── ActionCardAction.java │ │ │ │ ├── ActionCardMessage.java │ │ │ │ ├── FeedCardMessage.java │ │ │ │ ├── FeedCardMessageItem.java │ │ │ │ ├── LinkMessage.java │ │ │ │ ├── MarkdownMessage.java │ │ │ │ ├── Message.java │ │ │ │ ├── SingleTargetActionCardMessage.java │ │ │ │ └── TextMessage.java │ │ └── isv │ │ │ └── message │ │ │ ├── FileMessage.java │ │ │ ├── ImageMessage.java │ │ │ ├── Link.java │ │ │ ├── LinkMessage.java │ │ │ ├── Markdown.java │ │ │ ├── MarkdownMessage.java │ │ │ ├── Media.java │ │ │ ├── Message.java │ │ │ ├── Text.java │ │ │ ├── TextMessage.java │ │ │ ├── Voice.java │ │ │ └── VoiceMessage.java │ │ └── vo │ │ ├── DingDepartment.java │ │ └── Status.java │ └── resources │ └── sqls │ ├── acl │ ├── permission.sql │ ├── role.sql │ └── user.sql │ └── branch │ └── branch.sql ├── pom.xml ├── rest ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── rekoe │ │ ├── MainLauncher.java │ │ ├── job │ │ ├── DingTalkStatusJob.java │ │ ├── DingUserStatusJob.java │ │ ├── NotificationMealJob.java │ │ └── ReportMealJob.java │ │ ├── module │ │ ├── DingCanModule.java │ │ ├── DingTalkLoginModule.java │ │ ├── DingTalkModule.java │ │ ├── FoodCategoryModule.java │ │ ├── LoginModule.java │ │ ├── MealFoodModule.java │ │ ├── MealOrderModule.java │ │ ├── MealSellerModule.java │ │ ├── PermissionModule.java │ │ ├── RoleModule.java │ │ ├── SellerOrderModule.java │ │ └── UserModule.java │ │ ├── service │ │ ├── BaseService.java │ │ ├── DingCanService.java │ │ ├── DingOauthService.java │ │ ├── DingTalkService.java │ │ ├── DingTalkUserService.java │ │ ├── FoodCategoryService.java │ │ ├── MealFoodService.java │ │ ├── MealOrderService.java │ │ ├── MealSellerService.java │ │ ├── PermissionService.java │ │ ├── RoleService.java │ │ ├── UserService.java │ │ ├── WebServiceClient.java │ │ └── entity │ │ │ └── PageredData.java │ │ ├── shiro │ │ ├── LoginRealm.java │ │ ├── ShiroSessionListener.java │ │ └── SimpleAuthorizingRealm.java │ │ ├── utils │ │ ├── DingTalkJsApiSingnature.java │ │ ├── Env.java │ │ ├── HTMLEntities.java │ │ └── Helper.java │ │ └── websocket │ │ ├── OmWebsocket.java │ │ └── OmWsHandler.java │ └── resources │ ├── application.properties │ ├── ehcache.xml │ ├── ioc │ └── wx.js │ ├── log4j.properties │ ├── oauth_consumer.properties │ └── static │ ├── index.html │ ├── static │ ├── css │ │ ├── app.360141a6db3f98e86394034a4b096d48.css │ │ ├── app.360141a6db3f98e86394034a4b096d48.css.gz │ │ ├── app.360141a6db3f98e86394034a4b096d48.css.map │ │ └── reset.css │ ├── fonts │ │ ├── fontawesome-webfont.674f50d.eot │ │ ├── fontawesome-webfont.af7ae50.woff2 │ │ ├── fontawesome-webfont.b06871f.ttf │ │ └── fontawesome-webfont.fee66e7.woff │ ├── icon │ │ └── favicon.ico │ ├── img │ │ ├── anonymity.3f9b695.png │ │ ├── background.2e65c38.png │ │ └── fontawesome-webfont.912ec66.svg │ └── js │ │ ├── app.e792d06cbdf7528ee766.js │ │ ├── app.e792d06cbdf7528ee766.js.gz │ │ ├── app.e792d06cbdf7528ee766.js.map │ │ ├── manifest.7d41dc005464a20dda04.js │ │ ├── manifest.7d41dc005464a20dda04.js.map │ │ ├── vendor.046921ea18d121bcc641.js │ │ ├── vendor.046921ea18d121bcc641.js.gz │ │ └── vendor.046921ea18d121bcc641.js.map │ └── style │ └── img │ ├── 154901190572945.png │ ├── bulletin@2x.png │ └── default.jpeg └── ui ├── pom.xml └── src └── main ├── images ├── 1.png ├── 2.jpeg ├── 3.jpeg ├── 4.jpeg ├── 5.jpeg ├── 6.jpeg └── 7.jpeg └── resources ├── .babelrc ├── .vscode-upload.json ├── .vscode └── settings.json ├── build ├── build.js ├── check-versions.js ├── dev-client.js ├── dev-server.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── package.json ├── src ├── App.vue ├── api │ ├── acl │ │ ├── permission.js │ │ ├── role.js │ │ └── user.js │ ├── dingcan │ │ └── index.js │ ├── dingtalk │ │ └── index.js │ ├── index.js │ └── meal │ │ ├── category.js │ │ ├── food.js │ │ ├── order.js │ │ ├── seller.js │ │ └── seller_order.js ├── assets │ ├── images │ │ ├── Github.png │ │ ├── a_logo.jpg │ │ ├── background.png │ │ ├── dingtalk.png │ │ ├── f_logo.jpg │ │ ├── facebook.png │ │ └── google.png │ └── style.less ├── common │ ├── css │ │ └── icon.css │ ├── fonts │ │ ├── mt-app.eot │ │ ├── mt-app.svg │ │ ├── mt-app.ttf │ │ └── mt-app.woff │ ├── js │ │ └── util.js │ ├── mixin.scss │ └── util.js ├── components │ ├── MapPosition.vue │ ├── SvgIcon │ │ └── index.vue │ ├── cartcontrol │ │ └── CartControl.vue │ ├── goods │ │ ├── Goods.vue │ │ └── img │ │ │ └── btn_yellow_highlighted@2x.png │ ├── header │ │ ├── Header.vue │ │ └── img │ │ │ ├── search.png │ │ │ └── star.png │ ├── nav │ │ └── Nav.vue │ ├── productDetail │ │ ├── img │ │ │ ├── Food.vue │ │ │ ├── anonymity.png │ │ │ ├── more.png │ │ │ └── share.png │ │ └── productDetail.vue │ ├── ratings │ │ ├── Ratings.vue │ │ └── img │ │ │ ├── anonymity.png │ │ │ ├── icon_sub_tab_dp_highlighted@2x.png │ │ │ └── icon_sub_tab_dp_normal@2x.png │ ├── seller │ │ ├── Seller.vue │ │ ├── address.png │ │ ├── delivery.png │ │ ├── line.png │ │ ├── phone.png │ │ ├── safety.png │ │ ├── server.png │ │ └── time.png │ ├── shopcart │ │ ├── Shopcart.vue │ │ └── img │ │ │ └── ash_bin.png │ ├── split │ │ └── Split.vue │ └── star │ │ ├── Star.vue │ │ └── img │ │ ├── star24_half@2x.png │ │ ├── star24_off@2x.png │ │ └── star24_on@2x.png ├── http │ └── index.js ├── icons │ ├── index.js │ └── svg │ │ ├── clipboard.svg │ │ ├── component.svg │ │ ├── dashboard.svg │ │ ├── international.svg │ │ ├── language.svg │ │ ├── message.svg │ │ ├── money.svg │ │ ├── people.svg │ │ ├── peoples.svg │ │ └── shoppingCard.svg ├── lang │ ├── en.js │ ├── index.js │ └── zh.js ├── main.js ├── routes.js ├── rules │ └── index.js ├── styles │ └── vars.scss ├── utils │ ├── clipboard.js │ ├── i18n.js │ ├── logger.js │ ├── openWindow.js │ └── tools.js ├── views │ ├── 404.vue │ ├── DingCan.vue │ ├── Home.vue │ ├── Login.vue │ ├── acl │ │ ├── Permission.vue │ │ ├── Role.vue │ │ └── User.vue │ ├── dashbord │ │ └── DashBoard.vue │ ├── meal │ │ ├── Food.vue │ │ ├── FoodCategory.vue │ │ ├── MealOrder.vue │ │ ├── Seller.vue │ │ └── SellerOrder.vue │ ├── socialsignin.vue │ └── svg-icons │ │ ├── generateIconsView.js │ │ └── index.vue └── vuex │ └── store.js └── static ├── .gitkeep ├── css └── reset.css └── icon └── favicon.ico /README.md: -------------------------------------------------------------------------------- 1 | # nutz-dingtalk 2 | ### 1)创建数据库 3 | ``` 4 | create database dingtalk_meal charset utf8; 5 | ``` 6 | ### 2)构建前端 7 | 8 | ``` 9 | cd nutz-dingtalk/ui/src/main/resources 10 | 11 | npm install 12 | 13 | npm run dev 14 | 15 | npm run build 16 | 17 | ``` 18 | 19 | ### 3)钉钉后台申请 20 | 登陆 https://open-dev.dingtalk.com/#/loginAndShareApp 21 | 22 | 申请-扫码登录应用授权应用 23 | 24 | 记录下 appId、appSecret、回调域名(例如:http://dingtalk.rekoe.com/oauth/dingding/callback ) 域名配置自己的 25 | 26 | ### 4)创建微应用 27 | 登陆获取方式:[地址](https://open-dev.dingtalk.com/#/loginAndShareApp) 28 | 29 | 微应用-微应用管理-创建微应用 30 | 31 | 方式选择:企业内部自主开发 32 | 33 | 配置好应用首页地址:http://dingtalk.rekoe.com/#/goods/1(域名填写自己的) 34 | 35 | 提交完后记录下 AgentID值 36 | 37 | ### 4)修改nutz-dingtalk/rest/src/main/resources/application.properties 38 | 39 | 修改数据库密码 40 | 修改ngrok的token(token获取可以登陆nutz.cn,用户中心) 41 | 42 | ### 钉钉扫码登陆 43 | dingtalk.oauth.appid=xxx(步骤3中获取) 44 | 45 | dingtalk.oauth.appsecret=xxx(步骤3中获取) 46 | 47 | ### 钉钉内部应用 48 | 49 | dingtalk.agentid=xxx(步骤4中获取) 50 | 51 | dingtalk.corpid=xxx([查看地址](https://open-dev.dingtalk.com/#/index)) 52 | 53 | dingtalk.corpsecret=xxx([开发着账号获取链接](https://open-dev.dingtalk.com/#/corpAuthInfo) 开发信息-开发者账号) 54 | 55 | ### 5)配置构建地址 56 | ``` 57 | 打开文件 nutz-dingtalk/ui/src/main/resources/config/index.js 58 | ``` 59 | 60 | 修改第三行 61 | 62 | var buildpath = '../dist' 63 | 64 | 修改为 65 | 66 | ``` 67 | var buildpath = '~/git/nutz-dingtalk/rest/src/main/resources/static/' 68 | ``` 69 | 70 | 或者直接把构建完的dist目录copy到 `` nutz-dingtalk/rest/src/main/resources/static/`` 71 | 72 | 启动运行 登陆到钉钉入口查看效果 73 | 74 | 默认登陆是钉钉扫码,可以切换账号登陆 75 | 76 | 默认账号admin 密码:12345678 77 | 78 | 后台商家管理可以通过采集美团外卖的数据 79 | 80 | 测试地址(因美团做了Cookie 验证 所以首次会跳转到引导页,可以忽略 按照提示多提交几次,采集成功) 81 | 82 | http://waimai.meituan.com/restaurant/144689920684303686 83 | 84 | ## 演示 85 | 86 | ![view_1](ui/src/main/images/1.png) 87 | 88 | ![view_2](ui/src/main/images/2.jpeg) 89 | 90 | ![view_3](ui/src/main/images/3.jpeg) 91 | 92 | ![view_4](ui/src/main/images/4.jpeg) 93 | 94 | ![view_5](ui/src/main/images/5.jpeg) 95 | 96 | ![view_6](ui/src/main/images/6.jpeg) 97 | 98 | ![view_7](ui/src/main/images/7.jpeg) -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.rekoe 7 | nutz-dingtalk 8 | 1.0-SNAPSHOT 9 | 10 | nutz-dingtalk-common 11 | 12 | 13 | 14 | com.rekoe 15 | nutz-dingtalk-core 16 | ${project.version} 17 | 18 | 19 | org.nutz 20 | nutz-integration-json4excel 21 | ${nutz.version} 22 | 23 | 24 | org.apache.commons 25 | commons-lang3 26 | ${commons-lang.version} 27 | 28 | 29 | com.fasterxml.jackson.core 30 | jackson-databind 31 | 2.9.10.1 32 | 33 | 34 | org.nutz 35 | nutz-plugins-websocket 36 | 37 | 38 | org.nutz 39 | nutzboot-starter-redis 40 | 41 | 42 | org.nutz 43 | nutzboot-starter-shiro 44 | 45 | 46 | javax.websocket 47 | javax.websocket-api 48 | 1.1 49 | provided 50 | 51 | 52 | com.sun.xml.ws 53 | jaxws-rt 54 | 2.1.4 55 | 56 | 57 | 58 | 59 | nutz-snapshots 60 | http://jfrog.nutz.cn/artifactory/snapshots 61 | 62 | true 63 | always 64 | 65 | 66 | false 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.nutz 74 | nutzboot-parent 75 | ${nutzboot.version} 76 | pom 77 | import 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/ex/ImageParseException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.ex; 2 | 3 | /** 4 | * @author mdc 5 | * @date 2016年4月2日 6 | */ 7 | public class ImageParseException extends RuntimeException { 8 | private static final long serialVersionUID = 1L; 9 | 10 | public ImageParseException(String message) { 11 | super(message); 12 | } 13 | 14 | public ImageParseException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public ImageParseException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/Colormap.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2006 Jerry Huxtable 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package com.rekoe.common.image.filter; 18 | 19 | /** 20 | * An interface for color maps. These are passed to filters which convert gray values to 21 | * colors. This is similar to the ColorModel class but works with floating point values. 22 | */ 23 | public interface Colormap { 24 | /** 25 | * Convert a value in the range 0..1 to an RGB color. 26 | * @param v a value in the range 0..1 27 | * @return an RGB color 28 | */ 29 | public int getColor(float v); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/ContrastFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | /** 4 | * 此滤镜可更改图像的亮度和对比度。 5 | * 值为1表示图片初始值, 最小值为0 6 | */ 7 | public class ContrastFilter extends TransferFilter { 8 | 9 | /** 10 | * 亮度,初始为1 11 | */ 12 | private double brightness = 1.0f; 13 | /** 14 | * 对比度,初始为1 15 | */ 16 | private double contrast = 1.0f; 17 | 18 | public ContrastFilter() { 19 | } 20 | 21 | /** 22 | * @param brightness 亮度,初始为1 23 | */ 24 | public ContrastFilter(double brightness) { 25 | this.brightness = brightness; 26 | } 27 | 28 | /** 29 | * @param brightness 亮度,初始为1 30 | * @param contrast 对比度,初始为1 31 | */ 32 | public ContrastFilter(double brightness, double contrast) { 33 | this.brightness = brightness; 34 | this.contrast = contrast; 35 | } 36 | 37 | @Override 38 | protected float transferFunction(float f) { 39 | f = (float)(f * brightness); 40 | f = (float)((f - 0.5f) * contrast + 0.5f); 41 | return f; 42 | } 43 | 44 | /** 45 | * 设置滤镜亮度 46 | * 47 | * @param brightness 亮度值,1为当前图片亮度 48 | * @min-value 0 49 | * @see #getBrightness 50 | */ 51 | public void setBrightness(double brightness) { 52 | this.brightness = brightness; 53 | initialized = false; 54 | } 55 | 56 | /** 57 | * 获取滤镜亮度 58 | * 59 | * @return 亮度值 60 | * @see #setBrightness 61 | */ 62 | public double getBrightness() { 63 | return brightness; 64 | } 65 | 66 | /** 67 | * 设置滤镜对比度 68 | * @param contrast 范围在0到1之间 69 | * @min-value 0 70 | * @see #getContrast 71 | */ 72 | public void setContrast(double contrast) { 73 | this.contrast = contrast; 74 | initialized = false; 75 | } 76 | 77 | /** 78 | * 获取滤镜对比度 79 | * @return 对比度值范围在0到1之间 80 | * @see #setContrast 81 | */ 82 | public double getContrast() { 83 | return contrast; 84 | } 85 | 86 | public String toString() { 87 | return "Colors/Contrast..."; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/GrayscaleFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.awt.image.WritableRaster; 5 | 6 | /** 7 | * 灰度滤镜 8 | */ 9 | public class GrayscaleFilter extends AbstractBufferedImageOp { 10 | protected boolean canFilterIndexColorModel = false; 11 | 12 | public GrayscaleFilter() { 13 | canFilterIndexColorModel = true; 14 | } 15 | 16 | public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 17 | int width = src.getWidth(); 18 | int height = src.getHeight(); 19 | int type = src.getType(); 20 | WritableRaster srcRaster = src.getRaster(); 21 | 22 | if ( dst == null ) 23 | dst = createCompatibleDestImage( src, null ); 24 | WritableRaster dstRaster = dst.getRaster(); 25 | 26 | setDimensions( width, height); 27 | 28 | int[] inPixels = new int[width]; 29 | for ( int y = 0; y < height; y++ ) { 30 | // We try to avoid calling getRGB on images as it causes them to become unmanaged, causing horrible performance problems. 31 | if ( type == BufferedImage.TYPE_INT_ARGB ) { 32 | srcRaster.getDataElements( 0, y, width, 1, inPixels ); 33 | for ( int x = 0; x < width; x++ ) 34 | inPixels[x] = filterRGB( x, y, inPixels[x] ); 35 | dstRaster.setDataElements( 0, y, width, 1, inPixels ); 36 | } else { 37 | src.getRGB( 0, y, width, 1, inPixels, 0, width ); 38 | for ( int x = 0; x < width; x++ ) 39 | inPixels[x] = filterRGB( x, y, inPixels[x] ); 40 | dst.setRGB( 0, y, width, 1, inPixels, 0, width ); 41 | } 42 | } 43 | 44 | return dst; 45 | } 46 | 47 | public void setDimensions(int width, int height) { 48 | } 49 | 50 | public int filterRGB(int x, int y, int rgb) { 51 | int a = rgb & 0xff000000; 52 | int r = (rgb >> 16) & 0xff; 53 | int g = (rgb >> 8) & 0xff; 54 | int b = rgb & 0xff; 55 | // rgb = (r + g + b) / 3; // simple average 56 | rgb = (r * 77 + g * 151 + b * 28) >> 8; // NTSC luma 57 | return a | (rgb << 16) | (rgb << 8) | rgb; 58 | } 59 | 60 | public String toString() { 61 | return "mdc/Grayscale"; 62 | } 63 | 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/HSBAdjustFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.Color; 4 | 5 | /** 6 | * 此滤镜可从图像的色调,饱和度和亮度通道的每一个中增加或减少给定量。例如,您可以使用它来着色图像或使颜色更饱和。 7 | * @author mdc 8 | * @date 2018年6月7日 9 | */ 10 | public class HSBAdjustFilter extends PointFilter { 11 | 12 | /** 13 | * 色相值, 最大为1 14 | */ 15 | private double hFactor; 16 | /** 17 | * 饱和度值, 最大为1 18 | */ 19 | private double sFactor; 20 | /** 21 | * 亮度值, 最大为1 22 | */ 23 | private double bFactor; 24 | 25 | private float[] hsb = new float[3]; 26 | 27 | public HSBAdjustFilter() { 28 | this(0, 0, 0); 29 | } 30 | 31 | /** 32 | * 构造器 33 | * @param r 色相值, 最大为1 34 | * @param g 饱和度值, 最大为1 35 | * @param b 亮度值, 最大为1 36 | */ 37 | public HSBAdjustFilter(double r, double g, double b) { 38 | hFactor = r; 39 | sFactor = g; 40 | bFactor = b; 41 | canFilterIndexColorModel = true; 42 | } 43 | 44 | public void setHFactor( double hFactor ) { 45 | this.hFactor = hFactor; 46 | } 47 | 48 | public double getHFactor() { 49 | return hFactor; 50 | } 51 | 52 | public void setSFactor( double sFactor ) { 53 | this.sFactor = sFactor; 54 | } 55 | 56 | public double getSFactor() { 57 | return sFactor; 58 | } 59 | 60 | public void setBFactor( double bFactor ) { 61 | this.bFactor = bFactor; 62 | } 63 | 64 | public double getBFactor() { 65 | return bFactor; 66 | } 67 | 68 | @Override 69 | public int filterRGB(int x, int y, int rgb) { 70 | int a = rgb & 0xff000000; 71 | int r = (rgb >> 16) & 0xff; 72 | int g = (rgb >> 8) & 0xff; 73 | int b = rgb & 0xff; 74 | Color.RGBtoHSB(r, g, b, hsb); 75 | hsb[0] += hFactor; 76 | while (hsb[0] < 0) 77 | hsb[0] += Math.PI * 2; 78 | hsb[1] += sFactor; 79 | if (hsb[1] < 0) 80 | hsb[1] = 0; 81 | else if (hsb[1] > 1.0) 82 | hsb[1] = 1.0f; 83 | hsb[2] += bFactor; 84 | if (hsb[2] < 0) 85 | hsb[2] = 0; 86 | else if (hsb[2] > 1.0) 87 | hsb[2] = 1.0f; 88 | rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]); 89 | return a | (rgb & 0xffffff); 90 | } 91 | 92 | public String toString() { 93 | return "Colors/Adjust HSB..."; 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/LinearColormap.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2006 Jerry Huxtable 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package com.rekoe.common.image.filter; 18 | 19 | /** 20 | * A colormap which interpolates linearly between two colors. 21 | */ 22 | public class LinearColormap implements Colormap { 23 | 24 | private int color1; 25 | private int color2; 26 | 27 | /** 28 | * Construct a color map with a grayscale ramp from black to white. 29 | */ 30 | public LinearColormap() { 31 | this(0xff000000, 0xffffffff); 32 | } 33 | 34 | /** 35 | * Construct a linear color map. 36 | * @param color1 the color corresponding to value 0 in the colormap 37 | * @param color2 the color corresponding to value 1 in the colormap 38 | */ 39 | public LinearColormap(int color1, int color2) { 40 | this.color1 = color1; 41 | this.color2 = color2; 42 | } 43 | 44 | /** 45 | * Set the first color. 46 | * @param color1 the color corresponding to value 0 in the colormap 47 | */ 48 | public void setColor1(int color1) { 49 | this.color1 = color1; 50 | } 51 | 52 | /** 53 | * Get the first color. 54 | * @return the color corresponding to value 0 in the colormap 55 | */ 56 | public int getColor1() { 57 | return color1; 58 | } 59 | 60 | /** 61 | * Set the second color. 62 | * @param color2 the color corresponding to value 1 in the colormap 63 | */ 64 | public void setColor2(int color2) { 65 | this.color2 = color2; 66 | } 67 | 68 | /** 69 | * Get the second color. 70 | * @return the color corresponding to value 1 in the colormap 71 | */ 72 | public int getColor2() { 73 | return color2; 74 | } 75 | 76 | /** 77 | * Convert a value in the range 0..1 to an RGB color. 78 | * @param v a value in the range 0..1 79 | * @return an RGB color 80 | */ 81 | public int getColor(float v) { 82 | return ImageMath.mixColors(ImageMath.clamp(v, 0, 1.0f), color1, color2); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/PixellateFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * 像素效果 7 | * @author mdc 8 | * @date 2016年5月15日 9 | */ 10 | public class PixellateFilter extends AbstractBufferedImageOp { 11 | private int size; 12 | 13 | public PixellateFilter() { 14 | size = 10; // default block size=10x10 15 | } 16 | 17 | public PixellateFilter(int size) { 18 | this.size = size; 19 | } 20 | 21 | /** 22 | * @return 获取{@link #size} 23 | */ 24 | public int getSize() { 25 | return size; 26 | } 27 | 28 | /** 29 | * @param size 设置size 30 | */ 31 | public void setSize(int size) { 32 | this.size = size; 33 | } 34 | 35 | @Override 36 | public BufferedImage filter(BufferedImage src, BufferedImage dest) { 37 | int width = src.getWidth(); 38 | int height = src.getHeight(); 39 | 40 | if (dest == null) { 41 | dest = createCompatibleDestImage(src, null); 42 | } 43 | 44 | int[] inPixels = new int[width * height]; 45 | int[] outPixels = new int[width * height]; 46 | getRGB(src, 0, 0, width, height, inPixels); 47 | int index = 0; 48 | 49 | int offsetX = 0, offsetY = 0; 50 | int newX = 0, newY = 0; 51 | double total = size * size; 52 | double sumred = 0, sumgreen = 0, sumblue = 0; 53 | for (int row = 0; row < height; row++) { 54 | int ta = 0, tr = 0, tg = 0, tb = 0; 55 | for (int col = 0; col < width; col++) { 56 | newY = (row / size) * size; 57 | newX = (col / size) * size; 58 | offsetX = newX + size; 59 | offsetY = newY + size; 60 | 61 | for (int subRow = newY; subRow < offsetY; subRow++) { 62 | for (int subCol = newX; subCol < offsetX; subCol++) { 63 | if (subRow < 0 || subRow >= height) { 64 | continue; 65 | } 66 | if (subCol < 0 || subCol >= width) { 67 | continue; 68 | } 69 | index = subRow * width + subCol; 70 | ta = (inPixels[index] >> 24) & 0xff; 71 | sumred += (inPixels[index] >> 16) & 0xff; 72 | sumgreen += (inPixels[index] >> 8) & 0xff; 73 | sumblue += inPixels[index] & 0xff; 74 | } 75 | } 76 | index = row * width + col; 77 | tr = (int) (sumred / total); 78 | tg = (int) (sumgreen / total); 79 | tb = (int) (sumblue / total); 80 | outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb; 81 | 82 | sumred = sumgreen = sumblue = 0; // reset them... 83 | } 84 | } 85 | 86 | setRGB(dest, 0, 0, width, height, outPixels); 87 | return dest; 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/PointFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.image.*; 4 | 5 | /** 6 | * An abstract superclass for point filters. The interface is the same as the old RGBImageFilter. 7 | */ 8 | public abstract class PointFilter extends AbstractBufferedImageOp { 9 | 10 | protected boolean canFilterIndexColorModel = false; 11 | 12 | public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 13 | int width = src.getWidth(); 14 | int height = src.getHeight(); 15 | int type = src.getType(); 16 | WritableRaster srcRaster = src.getRaster(); 17 | 18 | if ( dst == null ) 19 | dst = createCompatibleDestImage( src, null ); 20 | WritableRaster dstRaster = dst.getRaster(); 21 | 22 | setDimensions( width, height); 23 | 24 | int[] inPixels = new int[width]; 25 | for ( int y = 0; y < height; y++ ) { 26 | // We try to avoid calling getRGB on images as it causes them to become unmanaged, causing horrible performance problems. 27 | if ( type == BufferedImage.TYPE_INT_ARGB ) { 28 | srcRaster.getDataElements( 0, y, width, 1, inPixels ); 29 | for ( int x = 0; x < width; x++ ) 30 | inPixels[x] = filterRGB( x, y, inPixels[x] ); 31 | dstRaster.setDataElements( 0, y, width, 1, inPixels ); 32 | } else { 33 | src.getRGB( 0, y, width, 1, inPixels, 0, width ); 34 | for ( int x = 0; x < width; x++ ) 35 | inPixels[x] = filterRGB( x, y, inPixels[x] ); 36 | dst.setRGB( 0, y, width, 1, inPixels, 0, width ); 37 | } 38 | } 39 | 40 | return dst; 41 | } 42 | 43 | public void setDimensions(int width, int height) { 44 | } 45 | 46 | public abstract int filterRGB(int x, int y, int rgb); 47 | } 48 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/RotateFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.Point; 4 | import java.awt.Rectangle; 5 | 6 | /** 7 | * 旋转滤镜 8 | */ 9 | public class RotateFilter extends TransformFilter { 10 | 11 | private double angle; 12 | private double cos, sin; 13 | private boolean resize = true; 14 | 15 | /** 16 | * Construct a RotateFilter. 17 | */ 18 | public RotateFilter() { 19 | this(ImageMath.PI); 20 | } 21 | 22 | /** 23 | * Construct a RotateFilter. 24 | * @param angle the angle to rotate 25 | */ 26 | public RotateFilter(double angle) { 27 | this(angle, true); 28 | } 29 | 30 | /** 31 | * Construct a RotateFilter. 32 | * @param angle the angle to rotate 33 | * @param resize true if the output image should be resized 34 | */ 35 | public RotateFilter(double angle, boolean resize) { 36 | setAngle(angle); 37 | this.resize = resize; 38 | } 39 | 40 | /** 41 | * Specifies the angle of rotation. 42 | * @param angle the angle of rotation. 43 | * @angle 44 | * @see #getAngle 45 | */ 46 | public void setAngle(double angle) { 47 | this.angle = angle; 48 | cos = Math.cos(this.angle); 49 | sin = Math.sin(this.angle); 50 | } 51 | 52 | /** 53 | * Returns the angle of rotation. 54 | * @return the angle of rotation. 55 | * @see #setAngle 56 | */ 57 | public double getAngle() { 58 | return angle; 59 | } 60 | 61 | protected void transformSpace(Rectangle rect) { 62 | if (resize) { 63 | Point out = new Point(0, 0); 64 | int minx = Integer.MAX_VALUE; 65 | int miny = Integer.MAX_VALUE; 66 | int maxx = Integer.MIN_VALUE; 67 | int maxy = Integer.MIN_VALUE; 68 | int w = rect.width; 69 | int h = rect.height; 70 | int x = rect.x; 71 | int y = rect.y; 72 | 73 | for (int i = 0; i < 4; i++) { 74 | switch (i) { 75 | case 0: transform(x, y, out); break; 76 | case 1: transform(x + w, y, out); break; 77 | case 2: transform(x, y + h, out); break; 78 | case 3: transform(x + w, y + h, out); break; 79 | } 80 | minx = Math.min(minx, out.x); 81 | miny = Math.min(miny, out.y); 82 | maxx = Math.max(maxx, out.x); 83 | maxy = Math.max(maxy, out.y); 84 | } 85 | 86 | rect.x = minx; 87 | rect.y = miny; 88 | rect.width = maxx - rect.x; 89 | rect.height = maxy - rect.y; 90 | } 91 | } 92 | 93 | private void transform(int x, int y, Point out) { 94 | out.x = (int)((x * cos) + (y * sin)); 95 | out.y = (int)((y * cos) - (x * sin)); 96 | } 97 | 98 | protected void transformInverse(int x, int y, float[] out) { 99 | out[0] = (float) ((x * cos) - (y * sin)); 100 | out[1] = (float) ((y * cos) + (x * sin)); 101 | } 102 | 103 | public String toString() { 104 | return "Rotate "+(int)(angle * 180 / Math.PI); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/ScaleFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.Graphics2D; 4 | import java.awt.Image; 5 | import java.awt.image.BufferedImage; 6 | import java.awt.image.ColorModel; 7 | 8 | /** 9 | * 图片缩放滤镜 10 | */ 11 | public class ScaleFilter extends AbstractBufferedImageOp { 12 | 13 | private int width; 14 | private int height; 15 | 16 | /** 17 | * Construct a ScaleFilter. 18 | */ 19 | public ScaleFilter() { 20 | this(32, 32); 21 | } 22 | 23 | /** 24 | * Construct a ScaleFilter. 25 | * @param width the width to scale to 26 | * @param height the height to scale to 27 | */ 28 | public ScaleFilter(int width, int height) { 29 | this.width = width; 30 | this.height = height; 31 | } 32 | 33 | @Override 34 | public BufferedImage filter(BufferedImage src, BufferedImage dst) { 35 | 36 | if (dst == null) { 37 | ColorModel dstCM = src.getColorModel(); 38 | dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(width, height), dstCM.isAlphaPremultiplied(), null); 39 | } 40 | 41 | Image scaleImage = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); 42 | Graphics2D g = dst.createGraphics(); 43 | g.drawImage(scaleImage, 0, 0, width, height, null); 44 | g.dispose(); 45 | 46 | return dst; 47 | } 48 | 49 | public String toString() { 50 | return "mdc/Scale"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/SepiaToneFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * 黄褐色特效(老照片效果)滤镜 7 | * @author mdc 8 | * @date 2016年5月15日 9 | */ 10 | public class SepiaToneFilter extends AbstractBufferedImageOp { 11 | 12 | @Override 13 | public BufferedImage filter(BufferedImage src, BufferedImage dest) { 14 | 15 | int width = src.getWidth(); 16 | int height = src.getHeight(); 17 | 18 | if (dest == null) { 19 | dest = createCompatibleDestImage(src, null); 20 | } 21 | 22 | int[] inPixels = new int[width * height]; 23 | int[] outPixels = new int[width * height]; 24 | getRGB(src, 0, 0, width, height, inPixels); 25 | int index = 0; 26 | 27 | for (int row = 0; row < height; row++) { 28 | int ta = 0, tr = 0, tg = 0, tb = 0; 29 | for (int col = 0; col < width; col++) { 30 | index = row * width + col; 31 | ta = (inPixels[index] >> 24) & 0xff; 32 | tr = (inPixels[index] >> 16) & 0xff; 33 | tg = (inPixels[index] >> 8) & 0xff; 34 | tb = inPixels[index] & 0xff; 35 | 36 | int fr = (int) colorBlend(noise(), (tr * 0.393) + (tg * 0.769) + (tb * 0.189), tr); 37 | int fg = (int) colorBlend(noise(), (tr * 0.349) + (tg * 0.686) + (tb * 0.168), tg); 38 | int fb = (int) colorBlend(noise(), (tr * 0.272) + (tg * 0.534) + (tb * 0.131), tb); 39 | 40 | outPixels[index] = (ta << 24) | (clamp(fr) << 16) | (clamp(fg) << 8) | clamp(fb); 41 | 42 | } 43 | } 44 | setRGB(dest, 0, 0, width, height, outPixels); 45 | return dest; 46 | } 47 | 48 | private double noise() { 49 | return Math.random() * 0.5 + 0.5; 50 | } 51 | 52 | private double colorBlend(double scale, double dest, double src) { 53 | return (scale * dest + (1.0 - scale) * src); 54 | } 55 | 56 | public static int clamp(int c) { 57 | return c > 255 ? 255 : ((c < 0) ? 0 : c); 58 | } 59 | 60 | public String toString() { 61 | return "Sepia Tone Effect - Effect from Photoshop App"; 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/ThresholdFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | 4 | /** 5 | *图像二值化处理 6 | */ 7 | public class ThresholdFilter extends PointFilter { 8 | 9 | private int lowerThreshold; 10 | private int upperThreshold; 11 | private int white = 0xffffff; 12 | private int black = 0x000000; 13 | 14 | /** 15 | * Construct a ThresholdFilter. 16 | */ 17 | public ThresholdFilter() { 18 | this(127); 19 | } 20 | 21 | /** 22 | * Construct a ThresholdFilter. 23 | * @param t the threshold value 24 | */ 25 | public ThresholdFilter(int t) { 26 | setLowerThreshold(t); 27 | setUpperThreshold(t); 28 | } 29 | 30 | /** 31 | * Set the lower threshold value. 32 | * @param lowerThreshold the threshold value 33 | * @see #getLowerThreshold 34 | */ 35 | public void setLowerThreshold(int lowerThreshold) { 36 | this.lowerThreshold = lowerThreshold; 37 | } 38 | 39 | /** 40 | * Get the lower threshold value. 41 | * @return the threshold value 42 | * @see #setLowerThreshold 43 | */ 44 | public int getLowerThreshold() { 45 | return lowerThreshold; 46 | } 47 | 48 | /** 49 | * Set the upper threshold value. 50 | * @param upperThreshold the threshold value 51 | * @see #getUpperThreshold 52 | */ 53 | public void setUpperThreshold(int upperThreshold) { 54 | this.upperThreshold = upperThreshold; 55 | } 56 | 57 | /** 58 | * Get the upper threshold value. 59 | * @return the threshold value 60 | * @see #setUpperThreshold 61 | */ 62 | public int getUpperThreshold() { 63 | return upperThreshold; 64 | } 65 | 66 | /** 67 | * Set the color to be used for pixels above the upper threshold. 68 | * @param white the color 69 | * @see #getWhite 70 | */ 71 | public void setWhite(int white) { 72 | this.white = white; 73 | } 74 | 75 | /** 76 | * Get the color to be used for pixels above the upper threshold. 77 | * @return the color 78 | * @see #setWhite 79 | */ 80 | public int getWhite() { 81 | return white; 82 | } 83 | 84 | /** 85 | * Set the color to be used for pixels below the lower threshold. 86 | * @param black the color 87 | * @see #getBlack 88 | */ 89 | public void setBlack(int black) { 90 | this.black = black; 91 | } 92 | 93 | /** 94 | * Set the color to be used for pixels below the lower threshold. 95 | * @return the color 96 | * @see #setBlack 97 | */ 98 | public int getBlack() { 99 | return black; 100 | } 101 | 102 | public int filterRGB(int x, int y, int rgb) { 103 | int v = PixelUtils.brightness( rgb ); 104 | float f = ImageMath.smoothStep( lowerThreshold, upperThreshold, v ); 105 | return (rgb & 0xff000000) | (ImageMath.mixColors( f, black, white ) & 0xffffff); 106 | } 107 | 108 | public String toString() { 109 | return "Stylize/Threshold..."; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/TransferFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | public abstract class TransferFilter extends PointFilter { 6 | 7 | protected int[] rTable, gTable, bTable; 8 | protected boolean initialized = false; 9 | 10 | public TransferFilter() { 11 | canFilterIndexColorModel = true; 12 | } 13 | 14 | public int filterRGB(int x, int y, int rgb) { 15 | int a = rgb & 0xff000000; 16 | int r = (rgb >> 16) & 0xff; 17 | int g = (rgb >> 8) & 0xff; 18 | int b = rgb & 0xff; 19 | r = rTable[r]; 20 | g = gTable[g]; 21 | b = bTable[b]; 22 | return a | (r << 16) | (g << 8) | b; 23 | } 24 | 25 | public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 26 | if (!initialized) 27 | initialize(); 28 | return super.filter( src, dst ); 29 | } 30 | 31 | protected void initialize() { 32 | initialized = true; 33 | rTable = gTable = bTable = makeTable(); 34 | } 35 | 36 | protected int[] makeTable() { 37 | int[] table = new int[256]; 38 | for (int i = 0; i < 256; i++) 39 | table[i] = PixelUtils.clamp( (int)( 255 * transferFunction( i / 255.0f ) ) ); 40 | return table; 41 | } 42 | 43 | protected float transferFunction( float v ) { 44 | return 0; 45 | } 46 | 47 | public int[] getLUT() { 48 | if (!initialized) 49 | initialize(); 50 | int[] lut = new int[256]; 51 | for ( int i = 0; i < 256; i++ ) { 52 | lut[i] = filterRGB( 0, 0, (i << 24) | (i << 16) | (i << 8) | i ); 53 | } 54 | return lut; 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/filter/WholeImageFilter.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.filter; 2 | 3 | import java.awt.Rectangle; 4 | import java.awt.image.BufferedImage; 5 | import java.awt.image.ColorModel; 6 | 7 | /** 8 | * A filter which acts as a superclass for filters which need to have the whole image in memory 9 | * to do their stuff. 10 | */ 11 | public abstract class WholeImageFilter extends AbstractBufferedImageOp { 12 | 13 | /** 14 | * The output image bounds. 15 | */ 16 | protected Rectangle transformedSpace; 17 | 18 | /** 19 | * The input image bounds. 20 | */ 21 | protected Rectangle originalSpace; 22 | 23 | /** 24 | * Construct a WholeImageFilter. 25 | */ 26 | public WholeImageFilter() { 27 | } 28 | 29 | public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 30 | int width = src.getWidth(); 31 | int height = src.getHeight(); 32 | 33 | originalSpace = new Rectangle(0, 0, width, height); 34 | transformedSpace = new Rectangle(0, 0, width, height); 35 | transformSpace(transformedSpace); 36 | 37 | if ( dst == null ) { 38 | ColorModel dstCM = src.getColorModel(); 39 | dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null); 40 | } 41 | 42 | int[] inPixels = getRGB( src, 0, 0, width, height, null ); 43 | inPixels = filterPixels( width, height, inPixels, transformedSpace ); 44 | setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels ); 45 | 46 | return dst; 47 | } 48 | 49 | /** 50 | * Calculate output bounds for given input bounds. 51 | * @param rect input and output rectangle 52 | */ 53 | protected void transformSpace(Rectangle rect) { 54 | } 55 | 56 | /** 57 | * Actually filter the pixels. 58 | * @param width the image width 59 | * @param height the image height 60 | * @param inPixels the image pixels 61 | * @param transformedSpace the output bounds 62 | * @return the output pixels 63 | */ 64 | protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ); 65 | } 66 | 67 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/kit/IOKit.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.kit; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import javax.imageio.stream.ImageInputStream; 8 | import javax.imageio.stream.ImageOutputStream; 9 | 10 | /** 11 | * @author mdc 12 | * @date 2016年8月14日 13 | */ 14 | public class IOKit { 15 | 16 | public static void closeQuietly(OutputStream closeable) { 17 | try { 18 | if (closeable != null) { 19 | closeable.close(); 20 | } 21 | } catch (IOException ioe) { 22 | // ignore 23 | } 24 | } 25 | 26 | public static void closeQuietly(InputStream closeable) { 27 | try { 28 | if (closeable != null) { 29 | closeable.close(); 30 | } 31 | } catch (IOException ioe) { 32 | // ignore 33 | } 34 | } 35 | 36 | public static void closeQuietly(ImageInputStream closeable) { 37 | try { 38 | if (closeable != null) { 39 | closeable.close(); 40 | } 41 | } catch (IOException ioe) { 42 | // ignore 43 | } 44 | } 45 | public static void closeQuietly(ImageOutputStream closeable) { 46 | try { 47 | if (closeable != null) { 48 | closeable.close(); 49 | } 50 | } catch (IOException ioe) { 51 | // ignore 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/kit/StringKit.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.kit; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | /** 6 | * 字符串处理 7 | * @author mdc 8 | * @date 2016年8月14日 9 | */ 10 | public class StringKit { 11 | 12 | /** 13 | * Constructs a new String by decoding the specified array of bytes using the UTF-8 charset. 14 | * 15 | * @param bytes 16 | * The bytes to be decoded into characters 17 | * @return A new String decoded from the specified array of bytes using the UTF-8 charset, 18 | * or {@code null} if the input byte array was {@code null}. 19 | * @throws NullPointerException 20 | * Thrown if {@link Charsets#UTF_8} is not initialized, which should never happen since it is 21 | * required by the Java platform specification. 22 | * @since As of 1.7, throws {@link NullPointerException} instead of UnsupportedEncodingException 23 | */ 24 | public static String newStringUtf8(final byte[] bytes) { 25 | return bytes == null ? null : new String(bytes, Charset.forName("UTF-8")); 26 | } 27 | 28 | /** 29 | * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte 30 | * array. 31 | * 32 | * @param string 33 | * the String to encode, may be {@code null} 34 | * @return encoded bytes, or {@code null} if the input string was {@code null} 35 | * @throws NullPointerException 36 | * Thrown if {@link Charsets#UTF_8} is not initialized, which should never happen since it is 37 | * required by the Java platform specification. 38 | * @since As of 1.7, throws {@link NullPointerException} instead of UnsupportedEncodingException 39 | * @see Standard charsets 40 | * @see #getBytesUnchecked(String, String) 41 | */ 42 | public static byte[] getBytesUtf8(final String string) { 43 | if (string == null) { 44 | return null; 45 | } 46 | return string.getBytes(Charset.forName("UTF-8")); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/image/type/ImageType.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.image.type; 2 | 3 | /** 4 | * 图片类型 5 | * @author mdc 6 | * @date 2015年2月27日 7 | */ 8 | public enum ImageType { 9 | 10 | /** 11 | * png图片 12 | */ 13 | PNG("image/png", "png", "data:image/png;base64,"), 14 | /** 15 | * jpg图片 16 | */ 17 | JPG("image/jpg", "jpg", "data:image/jpeg;base64,"), 18 | /** 19 | * jpg图片 20 | */ 21 | JPEG("image/jpeg", "jpeg", "data:image/jpeg;base64,"), 22 | /** 23 | * bmp图片 24 | */ 25 | BMP("image/bmp", "bmp", "data:image/bmp;base64,"), 26 | /** 27 | * wbmp图片 28 | */ 29 | WBMP("image/vnd.wap.wbmp", "wbmp", "data:image/wbmp;base64,"), 30 | /** 31 | * gif图片 32 | */ 33 | GIF("image/gif", "gif", "data:image/gif;base64,"); 34 | 35 | private String type; 36 | private String media; 37 | private String b64Prefix; //base64编码前缀 38 | 39 | ImageType(String media, String type, String b64Prefix){ 40 | this.media = media; 41 | this.type = type; 42 | this.b64Prefix = b64Prefix; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return this.type; 48 | } 49 | 50 | /** 51 | * 获取图片类型 52 | * @author mdc 53 | * @date 2015年2月27日 54 | * @return 55 | */ 56 | public String getType(){ 57 | return this.type; 58 | } 59 | 60 | /** 61 | * 获取图片的Media 62 | * @author mdc 63 | * @date 2015年6月10日 64 | * @return 65 | */ 66 | public String getMedia(){ 67 | return this.media; 68 | } 69 | 70 | /** 71 | * @return 获取{@link #b64Prefix} 72 | */ 73 | public String getB64Prefix() { 74 | return b64Prefix; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/checkedRun/MainApp.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.checkedRun; 2 | 3 | import java.nio.file.Files; 4 | import java.nio.file.Paths; 5 | import java.util.List; 6 | 7 | import org.nutz.log.Log; 8 | import org.nutz.log.Logs; 9 | 10 | import com.rekoe.common.large.excell.to.bean.ta.bean.ExampleBean; 11 | import com.rekoe.common.large.excell.to.bean.ta.utilities.enums.ExcelFactoryType; 12 | import com.rekoe.common.large.excell.to.bean.ta.utilities.factory.Parser; 13 | /** 14 | * 15 | * @author Taleh Algayev 16 | * Jun 1, 2018 17 | */ 18 | public class MainApp { 19 | final static Log log = Logs.get(); 20 | public static void main(String[] args) throws Exception { 21 | 22 | Parser parser = new Parser(ExampleBean.class, ExcelFactoryType.COLUMN_INDEX_BASED_EXTRACTION,true); 23 | parser.setSkipHeader(true); 24 | 25 | long start = System.currentTimeMillis(); 26 | byte [] file = Files.readAllBytes(Paths.get(MainApp.class.getClassLoader().getResource("sample.xlsx").toURI())); 27 | log.info("convert to byte -> "+(System.currentTimeMillis()-start)); 28 | start = System.currentTimeMillis(); 29 | List resultAfterParse = parser.parse(file); 30 | log.info("convert to bean -> "+(System.currentTimeMillis()-start)); 31 | log.info("excell row size - > "+resultAfterParse.size()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/CloseException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | 3 | /** 4 | * 5 | * @author Taleh Algayev 6 | * Jun 1, 2018 7 | */ 8 | public class CloseException extends RuntimeException { 9 | 10 | public CloseException() { 11 | super(); 12 | } 13 | 14 | public CloseException(String msg) { 15 | super(msg); 16 | } 17 | 18 | public CloseException(Exception e) { 19 | super(e); 20 | } 21 | 22 | public CloseException(String msg, Exception e) { 23 | super(msg, e); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/MissingSheetException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | public class MissingSheetException extends RuntimeException { 8 | 9 | public MissingSheetException() { 10 | super(); 11 | } 12 | 13 | public MissingSheetException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public MissingSheetException(Exception e) { 18 | super(e); 19 | } 20 | 21 | public MissingSheetException(String msg, Exception e) { 22 | super(msg, e); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/NotSupportedException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | public class NotSupportedException extends RuntimeException { 8 | 9 | public NotSupportedException() { 10 | super(); 11 | } 12 | 13 | public NotSupportedException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public NotSupportedException(Exception e) { 18 | super(e); 19 | } 20 | 21 | public NotSupportedException(String msg, Exception e) { 22 | super(msg, e); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/OpenException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | 3 | /** 4 | * 5 | * @author Taleh Algayev 6 | * Jun 1, 2018 7 | */ 8 | public class OpenException extends RuntimeException { 9 | 10 | public OpenException() { 11 | super(); 12 | } 13 | 14 | public OpenException(String msg) { 15 | super(msg); 16 | } 17 | 18 | public OpenException(Exception e) { 19 | super(e); 20 | } 21 | 22 | public OpenException(String msg, Exception e) { 23 | super(msg, e); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/ParseException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | public class ParseException extends RuntimeException { 8 | 9 | public ParseException() { 10 | super(); 11 | } 12 | 13 | public ParseException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public ParseException(Exception e) { 18 | super(e); 19 | } 20 | 21 | public ParseException(String msg, Exception e) { 22 | super(msg, e); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/exceptions/ReadException.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.exceptions; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | public class ReadException extends RuntimeException { 8 | 9 | public ReadException() { 10 | super(); 11 | } 12 | 13 | public ReadException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public ReadException(Exception e) { 18 | super(e); 19 | } 20 | 21 | public ReadException(String msg, Exception e) { 22 | super(msg, e); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/impl/StringSupplier.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.impl; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | class StringSupplier implements Supplier { 8 | private final String val; 9 | 10 | StringSupplier(String val) { 11 | this.val = val; 12 | } 13 | 14 | @Override 15 | public Object getContent() { 16 | return val; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/impl/Supplier.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.impl; 2 | /** 3 | * 4 | * @author Taleh Algayev 5 | * Jun 1, 2018 6 | */ 7 | interface Supplier { 8 | Object getContent(); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import javax.xml.parsers.DocumentBuilderFactory; 7 | import javax.xml.parsers.ParserConfigurationException; 8 | import javax.xml.xpath.XPathConstants; 9 | import javax.xml.xpath.XPathExpressionException; 10 | import javax.xml.xpath.XPathFactory; 11 | 12 | import org.w3c.dom.Document; 13 | import org.w3c.dom.NodeList; 14 | import org.xml.sax.SAXException; 15 | 16 | import com.rekoe.common.large.excell.to.bean.ta.exceptions.ParseException; 17 | /** 18 | * 19 | * @author Taleh Algayev 20 | * Jun 1, 2018 21 | */ 22 | public class XmlUtils { 23 | public static Document document(InputStream is) { 24 | try { 25 | return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); 26 | } catch(SAXException | IOException | ParserConfigurationException e) { 27 | throw new ParseException(e); 28 | } 29 | } 30 | 31 | public static NodeList searchForNodeList(Document document, String xpath) { 32 | try { 33 | return (NodeList) XPathFactory.newInstance().newXPath().compile(xpath) 34 | .evaluate(document, XPathConstants.NODESET); 35 | } catch(XPathExpressionException e) { 36 | throw new ParseException(e); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/annotations/ExcelBean.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.annotations; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | /** 7 | * 8 | * @author Taleh Algayev 9 | * Jun 1, 2018 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | public @interface ExcelBean { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/annotations/ExcelColumnHeader.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 10 | * @author Taleh Algayev 11 | * Jun 1, 2018 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.FIELD) 15 | public @interface ExcelColumnHeader { 16 | 17 | /** 18 | * Data extraction based on the column header instead of column index.
19 | * If ExcelFactoryType is COLUMN_NAME_BASED then the first row will be treated as headers.
20 | * These headers will be used later to fetch the data
21 | * @return 22 | */ 23 | String columnHeader(); 24 | 25 | /** 26 | * Specify the cell data type, if dataType is provided the extracted cell 27 | * value is parsed and converted into specified dataType. possible values 28 | * are
29 | *
    30 | *
  • "int" : returns the Integer value
  • 31 | *
  • "long" : returns the long value
  • 32 | *
  • "bool" : returns the boolean representation
  • 33 | *
  • "string" returns string representation, it's by default 34 | *
  • "double" returns the double value
  • 35 | *
  • "date" returns the java.util.date object
  • 36 | *
37 | * 38 | * @return 39 | */ 40 | String dataType() default "string"; 41 | 42 | /** 43 | * Specifies the default value, if data is not found in the cell ( either 44 | * blank or null ), then it will put the default value
45 | * Default values will also be casted in their dataType 46 | * 47 | * @return 48 | */ 49 | String defaultValue() default ""; 50 | } 51 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/annotations/ExcelColumnIndex.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 10 | * @author Taleh Algayev 11 | * Jun 1, 2018 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.FIELD) 15 | public @interface ExcelColumnIndex { 16 | 17 | /** 18 | * Zero based column index can be used to pull cell data in the annotated 19 | * field.
20 | * For instance : Any field annotated with columnIndex("2"), that field will 21 | * be initialized with the value contained in column number 2 starting from 0. 22 | * @return 23 | */ 24 | String columnIndex(); 25 | 26 | /** 27 | * Specify the cell data type, if dataType is provided the extracted cell 28 | * value is parsed and converted into specified dataType. possible values 29 | * are
30 | *
    31 | *
  • "int" : returns the Integer value
  • 32 | *
  • "long" : returns the long value
  • 33 | *
  • "bool" : returns the boolean representation
  • 34 | *
  • "string" returns string representation, it's by default 35 | *
  • "double" returns the double value
  • 36 | *
  • "date" returns the java.util.date object
  • 37 | *
38 | * 39 | * @return 40 | */ 41 | String dataType() default "string"; 42 | 43 | /** 44 | * Specifies the default value, if data is not found in the cell ( either 45 | * blank or null ), then it will put the default value
46 | * Default values will also be casted in their dataType 47 | * 48 | * @return 49 | */ 50 | String defaultValue() default ""; 51 | } 52 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/bean/ResponseBean.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.bean; 2 | 3 | import com.rekoe.common.large.excell.to.bean.ta.utilities.enums.CoreMessages; 4 | /** 5 | * 6 | * @author Taleh Algayev 7 | * Jun 1, 2018 8 | */ 9 | public class ResponseBean { 10 | 11 | private long rowId; 12 | 13 | private CoreMessages errorCode; 14 | 15 | public CoreMessages getErrorCode() { 16 | return errorCode; 17 | } 18 | 19 | public void setErrorCode(CoreMessages errorCode) { 20 | this.errorCode = errorCode; 21 | } 22 | 23 | public long getRowId() { 24 | return rowId; 25 | } 26 | 27 | public void setRowId(long rowId) { 28 | this.rowId = rowId; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/enums/ExcelFactoryType.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.enums; 2 | 3 | import com.rekoe.common.large.excell.to.bean.ta.utilities.annotations.ExcelBean; 4 | import com.rekoe.common.large.excell.to.bean.ta.utilities.annotations.ExcelColumnIndex; 5 | 6 | /** 7 | * Defines the excel factory type.
8 | * Based on this ExcelFactory, you can choose whether you want to extract cell 9 | * values based on (columns names) or (column index). 10 | * 11 | * @author Taleh Alqayev 12 | * @see ExcelBean 13 | * @see ExcelColumnIndex 14 | */ 15 | public enum ExcelFactoryType { 16 | COLUMN_INDEX_BASED_EXTRACTION, COLUMN_NAME_BASED_EXTRACTION; 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/large/excell/to/bean/ta/utilities/factory/Test.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.large.excell.to.bean.ta.utilities.factory; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.poi.ss.usermodel.Cell; 6 | import org.apache.poi.ss.usermodel.Row; 7 | import org.apache.poi.ss.usermodel.Sheet; 8 | import org.apache.poi.ss.usermodel.Workbook; 9 | import org.nutz.lang.Files; 10 | 11 | import com.rekoe.common.large.excell.to.bean.ta.utilities.StreamingReader; 12 | 13 | public class Test { 14 | 15 | public static void main(String[] args) { 16 | File file = Files.findFile("/Users/kouxian/Desktop/20180904.jason.xlsx"); 17 | Workbook wb = StreamingReader.builder().rowCacheSize(5000).bufferSize(4096).open(file); 18 | int sheetNumber = wb.getNumberOfSheets(); 19 | System.out.println(sheetNumber); 20 | for (int i = 0; i < sheetNumber; i++) { 21 | //Sheet sheet = wb.getSheetAt(i); 22 | //String sheetName = sheet.getSheetName(); 23 | //System.out.println(sheetName); 24 | for (Sheet sheet : wb){ 25 | for (Row row : sheet) { 26 | int rowNumber = row.getRowNum(); 27 | if(rowNumber==0) { 28 | int cellNumber = row.getPhysicalNumberOfCells(); 29 | for(int j=0;j 12 | * See CasSubjectFactory 13 | * 14 | * @author Shengzhao Li 15 | */ 16 | public class OAuth2SubjectFactory extends DefaultWebSubjectFactory { 17 | 18 | @Override 19 | public Subject createSubject(SubjectContext context) { 20 | 21 | boolean authenticated = context.isAuthenticated(); 22 | 23 | if (authenticated) { 24 | 25 | AuthenticationToken token = context.getAuthenticationToken(); 26 | 27 | if (token != null && token instanceof UsernamePasswordToken) { 28 | UsernamePasswordToken oAuth2Token = (UsernamePasswordToken) token; 29 | if (oAuth2Token.isRememberMe()) { 30 | context.setAuthenticated(false); 31 | } 32 | } 33 | } 34 | 35 | return super.createSubject(context); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/vo/GrantDTO.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.vo; 2 | 3 | /** 4 | * @author kerbores 5 | * 6 | */ 7 | public class GrantDTO { 8 | private long id; 9 | 10 | private long[] grantIds; 11 | 12 | /** 13 | * @return the id 14 | */ 15 | public long getId() { 16 | return id; 17 | } 18 | 19 | /** 20 | * @param id 21 | * the id to set 22 | */ 23 | public void setId(long id) { 24 | this.id = id; 25 | } 26 | 27 | public long[] getGrantIds() { 28 | return grantIds; 29 | } 30 | 31 | public void setGrantIds(long[] grantIds) { 32 | this.grantIds = grantIds; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/vo/OperationState.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.vo; 2 | 3 | public enum OperationState { 4 | 5 | /** 6 | * 成功 7 | */ 8 | SUCCESS("成功", 0), 9 | /** 10 | * 失败 11 | */ 12 | FAIL("失败", 1), 13 | /** 14 | * 异常 15 | */ 16 | EXCEPTION("异常发生", -1); 17 | 18 | String mgs; 19 | 20 | int code; 21 | 22 | /** 23 | * @param mgs 24 | * @param code 25 | */ 26 | private OperationState(String mgs, int code) { 27 | this.mgs = mgs; 28 | this.code = code; 29 | } 30 | 31 | /** 32 | * @return the mgs 33 | */ 34 | public String getMgs() { 35 | return mgs; 36 | } 37 | 38 | /** 39 | * @param mgs 40 | * the mgs to set 41 | */ 42 | public void setMgs(String mgs) { 43 | this.mgs = mgs; 44 | } 45 | 46 | /** 47 | * @return the code 48 | */ 49 | public int getCode() { 50 | return code; 51 | } 52 | 53 | /** 54 | * @param code 55 | * the code to set 56 | */ 57 | public void setCode(int code) { 58 | this.code = code; 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /common/src/main/java/com/rekoe/common/vo/UserLoginDto.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.common.vo; 2 | 3 | /** 4 | * @author kerbores kerbores@gmail.com 5 | * 6 | */ 7 | public class UserLoginDto { 8 | 9 | /** 10 | * 用户名 11 | */ 12 | private String userName; 13 | 14 | /** 15 | * 密码 16 | */ 17 | private String password; 18 | 19 | /** 20 | * 记住用户密码 21 | */ 22 | private boolean rememberMe = true; 23 | 24 | /** 25 | * 验证码 26 | */ 27 | private String captcha; 28 | 29 | /** 30 | * @return the captcha 31 | */ 32 | public String getCaptcha() { 33 | return captcha; 34 | } 35 | 36 | /** 37 | * @return the password 38 | */ 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | /** 44 | * @return the userName 45 | */ 46 | public String getUserName() { 47 | return userName; 48 | } 49 | 50 | /** 51 | * @return the rememberMe 52 | */ 53 | public boolean isRememberMe() { 54 | return rememberMe; 55 | } 56 | 57 | /** 58 | * @param captcha 59 | * the captcha to set 60 | */ 61 | public void setCaptcha(String captcha) { 62 | this.captcha = captcha; 63 | } 64 | 65 | /** 66 | * @param password 67 | * the password to set 68 | */ 69 | public void setPassword(String password) { 70 | this.password = password; 71 | } 72 | 73 | /** 74 | * @param rememberMe 75 | * the rememberMe to set 76 | */ 77 | public void setRememberMe(boolean rememberMe) { 78 | this.rememberMe = rememberMe; 79 | } 80 | 81 | /** 82 | * @param userName 83 | * the userName to set 84 | */ 85 | public void setUserName(String userName) { 86 | this.userName = userName; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.rekoe 6 | nutz-dingtalk 7 | 1.0-SNAPSHOT 8 | 9 | nutz-dingtalk-core 10 | 11 | 12 | 13 | org.nutz 14 | nutz 15 | ${nutz.version} 16 | 17 | 18 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/BasePojo.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import org.nutz.dao.entity.annotation.Column; 7 | import org.nutz.dao.entity.annotation.EL; 8 | import org.nutz.dao.entity.annotation.Prev; 9 | import org.nutz.lang.Times; 10 | 11 | public class BasePojo extends DataBaseEntity implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Prev(els = @EL("$me.now()")) 16 | @Column("ct") 17 | protected Date createTime; 18 | 19 | @Prev(els = @EL("$me.now()")) 20 | @Column("ut") 21 | protected Date updateTime; 22 | 23 | public Date getCreateTime() { 24 | return createTime; 25 | } 26 | 27 | public void setCreateTime(Date createTime) { 28 | this.createTime = createTime; 29 | } 30 | 31 | public Date getUpdateTime() { 32 | return updateTime; 33 | } 34 | 35 | public void setUpdateTime(Date updateTime) { 36 | this.updateTime = updateTime; 37 | } 38 | 39 | public Date now() { 40 | return Times.now(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/DataBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean; 2 | 3 | import org.nutz.castor.Castors; 4 | import org.nutz.json.Json; 5 | import org.nutz.json.JsonFormat; 6 | 7 | public class DataBaseEntity { 8 | 9 | public T exchange(Class clazz) { 10 | return Castors.me().castTo(this, clazz); 11 | 12 | } 13 | 14 | public String toString() { 15 | return Json.toJson(this, JsonFormat.compact().setQuoteName(true).setIgnoreNull(false)); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/dingtalk/DingTalkUser.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean.dingtalk; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.nutz.dao.entity.annotation.ColDefine; 6 | import org.nutz.dao.entity.annotation.Column; 7 | import org.nutz.dao.entity.annotation.Default; 8 | import org.nutz.dao.entity.annotation.Index; 9 | import org.nutz.dao.entity.annotation.Name; 10 | import org.nutz.dao.entity.annotation.Table; 11 | import org.nutz.dao.entity.annotation.TableIndexes; 12 | 13 | import com.rekoe.core.bean.DataBaseEntity; 14 | 15 | @Table("ding_talk_user") 16 | @TableIndexes({ @Index(name = "d_user_userid_index", fields = { "userid" }, unique = true) }) 17 | public class DingTalkUser extends DataBaseEntity implements Serializable { 18 | 19 | private static final long serialVersionUID = 4754977073745895453L; 20 | 21 | @Name 22 | @Column(hump = true) 23 | private String openId; 24 | 25 | @Column 26 | private String userid; 27 | 28 | @Column(hump = true) 29 | private String dingId; 30 | 31 | @Column 32 | private String name; 33 | 34 | @Default("1") 35 | @Column("is_active") 36 | private boolean active; 37 | 38 | @Column 39 | @Default("http://momshop-media-hk.oss-cn-hongkong.aliyuncs.com/momshop-image-temp/155003795683146.jpeg") 40 | @ColDefine(width = 1024) 41 | private String avatar; 42 | 43 | @Default("") 44 | @Column(hump = true) 45 | private String userProvince; 46 | 47 | public String getOpenId() { 48 | return openId; 49 | } 50 | 51 | public void setOpenId(String openId) { 52 | this.openId = openId; 53 | } 54 | 55 | public String getUserid() { 56 | return userid; 57 | } 58 | 59 | public void setUserid(String userid) { 60 | this.userid = userid; 61 | } 62 | 63 | public String getDingId() { 64 | return dingId; 65 | } 66 | 67 | public void setDingId(String dingId) { 68 | this.dingId = dingId; 69 | } 70 | 71 | public String getName() { 72 | return name; 73 | } 74 | 75 | public void setName(String name) { 76 | this.name = name; 77 | } 78 | 79 | public boolean isActive() { 80 | return active; 81 | } 82 | 83 | public void setActive(boolean active) { 84 | this.active = active; 85 | } 86 | 87 | public String getAvatar() { 88 | return avatar; 89 | } 90 | 91 | public void setAvatar(String avatar) { 92 | this.avatar = avatar; 93 | } 94 | 95 | public String getUserProvince() { 96 | return userProvince; 97 | } 98 | 99 | public void setUserProvince(String userProvince) { 100 | this.userProvince = userProvince; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/meal/FoodCategory.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean.meal; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | import org.nutz.dao.entity.annotation.Column; 7 | import org.nutz.dao.entity.annotation.Default; 8 | import org.nutz.dao.entity.annotation.Id; 9 | import org.nutz.dao.entity.annotation.Index; 10 | import org.nutz.dao.entity.annotation.ManyMany; 11 | import org.nutz.dao.entity.annotation.Table; 12 | import org.nutz.dao.entity.annotation.TableIndexes; 13 | 14 | import com.rekoe.core.bean.DataBaseEntity; 15 | 16 | @Table("food_category") 17 | @TableIndexes({ @Index(name = "m_f_c_unique_index", fields = { "name", "sellerId" }, unique = true) }) 18 | public class FoodCategory extends DataBaseEntity implements Serializable { 19 | 20 | private static final long serialVersionUID = 8599145812856391655L; 21 | 22 | @Id 23 | private long id; 24 | 25 | @Column 26 | private String name; 27 | 28 | @Column 29 | private int type; 30 | 31 | @Column(hump = true) 32 | private long sellerId; 33 | 34 | @Default("1") 35 | @Column(hump = true) 36 | private boolean onSale; 37 | 38 | @ManyMany(target = MealFood.class, relation = "meal_food_category", from = "category_id", to = "food_id") 39 | private List foods; 40 | 41 | 42 | public FoodCategory() { 43 | super(); 44 | } 45 | 46 | public FoodCategory(String name, int type, long sellerId, boolean onSale) { 47 | super(); 48 | this.name = name; 49 | this.type = type; 50 | this.sellerId = sellerId; 51 | this.onSale = onSale; 52 | } 53 | 54 | public long getId() { 55 | return id; 56 | } 57 | 58 | public void setId(long id) { 59 | this.id = id; 60 | } 61 | 62 | public String getName() { 63 | return name; 64 | } 65 | 66 | public void setName(String name) { 67 | this.name = name; 68 | } 69 | 70 | public int getType() { 71 | return type; 72 | } 73 | 74 | public void setType(int type) { 75 | this.type = type; 76 | } 77 | 78 | public List getFoods() { 79 | return foods; 80 | } 81 | 82 | public void setFoods(List foods) { 83 | this.foods = foods; 84 | } 85 | 86 | public long getSellerId() { 87 | return sellerId; 88 | } 89 | 90 | public void setSellerId(long sellerId) { 91 | this.sellerId = sellerId; 92 | } 93 | 94 | public boolean isOnSale() { 95 | return onSale; 96 | } 97 | 98 | public void setOnSale(boolean onSale) { 99 | this.onSale = onSale; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/meal/FoodRating.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean.meal; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.nutz.dao.entity.annotation.ColDefine; 8 | import org.nutz.dao.entity.annotation.ColType; 9 | import org.nutz.dao.entity.annotation.Column; 10 | import org.nutz.dao.entity.annotation.Id; 11 | import org.nutz.dao.entity.annotation.One; 12 | import org.nutz.dao.entity.annotation.Table; 13 | 14 | import com.rekoe.core.bean.DataBaseEntity; 15 | 16 | @Table("food_ratings") 17 | public class FoodRating extends DataBaseEntity implements Serializable { 18 | 19 | private static final long serialVersionUID = -4520622931825744912L; 20 | 21 | @Id 22 | private long id; 23 | 24 | @Column(hump = true) 25 | private String dingTalkId; 26 | 27 | @Column(hump = true) 28 | @ColDefine(type = ColType.TIMESTAMP) 29 | private Date rateTime; 30 | 31 | @Column(hump = true) 32 | private int rateType; 33 | 34 | @Column 35 | @ColDefine(type = ColType.TEXT) 36 | private String text; 37 | 38 | @Column(hump = true) 39 | private long foodId; 40 | 41 | @One(target = MealFood.class, field = "foodId") 42 | private MealFood food; 43 | 44 | @Column 45 | //@Default("") 46 | @ColDefine(type = ColType.MYSQL_JSON) 47 | private List recommend; 48 | 49 | public long getId() { 50 | return id; 51 | } 52 | 53 | public void setId(long id) { 54 | this.id = id; 55 | } 56 | 57 | public List getRecommend() { 58 | return recommend; 59 | } 60 | 61 | public void setRecommend(List recommend) { 62 | this.recommend = recommend; 63 | } 64 | 65 | public String getDingTalkId() { 66 | return dingTalkId; 67 | } 68 | 69 | public void setDingTalkId(String dingTalkId) { 70 | this.dingTalkId = dingTalkId; 71 | } 72 | 73 | public Date getRateTime() { 74 | return rateTime; 75 | } 76 | 77 | public void setRateTime(Date rateTime) { 78 | this.rateTime = rateTime; 79 | } 80 | 81 | public int getRateType() { 82 | return rateType; 83 | } 84 | 85 | public void setRateType(int rateType) { 86 | this.rateType = rateType; 87 | } 88 | 89 | public String getText() { 90 | return text; 91 | } 92 | 93 | public void setText(String text) { 94 | this.text = text; 95 | } 96 | 97 | public long getFoodId() { 98 | return foodId; 99 | } 100 | 101 | public void setFoodId(long foodId) { 102 | this.foodId = foodId; 103 | } 104 | 105 | public MealFood getFood() { 106 | return food; 107 | } 108 | 109 | public void setFood(MealFood food) { 110 | this.food = food; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/meal/MealOrder.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean.meal; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.nutz.dao.entity.annotation.ColDefine; 8 | import org.nutz.dao.entity.annotation.ColType; 9 | import org.nutz.dao.entity.annotation.Column; 10 | import org.nutz.dao.entity.annotation.EL; 11 | import org.nutz.dao.entity.annotation.Id; 12 | import org.nutz.dao.entity.annotation.Index; 13 | import org.nutz.dao.entity.annotation.Many; 14 | import org.nutz.dao.entity.annotation.Prev; 15 | import org.nutz.dao.entity.annotation.Table; 16 | import org.nutz.dao.entity.annotation.TableIndexes; 17 | import org.nutz.lang.Times; 18 | 19 | import com.rekoe.core.bean.DataBaseEntity; 20 | 21 | @Table("meal_order") 22 | @TableIndexes({ @Index(name = "m_o_unique_index", fields = { "dingTalkId", "time", "deleted" }, unique = false) }) 23 | public class MealOrder extends DataBaseEntity implements Serializable { 24 | 25 | private static final long serialVersionUID = 727836576675773576L; 26 | 27 | @Id(auto = false) 28 | @Prev(els = @EL("ig()")) 29 | private long id; 30 | 31 | @Column 32 | private String time; 33 | 34 | @Column(hump = true) 35 | private String dingTalkId; 36 | 37 | @Column(hump = true) 38 | @ColDefine(type = ColType.TIMESTAMP, insert = true) 39 | private Date createTime; 40 | 41 | @Column("is_deleted") 42 | private boolean deleted; 43 | 44 | @Many(target = MealOrderInfo.class, field = "mealOrderId") 45 | private List mealOrderInfos; 46 | 47 | public MealOrder() { 48 | super(); 49 | } 50 | 51 | public MealOrder(String dingTalkId, String time) { 52 | super(); 53 | this.dingTalkId = dingTalkId; 54 | this.createTime = Times.now(); 55 | this.time = time; 56 | } 57 | 58 | public long getId() { 59 | return id; 60 | } 61 | 62 | public void setId(long id) { 63 | this.id = id; 64 | } 65 | 66 | public String getTime() { 67 | return time; 68 | } 69 | 70 | public void setTime(String time) { 71 | this.time = time; 72 | } 73 | 74 | public String getDingTalkId() { 75 | return dingTalkId; 76 | } 77 | 78 | public void setDingTalkId(String dingTalkId) { 79 | this.dingTalkId = dingTalkId; 80 | } 81 | 82 | public Date getCreateTime() { 83 | return createTime; 84 | } 85 | 86 | public void setCreateTime(Date createTime) { 87 | this.createTime = createTime; 88 | } 89 | 90 | public boolean isDeleted() { 91 | return deleted; 92 | } 93 | 94 | public void setDeleted(boolean deleted) { 95 | this.deleted = deleted; 96 | } 97 | 98 | public List getMealOrderInfos() { 99 | return mealOrderInfos; 100 | } 101 | 102 | public void setMealOrderInfos(List mealOrderInfos) { 103 | this.mealOrderInfos = mealOrderInfos; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/bean/meal/MealOrderInfo.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.bean.meal; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.nutz.dao.entity.annotation.Column; 6 | import org.nutz.dao.entity.annotation.Id; 7 | import org.nutz.dao.entity.annotation.One; 8 | import org.nutz.dao.entity.annotation.Table; 9 | 10 | import com.rekoe.core.bean.DataBaseEntity; 11 | 12 | @Table("meal_order_info") 13 | public class MealOrderInfo extends DataBaseEntity implements Serializable { 14 | 15 | private static final long serialVersionUID = -518479485306295187L; 16 | 17 | @Id(auto = true) 18 | private long id; 19 | 20 | @Column(hump = true) 21 | private long itemId; 22 | 23 | @Column 24 | private int number; 25 | 26 | @Column(hump = true) 27 | private long mealOrderId; 28 | 29 | @One(target = MealOrder.class, field = "mealOrderId") 30 | private MealOrder mealOrde; 31 | 32 | public MealOrderInfo(long itemId, int number, long mealOrderId) { 33 | super(); 34 | this.itemId = itemId; 35 | this.number = number; 36 | this.mealOrderId = mealOrderId; 37 | } 38 | 39 | public MealOrderInfo() { 40 | super(); 41 | } 42 | 43 | public long getId() { 44 | return id; 45 | } 46 | 47 | public void setId(long id) { 48 | this.id = id; 49 | } 50 | 51 | public long getItemId() { 52 | return itemId; 53 | } 54 | 55 | public void setItemId(long itemId) { 56 | this.itemId = itemId; 57 | } 58 | 59 | public int getNumber() { 60 | return number; 61 | } 62 | 63 | public void setNumber(int number) { 64 | this.number = number; 65 | } 66 | 67 | public long getMealOrderId() { 68 | return mealOrderId; 69 | } 70 | 71 | public void setMealOrderId(long mealOrderId) { 72 | this.mealOrderId = mealOrderId; 73 | } 74 | 75 | public MealOrder getMealOrde() { 76 | return mealOrde; 77 | } 78 | 79 | public void setMealOrde(MealOrder mealOrde) { 80 | this.mealOrde = mealOrde; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/SendResult.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.nutz.json.Json; 7 | 8 | /** 9 | * Created by dustin on 2017/3/17. 10 | */ 11 | public class SendResult { 12 | private boolean isSuccess; 13 | private Integer errorCode; 14 | private String errorMsg; 15 | 16 | public boolean isSuccess() { 17 | return isSuccess; 18 | } 19 | 20 | public void setIsSuccess(boolean isSuccess) { 21 | this.isSuccess = isSuccess; 22 | } 23 | 24 | public Integer getErrorCode() { 25 | return errorCode; 26 | } 27 | 28 | public void setErrorCode(Integer errorCode) { 29 | this.errorCode = errorCode; 30 | } 31 | 32 | public String getErrorMsg() { 33 | return errorMsg; 34 | } 35 | 36 | public void setErrorMsg(String errorMsg) { 37 | this.errorMsg = errorMsg; 38 | } 39 | 40 | public String toString() { 41 | Map items = new HashMap(); 42 | items.put("errorCode", errorCode); 43 | items.put("errorMsg", errorMsg); 44 | items.put("isSuccess", isSuccess); 45 | return Json.toJson(items); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/ActionButtonStyle.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | /** 4 | * Created by dustin on 2017/3/19. 5 | */ 6 | public enum ActionButtonStyle { 7 | HORIZONTAL, 8 | VERTICAL 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/ActionCardAction.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | /** 4 | * Created by dustin on 2017/3/19. 5 | */ 6 | public class ActionCardAction { 7 | private String title; 8 | private String actionURL; 9 | 10 | public ActionCardAction(String text, String actionURL) { 11 | this.title = text; 12 | this.actionURL = actionURL; 13 | } 14 | 15 | public String getTitle() { 16 | return title; 17 | } 18 | 19 | public void setTitle(String title) { 20 | this.title = title; 21 | } 22 | 23 | public String getActionURL() { 24 | return actionURL; 25 | } 26 | 27 | public void setActionURL(String actionURL) { 28 | this.actionURL = actionURL; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/FeedCardMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.nutz.json.Json; 8 | import org.nutz.lang.Strings; 9 | 10 | /** 11 | * Created by dustin on 2017/3/19. 12 | */ 13 | public class FeedCardMessage implements Message { 14 | 15 | private List feedItems; 16 | 17 | public List getFeedItems() { 18 | return feedItems; 19 | } 20 | 21 | public void setFeedItems(List feedItems) { 22 | this.feedItems = feedItems; 23 | } 24 | 25 | public String toJsonString() { 26 | Map items = new HashMap(); 27 | items.put("msgtype", "feedCard"); 28 | 29 | Map feedCard = new HashMap(); 30 | 31 | if (feedItems == null || feedItems.isEmpty()) { 32 | throw new IllegalArgumentException("feedItems should not be null or empty"); 33 | } 34 | for (FeedCardMessageItem item : feedItems) { 35 | if (Strings.isBlank(item.getTitle())) { 36 | throw new IllegalArgumentException("title should not be blank"); 37 | } 38 | if (Strings.isBlank(item.getMessageURL())) { 39 | throw new IllegalArgumentException("messageURL should not be blank"); 40 | } 41 | if (Strings.isBlank(item.getPicURL())) { 42 | throw new IllegalArgumentException("picURL should not be blank"); 43 | } 44 | } 45 | feedCard.put("links", feedItems); 46 | items.put("feedCard", feedCard); 47 | return Json.toJson(items); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/FeedCardMessageItem.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | /** 4 | * Created by dustin on 2017/3/19. 5 | */ 6 | public class FeedCardMessageItem { 7 | private String title; 8 | private String picURL; 9 | private String messageURL; 10 | 11 | public String getMessageURL() { 12 | return messageURL; 13 | } 14 | 15 | public void setMessageURL(String messageURL) { 16 | this.messageURL = messageURL; 17 | } 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | 23 | public void setTitle(String title) { 24 | this.title = title; 25 | } 26 | 27 | public String getPicURL() { 28 | return picURL; 29 | } 30 | 31 | public void setPicURL(String picURL) { 32 | this.picURL = picURL; 33 | } 34 | } -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/LinkMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.nutz.json.Json; 7 | import org.nutz.lang.Strings; 8 | 9 | /** 10 | * Created by dustin on 2017/3/18. 11 | */ 12 | public class LinkMessage implements Message { 13 | 14 | private String title; 15 | private String text; 16 | private String picUrl; 17 | private String messageUrl; 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | 23 | public void setTitle(String title) { 24 | this.title = title; 25 | } 26 | 27 | public String getText() { 28 | return text; 29 | } 30 | 31 | public void setText(String text) { 32 | this.text = text; 33 | } 34 | 35 | public String getPicUrl() { 36 | return picUrl; 37 | } 38 | 39 | public void setPicUrl(String picUrl) { 40 | this.picUrl = picUrl; 41 | } 42 | 43 | public String getMessageUrl() { 44 | return messageUrl; 45 | } 46 | 47 | public void setMessageUrl(String messageUrl) { 48 | this.messageUrl = messageUrl; 49 | } 50 | 51 | public String toJsonString() { 52 | Map items = new HashMap(); 53 | items.put("msgtype", "link"); 54 | 55 | Map linkContent = new HashMap(); 56 | if (Strings.isBlank(title)) { 57 | throw new IllegalArgumentException("title should not be blank"); 58 | } 59 | linkContent.put("title", title); 60 | 61 | if (Strings.isBlank(messageUrl)) { 62 | throw new IllegalArgumentException("messageUrl should not be blank"); 63 | } 64 | linkContent.put("messageUrl", messageUrl); 65 | 66 | if (Strings.isBlank(text)) { 67 | throw new IllegalArgumentException("text should not be blank"); 68 | } 69 | linkContent.put("text", text); 70 | 71 | if (Strings.isNotBlank(picUrl)) { 72 | linkContent.put("picUrl", picUrl); 73 | } 74 | items.put("link", linkContent); 75 | return Json.toJson(items); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/Message.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | /** 4 | * Created by dustin on 2017/3/17. 5 | */ 6 | public interface Message { 7 | 8 | /** 9 | * 返回消息的Json格式字符串 10 | * 11 | * @return 消息的Json格式字符串 12 | */ 13 | String toJsonString(); 14 | } 15 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/chatbot/message/TextMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.chatbot.message; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.nutz.json.Json; 8 | import org.nutz.lang.Strings; 9 | 10 | /** 11 | * Created by dustin on 2017/3/17. 12 | */ 13 | public class TextMessage implements Message { 14 | 15 | private String text; 16 | private List atMobiles; 17 | private boolean isAtAll; 18 | 19 | private String agentid; 20 | private List uids; 21 | 22 | public void setAgentid(String agentid) { 23 | this.agentid = agentid; 24 | } 25 | 26 | public void setUids(List uids) { 27 | this.uids = uids; 28 | } 29 | 30 | public TextMessage(String text) { 31 | this.text = text; 32 | } 33 | 34 | public String getText() { 35 | return text; 36 | } 37 | 38 | public void setText(String text) { 39 | this.text = text; 40 | } 41 | 42 | public List getAtMobiles() { 43 | return atMobiles; 44 | } 45 | 46 | public void setAtMobiles(List atMobiles) { 47 | this.atMobiles = atMobiles; 48 | } 49 | 50 | public boolean isAtAll() { 51 | return isAtAll; 52 | } 53 | 54 | public void setIsAtAll(boolean isAtAll) { 55 | this.isAtAll = isAtAll; 56 | } 57 | 58 | public String toJsonString() { 59 | Map items = new HashMap(); 60 | items.put("msgtype", "text"); 61 | 62 | Map textContent = new HashMap(); 63 | if (Strings.isBlank(text)) { 64 | throw new IllegalArgumentException("text should not be blank"); 65 | } 66 | textContent.put("content", text); 67 | items.put("text", textContent); 68 | 69 | Map atItems = new HashMap(); 70 | if (atMobiles != null && !atMobiles.isEmpty()) { 71 | atItems.put("atMobiles", atMobiles); 72 | } 73 | if (isAtAll) { 74 | atItems.put("isAtAll", isAtAll); 75 | } 76 | items.put("at", atItems); 77 | if (Strings.isNotBlank(agentid)) { 78 | items.put("agentid", agentid); 79 | StringBuffer sb = new StringBuffer(); 80 | for (String uid : uids) { 81 | sb.append(uid); 82 | sb.append("|"); 83 | } 84 | sb.deleteCharAt(sb.length() - 1); 85 | items.put("touser", sb); 86 | } 87 | return Json.toJson(items); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/FileMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午1:48:44 8 | */ 9 | public class FileMessage extends Message { 10 | 11 | private Media file; 12 | 13 | public Media getFile() { 14 | return file; 15 | } 16 | 17 | public void setFile(Media file) { 18 | this.file = file; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/ImageMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午1:48:44 8 | */ 9 | public class ImageMessage extends Message { 10 | 11 | private Media image; 12 | 13 | public Media getImage() { 14 | return image; 15 | } 16 | 17 | public void setImage(Media image) { 18 | this.image = image; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Link.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午2:08:10 8 | */ 9 | public class Link { 10 | // 消息点击链接地址 11 | private String messageUrl; 12 | 13 | // 图片媒体文件id,可以调用上传媒体文件接口获取 14 | private String picUrl; 15 | 16 | // 消息标题 17 | private String title; 18 | 19 | // 消息内容 20 | private String text; 21 | 22 | public String getMessageUrl() { 23 | return messageUrl; 24 | } 25 | 26 | public void setMessageUrl(String messageUrl) { 27 | this.messageUrl = messageUrl; 28 | } 29 | 30 | public String getPicUrl() { 31 | return picUrl; 32 | } 33 | 34 | public void setPicUrl(String picUrl) { 35 | this.picUrl = picUrl; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | 46 | public String getText() { 47 | return text; 48 | } 49 | 50 | public void setText(String text) { 51 | this.text = text; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/LinkMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午2:07:37 8 | */ 9 | public class LinkMessage extends Message { 10 | 11 | private Link link; 12 | 13 | public Link getLink() { 14 | return link; 15 | } 16 | 17 | public void setLink(Link link) { 18 | this.link = link; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Markdown.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午2:17:56 8 | */ 9 | public class Markdown { 10 | 11 | private String title; 12 | private String text; 13 | 14 | public String getTitle() { 15 | return title; 16 | } 17 | 18 | public void setTitle(String title) { 19 | this.title = title; 20 | } 21 | 22 | public String getText() { 23 | return text; 24 | } 25 | 26 | public void setText(String text) { 27 | this.text = text; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/MarkdownMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午2:19:43 8 | */ 9 | public class MarkdownMessage extends Message { 10 | 11 | private Markdown markdown; 12 | 13 | public Markdown getMarkdown() { 14 | return markdown; 15 | } 16 | 17 | public void setMarkdown(Markdown markdown) { 18 | this.markdown = markdown; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Media.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /**@desc : 4 | * 5 | * @author: shirayner 6 | * @date : 2017年9月28日 下午1:47:15 7 | */ 8 | public class Media { 9 | //图片媒体文件id,可以调用上传媒体文件接口获取。建议宽600像素 x 400像素,宽高比3:2 10 | private String media_id; 11 | 12 | public String getMedia_id() { 13 | return media_id; 14 | } 15 | 16 | public void setMedia_id(String media_id) { 17 | this.media_id = media_id; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Message.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午12:21:34 8 | */ 9 | public class Message { 10 | // 消息类型 11 | private String msgtype; // 必须 12 | private String agentid; // 必须 13 | 14 | private String touser; 15 | private String toparty; 16 | 17 | public String getMsgtype() { 18 | return msgtype; 19 | } 20 | 21 | public void setMsgtype(String msgtype) { 22 | this.msgtype = msgtype; 23 | } 24 | 25 | public String getAgentid() { 26 | return agentid; 27 | } 28 | 29 | public void setAgentid(String agentid) { 30 | this.agentid = agentid; 31 | } 32 | 33 | public String getTouser() { 34 | return touser; 35 | } 36 | 37 | public void setTouser(String touser) { 38 | this.touser = touser; 39 | } 40 | 41 | public String getToparty() { 42 | return toparty; 43 | } 44 | 45 | public void setToparty(String toparty) { 46 | this.toparty = toparty; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Text.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午12:54:05 8 | */ 9 | public class Text { 10 | // 消息内容 11 | private String content; 12 | 13 | public String getContent() { 14 | return content; 15 | } 16 | 17 | public void setContent(String content) { 18 | this.content = content; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/TextMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午12:52:17 8 | */ 9 | public class TextMessage extends Message { 10 | private Text text; 11 | 12 | public Text getText() { 13 | return text; 14 | } 15 | 16 | public void setText(Text text) { 17 | this.text = text; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/Voice.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午1:44:08 8 | */ 9 | public class Voice { 10 | 11 | // 语音媒体文件id,可以调用上传媒体文件接口获取。2MB,播放长度不超过60s,AMR格式 12 | private String media_id; 13 | // 正整数,小于60,表示音频时长 14 | private String duration; 15 | 16 | public String getMedia_id() { 17 | return media_id; 18 | } 19 | 20 | public void setMedia_id(String media_id) { 21 | this.media_id = media_id; 22 | } 23 | 24 | public String getDuration() { 25 | return duration; 26 | } 27 | 28 | public void setDuration(String duration) { 29 | this.duration = duration; 30 | } 31 | } -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/dingtalk/isv/message/VoiceMessage.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.dingtalk.isv.message; 2 | 3 | /** 4 | * @desc : 5 | * 6 | * @author: shirayner 7 | * @date : 2017年9月28日 下午1:41:47 8 | */ 9 | public class VoiceMessage extends Message { 10 | private Voice voice; 11 | 12 | public Voice getVoice() { 13 | return voice; 14 | } 15 | 16 | public void setVoice(Voice voice) { 17 | this.voice = voice; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/vo/DingDepartment.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.vo; 2 | 3 | public class DingDepartment { 4 | 5 | private int id; 6 | private String createDeptGroup; 7 | private String name; 8 | private boolean autoAddUser; 9 | 10 | public int getId() { 11 | return id; 12 | } 13 | 14 | public void setId(int id) { 15 | this.id = id; 16 | } 17 | 18 | public String getCreateDeptGroup() { 19 | return createDeptGroup; 20 | } 21 | 22 | public void setCreateDeptGroup(String createDeptGroup) { 23 | this.createDeptGroup = createDeptGroup; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public boolean isAutoAddUser() { 35 | return autoAddUser; 36 | } 37 | 38 | public void setAutoAddUser(boolean autoAddUser) { 39 | this.autoAddUser = autoAddUser; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/com/rekoe/core/vo/Status.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.core.vo; 2 | 3 | public enum Status { 4 | ACTIVED("正常"), DISABLED("禁用"), ALL("全部"), CANCELED("取消"), FULFILLMENT("已发货️"), OK("已确认️"); 5 | 6 | /** 7 | * 中文描述,主要用于页面展示 8 | */ 9 | private String name; 10 | 11 | private Status(String name) { 12 | this.name = name; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/resources/sqls/acl/permission.sql: -------------------------------------------------------------------------------- 1 | /* 2 | list.direct.permission.by.user.id 3 | */ 4 | SELECT 5 | * 6 | FROM 7 | t_permission p 8 | LEFT JOIN t_user_permission up ON p.id = up.p_id 9 | WHERE 10 | up.u_id = @userId 11 | /* 12 | list.indirect.permission.by.user.id 13 | */ 14 | SELECT 15 | p.* 16 | FROM 17 | t_permission p 18 | LEFT JOIN t_role_permission rp ON p.id = rp.p_id 19 | LEFT JOIN t_user_role ur ON ur.r_id = rp.r_id 20 | WHERE ur.u_id = @userId 21 | /* 22 | find.permissions.with.user.powered.info.by.user.id 23 | */ 24 | SELECT 25 | p.id , 26 | p.p_desc AS description , 27 | CASE sup.id IS NULL 28 | WHEN 1 THEN 29 | FALSE 30 | ELSE 31 | TRUE 32 | END AS selected 33 | FROM 34 | t_permission p 35 | LEFT JOIN( 36 | SELECT 37 | * 38 | FROM 39 | t_user_permission 40 | WHERE 41 | u_id = @id 42 | ) sup ON p.id = sup.p_id 43 | /* 44 | find.permissions.with.role.powered.info.by.role.id 45 | */ 46 | SELECT 47 | p.id , 48 | p.p_desc AS description , 49 | CASE srp.id IS NULL 50 | WHEN 1 THEN 51 | FALSE 52 | ELSE 53 | TRUE 54 | END AS selected 55 | FROM 56 | t_permission p 57 | LEFT JOIN( 58 | SELECT 59 | * 60 | FROM 61 | t_role_permission 62 | WHERE 63 | r_id =@id 64 | ) srp ON p.id = srp.p_id -------------------------------------------------------------------------------- /core/src/main/resources/sqls/acl/role.sql: -------------------------------------------------------------------------------- 1 | /* 2 | list.role.by.user.id 3 | */ 4 | SELECT 5 | r.* 6 | FROM 7 | t_role r 8 | LEFT JOIN t_user_role ur ON r.id = ur.r_id 9 | WHERE 10 | ur.u_id = @userId 11 | /* 12 | find.roles.with.user.powerd.info.by.user.id 13 | */ 14 | SELECT 15 | r.id, 16 | r.r_desc as description, 17 | CASE sur.id IS NULL 18 | WHEN 1 THEN 19 | FALSE 20 | ELSE 21 | TRUE 22 | END AS selected 23 | FROM 24 | t_role r 25 | LEFT JOIN ( 26 | SELECT 27 | * 28 | FROM 29 | t_user_role 30 | WHERE 31 | u_id = @id 32 | ) sur ON r.id = sur.r_id -------------------------------------------------------------------------------- /core/src/main/resources/sqls/acl/user.sql: -------------------------------------------------------------------------------- 1 | /* 2 | find.user.region.with.belong.info.by.user.id 3 | */ 4 | SELECT 5 | c.*, CASE ur.id IS NULL 6 | WHEN 1 THEN 7 | '' 8 | ELSE 9 | 'selected' 10 | END AS has_region 11 | FROM 12 | t_codebook c 13 | LEFT JOIN t_code_book_group g ON c.c_group_id = g.id 14 | LEFT JOIN ( 15 | SELECT 16 | * 17 | FROM 18 | t_user_region 19 | WHERE 20 | ur_user_id = @id 21 | ) ur ON c.c_name = ur.ur_region_code 22 | LEFT JOIN t_user u ON ur.ur_user_id = u.id 23 | WHERE 24 | g.g_name = @groupName 25 | 26 | /* 27 | list.user.by.role.and.region 28 | */ 29 | SELECT DISTINCT 30 | u.* 31 | FROM 32 | t_user u 33 | LEFT JOIN t_user_role ur ON u.id = ur.u_id 34 | LEFT JOIN t_role r ON r.id = ur.r_id 35 | LEFT JOIN t_user_region ure ON u.id = ure.ur_user_id 36 | $condition 37 | /* 38 | list.regions.by.user.id 39 | */ 40 | SELECT 41 | c.* 42 | FROM 43 | t_codebook c 44 | LEFT JOIN t_user_region ur ON ur.ur_region_code = c.c_name 45 | WHERE 46 | ur.ur_user_id = @userId -------------------------------------------------------------------------------- /core/src/main/resources/sqls/branch/branch.sql: -------------------------------------------------------------------------------- 1 | /* 2 | load.top.branchs 3 | */ 4 | SELECT 5 | id, 6 | sub_name AS `name`, 7 | sub_parent_id AS `pId`, 8 | TRUE AS `open`, 9 | TRUE AS `isParent` 10 | FROM 11 | t_branch 12 | WHERE 13 | sub_parent_id = 0 14 | /* 15 | load.branchs.by.id 16 | */ 17 | SELECT 18 | t.*, sub_name AS `name`, 19 | sub_parent_id AS `pId`, 20 | TRUE AS `open`, 21 | ( 22 | SELECT 23 | COUNT(id) 24 | FROM 25 | t_branch i 26 | WHERE 27 | i.sub_parent_id = t.id 28 | ) > 0 AS `isParent` 29 | FROM 30 | t_branch t 31 | WHERE 32 | sub_parent_id = @id 33 | 34 | /* 35 | list.top.branchs.by.page 36 | */ 37 | SELECT 38 | *, ( 39 | SELECT 40 | COUNT(id) 41 | FROM 42 | t_branch i 43 | WHERE 44 | i.sub_parent_id = t.id 45 | ) > 0 AS has_sub 46 | FROM 47 | t_branch t 48 | WHERE 49 | sub_parent_id = 0 50 | LIMIT @pageStart, 51 | @pageSize -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.rekoe 4 | nutz-dingtalk 5 | 1.0-SNAPSHOT 6 | pom 7 | nutz-dingtalk 8 | 配置中心 9 | 10 | 11 | 12 | maven-compiler-plugin 13 | 3.7.0 14 | 15 | 1.8 16 | 1.8 17 | 18 | 19 | 20 | 21 | 22 | rest 23 | core 24 | common 25 | 26 | 27 | 28 | nutz-jcenter 29 | http://jfrog.nutz.cn/artifactory/jcenter/ 30 | 31 | false 32 | 33 | 34 | 35 | nutz-snapshots 36 | http://jfrog.nutz.cn/artifactory/snapshots/ 37 | 38 | true 39 | 40 | 41 | 42 | 43 | UTF-8 44 | 1.r.68-SNAPSHOT 45 | 3.5 46 | 2.3-SNAPSHOT 47 | 48 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/job/DingTalkStatusJob.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.job; 2 | 3 | import org.nutz.integration.quartz.annotation.Scheduled; 4 | import org.nutz.ioc.loader.annotation.Inject; 5 | import org.nutz.ioc.loader.annotation.IocBean; 6 | import org.nutz.log.Log; 7 | import org.nutz.log.Logs; 8 | import org.quartz.Job; 9 | import org.quartz.JobExecutionContext; 10 | import org.quartz.JobExecutionException; 11 | 12 | import com.rekoe.service.DingTalkService; 13 | 14 | @IocBean 15 | @Scheduled(cron = "0 0 08 ? * MON-SAT") 16 | public class DingTalkStatusJob implements Job { 17 | 18 | private final static Log log = Logs.get(); 19 | 20 | @Inject 21 | private DingTalkService dingTalkService; 22 | 23 | @Override 24 | public void execute(JobExecutionContext context) throws JobExecutionException { 25 | try { 26 | dingTalkService.loadDingUser(); 27 | } catch (Exception e) { 28 | log.error(e); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/job/DingUserStatusJob.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.job; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.LinkedBlockingQueue; 5 | 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.nutz.dao.Chain; 8 | import org.nutz.dao.Cnd; 9 | import org.nutz.dao.Dao; 10 | import org.nutz.dao.Sqls; 11 | import org.nutz.dao.entity.Record; 12 | import org.nutz.dao.sql.Sql; 13 | import org.nutz.integration.quartz.annotation.Scheduled; 14 | import org.nutz.ioc.loader.annotation.Inject; 15 | import org.nutz.ioc.loader.annotation.IocBean; 16 | import org.nutz.lang.ContinueLoop; 17 | import org.nutz.lang.Each; 18 | import org.nutz.lang.ExitLoop; 19 | import org.nutz.lang.Lang; 20 | import org.nutz.lang.LoopException; 21 | import org.nutz.lang.util.NutMap; 22 | import org.nutz.log.Log; 23 | import org.nutz.log.Logs; 24 | import org.quartz.Job; 25 | import org.quartz.JobExecutionContext; 26 | import org.quartz.JobExecutionException; 27 | 28 | import com.rekoe.core.bean.acl.User; 29 | import com.rekoe.core.bean.dingtalk.DingTalkUser; 30 | import com.rekoe.service.DingTalkService; 31 | 32 | @IocBean(create = "exec") 33 | @Scheduled(cron = "0 0 09 ? * MON-SAT") 34 | public class DingUserStatusJob implements Job { 35 | 36 | private final static Log log = Logs.get(); 37 | 38 | private LinkedBlockingQueue uids = new LinkedBlockingQueue(10000); 39 | 40 | @Inject 41 | private Dao dao; 42 | 43 | @Inject 44 | private DingTalkService dingTalkService; 45 | 46 | @Override 47 | public void execute(JobExecutionContext context) throws JobExecutionException { 48 | Sql sql = Sqls.create("select userid,open_id from ding_talk_user where is_active = true"); 49 | sql.setCallback(Sqls.callback.records()); 50 | dao.execute(sql); 51 | List uids = sql.getList(Record.class); 52 | if (Lang.isNotEmpty(uids)) { 53 | this.uids.addAll(uids); 54 | } 55 | } 56 | 57 | public void exec() { 58 | new Thread(new Runnable() { 59 | @Override 60 | public void run() { 61 | while (true) { 62 | try { 63 | final Record record = uids.take(); 64 | String userid = record.getString("userid"); 65 | if (StringUtils.isNotBlank(userid)) { 66 | NutMap d = dingTalkService.listcontact(userid); 67 | Lang.each(d.getAsList("result", NutMap.class), new Each() { 68 | @Override 69 | public void invoke(int index, NutMap ele, int length) throws ExitLoop, ContinueLoop, LoopException { 70 | String userid = ele.getString("userid"); 71 | Chain chain = Chain.make("active", false); 72 | dao.update(DingTalkUser.class, chain, Cnd.where("userid", "=", userid)); 73 | dao.update(User.class, Chain.make("locked", true), Cnd.where("openid", "=", record.getString("open_id"))); 74 | } 75 | }); 76 | } 77 | } catch (InterruptedException e) { 78 | log.error(e); 79 | } 80 | } 81 | 82 | } 83 | }).start(); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/job/NotificationMealJob.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.job; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.nutz.dao.Cnd; 8 | import org.nutz.integration.quartz.annotation.Scheduled; 9 | import org.nutz.ioc.loader.annotation.Inject; 10 | import org.nutz.ioc.loader.annotation.IocBean; 11 | import org.nutz.lang.ContinueLoop; 12 | import org.nutz.lang.Each; 13 | import org.nutz.lang.ExitLoop; 14 | import org.nutz.lang.LoopException; 15 | import org.quartz.Job; 16 | import org.quartz.JobExecutionContext; 17 | import org.quartz.JobExecutionException; 18 | 19 | import com.rekoe.core.bean.dingtalk.DingTalkUser; 20 | import com.rekoe.service.DingTalkService; 21 | import com.rekoe.service.DingTalkUserService; 22 | 23 | @IocBean 24 | //@Scheduled(cron = "0 0 17 ? * MON-SAT") 25 | public class NotificationMealJob implements Job { 26 | 27 | @Inject 28 | private DingTalkUserService dingTalkUserService; 29 | 30 | @Inject 31 | private DingTalkService dingTalkService; 32 | 33 | @Override 34 | public void execute(JobExecutionContext context) throws JobExecutionException { 35 | List uids = new ArrayList<>(); 36 | dingTalkUserService.each(Cnd.where("active", "=", true), new Each() { 37 | @Override 38 | public void invoke(int index, DingTalkUser user, int length) throws ExitLoop, ContinueLoop, LoopException { 39 | String uid = user.getUserid(); 40 | if (StringUtils.isNotBlank(uid)) { 41 | uids.add(uid); 42 | } 43 | } 44 | }); 45 | dingTalkService.sendDingTalkMarkDownMsg(uids, "加班餐订餐提醒", "# 加班餐订餐提醒 \n 如果需要定加班餐请在\n 北京时间 18:00前\n 通过钉钉手机客户端[OM美食]进入订餐系统\n"); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/module/MealFoodModule.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.module; 2 | 3 | import org.nutz.dao.Chain; 4 | import org.nutz.dao.Cnd; 5 | import org.nutz.integration.shiro.annotation.NutzRequiresPermissions; 6 | import org.nutz.ioc.loader.annotation.Inject; 7 | import org.nutz.ioc.loader.annotation.IocBean; 8 | import org.nutz.lang.Lang; 9 | import org.nutz.mvc.annotation.At; 10 | import org.nutz.mvc.annotation.Ok; 11 | import org.nutz.mvc.annotation.Param; 12 | 13 | import com.rekoe.common.vo.Result; 14 | import com.rekoe.core.bean.meal.MealFood; 15 | import com.rekoe.service.MealFoodService; 16 | 17 | @IocBean 18 | @Ok("json") 19 | @At("/meal/food") 20 | public class MealFoodModule { 21 | 22 | @Inject 23 | private MealFoodService mealFoodService; 24 | 25 | @At 26 | @NutzRequiresPermissions(value = "meal.food.list", name = "菜单列表", tag = "订餐管理", enable = true) 27 | public Result list(@Param(value = "page", df = "1") int page) { 28 | return Result.success().addData("pager", mealFoodService.searchByPage(page, Cnd.NEW().asc("id"))); 29 | } 30 | 31 | @At 32 | @NutzRequiresPermissions(value = "meal.food.list", name = "菜单列表", tag = "订餐管理", enable = false) 33 | public Result search(@Param("key") String key, @Param(value = "page", df = "1") int page) { 34 | return Result.success().addData("pager", mealFoodService.searchByKeyAndPage(key, page, "name", "description").addParam("key", key)); 35 | } 36 | 37 | @At 38 | @Ok("json") 39 | @NutzRequiresPermissions(value = "meal.food.edit", name = "菜单编辑", tag = "订餐管理", enable = true) 40 | public Result status(@Param("id") long id) { 41 | MealFood mealFood = mealFoodService.fetch(id); 42 | if (Lang.isNotEmpty(mealFood)) { 43 | boolean onSale = mealFood.isOnSale(); 44 | mealFoodService.update(Chain.make("on_sale", !onSale), Cnd.where("id", "=", id)); 45 | return Result.success(); 46 | } 47 | return Result.fail("未找到数据"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/DingCanService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import java.util.List; 4 | 5 | import org.nutz.el.opt.RunMethod; 6 | import org.nutz.ioc.loader.annotation.Inject; 7 | import org.nutz.ioc.loader.annotation.IocBean; 8 | 9 | import xyz.downgoon.snowflake.Snowflake; 10 | 11 | @IocBean 12 | public class DingCanService implements RunMethod { 13 | 14 | @Inject 15 | private Snowflake snowflake; 16 | 17 | @Override 18 | public Object run(List fetchParam) { 19 | return next(); 20 | } 21 | 22 | private long next() { 23 | return snowflake.nextId(); 24 | } 25 | 26 | @Override 27 | public String fetchSelf() { 28 | return "ig"; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/DingTalkUserService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import org.nutz.ioc.loader.annotation.IocBean; 4 | 5 | import com.rekoe.core.bean.dingtalk.DingTalkUser; 6 | 7 | @IocBean(fields = { "dao" }) 8 | public class DingTalkUserService extends BaseService{ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/FoodCategoryService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import org.nutz.ioc.loader.annotation.IocBean; 4 | 5 | import com.rekoe.core.bean.meal.FoodCategory; 6 | 7 | @IocBean(fields = { "dao" }) 8 | public class FoodCategoryService extends BaseService{ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/MealFoodService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import org.nutz.ioc.loader.annotation.IocBean; 4 | 5 | import com.rekoe.core.bean.meal.MealFood; 6 | 7 | @IocBean(fields = { "dao" }) 8 | public class MealFoodService extends BaseService{ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/MealOrderService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import java.util.List; 4 | 5 | import org.nutz.dao.Sqls; 6 | import org.nutz.dao.entity.Record; 7 | import org.nutz.dao.sql.Sql; 8 | import org.nutz.ioc.loader.annotation.IocBean; 9 | import org.nutz.lang.Times; 10 | 11 | import com.rekoe.core.bean.meal.MealOrder; 12 | 13 | @IocBean(fields = { "dao" }) 14 | public class MealOrderService extends BaseService { 15 | 16 | public List orderInfo(String userid) { 17 | String time = Times.format("yyyyMMdd", Times.now()); 18 | Sql sql = Sqls.createf("select f.name,i.item_id,f.price,i.number from meal_order as o left join meal_order_info as i on i.meal_order_id=o.id left join meal_food as f on f.id=i.item_id where o.ding_talk_id='%s' and o.time='%s' and o.is_deleted=0", userid, time); 19 | sql.setCallback(Sqls.callback.records()); 20 | dao().execute(sql); 21 | return sql.getList(Record.class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/MealSellerService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import org.nutz.ioc.loader.annotation.IocBean; 4 | 5 | import com.rekoe.core.bean.meal.MealSeller; 6 | 7 | @IocBean(fields = { "dao" }) 8 | public class MealSellerService extends BaseService { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/PermissionService.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | import org.nutz.dao.Cnd; 11 | import org.nutz.ioc.loader.annotation.Inject; 12 | import org.nutz.ioc.loader.annotation.IocBean; 13 | import org.nutz.lang.ContinueLoop; 14 | import org.nutz.lang.Each; 15 | import org.nutz.lang.ExitLoop; 16 | import org.nutz.lang.Lang; 17 | import org.nutz.lang.LoopException; 18 | 19 | import com.rekoe.core.bean.acl.Permission; 20 | import com.rekoe.core.bean.acl.Role; 21 | 22 | /** 23 | * @author 科技㊣²º¹³
24 | * 2014年2月3日 下午4:48:45
25 | * http://www.rekoe.com
26 | * QQ:5382211 27 | */ 28 | @IocBean(fields = { "dao" }) 29 | public class PermissionService extends BaseService { 30 | 31 | public List list() { 32 | return query(null, null); 33 | } 34 | 35 | public Map map() { 36 | Map map = new HashMap(); 37 | dao().each(getEntityClass(), Cnd.orderBy().desc("id"), new Each() { 38 | @Override 39 | public void invoke(int index, Permission permission, int length) throws ExitLoop, ContinueLoop, LoopException { 40 | map.put(permission.getId(), permission.getName()); 41 | } 42 | }); 43 | return map; 44 | } 45 | 46 | public Permission insert(Permission permission) { 47 | return dao().insert(permission); 48 | } 49 | 50 | public Permission view(Long id) { 51 | return fetch(id); 52 | } 53 | 54 | public int update(Permission permission) { 55 | return dao().update(permission); 56 | } 57 | 58 | @Inject 59 | private RoleService roleService; 60 | 61 | public Set permissionInfos(String name) { 62 | List roles = roleService.roles(name); 63 | List permissions = new ArrayList<>(); 64 | Lang.each(roles, new Each() { 65 | @Override 66 | public void invoke(int index, Role role, int length) throws ExitLoop, ContinueLoop, LoopException { 67 | role = dao().fetchLinks(role, "permissions"); 68 | if (Lang.isEmpty(role.getPermissions())) { 69 | return; 70 | } 71 | permissions.addAll(role.getPermissions()); 72 | } 73 | }); 74 | final Set target = new HashSet<>(); 75 | Lang.each(permissions, new Each() { 76 | @Override 77 | public void invoke(int arg0, Permission permission, int arg2) throws ExitLoop, ContinueLoop, LoopException { 78 | target.add(permission.getName()); 79 | } 80 | }); 81 | return target; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/service/entity/PageredData.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.service.entity; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.nutz.dao.pager.Pager; 8 | 9 | public class PageredData { 10 | 11 | /** 12 | * 分页信息 13 | */ 14 | private Pager pager; 15 | 16 | /** 17 | * 分页参数(带有一堆参数的分页) 18 | */ 19 | private Map paras; 20 | 21 | /** 22 | * 数据列表 23 | */ 24 | private List dataList; 25 | 26 | public Pager getPager() { 27 | return pager; 28 | } 29 | 30 | public void setPager(Pager pager) { 31 | this.pager = pager; 32 | } 33 | 34 | public List getDataList() { 35 | return dataList; 36 | } 37 | 38 | public void setDataList(List dataList) { 39 | this.dataList = dataList; 40 | } 41 | 42 | /** 43 | * @return the paras 44 | */ 45 | public Map getParas() { 46 | return paras; 47 | } 48 | 49 | /** 50 | * @param paras 51 | * the paras to set 设置分页查询参数一些查询的筛选条件 按照mvc参数key-value的形式 52 | */ 53 | public void setParas(Map paras) { 54 | this.paras = paras; 55 | } 56 | 57 | public PageredData addParam(String key, Object value) { 58 | if (this.paras == null) { 59 | this.paras = new HashMap(); 60 | } 61 | this.paras.put(key, value); 62 | return this; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/shiro/ShiroSessionListener.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.shiro; 2 | 3 | import org.apache.shiro.session.Session; 4 | import org.apache.shiro.session.SessionListener; 5 | import org.nutz.ioc.loader.annotation.IocBean; 6 | 7 | @IocBean 8 | public class ShiroSessionListener implements SessionListener { 9 | 10 | @Override 11 | public void onStart(Session session) { 12 | System.err.println("ShiroSessionListener onStart : " + session.getId()); 13 | } 14 | 15 | @Override 16 | public void onStop(Session session) { 17 | 18 | } 19 | 20 | @Override 21 | public void onExpiration(Session session) { 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/utils/DingTalkJsApiSingnature.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.utils; 2 | 3 | import java.security.MessageDigest; 4 | import java.util.Formatter; 5 | 6 | /** 7 | * 钉钉jsapi签名工具类 8 | */ 9 | public class DingTalkJsApiSingnature { 10 | /** 11 | * 获取jsapi签名 12 | * 13 | * @param url 14 | * @param nonce 15 | * @param timeStamp 16 | * @param jsTicket 17 | * @return 18 | * @throws DingTalkEncryptException 19 | */ 20 | public static String getJsApiSingnature(String url, String nonce, Long timeStamp, String jsTicket) throws Exception { 21 | String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonce + "×tamp=" + timeStamp + "&url=" + url; 22 | System.out.println(plainTex); 23 | String signature = ""; 24 | try { 25 | MessageDigest crypt = MessageDigest.getInstance("SHA-1"); 26 | crypt.reset(); 27 | crypt.update(plainTex.getBytes("UTF-8")); 28 | signature = byteToHex(crypt.digest()); 29 | return signature; 30 | } catch (Exception e) { 31 | throw e; 32 | } 33 | } 34 | 35 | private static String byteToHex(final byte[] hash) { 36 | Formatter formatter = new Formatter(); 37 | for (byte b : hash) { 38 | formatter.format("%02x", b); 39 | } 40 | String result = formatter.toString(); 41 | formatter.close(); 42 | return result; 43 | } 44 | 45 | public static void main1(String args[]) throws Exception { 46 | String url = "http://10.62.53.138:3000/jsapi"; 47 | String nonce = "abcdefgh"; 48 | Long timeStamp = 1437027269927L; 49 | String tikcet = "zHoQdGJuH0ZDebwo7sLqLzHGUueLmkWCC4RycYgkuvDu3eoROgN5qhwnQLgfzwEXtuR9SDzh6BdhyVngzAjrxV"; 50 | System.err.println(getJsApiSingnature(url, nonce, timeStamp, tikcet)); 51 | } 52 | 53 | public static void main(String[] args) { 54 | // "https://oapi.dingtalk.com/get_jsapi_ticket"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/utils/Env.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.utils; 2 | 3 | 4 | /** 5 | * 企业应用接入时的常量定义 6 | */ 7 | public class Env { 8 | 9 | /** 10 | * 企业应用接入秘钥相关 11 | */ 12 | public static final String APP_KEY = "ding61279fcb45e99b9735c2f4657eb6378f"; 13 | public static final String APP_SECRET = "0G95FrDWk5DpaZAepJtJSTcjBwhBCFzlxYReh3sohx3He6czMGoDxbz0blx7mp66"; 14 | 15 | /** 16 | * 钉钉网关gettoken地址 17 | */ 18 | public static final String URL_GET_TOKKEN = "https://oapi.dingtalk.com/gettoken"; 19 | /** 20 | *获取用户在企业内userId的接口URL 21 | */ 22 | public static final String URL_GET_USER_INFO = "https://oapi.dingtalk.com/user/getuserinfo"; 23 | /** 24 | *获取用户姓名的接口url 25 | */ 26 | public static final String URL_USER_GET = "https://oapi.dingtalk.com/user/get"; 27 | 28 | /** 29 | * DING API地址 30 | */ 31 | public static final String OAPI_HOST = "https://oapi.dingtalk.com"; 32 | /** 33 | * 企业应用后台地址,用户管理后台免登使用 34 | */ 35 | public static final String OA_BACKGROUND_URL = ""; 36 | 37 | 38 | /** 39 | * 企业通讯回调加密Token,注册事件回调接口时需要传递给钉钉服务器 40 | */ 41 | public static final String TOKEN = ""; 42 | public static final String ENCODING_AES_KEY = ""; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /rest/src/main/java/com/rekoe/websocket/OmWebsocket.java: -------------------------------------------------------------------------------- 1 | package com.rekoe.websocket; 2 | 3 | import javax.websocket.EndpointConfig; 4 | import javax.websocket.Session; 5 | import javax.websocket.server.ServerEndpoint; 6 | 7 | import org.nutz.dao.Dao; 8 | import org.nutz.integration.jedis.JedisAgent; 9 | import org.nutz.integration.jedis.pubsub.PubSub; 10 | import org.nutz.integration.jedis.pubsub.PubSubService; 11 | import org.nutz.ioc.loader.annotation.Inject; 12 | import org.nutz.ioc.loader.annotation.IocBean; 13 | import org.nutz.log.Log; 14 | import org.nutz.log.Logs; 15 | import org.nutz.plugins.mvc.websocket.AbstractWsEndpoint; 16 | import org.nutz.plugins.mvc.websocket.NutWsConfigurator; 17 | import org.nutz.plugins.mvc.websocket.WsHandler; 18 | import org.nutz.plugins.mvc.websocket.room.JedisRoomProvider; 19 | 20 | import redis.clients.jedis.Jedis; 21 | 22 | @ServerEndpoint(value = "/websocket", configurator = NutWsConfigurator.class) 23 | @IocBean(create = "init") 24 | public class OmWebsocket extends AbstractWsEndpoint implements PubSub { 25 | 26 | protected static final Log log = Logs.get(); 27 | 28 | @Inject 29 | protected PubSubService pubSubService; 30 | 31 | @Inject 32 | private Dao dao; 33 | 34 | @Inject 35 | protected JedisAgent jedisAgent; 36 | 37 | public void init() { 38 | roomPrefix = "wsroom:"; 39 | roomProvider = new JedisRoomProvider(jedisAgent); 40 | try (Jedis jedis = jedisAgent.getResource()) { 41 | for (String key : jedis.keys(roomPrefix + "*")) { 42 | switch (jedis.type(key)) { 43 | case "none": 44 | break; 45 | case "set": 46 | break; 47 | default: 48 | jedis.del(key); 49 | } 50 | } 51 | } 52 | pubSubService.reg(roomPrefix + "*", this); 53 | } 54 | 55 | @Override 56 | public void onMessage(String channel, String message) { 57 | if (log.isDebugEnabled()) 58 | log.debugf("GET PubSub channel=%s msg=%s", channel, message); 59 | each(channel, (index, session, length) -> session.getAsyncRemote().sendText(message)); 60 | } 61 | 62 | @Override 63 | public WsHandler createHandler(Session session, EndpointConfig config) { 64 | OmWsHandler handler = new OmWsHandler(roomPrefix, jedisAgent,dao); 65 | handler.setPubSubService(pubSubService); 66 | return handler; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /rest/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | nutz.mvc.ignore=/static/* 2 | nutz.mvc.exclusions=/res/*,*.html,/static/*,/swagger/*,/style/*,/undefined 3 | 4 | undertow.port=8080 5 | undertow.host=0.0.0.0 6 | 7 | jdbc.type=druid 8 | jdbc.url=jdbc:mysql://127.0.0.1:3306/dingtalk_meal?characterEncoding=utf8&useSSL=false 9 | jdbc.username=root 10 | jdbc.password=root 11 | jdbc.validationQuery=select 1 12 | jdbc.maxActive=50 13 | jdbc.testWhileIdle=true 14 | jdbc.filters=mergeStat 15 | jdbc.connectionProperties=druid.stat.slowSqlMillis=2000 16 | jdbc.defaultAutoCommit=false 17 | 18 | #redis 19 | redis.host=127.0.0.1 20 | redis.port=6379 21 | redis.timeout=2000 22 | redis.database=2 23 | 24 | #ngrok 25 | ngrok.client.auth_token=xxx 26 | ngrok.client.to_port=8080 27 | ngrok.client.enable=true 28 | 29 | #cache 30 | shiro.session.cache.type=redis 31 | nutz.dao.interceptor.cache.provider.type=jedis 32 | nutz.dao.interceptor.time.enable=true 33 | nutz.dao.interceptor.cache.enable=true 34 | nutz.dao.interceptor.cache.provider.memory.cacheSize=1000 35 | nutz.dao.interceptor.cache.table.names=meal_seller,meal_order,ding_talk_user,food_category,system_user,system_permission,system_role,system_user_role,food_ratings 36 | 37 | feign.encoder=nutzjson 38 | feign.decoder=nutzjson 39 | feign.logLevel=headers 40 | feign.url=https://oapi.dingtalk.com 41 | 42 | swagger.info.title=NutzBoot Swagger 43 | swagger.info.version=2.0-Beta 44 | swagger.info.contact.name=Wendal Chen 45 | swagger.info.contact.email=koukou890@gmail.com 46 | swagger.info.contact.url=https://nutz.io 47 | swagger.info.license.name=Apache v2 48 | 49 | #钉钉扫码登陆 50 | dingtalk.oauth.appid=xxx 51 | dingtalk.oauth.appsecret=xxx 52 | #钉钉内部应用 53 | dingtalk.agentid=xxx 54 | dingtalk.corpid=xxx 55 | dingtalk.corpsecret=xxx 56 | -------------------------------------------------------------------------------- /rest/src/main/resources/ehcache.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 16 | 17 | 21 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /rest/src/main/resources/ioc/wx.js: -------------------------------------------------------------------------------- 1 | var ioc = { 2 | wxJsapiTicketStore : { 3 | type : "org.nutz.weixin.at.impl.MemoryJsapiTicketStore" 4 | }, 5 | wxApi : { 6 | type : "org.nutz.weixin.impl.WxApi2Impl", 7 | fields : { 8 | token : { 9 | java : "$conf.get('weixin.token')" 10 | }, 11 | appid : { 12 | java : "$conf.get('weixin.appid')" 13 | }, 14 | appsecret : { 15 | java : "$conf.get('weixin.secret')" 16 | }, 17 | encodingAesKey : { 18 | java : "$conf.get('weixin.aes')" 19 | }, 20 | jsapiTicketStore : { 21 | refer : 'wxJsapiTicketStore' 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /rest/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO,Console 2 | 3 | log4j.logger.org.eclipse.jetty=OFF 4 | log4j.logger.org.apache.jasper=OFF 5 | log4j.logger.org.quartz.core=OFF 6 | log4j.logger.feign.slf4j=INFO 7 | log4j.logger.org.apache.commons=INFO 8 | log4j.logger.io.netty=INFO 9 | log4j.logger.org.nutz.dao=DEBUG 10 | log4j.logger.io.undertow=INFO 11 | log4j.logger.org.nutz.mvc.impl=DEBUG 12 | log4j.logger.org.nutz.integration.json4excel=INFO 13 | log4j.logger.com.rekoe.module=INFO 14 | log4j.logger.com.mongodb=INFO 15 | log4j.appender.Console=org.apache.log4j.ConsoleAppender 16 | log4j.appender.Console.layout=org.apache.log4j.PatternLayout 17 | log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss.SSS} %l - %m%n 18 | -------------------------------------------------------------------------------- /rest/src/main/resources/oauth_consumer.properties: -------------------------------------------------------------------------------- 1 | #google 2 | www.google.com.consumer_key=xxxx 3 | www.google.com.consumer_secret=xxx 4 | 5 | #twitter 6 | twitter.com.consumer_key=VV 7 | twitter.com.consumer_secret=VV 8 | 9 | #facebook 10 | graph.facebook.com.consumer_key=xxx 11 | graph.facebook.com.consumer_secret=xxx 12 | #github 13 | api.github.com.consumer_key=xxx 14 | api.github.com.consumer_secret=xxx 15 | api.github.com.custom_permissions=user:email 16 | 17 | #googleplus 18 | googleapis.com.consumer_key=xxx 19 | googleapis.com.consumer_secret=xxxx 20 | 21 | 22 | -------------------------------------------------------------------------------- /rest/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | OM-PLATFORM
-------------------------------------------------------------------------------- /rest/src/main/resources/static/static/css/app.360141a6db3f98e86394034a4b096d48.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/css/app.360141a6db3f98e86394034a4b096d48.css.gz -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/fonts/fontawesome-webfont.674f50d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/fonts/fontawesome-webfont.674f50d.eot -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/fonts/fontawesome-webfont.af7ae50.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/fonts/fontawesome-webfont.af7ae50.woff2 -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/fonts/fontawesome-webfont.b06871f.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/fonts/fontawesome-webfont.b06871f.ttf -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/fonts/fontawesome-webfont.fee66e7.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/fonts/fontawesome-webfont.fee66e7.woff -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/icon/favicon.ico -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/img/anonymity.3f9b695.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/img/anonymity.3f9b695.png -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/img/background.2e65c38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/img/background.2e65c38.png -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/js/app.e792d06cbdf7528ee766.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/rest/src/main/resources/static/static/js/app.e792d06cbdf7528ee766.js.gz -------------------------------------------------------------------------------- /rest/src/main/resources/static/static/js/manifest.7d41dc005464a20dda04.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,i){for(var u,a,f,s=0,l=[];s 3 | 4.0.0 4 | 5 | com.rekoe 6 | nutz-dingtalk 7 | 1.0-SNAPSHOT 8 | 9 | nutz-dingtalk-ui 10 | 11 | 12 | 13 | org.codehaus.mojo 14 | exec-maven-plugin 15 | 1.6.0 16 | 17 | 18 | exec-npm-install 19 | prepare-package 20 | 21 | exec 22 | 23 | 24 | ${npm} 25 | 26 | install 27 | 28 | ${basedir}/src/main/resources 29 | 30 | 31 | 32 | 33 | exec-npm-run-build 34 | prepare-package 35 | 36 | exec 37 | 38 | 39 | ${npm} 40 | 41 | run 42 | build 43 | 44 | ${basedir}/src/main/resources 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ${project.basedir}/src/main/resources/dist 53 | ${destDir} 54 | 55 | 56 | 57 | 58 | 59 | window 60 | 61 | npm.cmd 62 | 63 | 64 | 65 | unix 66 | 67 | cnpm 68 | 69 | 70 | true 71 | 72 | 73 | 74 | 75 | UTF-8 76 | ${project.build.outputDirectory}/META-INF/resources/ 77 | 78 | 79 | -------------------------------------------------------------------------------- /ui/src/main/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/1.png -------------------------------------------------------------------------------- /ui/src/main/images/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/2.jpeg -------------------------------------------------------------------------------- /ui/src/main/images/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/3.jpeg -------------------------------------------------------------------------------- /ui/src/main/images/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/4.jpeg -------------------------------------------------------------------------------- /ui/src/main/images/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/5.jpeg -------------------------------------------------------------------------------- /ui/src/main/images/6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/6.jpeg -------------------------------------------------------------------------------- /ui/src/main/images/7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/images/7.jpeg -------------------------------------------------------------------------------- /ui/src/main/resources/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "plugins": [ "istanbul" ] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ui/src/main/resources/.vscode-upload.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name":"", 3 | "host": "", 4 | "port": 22, 5 | "username": "", 6 | "password": "", 7 | "remotePath": "", 8 | "localPath": "", 9 | "disable": false, 10 | "private_key": "~/.ssh/id_rsa" 11 | },{ 12 | "name":"", 13 | "host": "", 14 | "port": 22, 15 | "username": "", 16 | "password": "", 17 | "remotePath": "", 18 | "localPath": "", 19 | "disable": false, 20 | "private_key": "~/.ssh/id_rsa" 21 | }] -------------------------------------------------------------------------------- /ui/src/main/resources/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "vetur.validation.template": false 3 | } -------------------------------------------------------------------------------- /ui/src/main/resources/build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /ui/src/main/resources/build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ui/src/main/resources/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /ui/src/main/resources/build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | var compiler = webpack(webpackConfig) 25 | 26 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 27 | publicPath: webpackConfig.output.publicPath, 28 | quiet: true 29 | }) 30 | 31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 32 | log: () => {} 33 | }) 34 | // force page reload when html-webpack-plugin template changes 35 | compiler.plugin('compilation', function (compilation) { 36 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 37 | hotMiddleware.publish({ action: 'reload' }) 38 | cb() 39 | }) 40 | }) 41 | 42 | // proxy api requests 43 | Object.keys(proxyTable).forEach(function (context) { 44 | var options = proxyTable[context] 45 | if (typeof options === 'string') { 46 | options = { target: options } 47 | } 48 | app.use(proxyMiddleware(options.filter || context, options)) 49 | }) 50 | 51 | // handle fallback for HTML5 history API 52 | app.use(require('connect-history-api-fallback')()) 53 | 54 | // serve webpack bundle output 55 | app.use(devMiddleware) 56 | 57 | // enable hot-reload and state-preserving 58 | // compilation error display 59 | app.use(hotMiddleware) 60 | 61 | // serve pure static assets 62 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 63 | app.use(staticPath, express.static('./static')) 64 | 65 | var uri = 'http://localhost:' + port 66 | 67 | var _resolve 68 | var readyPromise = new Promise(resolve => { 69 | _resolve = resolve 70 | }) 71 | 72 | console.log('> Starting dev server...') 73 | devMiddleware.waitUntilValid(() => { 74 | console.log('> Listening at ' + uri + '\n') 75 | // when env is testing, don't need open it 76 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 77 | opn(uri) 78 | } 79 | _resolve() 80 | }) 81 | 82 | var server = app.listen(port) 83 | 84 | module.exports = { 85 | ready: readyPromise, 86 | close: () => { 87 | server.close() 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ui/src/main/resources/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/build/logo.png -------------------------------------------------------------------------------- /ui/src/main/resources/build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | 73 | exports.createNotifierCallback = () => { 74 | const notifier = require('node-notifier') 75 | 76 | return (severity, errors) => { 77 | if (severity !== 'error') return 78 | 79 | const error = errors[0] 80 | const filename = error.file && error.file.split('!').pop() 81 | 82 | notifier.notify({ 83 | title: packageConfig.name, 84 | message: severity + ': ' + error.name, 85 | subtitle: filename || '', 86 | icon: path.join(__dirname, 'logo.png') 87 | }) 88 | } 89 | } -------------------------------------------------------------------------------- /ui/src/main/resources/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | const utils = require('./utils') 2 | const config = require('../config') 3 | const isProduction = process.env.NODE_ENV === 'production' 4 | const sourceMapEnabled = isProduction 5 | ? config.build.productionSourceMap 6 | : config.dev.cssSourceMap 7 | 8 | module.exports = { 9 | loaders: utils.cssLoaders({ 10 | sourceMap: sourceMapEnabled, 11 | extract: isProduction 12 | }), 13 | cssSourceMap: sourceMapEnabled, 14 | cacheBusting: config.dev.cacheBusting, 15 | transformToRequire: { 16 | video: ['src', 'poster'], 17 | source: 'src', 18 | img: 'src', 19 | image: 'xlink:href' 20 | } 21 | } -------------------------------------------------------------------------------- /ui/src/main/resources/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | const webpack = require('webpack') 6 | const vuxLoader = require('vux-loader') 7 | function resolve(dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | const webpackConfig = module.exports = { 12 | externals : { 13 | 'vue' : 'Vue', 14 | 'vue-router' : 'VueRouter', 15 | 'vuex' : 'Vuex', 16 | 'axios' : 'axios', 17 | 'element-ui' : 'ELEMENT' 18 | }, 19 | entry : { 20 | app : './src/main.js' 21 | }, 22 | output : { 23 | path : config.build.assetsRoot, 24 | filename : '[name].js', 25 | publicPath : process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath 26 | : config.dev.assetsPublicPath 27 | }, 28 | resolve : { 29 | extensions : [ '.js', '.vue', '.json' ], 30 | alias : { 31 | 'vue$' : 'vue/dist/vue.esm.js', 32 | '@' : resolve('src'), 33 | 'scss_vars' : '@/styles/vars.scss' 34 | } 35 | }, 36 | module : { 37 | rules : [ { 38 | test : /\.vue$/, 39 | loader : 'vue-loader', 40 | options : vueLoaderConfig 41 | }, { 42 | test : /\.js$/, 43 | loader : 'babel-loader', 44 | include : [ resolve('src'), resolve('test') ] 45 | }, { 46 | test : /\.(png|jpe?g|gif|svg)(\?.*)?$/, 47 | loader : 'url-loader', 48 | exclude : [ resolve('src/icons') ], 49 | options : { 50 | limit : 10000, 51 | name : utils.assetsPath('img/[name].[hash:7].[ext]') 52 | } 53 | }, { 54 | test : /\.svg$/, 55 | loader : 'svg-sprite-loader', 56 | include : [ resolve('src/icons') ], 57 | options : { 58 | symbolId : 'icon-[name]' 59 | } 60 | }, { 61 | test : /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader : 'url-loader', 63 | options : { 64 | limit : 10000, 65 | name : utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } ] 68 | }, 69 | plugins : [ new webpack.ProvidePlugin({ 70 | $ : "jquery", 71 | jQuery : "jquery", 72 | 'window.jQuery' : 'jquery' 73 | }) ] 74 | } 75 | 76 | module.exports = vuxLoader.merge(webpackConfig, { plugins: ['vux-ui'] }) -------------------------------------------------------------------------------- /ui/src/main/resources/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /ui/src/main/resources/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /ui/src/main/resources/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | var buildpath = '../dist' 4 | //var buildpath = '../disk'; 5 | module.exports = { 6 | build: { 7 | env: require('./prod.env'), 8 | index: path.resolve(__dirname, buildpath+'/index.html'), 9 | assetsRoot: path.resolve(__dirname, buildpath), 10 | assetsSubDirectory: 'static', 11 | assetsPublicPath: '/', 12 | productionSourceMap: true, 13 | // Gzip off by default as many popular static hosts such as 14 | // Surge or Netlify already gzip all static assets for you. 15 | // Before setting to `true`, make sure to: 16 | // npm install --save-dev compression-webpack-plugin 17 | productionGzip: true, 18 | productionGzipExtensions: ['js', 'css'], 19 | // Run the build command with an extra argument to 20 | // View the bundle analyzer report after build finishes: 21 | // `npm run build --report` 22 | // Set to `true` or `false` to always turn it on or off 23 | bundleAnalyzerReport: process.env.npm_config_report 24 | }, 25 | dev: { 26 | env: require('./dev.env'), 27 | port: 8888, 28 | autoOpenBrowser: true, 29 | assetsSubDirectory: 'static', 30 | assetsPublicPath: '/', 31 | proxyTable: { 32 | '/api': { 33 | target: 'http://rekoe.ngrok.wendal.cn/', 34 | changeOrigin: true, 35 | pathRewrite: { 36 | '/api': '' 37 | } 38 | } 39 | }, 40 | // CSS Sourcemaps off by default because relative paths are "buggy" 41 | // with this option, according to the CSS-Loader README 42 | // (https://github.com/webpack/css-loader#sourcemaps) 43 | // In our experience, they generally work as expected, 44 | // just be aware of this issue when enabling this option. 45 | cssSourceMap: false 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ui/src/main/resources/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /ui/src/main/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OM-PLATFORM 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 34 | 35 | 107 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/acl/permission.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | /** 5 | * 权限列表 6 | * @param {number} page 页码 7 | * @param {Function} success 回调 8 | */ 9 | list(page, success) { 10 | http.get('permission/list', { 11 | page: page 12 | }, success); 13 | }, 14 | /** 15 | * 权限检索 16 | * @param {number} page 页码 17 | * @param {string} key 关键词 18 | * @param {Function} success 回调 19 | */ 20 | search(page, key, success) { 21 | http.get('permission/search', { 22 | page: page, 23 | key: key 24 | }, success); 25 | }, 26 | /** 27 | * 添加权限 28 | * @param {Object} permission 权限 29 | * @param {Function} success 回调 30 | */ 31 | save(permission, success) { 32 | http.postBody('permission/add', permission, success) 33 | }, 34 | /** 35 | * 更新权限 36 | * @param {Object} permission 权限 37 | * @param {Function} success 回调 38 | */ 39 | update(permission, success) { 40 | http.postBody('permission/edit', permission, success) 41 | }, 42 | /** 43 | * 删除权限 44 | * @param {number} id 权限id 45 | * @param {*} success 回调 46 | */ 47 | delete(id, success) { 48 | http.get('permission/delete/' + id, success); 49 | } 50 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/acl/role.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | /** 5 | * 角色列表 6 | * @param {number} page 页码 7 | * @param {Function} success 回调 8 | */ 9 | list(page, success) { 10 | http.get('role/list', { 11 | page: page 12 | }, success); 13 | }, 14 | /** 15 | * 角色检索 16 | * @param {number} page 页码 17 | * @param {string} key 关键词 18 | * @param {Function} success 回调 19 | */ 20 | search(page, key, success) { 21 | http.get('role/search', { 22 | page: page, 23 | key: key 24 | }, success); 25 | }, 26 | /** 27 | * 添加角色 28 | * @param {Object} role 角色 29 | * @param {Function} success 回调 30 | */ 31 | save(role, success) { 32 | http.postBody('role/add', role, success) 33 | }, 34 | /** 35 | * 更新角色 36 | * @param {Object} role 角色 37 | * @param {Function} success 回调 38 | */ 39 | update(role, success) { 40 | http.postBody('role/edit', role, success) 41 | }, 42 | /** 43 | * 角色授权信息 44 | * @param {number} id 角色id 45 | * @param {Function} success 回调 46 | */ 47 | roleGrantInfo(id, success) { 48 | http.get('role/permission/' + id, success); 49 | }, 50 | /** 51 | * 角色授权 52 | * @param {number} id 角色id 53 | * @param {Array} powers 权限 54 | * @param {Function} success 回调 55 | */ 56 | grant(id, powers, success) { 57 | http.postBody('role/grant/', { 58 | id: id, 59 | grantIds: powers 60 | }, success) 61 | }, 62 | /** 63 | * 删除角色 64 | * @param {number} id 角色id 65 | * @param {*} success 回调 66 | */ 67 | delete(id, success) { 68 | http.get('role/delete/' + id, success); 69 | } 70 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/dingcan/index.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | query(success) { 5 | http.get('dingcan/query', {}, success); 6 | }, 7 | submit_order(orders,success){ 8 | http.postBody('dingcan/submit_order', orders, success) 9 | }, 10 | cancel_order(success){ 11 | http.get('dingcan/cancel_order', {}, success); 12 | }, 13 | goods(id,success){ 14 | http.get('dingcan/goods', {id:id}, success); 15 | }, 16 | new_goods(id,userProvince,success){ 17 | http.get('dingcan/new_goods', {id:id,user_province:userProvince}, success); 18 | }, 19 | new_ratings(success){ 20 | http.get('dingcan/new_ratings', {}, success); 21 | }, 22 | sellers(userProvince,success){ 23 | http.get('dingcan/sellers', {user_province:userProvince}, success); 24 | }, 25 | new_seller(success){ 26 | http.get('dingcan/new_seller', {}, success); 27 | }, 28 | header(success){ 29 | http.get('dingcan/header', {}, success); 30 | } 31 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/dingtalk/index.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | auth(code, success) { 5 | http.get('dingtalk/auth', { 6 | code: code 7 | }, success); 8 | }, 9 | sign(url,success) { 10 | http.get('sign', {url:url}, success); 11 | }, 12 | update_work_place(work_place,success) { 13 | http.get('update_work_place', {work_place:work_place}, success); 14 | } 15 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/index.js: -------------------------------------------------------------------------------- 1 | import User from './acl/user' 2 | import Role from './acl/role' 3 | import DingTalk from './dingtalk' 4 | import Permission from './acl/permission' 5 | import DingCan from './dingcan' 6 | import Seller from './meal/seller' 7 | import MCategory from './meal/category' 8 | import MFood from './meal/food' 9 | import MOrder from './meal/order' 10 | import MSellerOrder from './meal/seller_order' 11 | export default { 12 | User: User, 13 | Role: Role, 14 | Permission: Permission, 15 | DingTalk: DingTalk, 16 | DingCan: DingCan, 17 | Seller: Seller, 18 | MCategory: MCategory, 19 | MFood: MFood, 20 | MOrder: MOrder, 21 | MSellerOrder: MSellerOrder 22 | }; -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/meal/category.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | list(page, seller,success) { 5 | http.get('food/category/list', { 6 | page: page, 7 | seller: seller 8 | }, success); 9 | }, 10 | search(page, key, success) { 11 | http.get('food/category/search', { 12 | page: page, 13 | key: key 14 | }, success); 15 | }, 16 | status(id,success) { 17 | http.get('food/category/status', { 18 | id: id 19 | }, success); 20 | }, 21 | type(id,type,success) { 22 | http.get('food/category/type', { 23 | id: id, 24 | type:type 25 | }, success); 26 | } 27 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/meal/food.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | list(page, success) { 5 | http.get('meal/food/list', { 6 | page: page 7 | }, success); 8 | }, 9 | search(page, key, success) { 10 | http.get('meal/food/search', { 11 | page: page, 12 | key: key 13 | }, success); 14 | }, 15 | status(id,success) { 16 | http.get('meal/food/status', { 17 | id: id 18 | }, success); 19 | } 20 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/meal/order.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | list(page,success) { 5 | http.get('meal/order/list', { 6 | page: page 7 | }, success); 8 | }, 9 | search(page, key, success) { 10 | http.get('meal/order/search', { 11 | page: page, 12 | key: key 13 | }, success); 14 | } 15 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/meal/seller.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | list(page, success) { 5 | http.get('meal/seller/list', { 6 | page: page 7 | }, success); 8 | }, 9 | search(page, key, success) { 10 | http.get('meal/seller/search', { 11 | page: page, 12 | key: key 13 | }, success); 14 | }, 15 | save(seller, success) { 16 | http.get('meal/seller/collection', { 17 | url: seller.url, 18 | province:seller.province 19 | }, success); 20 | }, 21 | status(id,success) { 22 | http.get('meal/seller/status', {id:id}, success); 23 | } 24 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/api/meal/seller_order.js: -------------------------------------------------------------------------------- 1 | import http from '@/http' 2 | 3 | export default { 4 | list(page, success) { 5 | http.get('seller/order/list', { 6 | page: page 7 | }, success); 8 | } 9 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/Github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/Github.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/a_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/a_logo.jpg -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/background.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/dingtalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/dingtalk.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/f_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/f_logo.jpg -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/facebook.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/images/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/assets/images/google.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/assets/style.less: -------------------------------------------------------------------------------- 1 | [class^="el-icon-fa"], [class*=" el-icon-fa"] { 2 | display: inline-block; 3 | font: normal normal normal 14px/1 FontAwesome !important; 4 | font-size: inherit; 5 | text-rendering: auto; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | ; 11 | 12 | @import url("../../node_modules/font-awesome/less/font-awesome.less"); 13 | @fa-css-prefix: el-icon-fa; 14 | // @import url("../../node_modules/element-ui/lib/theme-chalk/index.css"); 15 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/css/icon.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'mt-app'; 3 | src: url('../fonts/mt-app.eot?w2jfmc'); 4 | src: url('../fonts/mt-app.eot?w2jfmc#iefix') format('embedded-opentype'), 5 | url('../fonts/mt-app.ttf?w2jfmc') format('truetype'), 6 | url('../fonts/mt-app.woff?w2jfmc') format('woff'), 7 | url('../fonts/mt-app.svg?w2jfmc#mt-app') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'mt-app' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-add_circle:before { 28 | content: "\e900"; 29 | } 30 | .icon-arrow_lift:before { 31 | content: "\e901"; 32 | } 33 | .icon-check_circle:before { 34 | content: "\e902"; 35 | } 36 | .icon-close:before { 37 | content: "\e903"; 38 | } 39 | .icon-favorite:before { 40 | content: "\e904"; 41 | } 42 | .icon-keyboard_arrow_right:before { 43 | content: "\e905"; 44 | } 45 | .icon-remove_circle_outline:before { 46 | content: "\e906"; 47 | } 48 | .icon-shopping_cart:before { 49 | content: "\e907"; 50 | } 51 | .icon-thumb_down:before { 52 | content: "\e908"; 53 | } 54 | .icon-thumb_up:before { 55 | content: "\e909"; 56 | } 57 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/fonts/mt-app.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/common/fonts/mt-app.eot -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/fonts/mt-app.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/fonts/mt-app.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/common/fonts/mt-app.ttf -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/fonts/mt-app.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/common/fonts/mt-app.woff -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin border-bottom-1px ($color) { 2 | position: relative; 3 | &:after{ 4 | content: ''; 5 | display: block; 6 | width:100%; 7 | border-bottom: 1px solid $color; 8 | position: absolute; 9 | left:0;bottom: 0; 10 | } 11 | @media only screen and (-webkit-min-device-pixel-ratio: 2.0){ 12 | //dpr为2的手机上 13 | &:after{ 14 | -webkit-transform: scaleY(0.5); 15 | transform: scaleY(0.5); 16 | } 17 | } 18 | @media only screen and (-webkit-min-device-pixel-ratio: 3.0){ 19 | //dpr为3的手机上 20 | &:after{ 21 | -webkit-transform: scaleY(0.33); 22 | transform: scaleY(0.33); 23 | } 24 | } 25 | } 26 | @mixin clear_bottom_1px () { 27 | &:after{ 28 | display: none; 29 | } 30 | } 31 | .clearfix:after{content:"";display: table;clear:both;} -------------------------------------------------------------------------------- /ui/src/main/resources/src/common/util.js: -------------------------------------------------------------------------------- 1 | // 解析url参数 2 | export function urlParse () { 3 | var url = window.location.search 4 | var obj = {} 5 | var reg = /[?&][^?&]+=[^?&]+/g 6 | var arr = url.match(reg) 7 | arr.forEach((item) => { 8 | let temp = item.substring(1).split('=') 9 | let key = decodeURIComponent(temp[0]) 10 | let value = decodeURIComponent(temp[1]) 11 | obj[key] = value 12 | }) 13 | console.log(obj) 14 | return obj 15 | } 16 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 33 | 34 | 43 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/goods/img/btn_yellow_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/goods/img/btn_yellow_highlighted@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/header/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/header/img/search.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/header/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/header/img/star.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/nav/Nav.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 50 | 51 | 83 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/productDetail/img/anonymity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/productDetail/img/anonymity.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/productDetail/img/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/productDetail/img/more.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/productDetail/img/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/productDetail/img/share.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/ratings/img/anonymity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/ratings/img/anonymity.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/ratings/img/icon_sub_tab_dp_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/ratings/img/icon_sub_tab_dp_highlighted@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/ratings/img/icon_sub_tab_dp_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/ratings/img/icon_sub_tab_dp_normal@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/address.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/delivery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/delivery.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/line.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/phone.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/safety.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/safety.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/server.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/seller/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/seller/time.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/shopcart/img/ash_bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/shopcart/img/ash_bin.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/split/Split.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/star/Star.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 56 | 57 | 84 | 85 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/star/img/star24_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/star/img/star24_half@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/star/img/star24_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/star/img/star24_off@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/components/star/img/star24_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/src/components/star/img/star24_on@2x.png -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon'// svg组件 3 | import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for @/views/icons , you can delete it 4 | 5 | // register globally 6 | Vue.component('svg-icon', SvgIcon) 7 | 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | const req = require.context('./svg', false, /\.svg$/) 10 | const iconMap = requireAll(req) 11 | 12 | generateIconsView.generate(iconMap) // just for @/views/icons , you can delete it 13 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/component.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/dashboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/international.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/language.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/people.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/icons/svg/shoppingCard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/lang/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import Cookies from 'js-cookie' 4 | import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang 5 | import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang 6 | import zhLocale from './zh' 7 | import enLocale from './en' 8 | 9 | Vue.use(VueI18n) 10 | const messages = { 11 | en: { 12 | ...enLocale, 13 | ...elementEnLocale 14 | }, 15 | zh: { 16 | ...zhLocale, 17 | ...elementZhLocale 18 | } 19 | } 20 | const i18n = new VueI18n({ 21 | locale: Cookies.get('language') || 'zh', 22 | messages 23 | }) 24 | ELEMENT.i18n((key, value) => i18n.t(key, value)) 25 | export default i18n 26 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from '@/App' 3 | import store from '@/vuex/store' 4 | import 'nprogress/nprogress.css' 5 | import NProgress from 'nprogress' 6 | import routes from '@/routes' 7 | import 'font-awesome/css/font-awesome.min.css' 8 | import '@/assets/style.less' 9 | import 'normalize.css' 10 | import '@/common/mixin.scss' 11 | import api from "@/api"; 12 | import http from '@/http' 13 | import rules from '@/rules' 14 | 15 | import i18n from '@/lang' 16 | import '@/icons' // icon 17 | import BgaBackTop from 'bga-back-top-vue' 18 | import infiniteScroll from 'vue-infinite-scroll' 19 | Vue.use(BgaBackTop) 20 | Vue.use(infiniteScroll) 21 | 22 | import utils from '@/common/js/util' 23 | import { AlertPlugin } from 'vux' 24 | import FastClick from 'fastclick' 25 | Vue.use(AlertPlugin) 26 | 27 | Vue.prototype.$http = http; 28 | Vue.prototype.$rules = rules; 29 | Vue.prototype.$api = api; 30 | Vue.prototype.$utils = utils; 31 | //Vue.prototype.$alert = Alert; 32 | global.baseUrl = process.env.NODE_ENV == "development" ? 'api' : ''; 33 | 34 | var ws; 35 | var WS_URL = (process.env.NODE_ENV == "development"?"rekoe.ngrok.wendal.cn":window.location.host) + "/websocket" 36 | Vue.prototype.websocket_init = function(){ 37 | this.ws = new WebSocket('ws://'+WS_URL); 38 | } 39 | Vue.prototype.websocket_join = function(room){ 40 | this.ws.onopen = function (evt) { 41 | this.send(JSON.stringify({room:room,action:'join'})); 42 | } 43 | } 44 | FastClick.attach(document.body); 45 | // NProgress.configure({ showSpinner: false }); 46 | const router = new VueRouter({ 47 | routes, 48 | //mode:"history", 49 | linkActiveClass:"active" 50 | }) 51 | 52 | router.beforeEach((to, from, next) => { 53 | NProgress.start(); 54 | if (to.path === '/') { 55 | store.commit('remove'); 56 | } 57 | next() 58 | }) 59 | 60 | router.afterEach(transition => { 61 | NProgress.done(); 62 | }); 63 | Vue.config.productionTip = false 64 | new Vue({ 65 | router, 66 | store, 67 | i18n, 68 | render: h => h(App) 69 | }).$mount('#app') -------------------------------------------------------------------------------- /ui/src/main/resources/src/styles/vars.scss: -------------------------------------------------------------------------------- 1 | $color-primary: #545c64; //#18c79c -------------------------------------------------------------------------------- /ui/src/main/resources/src/utils/clipboard.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Clipboard from 'clipboard' 3 | 4 | function clipboardSuccess() { 5 | Vue.prototype.$message({ 6 | message: 'Copy successfully', 7 | type: 'success', 8 | duration: 1500 9 | }) 10 | } 11 | 12 | function clipboardError() { 13 | Vue.prototype.$message({ 14 | message: 'Copy failed', 15 | type: 'error' 16 | }) 17 | } 18 | 19 | export default function handleClipboard(text, event) { 20 | const clipboard = new Clipboard(event.target, { 21 | text: () => text 22 | }) 23 | clipboard.on('success', () => { 24 | clipboardSuccess() 25 | clipboard.off('error') 26 | clipboard.off('success') 27 | clipboard.destroy() 28 | }) 29 | clipboard.on('error', () => { 30 | clipboardError() 31 | clipboard.off('error') 32 | clipboard.off('success') 33 | clipboard.destroy() 34 | }) 35 | clipboard.onClick(event) 36 | } 37 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/utils/i18n.js: -------------------------------------------------------------------------------- 1 | // translate router.meta.title, be used in breadcrumb sidebar tagsview 2 | export function generateTitle(title) { 3 | const hasKey = this.$te('route.' + title) 4 | const translatedTitle = this.$t('route.' + title) // $t :this method from vue-i18n, inject in @/lang/index.js 5 | 6 | if (hasKey) { 7 | return translatedTitle 8 | } 9 | return title 10 | } 11 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/utils/logger.js: -------------------------------------------------------------------------------- 1 | const HASCONSOLE = typeof console !== undefined; 2 | 3 | const logger = { 4 | warn: function (msg, e){ 5 | if (HASCONSOLE) { 6 | console.warn('[DING WEB SDK Warning]:', msg); 7 | if (e) { 8 | throw e; 9 | } else { 10 | const warning = new Error('WARNING STACK TRACE'); 11 | console.warn(warning.stack); 12 | } 13 | } 14 | }, 15 | info: function (msg){ 16 | if (HASCONSOLE) { 17 | console.info('[DING WEB SDK INFO]:', msg); 18 | } 19 | }, 20 | error: function (msg){ 21 | if (HASCONSOLE){ 22 | console.error('[DING WEB SDK ERROR]:', msg); 23 | } 24 | } 25 | }; 26 | 27 | if (process.env.NODE_ENV !== 'production') { 28 | 29 | } 30 | 31 | export default logger; -------------------------------------------------------------------------------- /ui/src/main/resources/src/utils/openWindow.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Created by jiachenpan on 16/11/29. 3 | * @param {Sting} url 4 | * @param {Sting} title 5 | * @param {Number} w 6 | * @param {Number} h 7 | */ 8 | 9 | export default function openWindow(url, title, w, h) { 10 | // Fixes dual-screen position Most browsers Firefox 11 | const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left 12 | const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top 13 | 14 | const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width 15 | const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height 16 | 17 | const left = ((width / 2) - (w / 2)) + dualScreenLeft 18 | const top = ((height / 2) - (h / 2)) + dualScreenTop 19 | const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left) 20 | 21 | // Puts focus on the newWindow 22 | if (window.focus) { 23 | newWindow.focus() 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/utils/tools.js: -------------------------------------------------------------------------------- 1 | export default { 2 | setStore (name, content) { 3 | if (!name) return 4 | if (typeof content !== 'string') { 5 | content = JSON.stringify(content) 6 | } 7 | window.localStorage.setItem(name, content) 8 | }, 9 | 10 | getStore (name) { 11 | if (!name) return 12 | return window.localStorage.getItem(name) 13 | }, 14 | 15 | removeStore (name) { 16 | if (!name) return 17 | return window.localStorage.removeItem(name) 18 | }, 19 | 20 | getLangage() { 21 | return { 22 | 'lang': this.getStore('lang') 23 | } 24 | }, 25 | getOpenid() { 26 | return { 27 | 'openid': this.getStore('openid') 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ui/src/main/resources/src/views/404.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/views/socialsignin.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 74 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/views/svg-icons/generateIconsView.js: -------------------------------------------------------------------------------- 1 | const data = { 2 | state: { 3 | iconsMap: [] 4 | }, 5 | generate(iconsMap) { 6 | this.state.iconsMap = iconsMap 7 | } 8 | } 9 | 10 | export default data 11 | -------------------------------------------------------------------------------- /ui/src/main/resources/src/views/svg-icons/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 50 | 51 | 75 | -------------------------------------------------------------------------------- /ui/src/main/resources/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/static/.gitkeep -------------------------------------------------------------------------------- /ui/src/main/resources/static/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /ui/src/main/resources/static/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rekoe/nutz-dingtalk/f857ba40a82b0b3979f4f0283235e5da46aac565/ui/src/main/resources/static/icon/favicon.ico --------------------------------------------------------------------------------