diff --git a/back/root/fo/src/main/java/sample/ustraframework/java/fo/config/InterfaceConfiguration.java b/back/root/fo/src/main/java/sample/ustraframework/java/fo/config/InterfaceConfiguration.java new file mode 100644 index 0000000..2b9299d --- /dev/null +++ b/back/root/fo/src/main/java/sample/ustraframework/java/fo/config/InterfaceConfiguration.java @@ -0,0 +1,19 @@ +package sample.ustraframework.java.fo.config; + +import java.io.IOException; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.gsitm.ustra.java.core.utils.UstraResourceUtils; +import com.gsitm.ustra.java.data.logging.interfaces.provider.InterfaceInfoProvider; +import com.gsitm.ustra.java.data.logging.interfaces.provider.XmlResourceInterfaceInfoProvider; + +@Configuration +public class InterfaceConfiguration { + + @Bean + public InterfaceInfoProvider interfaceInfoProvider() throws IOException { + return new XmlResourceInterfaceInfoProvider(UstraResourceUtils.getResourcesByPattern("classpath*:/data/interfaces-*.xml")); + } +} diff --git a/back/root/fo/src/main/java/sample/ustraframework/java/fo/sample/interfaces/InterfaceApiController.java b/back/root/fo/src/main/java/sample/ustraframework/java/fo/sample/interfaces/InterfaceApiController.java new file mode 100644 index 0000000..80e92ea --- /dev/null +++ b/back/root/fo/src/main/java/sample/ustraframework/java/fo/sample/interfaces/InterfaceApiController.java @@ -0,0 +1,26 @@ +package sample.ustraframework.java.fo.sample.interfaces; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.gsitm.ustra.java.data.logging.interfaces.info.InterfaceInfo; +import com.gsitm.ustra.java.data.logging.interfaces.store.InterfaceInfoStore; + +@RestController +public class InterfaceApiController { + + @Autowired private InterfaceInfoStore interfaceInfoStore; + + @RequestMapping("/api/interface/all") + public List interfaceStore() { + return this.interfaceInfoStore.getAll() + .entrySet().stream() + .map(e->e.getValue()) + .collect(Collectors.toList()); + } + +} diff --git a/back/root/fo/src/main/resources/application.yml b/back/root/fo/src/main/resources/application.yml index 3bcc01d..78dd47e 100644 --- a/back/root/fo/src/main/resources/application.yml +++ b/back/root/fo/src/main/resources/application.yml @@ -34,6 +34,9 @@ ustra: driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy username: ENC(p6rIPoShJklFLPxHKNJYFLooNCd2xnkayNZ2f+GexyA17qEMS77u8g==) password: ENC(ohS/a1/Q/lKriwUq3rqJqht76fQ0Bnge) + logging: + interfaces: + enabled: true mvc: view: api-prefix: api diff --git a/back/root/fo/src/main/resources/data/interfaces-sample.xml b/back/root/fo/src/main/resources/data/interfaces-sample.xml new file mode 100644 index 0000000..8b8e744 --- /dev/null +++ b/back/root/fo/src/main/resources/data/interfaces-sample.xml @@ -0,0 +1,31 @@ + + + + IF-INBOUD-MOBILE01 + 1.0 + 모바일 인바운드 API + MOBILE_BRIDGE + ALL + INBOUND + FO + 샘플로 정의된 모바일 인바운드 API + + value1 + value2 + + + + IF-OUTBOUND-MOBILE01 + 1.0 + 모바일 아웃바운드 API + MOBILE_BRIDGE + ALL + OUTBOUND + FO + 샘플로 정의된 모바일 아웃바운드 API + + value1 + value2 + + + \ No newline at end of file diff --git a/front/fo/client/assets/global.scss b/front/fo/client/assets/global.scss index f6d9dd0..c0ef7ef 100644 --- a/front/fo/client/assets/global.scss +++ b/front/fo/client/assets/global.scss @@ -1,3 +1,155 @@ +@font-face { + font-family: NotoSansKR; + font-weight: 100; + font-style: normal; + src: url('/fonts/NotoSansKR-Thin.woff') format('woff'), url('/fonts/NotoSansKR-Thin.woff2') format('woff2'), url('/fonts/NotoSansKR-Thin.otf') format('opentype'); +} + +@font-face { + font-family: NotoSansKR; + font-weight: 300; + font-style: normal; + src: url('/fonts/NotoSansKR-Light.woff') format('woff'), url('/fonts/NotoSansKR-Light.woff2') format('woff2'), url('/fonts/NotoSansKR-Light.otf') format('opentype'); +} + +@font-face { + font-family: NotoSansKR; + font-weight: 400; + font-style: normal; + src: url('/fonts/NotoSansKR-Regular.woff') format('woff'), url('/fonts/NotoSansKR-Regular.woff2') format('woff2'), url('/fonts/NotoSansKR-Regular.otf') format('opentype'); +} + +@font-face { + font-family: NotoSansKR; + font-weight: 500; + font-style: normal; + src: url('/fonts/NotoSansKR-Medium.woff') format('woff'), url('/fonts/NotoSansKR-Medium.woff2') format('woff2'), url('/fonts/NotoSansKR-Medium.otf') format('opentype'); +} + +@font-face { + font-family: NotoSansKR; + font-weight: 700; + font-style: normal; + src: url('/fonts/NotoSansKR-Bold.woff') format('woff'), url('/fonts/NotoSansKR-Bold.woff2') format('woff2'), url('/fonts/NotoSansKR-Bold.otf') format('opentype'); +} + +@font-face { + font-family: NotoSansKR; + font-weight: 900; + font-style: normal; + src: url('/fonts/NotoSansKR-Black.woff') format('woff'), url('/fonts/NotoSansKR-Black.woff2') format('woff2'), url('/fonts/NotoSansKR-Black.otf') format('opentype'); +} + .sub-page-section { padding: 50px 0; } + +html, +body, +#__nuxt, +#__layout { + width: 100%; + height: 100%; +} + +#__layout { + display: flex; +} + +body, +code, +input, +textarea, +select { + font-family: NotoSansKR !important; + font-weight: 400; +} + +.container { + margin: 0 auto; + width: auto; + position: relative; + flex-grow: 1; +} + +.sidebar.b-sidebar { + & .sidebar-content { + min-width: 260px; + width: revert; + padding: 5px; + } +} + +.documentation { + position: relative; + + &:after &:before { + box-sizing: inherit; + } + .docs-template-horizontal { + position: relative; + display: flex; + flex-direction: row; + flex: 1; + + .sidebar { + display: flex; + flex-direction: column; + flex-shrink: 0; + // width: 16rem; + padding: 3rem 1rem; + background: #f5f5f5; + + .sidebar-menu { + width: 100%; + } + } + + .docs-main { + position: relative; + background: #fff; + overflow: hidden; + width: 100%; + + .docs-main-container { + padding: 3rem; + } + } + } + + .sidebar-bg { + position: absolute; + bottom: 0; + right: 50%; + left: 0; + top: 0; + background: #f5f5f5; + } +} + +.section-top { + margin-top: 60px; +} + +.ref-section { + padding: 60px; + display: flex; + flex-direction: column; + justify-content: center; +} + +.page-enter-active, +.page-leave-active { + transition: all 0.25s ease-out; +} +.page-enter, +.page-leave-active { + opacity: 0; + transform-origin: 50% 50%; +} + +.guide-index-button { + position: fixed; + bottom: 30px; + right: 30px; +} diff --git a/front/fo/client/components/layout/layout-navbar.vue b/front/fo/client/components/layout/layout-navbar.vue index 212c0ee..9b4a202 100644 --- a/front/fo/client/components/layout/layout-navbar.vue +++ b/front/fo/client/components/layout/layout-navbar.vue @@ -10,11 +10,13 @@ Home Introduce Customer + Sample @@ -38,6 +40,10 @@ export default class extends CustomFoComponent { return startsWith(this.$route.path, '/customer') } + get isActiveSample() { + return startsWith(this.$route.path, '/sample') + } + get isAuthenticated() { return this.$ustra.auth.isAutenticated() } diff --git a/front/fo/client/pages/customer/index.vue b/front/fo/client/pages/customer/index.vue index b87fb18..944e602 100644 --- a/front/fo/client/pages/customer/index.vue +++ b/front/fo/client/pages/customer/index.vue @@ -9,6 +9,10 @@ +
+
샘플 로그인 화면입니다. sample/sample 계정을 사용하여 로그인이 가능합니다.
+
+ Login @@ -37,7 +41,7 @@ export default class extends CustomFoComponent { }, }) - this.$router.push('/') + this.$router.push((this.$route.query.rtnUrl as string) || '/') } // #endregion // #region watches diff --git a/front/fo/client/pages/sample.vue b/front/fo/client/pages/sample.vue new file mode 100644 index 0000000..abbaa87 --- /dev/null +++ b/front/fo/client/pages/sample.vue @@ -0,0 +1,52 @@ + + + diff --git a/front/fo/client/pages/sample/index.vue b/front/fo/client/pages/sample/index.vue new file mode 100644 index 0000000..ed6f518 --- /dev/null +++ b/front/fo/client/pages/sample/index.vue @@ -0,0 +1,27 @@ + + + diff --git a/front/fo/client/pages/sample/md/mobile01.md b/front/fo/client/pages/sample/md/mobile01.md new file mode 100644 index 0000000..38910b6 --- /dev/null +++ b/front/fo/client/pages/sample/md/mobile01.md @@ -0,0 +1,11 @@ +```typescript +callOutbound() { + this.$ustra.mobile.bridge.callNative({ + id: 'IF-OUTBOUND-MOBILE01', + callback: result => { + console.log('result', result) + }, + timeout: 2000, + }) +} +``` \ No newline at end of file diff --git a/front/fo/client/pages/sample/md/mobile02.md b/front/fo/client/pages/sample/md/mobile02.md new file mode 100644 index 0000000..539ce64 --- /dev/null +++ b/front/fo/client/pages/sample/md/mobile02.md @@ -0,0 +1,9 @@ +```typescript +this.$ustra.mobile.bridge.addNativeListener('IF-INBOUD-MOBILE01', data => { + console.log('nativate inbound data', data) +}) + +// 브라우저 콘솔 창에서 아래와 같이 테스트 수행 +window['IF_INBOUD_MOBILE01']({ data: { param1: 'value1' }}) +``` + diff --git a/front/fo/client/pages/sample/mobile.vue b/front/fo/client/pages/sample/mobile.vue new file mode 100644 index 0000000..12cef25 --- /dev/null +++ b/front/fo/client/pages/sample/mobile.vue @@ -0,0 +1,63 @@ + + + diff --git a/front/fo/nuxt.config.ts b/front/fo/nuxt.config.ts index 9d8536e..0b6ecfe 100644 --- a/front/fo/nuxt.config.ts +++ b/front/fo/nuxt.config.ts @@ -12,7 +12,7 @@ export default async () => { title: 'U.STRA Node Framework Sample - FO', auth: { enabled: true, - loginUrl: '/', + loginUrl: '/customer', jwt: { useCookie: false, accessTokenKey: 'sample-fo-token', @@ -40,6 +40,7 @@ export default async () => { css: true, materialDesignIcons: true, }, + useMarkdown: true, }, css: ['~/assets/global.scss'], head: { @@ -50,6 +51,22 @@ export default async () => { generateDirPath: '../../../back/root/fo/src/main/resources/static', generateProfiles: [env.Profile.DEV, env.Profile.STAGING, env.Profile.PRODUCTION], }, + interfaces: { + initialDataApiUrl: '/api/interface/all', + }, + mobile: { + enabled: true, + hybrid: { + nativeAgent: { + android: 'client1', + ios: 'client2', + }, + bridge: { + enabled: true, + useTokenSecurity: false, + }, + }, + }, }, }