├── .gitattributes ├── index.ios.js ├── index.android.js ├── android ├── settings.gradle ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── java │ │ │ └── com │ │ │ │ └── awesomeproject │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ ├── BUCK │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── app.json ├── client ├── env │ ├── env.prod.js │ ├── env.pre_release.js │ ├── env.js │ └── env.test.js ├── styles │ ├── var.scss │ ├── styles.js │ ├── router.css │ └── style.scss ├── components │ ├── native-echarts │ │ ├── components │ │ │ ├── index.js │ │ │ ├── Container │ │ │ │ └── index.js │ │ │ └── Echarts │ │ │ │ ├── renderChart.js │ │ │ │ └── index.js │ │ ├── style.js │ │ ├── util │ │ │ └── toString.js │ │ └── index.js │ ├── TouchView.js │ ├── ImageChoose.js │ ├── RejectBox.js │ ├── Avatar.js │ ├── MonthChoose.js │ ├── ListItem.js │ └── AddressPopup.js ├── actions │ ├── actionCreator.js │ ├── app.js │ ├── boss.js │ └── user.js ├── page │ ├── home │ │ ├── BossHome.scss │ │ ├── index.js │ │ ├── Banbu.js │ │ ├── BossHome.js │ │ ├── personal.js │ │ └── UserHome.js │ └── Main.js ├── reducers │ ├── index.js │ ├── route.js │ ├── app.js │ └── user.js ├── data │ ├── app.js │ └── user.js ├── common │ ├── storage.js │ ├── axiosMiddlewareOptions.js │ ├── bbPlugin.js │ ├── ddAvatar.js │ ├── axiosConfig.js │ └── gps.js ├── connectRedux.js ├── store.js └── userScenes.js ├── img ├── NEW@2x.png ├── NEW@3x.png ├── down@2x.png ├── down@3x.png ├── up@2x.png ├── up@3x.png ├── banner@2x.png ├── ic_busi@2x.png ├── ic_busi@3x.png ├── ic_check@2x.png ├── ic_check@3x.png ├── ic_leave@2x.png ├── ic_leave@3x.png ├── ic_unfold@2x.png ├── ic_unfold@3x.png ├── icon-mobile.png ├── red-point@2x.png ├── red-point@3x.png ├── refresh@2x.png ├── refresh@3x.png ├── icon-password.png ├── personal-gz@2x.png ├── personal-gz@3x.png ├── personal-me@2x.png ├── personal-me@3x.png ├── personal-sb@2x.png ├── personal-sb@3x.png ├── personal-yb@2x.png ├── personal-yb@3x.png ├── timeline-REST.png ├── icon-category-0.png ├── icon-category-10.png ├── icon-category-20.png ├── icon-category-29.png ├── icon-category-30.png ├── icon-category-8.png ├── personal-gjj@2x.png ├── personal-gjj@3x.png ├── personal-help@2x.png ├── personal-help@3x.png ├── tabbar-icon-me@2x.png ├── tabbar-icon-me@3x.png ├── timeline-FUNERAL.png ├── timeline-REMARK.png ├── timeline-SIGNED.png ├── timeline-SIGN_IN.png ├── timeline-SIGN_OUT.png ├── icon-category-1@2x.png ├── icon-category-1@3x.png ├── icon-category-2@2x.png ├── icon-category-2@3x.png ├── icon-category-3@2x.png ├── icon-category-3@3x.png ├── icon-category-4@2x.png ├── icon-category-4@3x.png ├── icon-category-5@2x.png ├── icon-category-5@3x.png ├── icon-category-6@2x.png ├── icon-category-6@3x.png ├── icon-category-7@2x.png ├── icon-category-7@3x.png ├── icon-category-srhk.png ├── icon-category-znfk.png ├── icon-category-znzf.png ├── personal-setting@2x.png ├── personal-setting@3x.png ├── tabbar-icon-home@2x.png ├── tabbar-icon-home@3x.png ├── timeline-SICK_LEAVE.png ├── personal-feedback@2x.png ├── personal-feedback@3x.png ├── tabbar-icon-banbu@2x.png ├── tabbar-icon-banbu@3x.png ├── timeline-ANNUAL_LEAVE.png ├── timeline-CASUAL_LEAVE.png ├── timeline-REST-active.png ├── tabbar-icon-me-active@2x.png ├── tabbar-icon-me-active@3x.png ├── timeline-FUNERAL-active.png ├── timeline-MARRIAGE_LEAVE.png ├── timeline-MATERNITY_LEAVE.png ├── timeline-OFFIC_BUSI_AWAY.png ├── timeline-SIGN_IN-active.png ├── timeline-SIGN_OUT-active.png ├── tabbar-icon-banbu-active@2x.png ├── tabbar-icon-banbu-active@3x.png ├── tabbar-icon-home-active@2x.png ├── tabbar-icon-home-active@3x.png ├── timeline-SICK_LEAVE-active.png ├── timeline-ANNUAL_LEAVE-active.png ├── timeline-CASUAL_LEAVE-active.png ├── timeline-MARRIAGE_LEAVE-active.png ├── timeline-MATERNITY_LEAVE-active.png └── timeline-OFFIC_BUSI_AWAY-active.png ├── .babelrc ├── .buckconfig ├── readme.md ├── __tests__ ├── index.ios.js └── index.android.js ├── ios ├── AwesomeProject │ ├── AppDelegate.h │ ├── main.m │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── AwesomeProjectTests │ ├── Info.plist │ └── AwesomeProjectTests.m ├── AwesomeProject-tvOSTests │ └── Info.plist ├── AwesomeProject-tvOS │ └── Info.plist └── AwesomeProject.xcodeproj │ └── xcshareddata │ └── xcschemes │ ├── AwesomeProject.xcscheme │ └── AwesomeProject-tvOS.xcscheme ├── package.json ├── .gitignore ├── index.js └── .flowconfig /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./index.js'); -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./index.js'); -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'AwesomeProject' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AwesomeProject", 3 | "displayName": "AwesomeProject" 4 | } -------------------------------------------------------------------------------- /client/env/env.prod.js: -------------------------------------------------------------------------------- 1 | export default { 2 | API_HOST: 'http://prod.ibanbu.com' 3 | } -------------------------------------------------------------------------------- /img/NEW@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/NEW@2x.png -------------------------------------------------------------------------------- /img/NEW@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/NEW@3x.png -------------------------------------------------------------------------------- /img/down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/down@2x.png -------------------------------------------------------------------------------- /img/down@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/down@3x.png -------------------------------------------------------------------------------- /img/up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/up@2x.png -------------------------------------------------------------------------------- /img/up@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/up@3x.png -------------------------------------------------------------------------------- /img/banner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/banner@2x.png -------------------------------------------------------------------------------- /client/env/env.pre_release.js: -------------------------------------------------------------------------------- 1 | export default { 2 | API_HOST: 'http://prerelease.ibanbu.com' 3 | } -------------------------------------------------------------------------------- /img/ic_busi@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_busi@2x.png -------------------------------------------------------------------------------- /img/ic_busi@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_busi@3x.png -------------------------------------------------------------------------------- /img/ic_check@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_check@2x.png -------------------------------------------------------------------------------- /img/ic_check@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_check@3x.png -------------------------------------------------------------------------------- /img/ic_leave@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_leave@2x.png -------------------------------------------------------------------------------- /img/ic_leave@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_leave@3x.png -------------------------------------------------------------------------------- /img/ic_unfold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_unfold@2x.png -------------------------------------------------------------------------------- /img/ic_unfold@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/ic_unfold@3x.png -------------------------------------------------------------------------------- /img/icon-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-mobile.png -------------------------------------------------------------------------------- /img/red-point@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/red-point@2x.png -------------------------------------------------------------------------------- /img/red-point@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/red-point@3x.png -------------------------------------------------------------------------------- /img/refresh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/refresh@2x.png -------------------------------------------------------------------------------- /img/refresh@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/refresh@3x.png -------------------------------------------------------------------------------- /img/icon-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-password.png -------------------------------------------------------------------------------- /img/personal-gz@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-gz@2x.png -------------------------------------------------------------------------------- /img/personal-gz@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-gz@3x.png -------------------------------------------------------------------------------- /img/personal-me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-me@2x.png -------------------------------------------------------------------------------- /img/personal-me@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-me@3x.png -------------------------------------------------------------------------------- /img/personal-sb@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-sb@2x.png -------------------------------------------------------------------------------- /img/personal-sb@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-sb@3x.png -------------------------------------------------------------------------------- /img/personal-yb@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-yb@2x.png -------------------------------------------------------------------------------- /img/personal-yb@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-yb@3x.png -------------------------------------------------------------------------------- /img/timeline-REST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-REST.png -------------------------------------------------------------------------------- /img/icon-category-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-0.png -------------------------------------------------------------------------------- /img/icon-category-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-10.png -------------------------------------------------------------------------------- /img/icon-category-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-20.png -------------------------------------------------------------------------------- /img/icon-category-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-29.png -------------------------------------------------------------------------------- /img/icon-category-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-30.png -------------------------------------------------------------------------------- /img/icon-category-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-8.png -------------------------------------------------------------------------------- /img/personal-gjj@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-gjj@2x.png -------------------------------------------------------------------------------- /img/personal-gjj@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-gjj@3x.png -------------------------------------------------------------------------------- /img/personal-help@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-help@2x.png -------------------------------------------------------------------------------- /img/personal-help@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-help@3x.png -------------------------------------------------------------------------------- /img/tabbar-icon-me@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-me@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-me@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-me@3x.png -------------------------------------------------------------------------------- /img/timeline-FUNERAL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-FUNERAL.png -------------------------------------------------------------------------------- /img/timeline-REMARK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-REMARK.png -------------------------------------------------------------------------------- /img/timeline-SIGNED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SIGNED.png -------------------------------------------------------------------------------- /img/timeline-SIGN_IN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SIGN_IN.png -------------------------------------------------------------------------------- /img/timeline-SIGN_OUT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SIGN_OUT.png -------------------------------------------------------------------------------- /img/icon-category-1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-1@2x.png -------------------------------------------------------------------------------- /img/icon-category-1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-1@3x.png -------------------------------------------------------------------------------- /img/icon-category-2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-2@2x.png -------------------------------------------------------------------------------- /img/icon-category-2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-2@3x.png -------------------------------------------------------------------------------- /img/icon-category-3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-3@2x.png -------------------------------------------------------------------------------- /img/icon-category-3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-3@3x.png -------------------------------------------------------------------------------- /img/icon-category-4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-4@2x.png -------------------------------------------------------------------------------- /img/icon-category-4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-4@3x.png -------------------------------------------------------------------------------- /img/icon-category-5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-5@2x.png -------------------------------------------------------------------------------- /img/icon-category-5@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-5@3x.png -------------------------------------------------------------------------------- /img/icon-category-6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-6@2x.png -------------------------------------------------------------------------------- /img/icon-category-6@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-6@3x.png -------------------------------------------------------------------------------- /img/icon-category-7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-7@2x.png -------------------------------------------------------------------------------- /img/icon-category-7@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-7@3x.png -------------------------------------------------------------------------------- /img/icon-category-srhk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-srhk.png -------------------------------------------------------------------------------- /img/icon-category-znfk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-znfk.png -------------------------------------------------------------------------------- /img/icon-category-znzf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/icon-category-znzf.png -------------------------------------------------------------------------------- /img/personal-setting@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-setting@2x.png -------------------------------------------------------------------------------- /img/personal-setting@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-setting@3x.png -------------------------------------------------------------------------------- /img/tabbar-icon-home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-home@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-home@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-home@3x.png -------------------------------------------------------------------------------- /img/timeline-SICK_LEAVE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SICK_LEAVE.png -------------------------------------------------------------------------------- /img/personal-feedback@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-feedback@2x.png -------------------------------------------------------------------------------- /img/personal-feedback@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/personal-feedback@3x.png -------------------------------------------------------------------------------- /img/tabbar-icon-banbu@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-banbu@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-banbu@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-banbu@3x.png -------------------------------------------------------------------------------- /img/timeline-ANNUAL_LEAVE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-ANNUAL_LEAVE.png -------------------------------------------------------------------------------- /img/timeline-CASUAL_LEAVE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-CASUAL_LEAVE.png -------------------------------------------------------------------------------- /img/timeline-REST-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-REST-active.png -------------------------------------------------------------------------------- /img/tabbar-icon-me-active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-me-active@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-me-active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-me-active@3x.png -------------------------------------------------------------------------------- /img/timeline-FUNERAL-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-FUNERAL-active.png -------------------------------------------------------------------------------- /img/timeline-MARRIAGE_LEAVE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-MARRIAGE_LEAVE.png -------------------------------------------------------------------------------- /img/timeline-MATERNITY_LEAVE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-MATERNITY_LEAVE.png -------------------------------------------------------------------------------- /img/timeline-OFFIC_BUSI_AWAY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-OFFIC_BUSI_AWAY.png -------------------------------------------------------------------------------- /img/timeline-SIGN_IN-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SIGN_IN-active.png -------------------------------------------------------------------------------- /img/timeline-SIGN_OUT-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SIGN_OUT-active.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AwesomeProject 3 | 4 | -------------------------------------------------------------------------------- /client/env/env.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // API_HOST: 'http://192.168.1.13:8080', 3 | API_HOST: 'http://test.yowits.net', 4 | } -------------------------------------------------------------------------------- /img/tabbar-icon-banbu-active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-banbu-active@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-banbu-active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-banbu-active@3x.png -------------------------------------------------------------------------------- /img/tabbar-icon-home-active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-home-active@2x.png -------------------------------------------------------------------------------- /img/tabbar-icon-home-active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/tabbar-icon-home-active@3x.png -------------------------------------------------------------------------------- /img/timeline-SICK_LEAVE-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-SICK_LEAVE-active.png -------------------------------------------------------------------------------- /img/timeline-ANNUAL_LEAVE-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-ANNUAL_LEAVE-active.png -------------------------------------------------------------------------------- /img/timeline-CASUAL_LEAVE-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-CASUAL_LEAVE-active.png -------------------------------------------------------------------------------- /img/timeline-MARRIAGE_LEAVE-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-MARRIAGE_LEAVE-active.png -------------------------------------------------------------------------------- /img/timeline-MATERNITY_LEAVE-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-MATERNITY_LEAVE-active.png -------------------------------------------------------------------------------- /img/timeline-OFFIC_BUSI_AWAY-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/img/timeline-OFFIC_BUSI_AWAY-active.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "react-native-stage-0" ], 3 | "plugins": [["import", { "libraryName": "antd-mobile", "libraryDirectory": "lib" }]] 4 | } -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /client/styles/var.scss: -------------------------------------------------------------------------------- 1 | $primary: #1ab394; 2 | $waring: #ffa900; 3 | $danger: #ff4141; 4 | $black: #222222; 5 | $gray: #929292; 6 | 7 | $fenge: #e0e0e0; -------------------------------------------------------------------------------- /client/components/native-echarts/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Container } from './Container'; 2 | export { default as Echarts } from './Echarts'; 3 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yjj5855/react-native-demo/master/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 常用命令 2 | 3 | watchman watch-del-all 4 | 5 | rm -rf node_modules && npm install 6 | 7 | rm -fr $TMPDIR/react-* 8 | npm start -- --reset-cache 9 | 10 | 11 | # 安装 -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /client/components/native-echarts/style.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | 3 | export default StyleSheet.create({ 4 | container: { 5 | flexDirection: 'row', 6 | }, 7 | }) 8 | -------------------------------------------------------------------------------- /client/env/env.test.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // API_HOST: 'http://192.168.1.13:8080', 3 | API_HOST: 'http://106.14.42.162:55004', 4 | // API_HOST: 'http://ddapi.yowits.net:55004' 5 | } -------------------------------------------------------------------------------- /client/actions/actionCreator.js: -------------------------------------------------------------------------------- 1 | import * as app from './app' 2 | import * as boss from './boss' 3 | import * as user from './user' 4 | 5 | export default { 6 | ...app, 7 | ...boss, 8 | ...user 9 | } -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /client/components/native-echarts/util/toString.js: -------------------------------------------------------------------------------- 1 | export default function toString(obj) { 2 | return JSON.stringify(obj, function(key, val) { 3 | if (typeof val === 'function') { 4 | return `~--demo--~${val}~--demo--~`; 5 | } 6 | return val; 7 | }).replace('\"~--demo--~', '').replace('~--demo--~\"', '').replace(/\\n/g, ''); 8 | } 9 | -------------------------------------------------------------------------------- /__tests__/index.ios.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.ios.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /client/page/home/BossHome.scss: -------------------------------------------------------------------------------- 1 | .grid-item{ 2 | height: 1rem; 3 | padding-left: .3rem; 4 | 5 | img{ 6 | width: .6rem; 7 | height: .6rem; 8 | } 9 | 10 | .grid-item-right{ 11 | padding-left: .1rem; 12 | } 13 | .text_gray{ 14 | font-size: 14px; 15 | } 16 | .text_small{ 17 | font-size: 12px; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /client/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux-immutable' 2 | 3 | 4 | import routes from './route' 5 | import app from './app' 6 | import boss from './boss' 7 | import user from './user' 8 | 9 | const rootReducer = combineReducers({ 10 | app, 11 | boss, 12 | user, 13 | routes 14 | }); 15 | 16 | export default rootReducer; -------------------------------------------------------------------------------- /__tests__/index.android.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.android.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /client/data/app.js: -------------------------------------------------------------------------------- 1 | const app = { 2 | isLoading: false, //路由加载标志位 3 | selectedTab: 'home', //主页tab 4 | ddConfig: null, 5 | 6 | user: { 7 | name: '', 8 | dept: '', 9 | avatar: '' 10 | }, 11 | boss: null, 12 | 13 | showCompanyManagement: false, //是否显示公司管理 14 | showWage: false, //是否显示工资模块 15 | 16 | } 17 | export default app; -------------------------------------------------------------------------------- /client/components/native-echarts/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { WebView, View } from 'react-native'; 3 | import { Container, Echarts } from './components' 4 | 5 | export default class App extends Component { 6 | render() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/components/native-echarts/components/Container/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View } from 'react-native'; 3 | import styles from '../../style'; 4 | 5 | export default class App extends Component { 6 | render() { 7 | return ( 8 | 9 | {this.props.children} 10 | 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/common/storage.js: -------------------------------------------------------------------------------- 1 | import { AsyncStorage } from 'react-native' 2 | 3 | export default { 4 | getItem : async function (key){ 5 | let value = await AsyncStorageGetItem(key) 6 | return { '1': 0, '2': 0, '3': 0 } 7 | } 8 | } 9 | 10 | async function AsyncStorageGetItem(key) { 11 | return new Promise((resolve,reject)=>{ 12 | AsyncStorage.getItem(key, function (value) { 13 | resolve(value) 14 | }) 15 | }) 16 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/awesomeproject/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.awesomeproject; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "AwesomeProject"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ios/AwesomeProject/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /client/connectRedux.js: -------------------------------------------------------------------------------- 1 | import { bindActionCreators } from 'redux' 2 | import { connect } from 'react-redux' 3 | import actionCreators from './actions/actionCreator' 4 | 5 | function mapStateToProps(state) { 6 | return { 7 | $$app: state.get('app'), 8 | $$boss: state.get('boss'), 9 | $$user: state.get('user'), 10 | } 11 | } 12 | 13 | function mapDispachToProps(dispatch) { 14 | return bindActionCreators(actionCreators, dispatch) 15 | } 16 | 17 | export default function (Component) { 18 | return connect(mapStateToProps, mapDispachToProps)(Component); 19 | }; -------------------------------------------------------------------------------- /client/reducers/route.js: -------------------------------------------------------------------------------- 1 | import { ActionConst } from 'react-native-router-flux' 2 | import Immutable from 'immutable' 3 | 4 | const initialState = Immutable.fromJS({ 5 | scene: {}, 6 | }); 7 | 8 | export default function reducer(state = initialState, action = {}) { 9 | switch (action.type) { 10 | // focus action is dispatched when a new screen comes into focus 11 | case ActionConst.FOCUS: 12 | return state.setIn(['scene'], Immutable.fromJS(action.scene) ); 13 | 14 | // ...other actions 15 | 16 | default: 17 | return state; 18 | } 19 | } -------------------------------------------------------------------------------- /client/common/axiosMiddlewareOptions.js: -------------------------------------------------------------------------------- 1 | 2 | export const returnRejectedPromiseOnError = true; 3 | 4 | export const onComplete = ( { action, next, getState, dispatch }, actionOptions) => { 5 | const previousAction = action.meta.previousAction; 6 | const nextAction = { 7 | type: getActionTypes(previousAction, actionOptions)[0]+'_COMPLETE', 8 | meta: { 9 | previousAction: previousAction 10 | } 11 | }; 12 | next(nextAction); 13 | return nextAction; 14 | }; 15 | 16 | function getActionTypes(actionOptions) { 17 | return actionOptions[0]+'_COMPLETE' 18 | } -------------------------------------------------------------------------------- /ios/AwesomeProject/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/components/native-echarts/components/Echarts/renderChart.js: -------------------------------------------------------------------------------- 1 | import echarts from './echarts.min'; 2 | import { Map } from 'immutable' 3 | import toString from '../../util/toString'; 4 | 5 | export default function renderChart(props) { 6 | const height = props.height || 400; 7 | let option = {}; 8 | if(Map.isMap(props.option)){ 9 | option = props.option.toJS(); 10 | }else{ 11 | option = props.option; 12 | } 13 | return ` 14 | document.getElementById('main').style.height = "${height}px"; 15 | var myChart = echarts.init(document.getElementById('main')); 16 | myChart.setOption(${toString(option)}); 17 | ` 18 | } 19 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.3.1' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/AwesomeProject/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /client/components/TouchView.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | View, 4 | TouchableHighlight, 5 | StyleSheet 6 | } from 'react-native' 7 | 8 | 9 | class TouchView extends Component{ 10 | 11 | constructor(props) { 12 | super(props); 13 | }; 14 | 15 | static get defaultProps() { 16 | return { 17 | onPress: ()=>{} 18 | } 19 | } 20 | render(){ 21 | 22 | return ( 23 | 24 | 25 | {this.props.children} 26 | 27 | 28 | ) 29 | } 30 | 31 | } 32 | 33 | export default TouchView -------------------------------------------------------------------------------- /ios/AwesomeProjectTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/AwesomeProject-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/components/native-echarts/components/Echarts/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { WebView, View, StyleSheet } from 'react-native'; 3 | import renderChart from './renderChart'; 4 | import echarts from './echarts.min'; 5 | 6 | export default class App extends Component { 7 | componentWillReceiveProps(nextProps) { 8 | if(nextProps.option !== this.props.option) { 9 | this.refs.chart.reload(); 10 | } 11 | } 12 | 13 | render() { 14 | return ( 15 | 16 | 25 | 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /client/styles/styles.js: -------------------------------------------------------------------------------- 1 | import { 2 | Text, 3 | View, 4 | StyleSheet, 5 | Platform 6 | } from 'react-native'; 7 | 8 | export const styles = StyleSheet.create({ 9 | navigationBarStyle: { 10 | backgroundColor: '#fff', 11 | }, 12 | navbar: { 13 | ...Platform.select({ 14 | ios: { 15 | marginTop: 20, 16 | height: 44, 17 | }, 18 | android: { 19 | marginTop: 0, 20 | height: 54, 21 | }, 22 | }), 23 | }, 24 | navbarTitle: { 25 | textAlign: 'center', 26 | fontSize: 17, 27 | color: '#333', 28 | fontWeight: '900' 29 | }, 30 | content: { 31 | ...Platform.select({ 32 | ios: { 33 | marginTop: 64, 34 | }, 35 | android: { 36 | marginTop: 54, 37 | }, 38 | }), 39 | flex: 1, 40 | backgroundColor: '#f8f8f8', 41 | }, 42 | scrollView: { 43 | flex: 1, 44 | backgroundColor: 'white', 45 | }, 46 | textStyle: { 47 | color: 'black', 48 | }, 49 | }); -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /client/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, compose, applyMiddleware } from 'redux' 2 | 3 | import promiseMiddleware from 'redux-promise'; 4 | 5 | import rootReducer from './reducers/index' 6 | 7 | import Immutable from 'immutable' 8 | import app from './data/app' 9 | import boss from './data/boss' 10 | import user from './data/user' 11 | 12 | import axios from 'axios'; 13 | import './common/axiosConfig' 14 | import axiosMiddleware from 'redux-axios-middleware'; 15 | import * as axiosMiddlewareOptions from './common/axiosMiddlewareOptions' 16 | 17 | 18 | //create an object on the default data 19 | const defaultState = Immutable.fromJS({ 20 | app, 21 | boss, 22 | user, 23 | }); 24 | 25 | const enhancers = compose( 26 | applyMiddleware( 27 | promiseMiddleware, 28 | axiosMiddleware(axios, {...axiosMiddlewareOptions}), //axios 中间件 29 | ) 30 | ); 31 | export const store = createStore( 32 | rootReducer, 33 | defaultState, 34 | enhancers 35 | ); -------------------------------------------------------------------------------- /client/page/Main.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | Text, 4 | View, 5 | StyleSheet, 6 | Platform 7 | } from 'react-native'; 8 | import connectRedux from '../connectRedux' 9 | import {styles} from '../styles/styles' 10 | 11 | class Main extends Component { 12 | constructor(props) { 13 | super(props); 14 | }; 15 | 16 | componentWillMount(){ 17 | 18 | let userInfo = { type: 1 } 19 | if(userInfo){ 20 | this.props.updateUserInfo(userInfo) 21 | } 22 | 23 | } 24 | 25 | render(){ 26 | const { routes } = this.context; 27 | 28 | const app = this.props.$$app.toJS(); 29 | 30 | return ( 31 | 32 | hello world!!! 33 | {app.selectedTab} 34 | 35 | ) 36 | } 37 | } 38 | 39 | export default connectRedux(Main); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AwesomeProject", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest" 8 | }, 9 | "dependencies": { 10 | "antd-mobile": "^0.9.14", 11 | "axios": "^0.15.3", 12 | "babel-plugin-import": "^1.1.0", 13 | "babel-preset-es2015": "^6.22.0", 14 | "promise.prototype.finally": "^2.0.1", 15 | "react": "~15.4.0", 16 | "react-native": "0.41.2", 17 | "react-native-router-flux": "^3.37.0", 18 | "react-redux": "^5.0.2", 19 | "redux": "^3.6.0", 20 | "redux-axios-middleware": "^3.0.0", 21 | "redux-immutable": "^3.0.11" 22 | }, 23 | "devDependencies": { 24 | "babel-jest": "18.0.0", 25 | "babel-preset-react-native": "1.9.1", 26 | "babel-preset-react-native-stage-0": "^1.0.1", 27 | "jest": "18.1.0", 28 | "react-test-renderer": "~15.4.0", 29 | "redux-promise": "^0.5.3" 30 | }, 31 | "jest": { 32 | "preset": "react-native" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | android/app/libs 43 | *.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/Preview.html 54 | fastlane/screenshots 55 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | AppRegistry, 4 | StyleSheet, 5 | View, 6 | StatusBar, 7 | Platform, 8 | BackAndroid, 9 | DeviceEventEmitter, 10 | } from 'react-native'; 11 | import { Router, Actions, Scene } from 'react-native-router-flux'; 12 | import { connect, Provider } from 'react-redux'; 13 | import { store } from './client/store' 14 | import scenes from './client/userScenes' 15 | import storage from './client/common/storage' 16 | 17 | const RouterWithRedux = connect()(Router); 18 | 19 | export default class RootRouter extends Component { 20 | constructor(props) { 21 | super(props); 22 | }; 23 | render() { 24 | return ( 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | AppRegistry.registerComponent('AwesomeProject', () => { 36 | let data = storage.getItem('hhh') 37 | console.log(data) 38 | return RootRouter 39 | }); -------------------------------------------------------------------------------- /client/styles/router.css: -------------------------------------------------------------------------------- 1 | :global(.transitionWrapper-in-enter) { 2 | transform: translateX(100%); 3 | transition: all 500ms ; 4 | } 5 | 6 | :global(.transitionWrapper-in-enter.transitionWrapper-in-enter-active) { 7 | transform: translateX(0); 8 | z-index: 1; 9 | } 10 | 11 | :global(.transitionWrapper-in-leave) { 12 | transform: translateX(0); 13 | opacity: 1; 14 | transition: all 500ms ; 15 | } 16 | 17 | :global(.transitionWrapper-in-leave.transitionWrapper-in-leave-active) { 18 | transform: translateX(-10%); 19 | opacity: 0; 20 | } 21 | 22 | .transitionWrapper-in { 23 | position: relative; 24 | } 25 | 26 | :global(.transitionWrapper-out-enter) { 27 | transform: translateX(-10%); 28 | transition: all 500ms ; 29 | } 30 | 31 | :global(.transitionWrapper-out-enter.transitionWrapper-out-enter-active) { 32 | transform: translateX(0) 33 | } 34 | 35 | :global(.transitionWrapper-out-leave) { 36 | transform: translateX(0); 37 | transition: all 500ms ; 38 | } 39 | 40 | :global(.transitionWrapper-out-leave.transitionWrapper-out-leave-active) { 41 | transform: translateX(100%) 42 | } 43 | 44 | .transitionWrapper-out { 45 | position: relative; 46 | } -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/awesomeproject/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.awesomeproject; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactInstanceManager; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.react.shell.MainReactPackage; 11 | import com.facebook.soloader.SoLoader; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | return Arrays.asList( 27 | new MainReactPackage() 28 | ); 29 | } 30 | }; 31 | 32 | @Override 33 | public ReactNativeHost getReactNativeHost() { 34 | return mReactNativeHost; 35 | } 36 | 37 | @Override 38 | public void onCreate() { 39 | super.onCreate(); 40 | SoLoader.init(this, /* native exopackage */ false); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /client/components/ImageChoose.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ImagePicker } from 'antd-mobile' 3 | import callJsApi from '../common/ddPlugin' 4 | 5 | const ImageChoose = React.createClass({ 6 | 7 | getDefaultProps : function () { 8 | return { 9 | list: [], 10 | url_key: '', 11 | count: 1, 12 | }; 13 | }, 14 | onImageClick(index){ 15 | callJsApi('biz.util.previewImage',{ 16 | urls: this.props.list.map((item)=> this.props.url_key == '' ? item : item[this.props.url_key] ), 17 | current: this.props.url_key == '' ? this.props.list[index] : this.props.list[index][this.props.url_key], 18 | }) 19 | }, 20 | 21 | render(){ 22 | let files = this.props.list.map((item, index)=>{ 23 | return { 24 | url: this.props.url_key == '' ? item : item[this.props.url_key] 25 | } 26 | }); 27 | 28 | return 35 | } 36 | }) 37 | export default ImageChoose -------------------------------------------------------------------------------- /client/userScenes.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Router, Actions, Scene } from 'react-native-router-flux'; 3 | import { styles } from './styles/styles' 4 | 5 | import Main from './page/Main' 6 | import Home from './page/home' 7 | 8 | const scenes = Actions.create( 9 | 10 | 11 | 12 | 13 | ); 14 | 15 | export default scenes 16 | 17 | // 18 | // var tabSceneMenu = { 19 | // backTitle: '返回', 20 | // onBack: ()=>{ console.log('onBack') }, 21 | // backButtonImage: require('../img/ic_busi.png'), 22 | // backButtonTextStyle: { color: '#000'}, 23 | // renderTitle: this.renderTitle, 24 | // // onLeft :()=>{ console.log('onLeft') }, 25 | // // leftButtonImage:leftImage, 26 | // // getLeftTitle:this.getLeftTitle, 27 | // // getRightTitle:this.getRightTitle, 28 | // // onRight :()=>{ console.log('onRight') } 29 | // } 30 | 31 | function getSceneProps(component) { 32 | return { 33 | // getTitle: component.getTitle, 34 | renderTitle: component.renderTitle, 35 | } 36 | } -------------------------------------------------------------------------------- /client/reducers/app.js: -------------------------------------------------------------------------------- 1 | import { Map, List } from 'immutable' 2 | 3 | function app(state = Map({}), aciton) { 4 | 5 | switch (aciton.type){ 6 | 7 | 8 | case 'UPDATE_SELECTEDTAB': 9 | return state.set('selectedTab', aciton.tabName) 10 | case 'DDCONFIG_SUCCESS': 11 | return state.set('ddConfig', aciton.ddConfig) 12 | case 'DDCONFIG_ERROR': 13 | return state.set('ddConfig', false) 14 | 15 | case 'UPDATE_USERINFO': 16 | let userType = ''; 17 | if(aciton.userInfo.type == 0){ 18 | userType = 'boss' 19 | state = state.set('showWage', true) 20 | state = state.set('showCompanyManagement', true) 21 | }else{ 22 | userType = 'user' 23 | if(aciton.userInfo.type == 2){ 24 | state = state.set('showWage', true) 25 | state = state.set('showCompanyManagement', true) 26 | }else if(aciton.userInfo.type == 1){ 27 | state = state.set('showCompanyManagement', true) 28 | } 29 | } 30 | return state.set(userType, aciton.userInfo) 31 | default: 32 | return state; 33 | } 34 | 35 | 36 | } 37 | 38 | 39 | export default app; -------------------------------------------------------------------------------- /client/common/bbPlugin.js: -------------------------------------------------------------------------------- 1 | 2 | // 简单封装本地存储 3 | const localObj = { 4 | getItem: function (key) { 5 | if (typeof localStorage === 'object') { 6 | try { 7 | return JSON.parse(localStorage.getItem(key)); 8 | } catch (e) { 9 | alert('本站无痕浏览模式,请关闭后再试!'); 10 | } 11 | } 12 | }, 13 | setItem: function (key, value) { 14 | if (typeof localStorage === 'object') { 15 | try { 16 | return localStorage.setItem(key, JSON.stringify(value)); 17 | } catch (e) { 18 | alert('请关闭[无痕浏览]模式后再试!'); 19 | } 20 | } 21 | }, 22 | removeItem: function (key) { 23 | if (typeof localStorage === 'object') { 24 | try { 25 | return localStorage.removeItem(key); 26 | } catch (e) { 27 | alert('请关闭[无痕浏览]模式后再试!'); 28 | } 29 | } 30 | }, 31 | getUseSize: function () { 32 | if (typeof localStorage === 'object') { 33 | try { 34 | return JSON.stringify(localStorage).length; 35 | } catch (e) { 36 | alert('请关闭[无痕浏览]模式后再试!'); 37 | } 38 | } 39 | } 40 | }; 41 | 42 | export const _localStorage = localObj; 43 | 44 | 45 | export function getParamByName(name) { 46 | 47 | return null; 48 | } 49 | 50 | export function getOrgUrl() { 51 | return '/org/fwefjwejgweg' || ''; 52 | } -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | module.system=haste 26 | 27 | experimental.strict_type_args=true 28 | 29 | munge_underscores=true 30 | 31 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 32 | 33 | suppress_type=$FlowIssue 34 | suppress_type=$FlowFixMe 35 | suppress_type=$FixMe 36 | 37 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-7]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 38 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-7]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 40 | 41 | unsafe.enable_getters_and_setters=true 42 | 43 | [version] 44 | ^0.37.0 45 | -------------------------------------------------------------------------------- /client/common/ddAvatar.js: -------------------------------------------------------------------------------- 1 | function _isEnglish(name) { 2 | return name.match(/^([a-zA-Z]|\s|,|\.)+$/) !== null; 3 | } 4 | const colors = ["#78c06e","#f65e8d","#f6bf26","#f65e5e","#5e97f6","#9a89b9","#a1887f","#ff943e","#5ec9f6","#3bc2b5","#5c6bc0","#bd84cd","#6bb5ce","#c5cb63","#ff8e6b","#78919d"]; 5 | const colorsLength = colors.length; 6 | 7 | 8 | const AvatarService = { 9 | getAvatar : function(nick,name){ 10 | 11 | var name = this._getShowName(nick || name); 12 | var color = this._getColor(name); 13 | 14 | return { 15 | name : name, 16 | color : color 17 | }; 18 | }, 19 | _getShowName : function(name){ 20 | var showName = name || "", 21 | arr = []; 22 | 23 | if (_isEnglish(showName)) { 24 | //将“,.”转为空格,如果导致出现连续空格(如原字符为", ",则转换后会为" "), 25 | //则将连续空格转换为单个空格 26 | showName = showName.replace(/,|\./g, " ").replace(/\s+/g, " "); 27 | 28 | arr = showName.split(" "); 29 | 30 | if (arr.length === 1) { 31 | return showName.slice(0, 2); 32 | } 33 | 34 | return arr[0].slice(0, 1) + arr[1].slice(0, 1); 35 | } 36 | return showName.replace(/,|\.|\s+/g, "").slice(-2); 37 | }, 38 | _getColor : function(name){ 39 | var total = 0; 40 | for (let char in name) { 41 | total += name.charCodeAt(char); 42 | } 43 | return colors[total % colorsLength]; 44 | } 45 | }; 46 | 47 | export default AvatarService; -------------------------------------------------------------------------------- /ios/AwesomeProject/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"AwesomeProject" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /client/actions/app.js: -------------------------------------------------------------------------------- 1 | import { getOrgUrl, getParamByName, _localStorage } from '../common/bbPlugin' 2 | export function updateSelectedTab(tabName){ 3 | return{ 4 | type: 'UPDATE_SELECTEDTAB', 5 | tabName 6 | } 7 | } 8 | 9 | export function ddConfigSuccess(ddConfig) { 10 | return{ 11 | type: 'DDCONFIG_SUCCESS', 12 | ddConfig 13 | } 14 | } 15 | 16 | export function ddConfigError() { 17 | return{ 18 | type: 'DDCONFIG_ERROR', 19 | } 20 | } 21 | 22 | export function updateCode(code) { 23 | return{ 24 | type: 'DDCONFIG_ERROR', 25 | code 26 | } 27 | } 28 | 29 | export function getUserInfo() { 30 | const infoJson = _localStorage.getItem('infoJson') || {}; 31 | const uuid = infoJson.empId || 0; 32 | return { 33 | type: 'GET_USERINFO', 34 | payload: { 35 | request:{ 36 | url: getOrgUrl() +'/empl/'+uuid 37 | } 38 | } 39 | } 40 | } 41 | 42 | export function updateUserInfo(userInfo) { 43 | return { 44 | type: 'UPDATE_USERINFO', 45 | userInfo 46 | } 47 | } 48 | 49 | export function signOutApp() { 50 | const infoJson = _localStorage.getItem('infoJson') || {}; 51 | return { 52 | type: 'SIGN_OUT_APP', 53 | payload: { 54 | request:{ 55 | method: 'delete', 56 | url: getOrgUrl() +'/loginOut', 57 | data: { 58 | corpId: getParamByName('corpid'), 59 | userId: infoJson.dingUserId, 60 | } 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /client/components/RejectBox.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Flex, TextareaItem, Button } from 'antd-mobile' 3 | 4 | 5 | const RejectBox = React.createClass({ 6 | 7 | getInitialState() { 8 | return { 9 | type: this.props.type || '', 10 | reasons: { 11 | '': [], 12 | businessOut: ['暂缓','工作无法排期','没有必要'], 13 | leave: ['时间过长','影响工作','不符公司规定'], 14 | sign: ['理由不充分','时间异常'] 15 | }, 16 | reason: '', 17 | } 18 | }, 19 | 20 | onReasonChange(value){ 21 | this.setState({reason: value}, ()=>{ 22 | this.props.onChange && this.props.onChange(this.state.reason) 23 | }) 24 | }, 25 | 26 | render(){ 27 | 28 | return ( 29 |
30 | 31 | {this.state.reasons[this.state.type].map((item, index)=> ( 32 | 36 | 37 | 38 | ))} 39 | 40 | 46 |
47 | ) 48 | } 49 | 50 | }) 51 | 52 | export default RejectBox -------------------------------------------------------------------------------- /client/common/axiosConfig.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | // import { _localStorage } from './bbPlugin' 3 | // import { logException } from './ravenConfig' 4 | import env from '../env/env' 5 | 6 | require('promise.prototype.finally').shim() //给axios添加finally方法 7 | 8 | const config = { 9 | 10 | // 请求方法同上 11 | method: 'get', // default 12 | 13 | // 基础url前缀 14 | // baseURL: 'http://116.236.230.131:55002', 15 | baseURL: env.API_HOST + '/rest/ding', 16 | 17 | //设置超时时间 18 | timeout: 20000, 19 | 20 | } 21 | 22 | //全局配置axios 23 | for(let key in config){ 24 | axios.defaults[key] = config[key]; 25 | } 26 | axios.interceptors.request.use(function (request) { 27 | let infoJson = {} 28 | let token = infoJson.token; 29 | if(token && (!request.params || request.params.send_token !== false)){ 30 | if(request.params){ 31 | request.params.dtoken = token 32 | }else{ 33 | request.params = { 34 | dtoken : token 35 | } 36 | } 37 | }else{ 38 | if(request.params){ 39 | delete request.params.send_token; 40 | } 41 | } 42 | return request 43 | }) 44 | //response过滤 45 | axios.interceptors.response.use(function (response) { 46 | // 这里提前处理返回的数据 47 | // if(typeof response == 'object'){ 48 | // if(response.status == 200){ 49 | // return response.data; 50 | // }else{ 51 | // logException(new Error(response.status+' 错误'), response) 52 | // } 53 | // }else{ 54 | // logException(new Error('接口返回不是一个对象'), response) 55 | // } 56 | return response; 57 | }, function (error) { 58 | 59 | return Promise.reject(error); 60 | }); 61 | 62 | export default config; -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.awesomeproject', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.awesomeproject', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /ios/AwesomeProject-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ios/AwesomeProject/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | AwesomeProject 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /client/components/Avatar.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | Text, 4 | View, 5 | StyleSheet, 6 | Platform, 7 | Image, 8 | } from 'react-native'; 9 | import { Badge, Flex } from 'antd-mobile' 10 | import AvatarService from '../common/ddAvatar' 11 | 12 | const sizeStyle = { 13 | md: 40, 14 | lg: 55, 15 | xlg: 100, 16 | } 17 | const fontSize = { 18 | md: 14, 19 | lg: 20, 20 | xlg: 30, 21 | } 22 | 23 | class Avatar extends Component{ 24 | 25 | constructor(props) { 26 | super(props); 27 | }; 28 | 29 | static get defaultProps() { 30 | return { 31 | src: false, 32 | nick: '', 33 | name: '', 34 | size: 'md' 35 | } 36 | } 37 | 38 | getUserAvatar = function(){ 39 | const user = AvatarService.getAvatar(this.props.nick, this.props.name); 40 | return user 41 | } 42 | 43 | render(){ 44 | let avatar = ; 45 | if(this.props.size == 'lg'){ 46 | 47 | }else{ 48 | 49 | } 50 | if(!this.props.src || this.props.src == ''){ 51 | const user = this.getUserAvatar(); 52 | avatar = ( 53 | 54 | {user.name || '12'} 55 | 56 | ) 57 | }else{ 58 | avatar = () 59 | } 60 | 61 | return ( 62 | {avatar} 63 | ) 64 | } 65 | 66 | } 67 | 68 | export default Avatar -------------------------------------------------------------------------------- /ios/AwesomeProjectTests/AwesomeProjectTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface AwesomeProjectTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation AwesomeProjectTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /client/components/MonthChoose.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react' 2 | import { Badge, Flex, Icon } from 'antd-mobile' 3 | 4 | 5 | const Component = React.createClass({ 6 | 7 | getInitialState() { 8 | return { 9 | canChooseFuture: this.props.chooseFuture || false, 10 | currentYear: this.props.year || new Date().getFullYear(), 11 | currentMonth: this.props.mouth || (new Date().getMonth()+1), 12 | } 13 | }, 14 | // shouldComponentUpdate(){ 15 | // return 16 | // }, 17 | preMonth(){ 18 | let state = {}; 19 | 20 | if(this.state.currentMonth <= 1){ 21 | state = { 22 | currentYear: this.state.currentYear - 1, 23 | currentMonth: 12, 24 | } 25 | }else{ 26 | state = { 27 | currentMonth: this.state.currentMonth - 1, 28 | } 29 | } 30 | this.setState(state,()=>{ 31 | this.props.onClickPreMonth && this.props.onClickPreMonth(this.state.currentYear,this.state.currentMonth) 32 | }) 33 | }, 34 | nextMonth(){ 35 | if(!this.state.canChooseFuture && 36 | this.state.currentYear == new Date().getFullYear() && 37 | this.state.currentMonth == (new Date().getMonth()+1)){ 38 | return 39 | } 40 | let state = {}; 41 | 42 | if(this.state.currentMonth >= 12){ 43 | state = { 44 | currentYear: this.state.currentYear + 1, 45 | currentMonth: 1, 46 | } 47 | }else{ 48 | state = { 49 | currentMonth: this.state.currentMonth + 1, 50 | } 51 | } 52 | this.setState(state,()=>{ 53 | this.props.onClickNextMonth && this.props.onClickNextMonth(this.state.currentYear,this.state.currentMonth) 54 | }) 55 | }, 56 | render(){ 57 | 58 | return ( 59 | 60 | 61 | 62 | 63 | 64 | {this.state.currentYear}年{this.state.currentMonth}月 65 | 66 | 67 | 68 | 69 | 70 | ) 71 | } 72 | }) 73 | 74 | export default Component 75 | 76 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # okhttp 54 | 55 | -keepattributes Signature 56 | -keepattributes *Annotation* 57 | -keep class okhttp3.** { *; } 58 | -keep interface okhttp3.** { *; } 59 | -dontwarn okhttp3.** 60 | 61 | # okio 62 | 63 | -keep class sun.misc.Unsafe { *; } 64 | -dontwarn java.nio.file.* 65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 66 | -dontwarn okio.** 67 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /ios/AwesomeProject/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /client/data/user.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment' 2 | 3 | const listData = { 4 | pageParam: { 5 | pageIndex: 1, 6 | pageLength: 20, 7 | 8 | }, 9 | pageData: { 10 | list: [], 11 | hasNextPage: true 12 | }, 13 | loading: false, 14 | } 15 | 16 | const user = { 17 | //yjj 18 | //公出详情 19 | businessOutDetail: {}, 20 | //审批中心 21 | approvalListData: { 22 | "tabSelected": '2', 23 | "summary": { 24 | "checkInOutCount": 0, 25 | "workOutCount": 0, 26 | "leaveCount": 0 27 | }, 28 | timestamp: { 29 | "1": 0, 30 | "2": 0, 31 | "3": 0 32 | }, 33 | "1": { 34 | pageData: { 35 | list: [], 36 | total: 0, 37 | hasNextPage: true 38 | }, 39 | pageParam: { 40 | pageIndex: 1, 41 | pageLength: 20, 42 | type: 1, 43 | }, 44 | loading: false, 45 | }, 46 | "2": { 47 | pageData: { 48 | list: [], 49 | total: 0, 50 | hasNextPage: true 51 | }, 52 | pageParam: { 53 | pageIndex: 1, 54 | pageLength: 20, 55 | type: 2, 56 | }, 57 | loading: false, 58 | }, 59 | "3": { 60 | pageData: { 61 | list: [], 62 | total: 0, 63 | hasNextPage: true 64 | }, 65 | pageParam: { 66 | pageIndex: 1, 67 | pageLength: 20, 68 | type: 3, 69 | }, 70 | loading: false, 71 | } 72 | }, 73 | 74 | //考勤中心 75 | attendanceData:{ 76 | //选择的 77 | selected: { 78 | dept:{ 79 | id: '', 80 | name: '' 81 | }, 82 | date: moment().format('YYYY-MM-DD') 83 | }, 84 | data: { 85 | "listOrg": [ 86 | 87 | ], 88 | "recordSummary": { 89 | "checkInOutCount": 0, 90 | "workOutCount": 0, 91 | "leaveCount": 0, 92 | "emplCount": 0, 93 | "checkInOutInfo": "", 94 | "leaveInfo": "", 95 | "workOutInfo": "" 96 | }, 97 | "listLeave": [], 98 | "listBusiness": [], 99 | "listSignRecord": [] 100 | } 101 | }, 102 | 103 | //公司默认上下班时间 104 | defaultTime: { 105 | signIn: '', 106 | signOut: '' 107 | }, 108 | 109 | //班步列表 110 | categoryListData: { 111 | //部门动态 112 | 'DEPT_EMPLOYEE_ENTRY,DEPT_EMPLOYEE_RESIGN,INTERVIEW': { 113 | title: '部门动态', 114 | list: [], 115 | loading: false 116 | } 117 | 118 | }, 119 | 120 | //班步详情列表 121 | categoryDetail:{ 122 | //公司公告 123 | COMP_ANNOUNCEMENTS: { 124 | ...listData 125 | }, 126 | //祝福提醒 127 | WISH_REMIND: { 128 | ...listData 129 | }, 130 | //班步动态 131 | BAMBOO_TRENDS: { 132 | ...listData 133 | }, 134 | //员工入职 135 | DEPT_EMPLOYEE_ENTRY: { 136 | ...listData 137 | }, 138 | //员工离职 139 | DEPT_EMPLOYEE_RESIGN: { 140 | ...listData 141 | }, 142 | //面试提醒 143 | INTERVIEW: { 144 | ...listData 145 | } 146 | }, 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | //zj 155 | userHome:[], 156 | userPast:{}, 157 | holidayType:[], 158 | offWorkApply:{}, 159 | getOffWorkDetail:{}, 160 | messageList:[], 161 | pastBuDetail:{}, 162 | benedictionIndex:[], 163 | benedictionDetail:{} 164 | } 165 | export default user; 166 | -------------------------------------------------------------------------------- /client/components/ListItem.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | Text, 4 | View, 5 | StyleSheet, 6 | Platform, 7 | Image, 8 | } from 'react-native'; 9 | import { Badge, Flex } from 'antd-mobile' 10 | import Avatar from './Avatar' 11 | 12 | export const style = StyleSheet.create({ 13 | box: { 14 | height: 65, 15 | // marginLeft: 15, 16 | paddingRight:15, 17 | paddingVertical:9, 18 | backgroundColor: '#fff', 19 | }, 20 | boxBorder: { 21 | borderBottomWidth: 0.5, 22 | borderBottomColor: '#dcdcdc', 23 | }, 24 | title: { 25 | fontSize: 15, 26 | color: '#333', 27 | marginBottom: 6 28 | }, 29 | subTitle: { 30 | fontSize: 13, 31 | color: '#7b7b7b' 32 | } 33 | }); 34 | 35 | class ListItem extends Component{ 36 | 37 | static get defaultProps () { 38 | return { 39 | img: false, 40 | nick: '', 41 | name: '', 42 | 43 | title: '', 44 | desc: '', 45 | oneline: true, 46 | hasBorder: true 47 | }; 48 | } 49 | 50 | render(){ 51 | 52 | let title = typeof this.props.title === 'string' 53 | ? {this.props.title} 54 | : this.props.title 55 | 56 | return ( 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | {title} 66 | 67 | {this.props.desc || ' '} 68 | 69 | 70 | {this.props.children} 71 | 72 | 73 | 74 | 75 | 76 | ) 77 | } 78 | 79 | } 80 | 81 | export default ListItem 82 | 83 | 84 | export function getCategoryPathAndIcon(category, uuid){ 85 | let path, image; 86 | switch (category) { 87 | case '0': 88 | path = '/boss-company-management' 89 | image = require('../../img/icon-category-0.png') 90 | break; 91 | case '1': //公司公告 92 | path = '/category/COMP_ANNOUNCEMENTS' 93 | image = require('../../img/icon-category-1.png') 94 | break; 95 | case '2': //祝福提醒 96 | path = '/category/WISH_REMIND' 97 | image = require('../../img/icon-category-2.png') 98 | break; 99 | case '3': //审批中心 100 | path = '/approval-center' 101 | image = require('../../img/icon-category-3.png') 102 | break; 103 | case '4': //考勤中心 104 | path = '/attendance-center' 105 | image = require('../../img/icon-category-4.png') 106 | break; 107 | case '5': //部门动态 108 | path = '/category-list/DEPT_EMPLOYEE_ENTRY,DEPT_EMPLOYEE_RESIGN,INTERVIEW' 109 | image = require('../../img/icon-category-5.png') 110 | break; 111 | case '6': //云档案 112 | path = null 113 | image = require('../../img/icon-category-6.png') 114 | break; 115 | case '7': //班步动态 116 | path = '/category/BAMBOO_TRENDS' 117 | image = require('../../img/icon-category-7.png') 118 | break; 119 | 120 | case '8': //生日祝福 121 | image = require('../../img/icon-category-8.png') 122 | break; 123 | case '10': //新人入职 124 | image = require('../../img/icon-category-10.png') 125 | break; 126 | 127 | case '20': //面试提醒 128 | path = '/category/INTERVIEW' 129 | image = require('../../img/icon-category-20.png') 130 | break; 131 | case '29': //员工入职 132 | path = '/category/DEPT_EMPLOYEE_ENTRY' 133 | image = require('../../img/icon-category-29.png') 134 | break; 135 | case '30': //员工离职 136 | path = '/category/DEPT_EMPLOYEE_RESIGN' 137 | image = require('../../img/icon-category-30.png') 138 | break; 139 | 140 | } 141 | return { 142 | path, 143 | image 144 | } 145 | } -------------------------------------------------------------------------------- /client/styles/style.scss: -------------------------------------------------------------------------------- 1 | @media only screen and (min-device-width: 320px) and (max-device-width: 374px) and (orientation : portrait) { 2 | /*iPhone 5 Portrait*/ 3 | html{ 4 | font-size: 48px; 5 | } 6 | } 7 | 8 | @media only screen and (min-device-width: 320px) and (max-device-width: 374px) and (orientation : landscape) { 9 | /*iPhone 5 landscape*/ 10 | html{ 11 | font-size: 48px; 12 | } 13 | } 14 | 15 | @media only screen and (min-device-width: 374px) and (max-device-width: 666px) and (orientation : portrait) { 16 | /*iPhone 6 Portrait*/ 17 | html{ 18 | font-size: 50px; 19 | } 20 | } 21 | 22 | @media only screen and (min-device-width: 374px) and (max-device-width: 666px) and (orientation : landscape) { 23 | /*iPhone 6 landscape*/ 24 | html{ 25 | font-size: 50px; 26 | } 27 | } 28 | 29 | @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (orientation : portrait) { 30 | /*iPhone 6+ Portrait*/ 31 | html{ 32 | font-size: 52px; 33 | } 34 | } 35 | 36 | @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (orientation : landscape) { 37 | /*iPhone 6+ landscape*/ 38 | html{ 39 | font-size: 52px; 40 | } 41 | } 42 | 43 | @import "var"; 44 | 45 | body { 46 | a { 47 | color: #474747; 48 | } 49 | * { 50 | box-sizing: border-box; 51 | } 52 | .am-tab-bar-bar{ 53 | z-index: 999; 54 | } 55 | img{ 56 | max-width: 100%; 57 | } 58 | .audit_icon{ 59 | color: $danger; 60 | } 61 | .check_icon{ 62 | color: $primary; 63 | } 64 | } 65 | .am-button-primary{ 66 | background-color: $primary; 67 | border: 1PX solid $primary; 68 | 69 | &.am-button-active{ 70 | background: darken($primary, 10%); 71 | } 72 | } 73 | 74 | .am-button-ghost{ 75 | 76 | &.btn-danger{ 77 | color: $danger; 78 | border: 1PX solid $danger; 79 | 80 | &.am-button-active{ 81 | color: #fff; 82 | background-color: $danger; 83 | border: 1PX solid $danger; 84 | } 85 | } 86 | } 87 | 88 | .bb{ 89 | .am-list-item{ 90 | 91 | .am-list-line{ 92 | 93 | &:after{ 94 | border-color: $fenge; 95 | } 96 | } 97 | .am-input-label,.am-list-content{ 98 | font-size: 0.32rem; 99 | color: $black; 100 | } 101 | .am-list-extra{ 102 | font-size: 0.32rem; 103 | color: $gray; 104 | } 105 | .am-input-control{ 106 | input{ 107 | font-size: 0.32rem; 108 | color: $gray; 109 | } 110 | } 111 | .am-textarea-control{ 112 | textarea{ 113 | font-size: 0.32rem; 114 | color: $gray; 115 | } 116 | } 117 | } 118 | 119 | 120 | //全局实心按钮设置 121 | .am-button{ 122 | 123 | &.btn-md{ 124 | height: .78rem; 125 | width: 2.58rem; 126 | line-height: .78rem; 127 | font-size: .36rem; 128 | } 129 | &.btn-sm{ 130 | height: .56rem; 131 | width: 1.04rem; 132 | line-height: .56rem; 133 | font-size: .24rem; 134 | padding: 0 .1rem; 135 | } 136 | 137 | &.btn-primary{ 138 | color: #fff; 139 | background-color: $primary; 140 | border: 1PX solid $primary; 141 | 142 | &.am-button-active{ 143 | background: darken($primary, 10%); 144 | } 145 | } 146 | &.btn-waring{ 147 | color: #fff; 148 | background-color: $waring; 149 | border: 1PX solid $waring; 150 | 151 | &.am-button-active{ 152 | background: darken($waring, 10%); 153 | } 154 | } 155 | &.btn-danger{ 156 | color: #fff; 157 | background-color: $danger; 158 | border: 1PX solid $danger; 159 | 160 | &.am-button-active{ 161 | background: darken($waring, 10%); 162 | } 163 | } 164 | 165 | &:disabled{ 166 | background-color: $gray!important; 167 | } 168 | } 169 | 170 | //全局空心按钮设置 171 | .am-button.am-button-ghost{ 172 | &.btn-primary{ 173 | color: $primary; 174 | background: none; 175 | border: 1PX solid $primary; 176 | 177 | &.am-button-active{ 178 | color: #fff; 179 | background-color: $primary; 180 | border: 1PX solid $primary; 181 | } 182 | } 183 | &.btn-waring{ 184 | color: $waring; 185 | background: none; 186 | border: 1PX solid $waring; 187 | 188 | &.am-button-active{ 189 | color: #fff; 190 | background-color: $waring; 191 | border: 1PX solid $waring; 192 | } 193 | } 194 | &.btn-danger{ 195 | color: $danger; 196 | background: none; 197 | border: 1PX solid $danger; 198 | 199 | &.am-button-active{ 200 | color: #fff; 201 | background-color: $danger; 202 | border: 1PX solid $danger; 203 | } 204 | } 205 | 206 | 207 | 208 | } 209 | 210 | } 211 | 212 | .left-60{ 213 | .am-list-content{ 214 | -ms-flex-preferred-size: initial!important; 215 | flex-basis: initial!important; 216 | } 217 | } 218 | .right-60{ 219 | .am-list-extra{ 220 | -ms-flex-preferred-size: initial!important; 221 | flex-basis: initial!important; 222 | } 223 | } -------------------------------------------------------------------------------- /client/common/gps.js: -------------------------------------------------------------------------------- 1 | var GPS = { 2 | PI: 3.14159265358979324, 3 | x_pi: 3.14159265358979324 * 3000.0 / 180.0, 4 | delta: function (lat, lon) { 5 | // Krasovsky 1940 6 | // 7 | // a = 6378245.0, 1/f = 298.3 8 | // b = a * (1 - f) 9 | // ee = (a^2 - b^2) / a^2; 10 | var a = 6378245.0; 11 | var ee = 0.00669342162296594323; 12 | var dLat = this.transformLat(lon - 105.0, lat - 35.0); 13 | var dLon = this.transformLon(lon - 105.0, lat - 35.0); 14 | var radLat = lat / 180.0 * this.PI; 15 | var magic = Math.sin(radLat); 16 | magic = 1 - ee * magic * magic; 17 | var sqrtMagic = Math.sqrt(magic); 18 | dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI); 19 | dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI); 20 | return {'lat': dLat, 'lon': dLon}; 21 | }, 22 | //WGS-84 to GCJ-02 23 | gcj_encrypt: function (wgsLat, wgsLon) { 24 | if (this.outOfChina(wgsLat, wgsLon)) 25 | return {'lat': wgsLat, 'lon': wgsLon}; 26 | 27 | var d = this.delta(wgsLat, wgsLon); 28 | return {'lat': wgsLat + d.lat, 'lon': wgsLon + d.lon}; 29 | }, 30 | //GCJ-02 to WGS-84 31 | gcj_decrypt: function (gcjLat, gcjLon) { 32 | if (this.outOfChina(gcjLat, gcjLon)) 33 | return {'lat': gcjLat, 'lon': gcjLon}; 34 | 35 | var d = this.delta(gcjLat, gcjLon); 36 | return {'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon}; 37 | }, 38 | //GCJ-02 to WGS-84 exactly 39 | gcj_decrypt_exact: function (gcjLat, gcjLon) { 40 | var initDelta = 0.01; 41 | var threshold = 0.000000001; 42 | var dLat = initDelta, dLon = initDelta; 43 | var mLat = gcjLat - dLat, mLon = gcjLon - dLon; 44 | var pLat = gcjLat + dLat, pLon = gcjLon + dLon; 45 | var wgsLat, wgsLon, i = 0; 46 | while (1) { 47 | wgsLat = (mLat + pLat) / 2; 48 | wgsLon = (mLon + pLon) / 2; 49 | var tmp = this.gcj_encrypt(wgsLat, wgsLon) 50 | dLat = tmp.lat - gcjLat; 51 | dLon = tmp.lon - gcjLon; 52 | if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold)) 53 | break; 54 | 55 | if (dLat > 0) pLat = wgsLat; else mLat = wgsLat; 56 | if (dLon > 0) pLon = wgsLon; else mLon = wgsLon; 57 | 58 | if (++i > 10000) break; 59 | } 60 | //console.log(i); 61 | return {'lat': wgsLat, 'lon': wgsLon}; 62 | }, 63 | //GCJ-02 to BD-09 64 | bd_encrypt: function (gcjLat, gcjLon) { 65 | var x = gcjLon, y = gcjLat; 66 | var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi); 67 | var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi); 68 | var bdLon = z * Math.cos(theta) + 0.0065; 69 | var bdLat = z * Math.sin(theta) + 0.006; 70 | return {'lat': bdLat, 'lon': bdLon}; 71 | }, 72 | //BD-09 to GCJ-02 73 | bd_decrypt: function (bdLat, bdLon) { 74 | var x = bdLon - 0.0065, y = bdLat - 0.006; 75 | var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi); 76 | var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi); 77 | var gcjLon = z * Math.cos(theta); 78 | var gcjLat = z * Math.sin(theta); 79 | return {'lat': gcjLat, 'lon': gcjLon}; 80 | }, 81 | distance: function (latA, logA, latB, logB) { 82 | var earthR = 6371000; 83 | var x = Math.cos(latA * Math.PI / 180) * Math.cos(latB * Math.PI / 180) * Math.cos((logA - logB) * Math.PI / 180); 84 | var y = Math.sin(latA * Math.PI / 180) * Math.sin(latB * Math.PI / 180); 85 | var s = x + y; 86 | if (s > 1) 87 | s = 1; 88 | if (s < -1) 89 | s = -1; 90 | var alpha = Math.acos(s); 91 | var distance = alpha * earthR; 92 | return distance; 93 | }, 94 | outOfChina: function (lat, lon) { 95 | if (lon < 72.004 || lon > 137.8347) 96 | return true; 97 | if (lat < 0.8293 || lat > 55.8271) 98 | return true; 99 | return false; 100 | }, 101 | transformLat: function (x, y) { 102 | var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); 103 | ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0; 104 | ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0; 105 | ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0; 106 | return ret; 107 | }, 108 | transformLon: function (x, y) { 109 | var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); 110 | ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0; 111 | ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0; 112 | ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0; 113 | return ret; 114 | } 115 | }; 116 | 117 | export default GPS; -------------------------------------------------------------------------------- /client/components/AddressPopup.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { List, Icon, Flex, SwipeAction } from 'antd-mobile' 3 | import { _localStorage } from '../common/bbPlugin' 4 | 5 | const ListItem = React.createClass({ 6 | 7 | getInitialState() { 8 | return { 9 | address_list: _localStorage.getItem('address_list') || [] 10 | } 11 | }, 12 | 13 | setStar(e, index) { 14 | e.stopPropagation(); 15 | let item = this.state.address_list[index]; 16 | item.star = !item.star; 17 | 18 | let tmp_list = [ 19 | ...this.state.address_list.slice(0,index), 20 | item, 21 | ...this.state.address_list.slice(index+1) 22 | ]; 23 | this.setState({ 24 | address_list: tmp_list 25 | }); 26 | _localStorage.setItem('address_list', tmp_list) 27 | }, 28 | deleteAddress(index){ 29 | 30 | let tmp_list = [ 31 | ...this.state.address_list.slice(0, index), 32 | ...this.state.address_list.slice(index+1) 33 | ] 34 | this.setState({ 35 | address_list: tmp_list 36 | }); 37 | _localStorage.setItem('address_list', tmp_list) 38 | }, 39 | setCompany(item){ 40 | this.props.onAddressChange && this.props.onAddressChange(item) 41 | }, 42 | 43 | getAddressList(list, star = true){ 44 | let dom, count = 0; 45 | dom = list.map((item, index)=>{ 46 | let flag; 47 | if(star){ 48 | flag = true 49 | }else{ 50 | flag = false 51 | } 52 | if(item.star == flag || (flag == false && !item.star)) { 53 | count++; 54 | return ( 55 | console.log('取消'), 64 | style: { backgroundColor: '#ddd', color: 'white' }, 65 | }, 66 | { 67 | text: '删除', 68 | onPress: () => { this.deleteAddress(index) }, 69 | style: { backgroundColor: '#F4333C', color: 'white' }, 70 | }, 71 | ]} 72 | > 73 | { this.setStar(e,index) }} type={star?'star':'star-o'} style={{padding:'.2rem',color: star?'orange':''}}/>} 75 | onClick={this.setCompany.bind(null, item)}> 76 | {item.company} 77 |  {item.address} 78 | 79 | 80 | ) 81 | } 82 | }) 83 | return { 84 | dom : dom, 85 | count: count 86 | }; 87 | }, 88 | render(){ 89 | 90 | const { address_list } = this.state; 91 | 92 | const use_list = this.getAddressList(address_list, true); 93 | const last_list = this.getAddressList(address_list, false); 94 | 95 | return ( 96 |
97 | 98 | { this.setCompany(false) } } 101 | > 102 | 103 | 104 | 105 | 0 ? '': 'none'}} 107 | className="popup-list" 108 | renderHeader={() => '常用地址'} 109 | > 110 | { use_list.dom } 111 | 112 | 113 | 0 ? '': 'none'}} 115 | className="popup-list" 116 | renderHeader={() => '最近' } 117 | > 118 | { last_list.dom } 119 | 120 | 121 |
124 | 您还没有常用地址 125 |
126 |
127 | ) 128 | } 129 | 130 | }) 131 | 132 | export default ListItem 133 | 134 | 135 | export function addAddress(item) { 136 | let list = _localStorage.getItem('address_list') || []; 137 | let flag = false; 138 | for(let i=0; i 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/AwesomeProject.xcodeproj/xcshareddata/xcschemes/AwesomeProject-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"] 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.awesomeproject" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile fileTree(dir: "libs", include: ["*.jar"]) 130 | compile "com.android.support:appcompat-v7:23.0.1" 131 | compile "com.facebook.react:react-native:+" // From node_modules 132 | } 133 | 134 | // Run this once to be able to run the application with BUCK 135 | // puts all compile dependencies into folder libs for BUCK to use 136 | task copyDownloadableDepsToLibs(type: Copy) { 137 | from configurations.compile 138 | into 'libs' 139 | } 140 | -------------------------------------------------------------------------------- /client/page/home/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Actions } from 'react-native-router-flux'; 3 | import { View, Image, Text, Alert, TouchableHighlight } from 'react-native' 4 | import { Icon, TabBar, Flex, Popover } from 'antd-mobile' 5 | import connectRedux from '../../connectRedux' 6 | import Banbu from './Banbu' 7 | // import BossHome from './BossHome' 8 | import UserHome from './UserHome' 9 | import Personal from './personal' 10 | import {styles} from '../../styles/styles' 11 | 12 | class Home extends Component{ 13 | static selectedTab = 'home' 14 | static renderTitle = function () { 15 | let navbar = 16 | if(Home.selectedTab == 'home'){ 17 | navbar = ( 18 | 19 | 上海云才网络科技有限公司), 23 | (上海云才网络科技有限公司1122143), 24 | (上海云才网络科技有限公司2), 25 | ]} 26 | onSelect={ ()=>{ console.log('onSelect') }} 27 | > 28 | 29 | 上海云才网络科技有限公司 30 | 31 | 32 | 33 | 34 | 35 | ) 36 | }else if (Home.selectedTab === 'banbu') { 37 | navbar = ( 38 | 39 | 班步 40 | 41 | ) 42 | }else if (Home.selectedTab === 'member') { 43 | navbar = ( 44 | 45 | 我的 46 | 47 | ) 48 | } 49 | return ( 50 | 51 | {navbar} 52 | 53 | ) 54 | } 55 | 56 | constructor(props) { 57 | super(props); 58 | this.state = { 59 | hidden: false, 60 | } 61 | } 62 | 63 | setSelectedTab = function(tabName) { 64 | this.props.updateSelectedTab(tabName) 65 | this.setTitle(tabName) 66 | } 67 | setTitle = function(tabName){ 68 | let title = ''; 69 | switch (tabName){ 70 | case 'home': 71 | title = '首页' 72 | break; 73 | case 'member': 74 | title = '我的' 75 | break; 76 | case 'banbu': 77 | title = '消息' 78 | break; 79 | } 80 | Home.selectedTab = tabName 81 | Actions.refresh({ selectedTab: tabName }) 82 | } 83 | getHomeByUserType = function(){ 84 | 85 | const user = this.props.$$app.get('user'); 86 | const boss = this.props.$$app.get('boss'); 87 | 88 | // if(boss !== null){ 89 | // return () 90 | // } 91 | // if(user !== null){ 92 | // return () 93 | // } 94 | 95 | return () 96 | } 97 | componentDidMount(){ 98 | let {selectedTab} = this.props.$$app.toJS(); 99 | this.setTitle(selectedTab) 100 | } 101 | render(){ 102 | 103 | let {selectedTab} = this.props.$$app.toJS(); 104 | 105 | return ( 106 | 107 | 144 | 145 | 146 | ) 147 | } 148 | } 149 | 150 | export default connectRedux(Home); -------------------------------------------------------------------------------- /client/page/home/Banbu.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | Image, 7 | Platform, 8 | BackAndroid, 9 | DeviceEventEmitter, 10 | } from 'react-native'; 11 | import {Badge, Flex, Button, ListView, RefreshControl, Tag} from 'antd-mobile'; 12 | import {is} from 'immutable' 13 | import ListItem, {getCategoryPathAndIcon, style as listItemStyle} from '../../components/ListItem' 14 | import {styles} from '../../styles/styles' 15 | 16 | const dataSource = new ListView.DataSource({ 17 | rowHasChanged: (row1, row2) => !is(row1, row2) || row1 !== row2, 18 | }); 19 | 20 | const _style = StyleSheet.create({ 21 | date: { 22 | color: '#959595', 23 | fontSize: 11, 24 | marginBottom: 10 25 | }, 26 | smallTag: { 27 | width: 27, 28 | height: 15, 29 | borderRadius: 7.5, 30 | borderWidth: 0.5, 31 | borderColor: '#1ab394', 32 | borderStyle: 'solid', 33 | }, 34 | smallTagText: { 35 | fontSize: 10, 36 | color: '#1ab394', 37 | backgroundColor: 'transparent', 38 | } 39 | }); 40 | 41 | class Banbu extends Component{ 42 | 43 | constructor(props) { 44 | super(props); 45 | this.state = { 46 | refreshing: false 47 | } 48 | } 49 | 50 | renderRow = function(item,s,index){ 51 | 52 | const {path, image} = getCategoryPathAndIcon(item.category, item.uuid); 53 | 54 | if(!item.category){ 55 | return () 56 | } 57 | const {routes} = this.context; 58 | 59 | if(item.category == '7'){ 60 | item.title = ( 61 | 62 | {item.title} 63 | 64 | 65 | 官方 66 | 67 | 68 | ) 69 | } 70 | return ( 71 | { console.log(123) }} hasBorder={item.border} 73 | key={index} title={item.title} desc={item.subTitle || ' '} img={image}> 74 | 75 | {item.showDate} 76 | { item.count>0 ? : } 77 | 78 | 79 | ) 80 | } 81 | onRefresh = function () { 82 | console.log(this) 83 | if(this.state.refreshing){ 84 | return; 85 | } 86 | this.setState({ refreshing: true }); 87 | 88 | this.props.messageList() 89 | .catch((err)=>{ 90 | console.log(err) 91 | }) 92 | .finally(()=>{ 93 | this.setState({ refreshing: false }); 94 | }) 95 | 96 | } 97 | componentWillMount(){ 98 | this.props.messageList().then((data)=>{ 99 | console.log(data) 100 | }).catch((err)=>{ 101 | console.log(err) 102 | }) 103 | } 104 | render(){ 105 | let messageList = this.props.$$user.get('messageList')?this.props.$$user.get('messageList').toJS():[]; 106 | 107 | const showCompanyManagement = this.props.$$app.get('showCompanyManagement'); 108 | messageList = [ 109 | { 110 | category: "1", 111 | count: 1, 112 | data:[], 113 | showDate:"11:18", 114 | subTitle:"公司域名即日起更改为:www.hr.ibanbu.com", 115 | title: "公司公告" 116 | }, 117 | { 118 | category: "2", 119 | count: 1, 120 | data:[], 121 | showDate:"10:22", 122 | subTitle:"销售一组张有学入职,快去送上祝福吧", 123 | title: "祝福提醒", 124 | border: false 125 | }, 126 | { 127 | 128 | }, 129 | { 130 | category: "5", 131 | count: 0, 132 | data:[], 133 | showDate:"", 134 | subTitle:"李晓华将于2016-06-01入职", 135 | title: "部门动态" 136 | }, 137 | { 138 | category: "3", 139 | count: 1, 140 | data:[], 141 | showDate:"10:10", 142 | subTitle:"吴彦祖将于2016-06-01公出", 143 | title: "审批中心" 144 | }, 145 | { 146 | category: "4", 147 | count: 0, 148 | data:[], 149 | showDate:"", 150 | subTitle:"", 151 | title: "考勤中心", 152 | border: false 153 | }, 154 | { 155 | 156 | }, 157 | { 158 | category: "6", 159 | count: 0, 160 | data:[], 161 | showDate:"", 162 | subTitle:"", 163 | title: "云档案", 164 | border: false 165 | }, 166 | { 167 | 168 | }, 169 | { 170 | category: "7", 171 | count: 0, 172 | data:[], 173 | showDate:"", 174 | subTitle:"", 175 | title: "班步动态", 176 | border: false 177 | }, 178 | ] 179 | 180 | const data = dataSource.cloneWithRows(messageList) 181 | 182 | return ( 183 | 184 | 185 | } 194 | /> 195 | 196 | 197 | ) 198 | } 199 | } 200 | 201 | export default Banbu -------------------------------------------------------------------------------- /client/page/home/BossHome.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | Platform, 7 | } from 'react-native'; 8 | import { List, Flex, WhiteSpace, Badge } from 'antd-mobile' 9 | import ECharts from '../../components/native-echarts' 10 | // import style from './BossHome.scss' 11 | import ListItem, { getCategoryPathAndIcon } from '../../components/ListItem' 12 | 13 | class Home extends Component{ 14 | 15 | componentDidMount(){ 16 | 17 | const homeTopDesc = this.props.$$boss.get('homeTopDesc').toJS(); 18 | if(homeTopDesc.compEmplCount == 0 ){ 19 | this.props.getTopCount() 20 | } 21 | 22 | const pie_bmtj = this.props.$$boss.get('pie_bmtj').toJS(); 23 | if(pie_bmtj.failed !== false ){ 24 | this.props.getPie_bmtj() 25 | } 26 | 27 | const line_cdtj = this.props.$$boss.get('line_cdtj').toJS(); 28 | if(line_cdtj.failed !== false ){ 29 | this.props.getLine_cdtj() 30 | } 31 | 32 | const withRemind = this.props.$$boss.get('withRemind').toJS(); 33 | if(withRemind.length == 0) { 34 | this.props.getWishRemindMsg() 35 | } 36 | 37 | } 38 | 39 | render(){ 40 | const $$pie_bmtj = this.props.$$boss.get('pie_bmtj'); 41 | const $$line_cdtj = this.props.$$boss.get('line_cdtj'); 42 | const homeTopDesc = this.props.$$boss.get('homeTopDesc').toJS(); 43 | const withRemind = this.props.$$boss.get('withRemind').toJS(); 44 | 45 | return ( 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 试用期/总人数 55 | {homeTopDesc.trialCount}人/{homeTopDesc.compEmplCount}人 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 新人人数/离职人数 66 | {homeTopDesc.newEmplCount}人/{homeTopDesc.leaveOfficeCount}人 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 本月工资成本 79 | {homeTopDesc.thisMonthTotalWages|| '0'}元 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 在招岗位/待招岗位 90 | {homeTopDesc.recruitingPostCount}人/{homeTopDesc.theNumberToBeRecruited}人 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |
部门统计
100 | 101 | {homeTopDesc.compEmplCount || '--'} 102 | 全部 103 | 104 |
105 | 106 | 107 | 108 |
迟到统计
109 | 110 | 111 | 112 |
113 | 114 | 115 | 116 | 祝福提醒 117 | 118 | {withRemind.map((item, index)=> 119 | 120 | 121 | 122 | {item.showDate} 123 | 124 |   125 | 126 | 127 | 128 | 129 | )} 130 | 131 | 132 | 133 |
134 | ) 135 | 136 | } 137 | } 138 | 139 | export default Home; -------------------------------------------------------------------------------- /client/actions/boss.js: -------------------------------------------------------------------------------- 1 | import {getOrgUrl} from '../common/bbPlugin' 2 | let nowDate = new Date(); 3 | let nowYear = nowDate.getFullYear(); 4 | export function getWishRemindMsg() { 5 | return { 6 | type: 'WISH_REMIND', 7 | payload: { 8 | request: { 9 | url: getOrgUrl() + '/msg/index/WISH_REMIND' 10 | } 11 | } 12 | } 13 | } 14 | export function getTopCount(config) { 15 | return { 16 | type: 'TOP_COUNT', 17 | payload: { 18 | request: { 19 | url: getOrgUrl() + '/statistica/index' 20 | } 21 | } 22 | } 23 | } 24 | 25 | export function getTodoList(config) { 26 | return { 27 | type: 'TODO_LIST', 28 | payload: { 29 | request: { 30 | url: getOrgUrl() + '/notification/taskcount.json' 31 | } 32 | } 33 | } 34 | } 35 | 36 | export function getPie_bmtj(config) { 37 | return { 38 | type: 'PIE_BMTJ', 39 | payload: { 40 | request: { 41 | url: getOrgUrl() + '/statistica/dept-empl' 42 | } 43 | } 44 | } 45 | } 46 | export function getLine_mygzcb(config) { 47 | return { 48 | type: 'LINE_MYGZCB', 49 | payload: { 50 | request:{ 51 | url: getOrgUrl()+'/statistica/empl-salaries' 52 | } 53 | } 54 | } 55 | } 56 | 57 | export function getBar_bmgzcb() { 58 | return { 59 | type: 'BAR_BMGZCB', 60 | payload: { 61 | request:{ 62 | url: getOrgUrl()+'/statistica/dept-salaries' 63 | } 64 | } 65 | } 66 | } 67 | export function getBar_bmpjgz() { 68 | return { 69 | type: 'BAR_BMPJGZ', 70 | payload: { 71 | request:{ 72 | url: getOrgUrl()+'/statistica/dept-salaries' 73 | } 74 | } 75 | } 76 | } 77 | 78 | export function getLine_cdtj(config) { 79 | return { 80 | type: 'LINE_CDTJ', 81 | payload: { 82 | request:{ 83 | url: getOrgUrl()+'/statistica/late-times-and-no-begin-end-times' 84 | } 85 | } 86 | } 87 | } 88 | 89 | 90 | export function getLine_mypjcql(config) { 91 | return { 92 | type: 'LINE_MYPJCQL', 93 | payload: { 94 | request: { 95 | url: getOrgUrl() + '/statistica/' 96 | } 97 | } 98 | } 99 | } 100 | 101 | //在职统计 102 | export function getPie_bossEmployIn() { 103 | return { 104 | type: 'PIE_BEIN', 105 | payload: { 106 | request: { 107 | url: getOrgUrl() + '/statistica/empl' 108 | } 109 | } 110 | } 111 | } 112 | //年龄统计 113 | export function getPie_bossEmployAge() { 114 | return { 115 | type: 'PIE_BEage', 116 | payload: { 117 | request: { 118 | url: getOrgUrl() + '/empls/pieChart/age/' + nowYear + '.json' 119 | } 120 | } 121 | } 122 | } 123 | //学历统计 124 | export function getPie_bossEmployEdu() { 125 | return { 126 | type: 'PIE_BEedu', 127 | payload: { 128 | request: { 129 | url: getOrgUrl() + '/empls/pieChart/education/' + nowYear + '.json' 130 | } 131 | } 132 | } 133 | } 134 | //性别统计 135 | export function getPie_bossEmploySex() { 136 | return { 137 | type: 'PIE_BEsex', 138 | payload: { 139 | request: { 140 | url: getOrgUrl() + '/empls/pieChart/sex/' + nowYear + '.json' 141 | } 142 | } 143 | } 144 | } 145 | //婚姻统计 146 | export function getPie_bossEmployMar() { 147 | return { 148 | type: 'PIE_BEmar', 149 | payload: { 150 | request: { 151 | url: getOrgUrl() + '/empls/pieChart/maritalStatus/' + nowYear + '.json' 152 | } 153 | } 154 | } 155 | } 156 | //生育统计 157 | export function getPie_bossEmployBorn() { 158 | return { 159 | type: 'PIE_BEborn', 160 | payload: { 161 | request: { 162 | url: getOrgUrl() + '/empls/pieChart/fertStatus/' + nowYear + '.json' 163 | } 164 | } 165 | } 166 | } 167 | //在职时间统计 168 | export function getPie_bossEmployYear(type) { 169 | return { 170 | type: type, 171 | payload: { 172 | request: { 173 | url: getOrgUrl() + '/empl-in-date-asc.json' 174 | } 175 | } 176 | } 177 | } 178 | 179 | //缺勤统计 180 | export function getGrid_bossEmployWorkTime() { 181 | return { 182 | type: 'Grid_BENcome', 183 | payload: { 184 | request: { 185 | url: getOrgUrl() + '/statistica/abse-times' 186 | } 187 | } 188 | } 189 | } 190 | 191 | //迟到未打卡统计 192 | export function getGrid_bossEmployLateNoCard() { 193 | return { 194 | type: 'Grid_BELNC', 195 | payload: { 196 | request: { 197 | url: getOrgUrl() + '/statistica/late-times-and-no-begin-end-times' 198 | } 199 | } 200 | } 201 | } 202 | 203 | //请假统计 204 | export function getGrid_bossEmployOffWork() { 205 | return { 206 | type: 'Grid_BEOFW', 207 | payload: { 208 | request: { 209 | url: getOrgUrl() + '/statistica/leave-times' 210 | } 211 | } 212 | } 213 | } 214 | 215 | //公出统计 216 | export function getGrid_bossEmployOutBuss() { 217 | return { 218 | type: 'Grid_BEOFB', 219 | payload: { 220 | request: { 221 | url: getOrgUrl() + '/statistica/busi-away-times' 222 | } 223 | } 224 | } 225 | } 226 | 227 | //今日公出统计 228 | export function getGrid_bossEmployOutBussToday(type) { 229 | return { 230 | type: type, 231 | payload: { 232 | request: { 233 | url: getOrgUrl() + '/offic-busi-away-table.json?draw=1&start=0&length=4' 234 | } 235 | } 236 | } 237 | } 238 | 239 | //今日请假统计 240 | 241 | export function getGrid_bossEmployOffWorkToday(type) { 242 | return { 243 | type: type, 244 | payload: { 245 | request: { 246 | url: getOrgUrl() + '/leave-record-list.json?draw=1&start=0&length=4' 247 | } 248 | } 249 | } 250 | } 251 | 252 | //生日祝福列表 253 | export function getGrid_bossCompanyCulBirth(type) { 254 | return { 255 | type: type, 256 | payload: { 257 | request: { 258 | url: getOrgUrl() + '/publish-msg-list.json?draw=1&start=0&length=4&type=1' 259 | } 260 | } 261 | } 262 | } 263 | //司龄祝福列表 264 | export function getGrid_bossCompanyCulBeDate(type) { 265 | return { 266 | type: type, 267 | payload: { 268 | request: { 269 | url: getOrgUrl() + '/publish-msg-list.json?draw=1&start=0&length=4&type=2' 270 | } 271 | } 272 | } 273 | } -------------------------------------------------------------------------------- /client/page/home/personal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | Platform, 7 | BackAndroid, 8 | Image, 9 | ScrollView 10 | } from 'react-native'; 11 | import { Flex, List, WhiteSpace, Modal } from 'antd-mobile'; 12 | import { _localStorage } from '../../common/bbPlugin' 13 | import Avatar from '../../components/Avatar' 14 | import ListItem from '../../components/ListItem' 15 | import { styles } from '../../styles/styles' 16 | 17 | 18 | const _style = StyleSheet.create({ 19 | item: { 20 | height: 50, 21 | }, 22 | itemTitle: { 23 | color: '#333', 24 | fontSize: 15, 25 | }, 26 | itemTitleGray: { 27 | color: '#aaa', 28 | fontSize: 15, 29 | }, 30 | itemText13: { 31 | color: '#aaa', 32 | fontSize: 13, 33 | }, 34 | itemImage: { 35 | width:20, 36 | height:20, 37 | marginRight: 16.5, 38 | }, 39 | 40 | itemBig: { 41 | height: 80, 42 | }, 43 | itemAvatar: { 44 | width: 55, 45 | height: 55, 46 | marginRight: 15, 47 | } 48 | }); 49 | 50 | 51 | class Personal extends React.Component { 52 | 53 | constructor(){ 54 | super(); 55 | this.state = { 56 | showModal: false 57 | } 58 | } 59 | 60 | render() { 61 | const infoJson = _localStorage.getItem('infoJson'); 62 | const boss = this.props.$$app.get('boss'); 63 | const user = this.props.$$app.get('user'); 64 | let userInfo = null; 65 | if(boss){ 66 | userInfo = boss 67 | }else{ 68 | userInfo = user 69 | } 70 | const {routes} = this.context 71 | return ( 72 | 75 | 76 | 80 | } 81 | arrow="horizontal" 82 | extra={} 83 | onClick={() => { console.log('头像') }} 84 | > 85 | 86 | 张三 87 | 88 | 产品规划部 89 | 产品经理 90 | 91 | 智者千虑,必有一失;愚者千虑,必有一得 92 | 93 | 94 | 95 | 96 | 97 | } 100 | arrow="horizontal" 101 | extra={ 102 | 103 | 完成度 104 | 80% 105 | 106 | 107 | } 108 | onClick={() => { 109 | console.log('个人信息') 110 | }} 111 | > 112 | 113 | 个人信息 114 | 115 | 116 | 117 | 118 | } 121 | onClick={()=>{ 122 | 123 | }} 124 | > 125 | 工资查询 126 | 127 | } 129 | onClick={()=>{ 130 | 131 | }} 132 | > 133 | 社保查询 134 | 135 | } 137 | onClick={()=>{ 138 | 139 | }} 140 | > 141 | 医保查询 142 | 143 | } 145 | onClick={()=>{ 146 | 147 | }} 148 | > 149 | 公积金查询 150 | 151 | 152 | 153 | 154 | 155 | } 158 | onClick={()=>{ 159 | 160 | }} 161 | > 162 | 设置 163 | 164 | } 167 | onClick={()=>{ 168 | 169 | }} 170 | > 171 | 帮助 172 | 173 | } 175 | onClick={()=>{ 176 | 177 | }} 178 | > 179 | 反馈 180 | 181 | 182 | 183 | 184 | 185 | ) 186 | } 187 | } 188 | 189 | export default Personal -------------------------------------------------------------------------------- /client/page/home/UserHome.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import { Actions } from 'react-native-router-flux'; 3 | import { 4 | StyleSheet, 5 | View, 6 | Text, 7 | Platform, 8 | BackAndroid, 9 | DeviceEventEmitter, 10 | TouchableHighlight, 11 | Image, 12 | ScrollView 13 | } from 'react-native'; 14 | import { is } from 'immutable' 15 | import {Button, List, Flex, WhiteSpace, Badge, Icon, ActionSheet, ListView, RefreshControl} from 'antd-mobile' 16 | import moment from 'moment' 17 | import TouchView from '../../components/TouchView' 18 | 19 | moment.locale('zh-cn'); 20 | 21 | const styles = StyleSheet.create({ 22 | btnSign: { 23 | position: 'relative', 24 | width: 92, 25 | height: 92, 26 | backgroundColor: '#1ab394', 27 | borderRadius: 92, 28 | }, 29 | btnSignBorder: { 30 | position: 'absolute', 31 | left: 0.5, 32 | top: 0.5, 33 | backgroundColor: 'transparent', 34 | width: 91, 35 | height: 91, 36 | borderRadius: 91, 37 | borderWidth: 4, 38 | borderColor: '#fff', 39 | borderStyle: 'solid' 40 | }, 41 | btnSignText: { 42 | fontSize: 16, 43 | textAlign: 'center', 44 | color: '#fff', 45 | backgroundColor: 'transparent', 46 | }, 47 | textTime: { 48 | textAlign: 'center', 49 | color: '#1ab394', 50 | fontSize: 20, 51 | marginBottom: 10 52 | }, 53 | textDate: { 54 | textAlign: 'center', 55 | color: '#aaa', 56 | fontSize: 13, 57 | marginBottom: 10 58 | }, 59 | textType: { 60 | textAlign: 'center', 61 | color: '#aaa', 62 | fontSize: 14 63 | }, 64 | 65 | line: { 66 | position: 'absolute', 67 | left: 0, 68 | top: 9, 69 | right: 0, 70 | width: 375, 71 | height: 1, 72 | backgroundColor: '#dcdcdc', 73 | }, 74 | 75 | gridTextNumber: { 76 | textAlign: 'center', 77 | fontSize: 20, 78 | color: '#535353', 79 | marginBottom: 15, 80 | fontWeight: '200' 81 | }, 82 | gridImage: { 83 | width: 31, 84 | height: 31, 85 | marginBottom: 10, 86 | }, 87 | gridTextDesc: { 88 | textAlign: 'center', 89 | fontSize: 13, 90 | color: '#7d7d7d' 91 | }, 92 | gridLine: { 93 | backgroundColor: '#dcdcdc', 94 | width: 0.5, 95 | height: 50 96 | } 97 | 98 | }); 99 | 100 | class Home extends Component{ 101 | constructor(props) { 102 | super(props); 103 | this.state = { 104 | refreshing: false 105 | } 106 | }; 107 | 108 | componentDidMount() { 109 | console.log('123') 110 | this.props.userHome() 111 | .then((data)=>{ 112 | console.log(data) 113 | }) 114 | .catch(err=>{ 115 | console.log(err) 116 | }) 117 | .finally((err)=>{ 118 | 119 | }) 120 | } 121 | renderRow = function(list, sectionID, rowID,){ 122 | return ( 123 | 124 | 125 | 126 | ) 127 | } 128 | onRefresh = function(){ 129 | if(this.state.refreshing){ 130 | return; 131 | } 132 | this.setState({ refreshing: true }); 133 | 134 | this.props.userHome().then(()=>{ 135 | this.setState({ refreshing: false }); 136 | }) 137 | 138 | } 139 | render(){ 140 | console.log(this.props.$$user) 141 | const userHome = this.props.$$user.get('userHome') ? this.props.$$user.get('userHome').toJS() : []; 142 | 143 | return ( 144 | 147 | 148 | 149 | 150 | 151 | 签到 152 | 153 | 154 | 155 | 15:26 156 | 2017/01/12 腊月十五 157 | 常规考勤 158 | 159 | 160 | 签退 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 09:00 175 | 176 | 18:00 177 | 178 | 179 | 180 | 181 | 182 | 当前不在考情范围内 183 | 184 | 185 | 186 | 刷新位置 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 21 195 | 出勤天数 196 | 197 | 198 | 199 | 0 200 | 迟到天数 201 | 202 | 203 | 204 | 1 205 | 缺卡天数 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 请假 214 | 215 | 216 | 217 | 218 | 219 | 220 | 公出 221 | 222 | 223 | 224 | 225 | 226 | 227 | 补签 228 | 229 | 230 | 231 | 232 | 233 | ) 234 | 235 | } 236 | } 237 | 238 | export default Home; -------------------------------------------------------------------------------- /client/actions/user.js: -------------------------------------------------------------------------------- 1 | import {getOrgUrl} from '../common/bbPlugin' 2 | import storage from '../common/storage' 3 | 4 | //yjj 5 | 6 | //公出申请 7 | export function businessOutApply(data) { 8 | return { 9 | type: 'APPLY_BUSINESS_OUT', 10 | payload: { 11 | request: { 12 | method: 'post', 13 | url: getOrgUrl() + '/apply-busi-out.json', 14 | data: {detail: data} 15 | } 16 | } 17 | } 18 | } 19 | 20 | //查询公出详情信息 21 | export function getBusinessOutDetail(id) { 22 | return { 23 | type: 'GET_BUSINESS_OUT', 24 | payload: { 25 | request: { 26 | url: getOrgUrl() + `/busi-outRecord/${id}.json`, 27 | } 28 | } 29 | } 30 | } 31 | 32 | //撤销公出详情信息 33 | export function removeBusinessOut(id) { 34 | return { 35 | type: 'DELETE_BUSINESS_OUT', 36 | payload: { 37 | request: { 38 | method: 'delete', 39 | url: getOrgUrl() + `/busi-outRecord/${id}.json`, 40 | } 41 | } 42 | } 43 | } 44 | 45 | //公出签到 46 | export function signInBusinessOut(form) { 47 | return { 48 | type: 'SIGN_BUSINESS_OUT', 49 | payload: { 50 | request: { 51 | method: 'post', 52 | url: getOrgUrl() + `/busi-outRecord/sign.json`, 53 | data: form 54 | } 55 | } 56 | } 57 | } 58 | 59 | //公出驳回 60 | export function rejectBusinessOut(data) { 61 | return { 62 | type: 'REJECT_BUSINESS_OUT', 63 | payload: { 64 | request: { 65 | method: 'post', 66 | url: getOrgUrl() + `/busi-outRecords/reply.json`, 67 | data: { 68 | ...data, 69 | isRefuse: true, 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | //审批中心列表 77 | export function getApprovalList(data, timestamp) { 78 | return { 79 | type: 'GET_APPROVAL_LIST', 80 | payload: { 81 | request: { 82 | method: 'post', 83 | url: getOrgUrl() + `/audit/list.json`, 84 | data: { 85 | "pageIndex": data.pageIndex, 86 | "pageLength": data.pageLength, 87 | "type": data.type, 88 | "timestamp": timestamp 89 | } 90 | } 91 | } 92 | } 93 | } 94 | 95 | //审批中心 tab切换 96 | export function selectApprovalTab(tabIndex) { 97 | return { 98 | type: 'UPDATE_APPROVAL_TAB', 99 | tabIndex, 100 | } 101 | } 102 | 103 | //请假驳回 104 | export function rejectLeave(data) { 105 | return { 106 | type: 'REJECT_LEAVE', 107 | payload: { 108 | request: { 109 | method: 'post', 110 | url: getOrgUrl() + `/leave/reply.json`, 111 | data: data 112 | } 113 | } 114 | } 115 | } 116 | 117 | //补签驳回 118 | export function rejectSign(data) { 119 | return { 120 | type: 'REJECT_SIGN', 121 | payload: { 122 | request: { 123 | method: 'post', 124 | url: getOrgUrl() + `/makeuptime/reply.json`, 125 | data: data 126 | } 127 | } 128 | } 129 | } 130 | 131 | //获取考勤中心首页 132 | export function getAttendanceData(data) { 133 | return { 134 | type: 'GET_ATTENDANCE', 135 | payload: { 136 | request: { 137 | method: 'get', 138 | url: getOrgUrl() + `/statisics/${data.date}/${data.deptUuid}.json`, 139 | deptUuid: data.deptUuid 140 | } 141 | } 142 | } 143 | } 144 | 145 | //更新考勤中心选择 146 | export function updateAttendanceSelect(data) { 147 | return { 148 | type: 'UPDATE_ATTENDANCE_SELECTED', 149 | data, 150 | } 151 | } 152 | 153 | //班步列表 154 | export function getCategoryDetail(category, data) { 155 | return { 156 | type: 'GET_CATEGORY_DETAIL', 157 | category, 158 | payload: { 159 | request: { 160 | method: 'get', 161 | url: getOrgUrl() + '/msg/detail/' + category, 162 | params: { 163 | start: data.pageIndex-1, 164 | length: data.pageLength, 165 | draw: 1, 166 | } 167 | }, 168 | } 169 | } 170 | } 171 | 172 | //班步首页 173 | export function getCategoryList(categoryList, data) { 174 | return { 175 | type: 'GET_CATEGORY_LIST', 176 | categoryList, 177 | payload: { 178 | request: { 179 | method: 'get', 180 | url: getOrgUrl() + '/msg/index/' + categoryList, 181 | }, 182 | } 183 | } 184 | } 185 | 186 | //反馈 187 | export function feedback(text) { 188 | return { 189 | type: 'FEEDBACK', 190 | payload: { 191 | request: { 192 | method: 'post', 193 | url: getOrgUrl() + '/feedback.json', 194 | data: { 195 | detail: text 196 | } 197 | }, 198 | } 199 | } 200 | } 201 | 202 | 203 | //zj 204 | let date = new Date(); 205 | let sjc = date.getTime(); 206 | 207 | //员工首页 208 | export async function userHome() { 209 | let local = await storage.getItem('approvalListData.timestamp') 210 | console.log('员工首页', local) 211 | return { 212 | type: 'USER_HOME_INITIAL', 213 | payload: { 214 | request: { 215 | url: getOrgUrl() + '/index' 216 | } 217 | } 218 | } 219 | } 220 | //上班签到 221 | export function userPastIn(data, cb) { 222 | return { 223 | type: 'USER_PASTIN', 224 | payload: { 225 | request: { 226 | method: 'post', 227 | data: {detail: data}, 228 | url: getOrgUrl() + '/signin.json' 229 | }, 230 | callBack: cb 231 | } 232 | } 233 | } 234 | //下班签退 235 | export function userPastOut(data, cb) { 236 | return { 237 | type: 'USER_PASTOUT', 238 | payload: { 239 | request: { 240 | method: 'post', 241 | data: {detail: data}, 242 | url: getOrgUrl() + '/signout.json' 243 | }, 244 | callBack: cb 245 | } 246 | } 247 | } 248 | 249 | //补打卡 250 | export function userPastBU(data, cb) { 251 | return { 252 | type: 'USER_PASTBU', 253 | payload: { 254 | request: { 255 | method: 'post', 256 | data: data, 257 | url: getOrgUrl() + '/apply-makeuptime.json' 258 | }, 259 | callBack: cb 260 | } 261 | } 262 | } 263 | 264 | //假期类型 265 | export function getHolidayType() { 266 | return { 267 | type: 'GET_HOLIDAY_TYPE', 268 | payload: { 269 | request: { 270 | method: 'GET', 271 | url: getOrgUrl() + '/leave-setting.json' 272 | }, 273 | } 274 | } 275 | } 276 | 277 | //提交请假申请 278 | export function submitOffApply(data) { 279 | return { 280 | type: 'SUBMIT_OFF_APPLY', 281 | payload: { 282 | request: { 283 | method: 'POST', 284 | data: {detail: data}, 285 | url: getOrgUrl() + '/apply-leave.json' 286 | }, 287 | } 288 | } 289 | } 290 | 291 | //提交请假图片 292 | export function updateWorkOffImg(id, file) { 293 | return { 294 | type: 'UPDATE_WORK_OFF', 295 | payload: { 296 | request: { 297 | method: 'POST', 298 | data: { 299 | file : file 300 | }, 301 | url: getOrgUrl() + `/apply-leave/${id}/upload.json` 302 | }, 303 | } 304 | } 305 | } 306 | 307 | //获取请假详情 308 | export function getOffWorkDetail(data) { 309 | return { 310 | type: 'GET_OFF_DETAIL', 311 | payload: { 312 | request: { 313 | method: 'get', 314 | url: getOrgUrl() + '/apply-leave/' + data + '.json' 315 | }, 316 | } 317 | } 318 | } 319 | 320 | //撤销请假 321 | export function cancelOffWork(data) { 322 | return { 323 | type: 'CANCEL_OFF_WORK', 324 | payload: { 325 | request: { 326 | method: 'DELETE', 327 | url: getOrgUrl() + '/apply-leave/' + data + '.json' 328 | }, 329 | } 330 | } 331 | } 332 | 333 | //班步首页 334 | export async function messageList() { 335 | let local = await storage.getItem('approvalListData.timestamp') 336 | let past = local ? local['1'] : '0'; 337 | let outWork = local ? local['2'] : '0'; 338 | let offWork = local ? local['3'] : '0'; 339 | return { 340 | type: 'MESSAGE_LIST', 341 | payload: { 342 | request: { 343 | method: 'get', 344 | url: `${getOrgUrl()}/msg/index/COMP_ANNOUNCEMENTS,WISH_REMIND,APPROVAL,ATTENDANCE,DEPARTMENT_TRENDS,DOCUMENT,BAMBOO_TRENDS?WORK_OUT=${outWork}&ASK_FOR_LEAVE=${offWork}&CLOCK_OUT=${past}&CLOCK_IN=${past}` 345 | }, 346 | } 347 | } 348 | } 349 | 350 | //补签详情 351 | export function pastBuDetail(uuid) { 352 | return { 353 | type: 'PAST_BU_DETAIL', 354 | payload: { 355 | request: { 356 | method: 'get', 357 | url: getOrgUrl() + '/makeuptime/' + uuid + '.json' 358 | }, 359 | } 360 | } 361 | } 362 | 363 | //同意补签 364 | export function pastAgree(uuid, isRefuse) { 365 | return { 366 | type: 'PAST_BU_DETAIL', 367 | payload: { 368 | request: { 369 | method: 'post', 370 | data: { 371 | uuid, 372 | isRefuse 373 | }, 374 | url: getOrgUrl() + '/makeuptime/reply.json' 375 | }, 376 | } 377 | } 378 | } 379 | 380 | //祝福列表 381 | //start表示页码 length表示每次返回的数据长 draw不用管 382 | export function benedictionIndex(pageNum = 0) { 383 | return { 384 | type: 'BENEDICTION_INDEX', 385 | payload: { 386 | request: { 387 | method: 'get', 388 | url: getOrgUrl() + '/msg/detail/WISH_REMIND?start=' + pageNum + '&length=10&draw=1' 389 | }, 390 | } 391 | } 392 | } 393 | 394 | //新人 生日 周年 生日贺卡 周年贺卡 395 | 396 | //祝福详情 397 | export function benedictionDetail(uuid) { 398 | return { 399 | type: 'BENEDICTION_DETAIL', 400 | payload: { 401 | request: { 402 | method: 'get', 403 | url: getOrgUrl() + '/support/detail/' + uuid 404 | }, 405 | } 406 | } 407 | } 408 | 409 | //祝福图标 410 | export function benedictionIcon(uuid, icon) { 411 | return { 412 | type: 'BENEDICTION_ICON', 413 | payload: { 414 | request: { 415 | method: 'POST', 416 | url: getOrgUrl() + '/support/sources/' + uuid + '/' + icon 417 | }, 418 | } 419 | } 420 | } -------------------------------------------------------------------------------- /client/reducers/user.js: -------------------------------------------------------------------------------- 1 | import {Map, List, fromJS} from 'immutable' 2 | import storage from '../common/storage' 3 | 4 | function user(state = Map({}), aciton) { 5 | 6 | 7 | let data = {}; 8 | switch (aciton.type) { 9 | 10 | //yjj 11 | //获取公出详情 12 | case 'GET_BUSINESS_OUT': 13 | return state; 14 | case 'GET_BUSINESS_OUT_SUCCESS': 15 | data = aciton.payload.data; 16 | return state.setIn(['businessOutDetail', data.uuid], data); 17 | case 'GET_BUSINESS_OUT_FAIL': 18 | return state; 19 | 20 | //公出签到 21 | case 'SIGN_BUSINESS_OUT_SUCCESS': 22 | data = aciton.payload.data; 23 | return state.setIn(['businessOutDetail', data.uuid], data); 24 | //公出驳回 25 | case 'REJECT_BUSINESS_OUT_SUCCESS': 26 | data = aciton.payload.data; 27 | return state.setIn(['businessOutDetail', data.uuid], data); 28 | 29 | //撤销公出信息 30 | case 'DELETE_BUSINESS_OUT': 31 | return state; 32 | case 'DELETE_BUSINESS_OUT_SUCCESS': 33 | data = aciton.payload.data; 34 | return state.deleteIn(['businessOutDetail', data.uuid]); 35 | case 'DELETE_BUSINESS_OUT_FAIL': 36 | return state; 37 | 38 | //获取审批中心 列表 39 | case 'UPDATE_APPROVAL_TAB': 40 | return state.setIn(['approvalListData', 'tabSelected'], String(aciton.tabIndex)) 41 | case 'GET_APPROVAL_LIST': 42 | let type1 = aciton.payload.request.data.type; 43 | return state.setIn(['approvalListData', String(type1), 'loading'], true); 44 | case 'GET_APPROVAL_LIST_SUCCESS': 45 | let {pageIndex, type} = aciton.meta.previousAction.payload.request.data; 46 | let {summary, timestamp, pageData} = aciton.payload.data; 47 | 48 | let oldList = state.getIn(['approvalListData', String(type), 'pageData', 'list']); 49 | if (!(pageIndex == 1)) { 50 | //合并列表 51 | pageData.list = oldList.toJS().concat(pageData.list); 52 | } 53 | state = state.setIn(['approvalListData', 'summary'], fromJS(summary)) 54 | state = state.setIn(['approvalListData', 'timestamp'], fromJS(timestamp)) 55 | state = state.setIn(['approvalListData', String(type), 'pageData'], fromJS(pageData)) 56 | state = state.setIn(['approvalListData', String(type), 'pageParam', 'pageIndex'], pageIndex + 1) 57 | return state.setIn(['approvalListData', String(type), 'loading'], false); 58 | case 'GET_APPROVAL_LIST_FAIL': 59 | let type3 = aciton.meta.previousAction.payload.request.data.type; 60 | return state.setIn(['approvalListData', String(type3), 'loading'], false); 61 | 62 | case 'UPDATE_ATTENDANCE_SELECTED': 63 | console.log(aciton, state); 64 | for (let key in aciton.data) { 65 | state = state.setIn(['attendanceData', 'selected', key], aciton.data[key]) 66 | } 67 | return state; 68 | //考勤中心主页 69 | case 'GET_ATTENDANCE': 70 | return state; 71 | case 'GET_ATTENDANCE_SUCCESS': 72 | let detpId = aciton.meta.previousAction.payload.request.deptUuid; 73 | data = aciton.payload.data || {}; 74 | 75 | if (data && detpId == '' && data.listOrg && data.listOrg[0]) { 76 | state = state.setIn(['attendanceData', 'selected', 'dept'], { 77 | id: data.listOrg[0].id, 78 | name: data.listOrg[0].name 79 | }) 80 | state = state.setIn(['attendanceData', 'data'], fromJS(data)) 81 | } 82 | return state; 83 | case 'GET_ATTENDANCE_FAIL': 84 | return state 85 | 86 | 87 | //班步列表 88 | case 'GET_CATEGORY_LIST': 89 | return state.setIn(['categoryListData', aciton.categoryList, 'loading'], true); 90 | break; 91 | 92 | case 'GET_CATEGORY_LIST_SUCCESS': 93 | const categoryList = aciton.meta.previousAction.categoryList; 94 | state = state.setIn(['categoryListData', categoryList, 'list'], fromJS(aciton.payload.data)) 95 | return state.setIn(['categoryListData', categoryList, 'loading'], false); 96 | break; 97 | case 'GET_CATEGORY_LIST_FAIL': 98 | const categoryList_1 = aciton.meta.previousAction.categoryList; 99 | return state.setIn(['categoryListData', categoryList_1, 'loading'], false); 100 | break; 101 | 102 | 103 | //班步详情列表 104 | case 'GET_CATEGORY_DETAIL': 105 | return state.setIn(['categoryDetail', aciton.category, 'loading'], true); 106 | break; 107 | case 'GET_CATEGORY_DETAIL_SUCCESS': 108 | const category = aciton.meta.previousAction.category; 109 | let {start, length} = aciton.meta.previousAction.payload.request.params; 110 | let b_data = aciton.payload.data.data; 111 | 112 | //判断最后一页 113 | if (b_data.length < length) { 114 | state = state.setIn(['categoryDetail', category, 'pageData', 'hasNextPage'], false) 115 | }else{ 116 | state = state.setIn(['categoryDetail', category, 'pageData', 'hasNextPage'], true) 117 | } 118 | 119 | let b_oldList = state.getIn(['categoryDetail', category, 'pageData', 'list']); 120 | if (!(start == 0)) { 121 | //合并列表 122 | b_data = b_oldList.toJS().concat(b_data); 123 | } 124 | state = state.setIn(['categoryDetail', category, 'pageData', 'list'], fromJS(b_data)) 125 | state = state.setIn(['categoryDetail', category, 'pageParam', 'pageIndex'], start + 2 ) 126 | 127 | return state.setIn(['categoryDetail', category, 'loading'], false); 128 | break; 129 | case 'GET_CATEGORY_DETAIL_FAIL': 130 | const category_1 = aciton.meta.previousAction.category; 131 | state = state.setIn(['categoryDetail', category_1, 'pageData', 'hasNextPage'], false) 132 | return state.setIn(['categoryDetail', category_1, 'loading'], false); 133 | break; 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | //zj 363 | //员工首页 364 | case 'USER_HOME_INITIAL': 365 | return state; 366 | case 'USER_HOME_INITIAL_SUCCESS': 367 | let userHomeInitial = state.get('userHome') ? state.get('userHome').toJS() : []; 368 | userHomeInitial = aciton.payload.data; 369 | 370 | userHomeInitial.map((item, index)=>{ 371 | if(item.type == 'SIGN_IN'){ 372 | state = state.setIn(['defaultTime', 'signIn'], item.startDate); 373 | }else if(item.type == 'SIGN_OUT'){ 374 | state = state.setIn(['defaultTime', 'signOut'], item.startDate); 375 | } 376 | }) 377 | 378 | 379 | return state.setIn(['userHome'], fromJS(userHomeInitial)); 380 | case 'USER_HOME_INITIAL_FAIL': 381 | return state; 382 | 383 | //员工上班签到 384 | case 'USER_PASTIN': 385 | return state; 386 | case 'USER_PASTIN_SUCCESS': 387 | aciton.meta.previousAction.payload.callBack(aciton.payload); 388 | return state; 389 | case 'USER_PASTIN_FAIL': 390 | aciton.meta.previousAction.payload.callBack(aciton.error.message); 391 | return state; 392 | //员工下班打卡 393 | case 'USER_PASTOUT': 394 | return state; 395 | case 'USER_PASTOUT_SUCCESS': 396 | aciton.meta.previousAction.payload.callBack(aciton.payload); 397 | return state; 398 | case 'USER_PASTOUT_FAIL': 399 | aciton.meta.previousAction.payload.callBack(aciton.error.message); 400 | return state; 401 | 402 | // 员工补打卡 403 | case 'USER_PASTBU': 404 | return state; 405 | case 'USER_PASTBU_SUCCESS': 406 | aciton.meta.previousAction.payload.callBack(aciton.payload.data.message); 407 | return state; 408 | case 'USER_PASTBU_FAIL': 409 | aciton.meta.previousAction.payload.callBack(aciton.error.message); 410 | return state; 411 | 412 | //假期类型 413 | case 'GET_HOLIDAY_TYPE': 414 | return state; 415 | case 'GET_HOLIDAY_TYPE_SUCCESS': 416 | let getHolidayType = state.get('holidayType') ? state.get('holidayType').toJS() : []; 417 | getHolidayType = aciton.payload.data; 418 | return state.setIn(['holidayType'], fromJS(getHolidayType)); 419 | case 'GET_HOLIDAY_TYPE_FAIL': 420 | return state; 421 | 422 | //请假申请 423 | case 'SUBMIT_OFF_APPLY': 424 | return state; 425 | case 'SUBMIT_OFF_APPLY_SUCCESS': 426 | let offWorkApply = state.get('offWorkApply') ? state.get('offWorkApply').toJS() : []; 427 | offWorkApply = aciton.payload; 428 | return state.setIn(['offWorkApply'], fromJS(offWorkApply)); 429 | case 'SUBMIT_OFF_APPLY_FAIL': 430 | return state; 431 | //提交请假证明 432 | case 'UPDATE_WORK_OFF_SUCCESS': 433 | return state.setIn(['getOffWorkDetail', aciton.payload.data.uuid], fromJS(aciton.payload.data)) 434 | //请假详情 435 | case 'GET_OFF_DETAIL': 436 | return state; 437 | case 'GET_OFF_DETAIL_SUCCESS': 438 | let getOffWorkDetail = state.get('getOffWorkDetail') ? state.get('getOffWorkDetail').toJS() : []; 439 | getOffWorkDetail = aciton.payload.data; 440 | return state.setIn(['getOffWorkDetail', aciton.payload.data.uuid], fromJS(getOffWorkDetail)); 441 | case 'GET_OFF_DETAIL_FAIL': 442 | return state; 443 | //班步首页 444 | case 'MESSAGE_LIST': 445 | return state; 446 | case 'MESSAGE_LIST_SUCCESS': 447 | 448 | let aa = storage.getItem('approvalListData.timestamp') 449 | console.log('aa', aa) 450 | return state 451 | 452 | let messageList = state.get('messageList') ? state.get('messageList').toJS() : []; 453 | messageList = aciton.payload.data; 454 | return state.setIn(['messageList'], fromJS(messageList)); 455 | case 'MESSAGE_LIST_FAIL': 456 | return state; 457 | 458 | //补签详情 PAST_BU_DETAIL 459 | case 'PAST_BU_DETAIL': 460 | return state; 461 | case 'PAST_BU_DETAIL_SUCCESS': 462 | let pastBuDetail = state.get('pastBuDetail') ? state.get('pastBuDetail').toJS() : []; 463 | pastBuDetail = aciton.payload.data; 464 | return state.setIn(['pastBuDetail', aciton.payload.data.uuid], fromJS(pastBuDetail)); 465 | case 'PAST_BU_DETAIL_FAIL': 466 | return state; 467 | 468 | //祝福详情BENEDICTION_DETAIL 469 | case 'BENEDICTION_DETAIL': 470 | return state; 471 | case 'BENEDICTION_DETAIL_SUCCESS': 472 | let benedictionDetail = state.get('benedictionDetail') ? state.get('benedictionDetail').toJS() : {}; 473 | benedictionDetail = aciton.payload.data; 474 | return state.setIn(['benedictionDetail'], fromJS(benedictionDetail)); 475 | case 'BENEDICTION_DETAIL_FAIL': 476 | return state; 477 | 478 | default: 479 | return state; 480 | } 481 | } 482 | 483 | 484 | export default user; --------------------------------------------------------------------------------