├── src
├── app
│ ├── shared
│ │ ├── components
│ │ │ ├── shop
│ │ │ │ ├── list
│ │ │ │ │ ├── shop-list.scss
│ │ │ │ │ ├── shop-list.ts
│ │ │ │ │ └── shop-list.html
│ │ │ │ ├── search
│ │ │ │ │ ├── shop-search.ts
│ │ │ │ │ ├── shop-search.html
│ │ │ │ │ └── shop-search.scss
│ │ │ │ ├── msite
│ │ │ │ │ ├── shop-msite.ts
│ │ │ │ │ ├── shop-msite.html
│ │ │ │ │ └── shop-msite.scss
│ │ │ │ └── evaluate
│ │ │ │ │ ├── evaluate.ts
│ │ │ │ │ └── evaluate.html
│ │ │ ├── index.ts
│ │ │ ├── svg
│ │ │ │ └── svg.ts
│ │ │ ├── login-header
│ │ │ │ ├── login-header.html
│ │ │ │ ├── login-header.scss
│ │ │ │ └── login-header.ts
│ │ │ ├── rating-star
│ │ │ │ ├── rating-star.ts
│ │ │ │ ├── rating-star.scss
│ │ │ │ └── rating-star.html
│ │ │ ├── loading
│ │ │ │ ├── loading.html
│ │ │ │ ├── loading.ts
│ │ │ │ └── loading.scss
│ │ │ ├── back
│ │ │ │ ├── back-header.ts
│ │ │ │ └── back-icon.ts
│ │ │ ├── buy-cart
│ │ │ │ ├── buy-cart.html
│ │ │ │ ├── buy-cart.scss
│ │ │ │ └── buy-cart.ts
│ │ │ └── components.module.ts
│ │ ├── index.ts
│ │ └── shared.module.ts
│ ├── class
│ │ ├── index.ts
│ │ └── userinfo.ts
│ ├── core
│ │ ├── index.ts
│ │ └── core.module.ts
│ ├── tabs
│ │ ├── tabs.page.scss
│ │ ├── tabs.page.ts
│ │ ├── tabs.page.html
│ │ ├── tabs.module.ts
│ │ └── tabs.router.module.ts
│ ├── config
│ │ └── env.ts
│ ├── app.component.html
│ ├── service
│ │ ├── index.ts
│ │ ├── convert-request.service.ts
│ │ ├── localstorage.service.ts
│ │ ├── shop.service.ts
│ │ ├── app.service.ts
│ │ └── cart.service.ts
│ ├── shop
│ │ ├── evaluate
│ │ │ ├── evaluate.page.html
│ │ │ ├── evaluate.module.ts
│ │ │ └── evaluate.page.ts
│ │ ├── detail
│ │ │ ├── shop-detail.module.ts
│ │ │ ├── shop-detail.page.ts
│ │ │ └── shop-detail.page.html
│ │ └── shop.module.ts
│ ├── food
│ │ └── food.module.ts
│ ├── home
│ │ ├── home.module.ts
│ │ ├── home.page.html
│ │ ├── home.page.ts
│ │ └── home.page.scss
│ ├── city
│ │ ├── city.module.ts
│ │ ├── city.page.html
│ │ ├── city.page.scss
│ │ └── city.page.ts
│ ├── login
│ │ ├── login.module.ts
│ │ ├── login.page.html
│ │ ├── login.page.scss
│ │ └── login.page.ts
│ ├── msite
│ │ ├── msite.module.ts
│ │ ├── msite.page.scss
│ │ ├── msite.page.html
│ │ └── msite.page.ts
│ ├── search
│ │ ├── search.module.ts
│ │ ├── search.page.html
│ │ ├── search.page.scss
│ │ └── search.page.ts
│ ├── profile
│ │ ├── profile.module.ts
│ │ ├── profile.page.ts
│ │ ├── profile.page.html
│ │ └── profile.page.scss
│ ├── order
│ │ ├── order-detail
│ │ │ ├── order-detail.module.ts
│ │ │ ├── order-detail.page.ts
│ │ │ ├── order-detail.page.html
│ │ │ └── order-detail.page.scss
│ │ ├── order.module.ts
│ │ ├── time-last.pipe.ts
│ │ ├── order.page.html
│ │ ├── order.page.ts
│ │ └── order.page.scss
│ ├── confirm-order
│ │ ├── remark
│ │ │ ├── remark.module.ts
│ │ │ ├── remark.page.html
│ │ │ ├── remark.page.ts
│ │ │ └── remark.page.scss
│ │ ├── choose-address
│ │ │ ├── choose-address.module.ts
│ │ │ ├── choose-address.page.scss
│ │ │ ├── choose-address.page.ts
│ │ │ └── choose-address.page.html
│ │ ├── payment
│ │ │ ├── payment.module.ts
│ │ │ ├── time-last.pipe.ts
│ │ │ ├── payment.page.html
│ │ │ ├── payment.page.ts
│ │ │ └── payment.page.scss
│ │ └── confirm-order.module.ts
│ ├── address
│ │ ├── add-address
│ │ │ ├── add-address.module.ts
│ │ │ ├── add-address.page.scss
│ │ │ ├── add-address.page.html
│ │ │ └── add-address.page.ts
│ │ ├── search-address
│ │ │ ├── search-address.module.ts
│ │ │ ├── search-address.page.html
│ │ │ ├── search-address.page.ts
│ │ │ └── search-address.page.scss
│ │ ├── address.module.ts
│ │ ├── address.page.ts
│ │ ├── address.page.html
│ │ └── address.page.scss
│ ├── app.component.ts
│ ├── app-routing.module.ts
│ └── app.module.ts
├── assets
│ ├── imgs
│ │ ├── logo.png
│ │ ├── qq.png
│ │ ├── jifen.jpeg
│ │ ├── no-log.png
│ │ ├── order.png
│ │ ├── search.png
│ │ ├── sheng.jpeg
│ │ ├── weixin.png
│ │ ├── activity.png
│ │ ├── add_phone.png
│ │ ├── bindphone.png
│ │ ├── elmlogo.jpeg
│ │ ├── expired.png
│ │ ├── fenxiang.png
│ │ ├── hongbao.png
│ │ ├── qianbao.png
│ │ ├── voucher.png
│ │ ├── zhifubao.png
│ │ ├── add_address.png
│ │ ├── description.png
│ │ ├── icon_point.png
│ │ ├── address_bottom.png
│ │ ├── icon_loading.png
│ │ ├── shopback.svg
│ │ └── fl.svg
│ ├── icon
│ │ ├── favicon.png
│ │ ├── mine.svg
│ │ ├── elm.svg
│ │ └── find.svg
│ ├── rem.js
│ └── shapes.svg
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── proxy.conf.json
├── zone-flags.ts
├── main.ts
├── test.ts
├── index.html
├── global.scss
├── style
│ ├── common.scss
│ ├── ionic.scss
│ └── mixin.scss
└── polyfills.ts
├── ionic.config.json
├── resources
├── icon.png
├── splash.png
├── ios
│ ├── icon
│ │ ├── icon.png
│ │ ├── icon-40.png
│ │ ├── icon-50.png
│ │ ├── icon-60.png
│ │ ├── icon-72.png
│ │ ├── icon-76.png
│ │ ├── icon@2x.png
│ │ ├── icon-1024.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-50@2x.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-72@2x.png
│ │ ├── icon-76@2x.png
│ │ ├── icon-small.png
│ │ ├── icon-83.5@2x.png
│ │ ├── icon-small@2x.png
│ │ └── icon-small@3x.png
│ └── splash
│ │ ├── Default-667h.png
│ │ ├── Default-736h.png
│ │ ├── Default~iphone.png
│ │ ├── Default@2x~iphone.png
│ │ ├── Default-Portrait~ipad.png
│ │ ├── Default-568h@2x~iphone.png
│ │ ├── Default-Landscape-736h.png
│ │ ├── Default-Landscape~ipad.png
│ │ ├── Default-Portrait@2x~ipad.png
│ │ ├── Default-Landscape@2x~ipad.png
│ │ ├── Default-Landscape@~ipadpro.png
│ │ ├── Default-Portrait@~ipadpro.png
│ │ └── Default@2x~universal~anyany.png
├── android
│ ├── icon
│ │ ├── drawable-hdpi-icon.png
│ │ ├── drawable-ldpi-icon.png
│ │ ├── drawable-mdpi-icon.png
│ │ ├── drawable-xhdpi-icon.png
│ │ ├── drawable-xxhdpi-icon.png
│ │ └── drawable-xxxhdpi-icon.png
│ └── splash
│ │ ├── drawable-land-hdpi-screen.png
│ │ ├── drawable-land-ldpi-screen.png
│ │ ├── drawable-land-mdpi-screen.png
│ │ ├── drawable-port-hdpi-screen.png
│ │ ├── drawable-port-ldpi-screen.png
│ │ ├── drawable-port-mdpi-screen.png
│ │ ├── drawable-land-xhdpi-screen.png
│ │ ├── drawable-land-xxhdpi-screen.png
│ │ ├── drawable-port-xhdpi-screen.png
│ │ ├── drawable-port-xxhdpi-screen.png
│ │ ├── drawable-land-xxxhdpi-screen.png
│ │ └── drawable-port-xxxhdpi-screen.png
└── README.md
├── screenshots
├── food.gif
├── login.gif
├── msite.gif
├── shop1.gif
├── shop2.gif
├── tabs.gif
└── search.gif
├── .gitattributes
├── e2e
├── tsconfig.e2e.json
├── src
│ ├── app.po.ts
│ └── app.e2e-spec.ts
├── tsconfig.json
└── protractor.conf.js
├── tsconfig.spec.json
├── tsconfig.app.json
├── browserslist
├── tsconfig.json
├── .gitignore
├── karma.conf.js
├── package.json
├── README.md
└── tslint.json
/src/app/shared/components/shop/list/shop-list.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/class/index.ts:
--------------------------------------------------------------------------------
1 | export * from './userinfo';
2 |
--------------------------------------------------------------------------------
/src/app/core/index.ts:
--------------------------------------------------------------------------------
1 | export * from './core.module';
2 |
--------------------------------------------------------------------------------
/src/app/shared/index.ts:
--------------------------------------------------------------------------------
1 | export * from './shared.module';
2 |
--------------------------------------------------------------------------------
/src/app/tabs/tabs.page.scss:
--------------------------------------------------------------------------------
1 | ion-tabbar {
2 | height: 2rem;
3 | }
--------------------------------------------------------------------------------
/src/app/shared/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components.module';
2 |
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "elmApp",
3 | "integrations": {},
4 | "type": "angular"
5 | }
6 |
--------------------------------------------------------------------------------
/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/icon.png
--------------------------------------------------------------------------------
/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/splash.png
--------------------------------------------------------------------------------
/screenshots/food.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/food.gif
--------------------------------------------------------------------------------
/screenshots/login.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/login.gif
--------------------------------------------------------------------------------
/screenshots/msite.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/msite.gif
--------------------------------------------------------------------------------
/screenshots/shop1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/shop1.gif
--------------------------------------------------------------------------------
/screenshots/shop2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/shop2.gif
--------------------------------------------------------------------------------
/screenshots/tabs.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/tabs.gif
--------------------------------------------------------------------------------
/src/app/config/env.ts:
--------------------------------------------------------------------------------
1 | const ImgBaseUrl = 'http://cangdu.org:8001/img/';
2 |
3 | export {ImgBaseUrl};
4 |
--------------------------------------------------------------------------------
/screenshots/search.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/screenshots/search.gif
--------------------------------------------------------------------------------
/src/assets/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/logo.png
--------------------------------------------------------------------------------
/src/assets/imgs/qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/qq.png
--------------------------------------------------------------------------------
/src/assets/imgs/jifen.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/jifen.jpeg
--------------------------------------------------------------------------------
/src/assets/imgs/no-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/no-log.png
--------------------------------------------------------------------------------
/src/assets/imgs/order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/order.png
--------------------------------------------------------------------------------
/src/assets/imgs/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/search.png
--------------------------------------------------------------------------------
/src/assets/imgs/sheng.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/sheng.jpeg
--------------------------------------------------------------------------------
/src/assets/imgs/weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/weixin.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon.png
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/assets/icon/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/icon/favicon.png
--------------------------------------------------------------------------------
/src/assets/imgs/activity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/activity.png
--------------------------------------------------------------------------------
/src/assets/imgs/add_phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/add_phone.png
--------------------------------------------------------------------------------
/src/assets/imgs/bindphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/bindphone.png
--------------------------------------------------------------------------------
/src/assets/imgs/elmlogo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/elmlogo.jpeg
--------------------------------------------------------------------------------
/src/assets/imgs/expired.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/expired.png
--------------------------------------------------------------------------------
/src/assets/imgs/fenxiang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/fenxiang.png
--------------------------------------------------------------------------------
/src/assets/imgs/hongbao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/hongbao.png
--------------------------------------------------------------------------------
/src/assets/imgs/qianbao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/qianbao.png
--------------------------------------------------------------------------------
/src/assets/imgs/voucher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/voucher.png
--------------------------------------------------------------------------------
/src/assets/imgs/zhifubao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/zhifubao.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-40.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-50.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-60.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-72.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-76.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon@2x.png
--------------------------------------------------------------------------------
/src/assets/imgs/add_address.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/add_address.png
--------------------------------------------------------------------------------
/src/assets/imgs/description.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/description.png
--------------------------------------------------------------------------------
/src/assets/imgs/icon_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/icon_point.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-1024.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-40@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-40@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-50@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-60@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-60@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-72@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-76@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-small.png
--------------------------------------------------------------------------------
/src/assets/imgs/address_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/address_bottom.png
--------------------------------------------------------------------------------
/src/assets/imgs/icon_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/src/assets/imgs/icon_loading.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-83.5@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-small@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/icon/icon-small@3x.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | apiUrl: 'http://cangdu.org:8001'
4 | };
5 |
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-hdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-hdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-ldpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-ldpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-mdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-mdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-xhdpi-icon.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-xxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/icon/drawable-xxxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Landscape@~ipadpro.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default-Portrait@~ipadpro.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~universal~anyany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/ios/splash/Default@2x~universal~anyany.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-xxhdpi-screen.png
--------------------------------------------------------------------------------
/src/proxy.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "/": {
3 | "target": "https://elm.cangdu.org",
4 | "changeOrigin": true,
5 | "secure": false,
6 | "logLevel": "debug"
7 | }
8 | }
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-land-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuonuoge/ionic6_angular10_elm/HEAD/resources/android/splash/drawable-port-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/src/zone-flags.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Prevents Angular change detection from
3 | * running with certain Web Component callbacks
4 | */
5 | (window as any).__Zone_disable_customElements = true;
6 |
--------------------------------------------------------------------------------
/src/app/service/index.ts:
--------------------------------------------------------------------------------
1 | export * from './data.service';
2 | export * from './localstorage.service';
3 | export * from './cart.service';
4 | export * from './shop.service';
5 | export * from './app.service';
6 |
--------------------------------------------------------------------------------
/src/app/shared/components/svg/svg.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'elm-svg',
5 | templateUrl: 'svg.html'
6 | })
7 | export class ElmSvgComponent {
8 | }
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | *.ts linguist-language=TypeScript
3 | *.js linguist-language=TypeScript
4 | *.html linguist-language=TypeScript
5 | *.scss linguist-language=TypeScript
--------------------------------------------------------------------------------
/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/shop/evaluate/evaluate.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getPageTitle() {
9 | return element(by.css('ion-title')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/tabs/tabs.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-tabs',
5 | templateUrl: 'tabs.page.html',
6 | styleUrls: ['tabs.page.scss']
7 | })
8 | export class TabsPage {
9 | constructor() {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/shared/components/login-header/login-header.html:
--------------------------------------------------------------------------------
1 | 登录|注册
2 |
--------------------------------------------------------------------------------
/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "jasminewd2",
10 | "node"
11 | ]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/shared/components/rating-star/rating-star.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'rating-star',
5 | templateUrl: 'rating-star.html',
6 | styleUrls: ['rating-star.scss']
7 | })
8 | export class RatingStarComponent {
9 | @Input() rating: number;
10 | }
11 |
--------------------------------------------------------------------------------
/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('new App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should display welcome message', () => {
11 | page.navigateTo();
12 | expect(page.getPageTitle()).toContain('Tab 1');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/spec",
5 | "types": [
6 | "jasmine",
7 | "node"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/core/core.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | @NgModule({
5 | imports: [
6 | CommonModule,
7 | FormsModule
8 | ],
9 | declarations: [
10 | ],
11 | exports: [
12 | ],
13 | entryComponents: []
14 | })
15 | export class CoreModule {}
16 |
--------------------------------------------------------------------------------
/src/app/shared/components/login-header/login-header.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../style/mixin.scss";
2 | :host {
3 | position: absolute;
4 | right: 0;
5 | top: calc(50% - .55rem);
6 | font-size: 1.1rem;
7 | }
8 | .login_span {
9 | margin-right: .8rem;
10 | color: #fff;
11 | }
12 | .user_avatar {
13 | margin-right: .8rem;
14 | @include wh(1.33rem, 1.33rem);
15 | fill: #fff;
16 | }
--------------------------------------------------------------------------------
/src/app/shared/components/shop/list/shop-list.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'shop-list',
5 | templateUrl: 'shop-list.html'
6 | })
7 | export class ShoplistComponent {
8 | @Input() shopList: any;
9 | @Input() type: string;
10 | @Input() geohash: string;
11 | touchend: boolean;
12 | showBackStatus: string;
13 | constructor() {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/food/food.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { FoodPage } from './food.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: FoodPage }])
10 | ],
11 | declarations: [FoodPage]
12 | })
13 | export class FoodPageModule {}
14 |
--------------------------------------------------------------------------------
/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { HomePage } from './home.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: HomePage }])
10 | ],
11 | declarations: [HomePage]
12 | })
13 | export class HomePageModule {}
14 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/src/app/city/city.module.ts:
--------------------------------------------------------------------------------
1 |
2 | import { RouterModule } from '@angular/router';
3 | import { NgModule } from '@angular/core';
4 | import { SharedModule } from '../shared';
5 | import { CityPage } from './city.page';
6 |
7 | @NgModule({
8 | imports: [
9 | SharedModule,
10 | RouterModule.forChild([{ path: '', component: CityPage }])
11 | ],
12 | declarations: [CityPage]
13 | })
14 | export class CityPageModule {}
15 |
--------------------------------------------------------------------------------
/src/app/login/login.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { LoginPage } from './login.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: LoginPage }])
10 | ],
11 | declarations: [LoginPage]
12 | })
13 | export class LoginPageModule {}
14 |
--------------------------------------------------------------------------------
/src/app/msite/msite.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { MsitePage } from './msite.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: MsitePage }])
10 | ],
11 | declarations: [MsitePage]
12 | })
13 | export class MsitePageModule {}
14 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/search/shop-search.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { ImgBaseUrl } from '../../../../config/env';
3 |
4 | @Component({
5 | selector: 'shop-search',
6 | templateUrl: 'shop-search.html',
7 | styleUrls: ['shop-search.scss']
8 | })
9 | export class ShopSearchComponent {
10 | @Input() shop: any;
11 | imgBaseUrl = ImgBaseUrl;
12 | constructor() {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/app/search/search.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { SearchPage } from './search.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: SearchPage }])
10 | ],
11 | declarations: [SearchPage]
12 | })
13 | export class SearchPageModule {}
14 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/app",
5 | "types": []
6 | },
7 | "files": [
8 | "src/main.ts",
9 | "src/polyfills.ts"
10 | ],
11 | "include": [
12 | "src/**/*.ts",
13 | "src/**/*.d.ts"
14 | ],
15 | "exclude": [
16 | "src/test.ts",
17 | "src/**/*.spec.ts",
18 | "src/environments/environment.prod.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/profile/profile.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { ProfilePage } from './profile.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: ProfilePage }])
10 | ],
11 | declarations: [ProfilePage]
12 | })
13 | export class ProfilePageModule {}
14 |
--------------------------------------------------------------------------------
/resources/README.md:
--------------------------------------------------------------------------------
1 | These are Cordova resources. You can replace icon.png and splash.png and run
2 | `ionic cordova resources` to generate custom icons and splash screens for your
3 | app. See `ionic cordova resources --help` for details.
4 |
5 | Cordova reference documentation:
6 |
7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
9 |
--------------------------------------------------------------------------------
/src/app/shop/detail/shop-detail.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { ShopDetailPage } from './shop-detail.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: ShopDetailPage }])
10 | ],
11 | declarations: [ShopDetailPage]
12 | })
13 | export class ShopDetailPageModule {}
14 |
15 |
--------------------------------------------------------------------------------
/src/app/shop/evaluate/evaluate.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { ShopEvaluatePage } from './evaluate.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: ShopEvaluatePage }])
10 | ],
11 | declarations: [ShopEvaluatePage]
12 | })
13 | export class ShopEvaluatePageModule {}
14 |
--------------------------------------------------------------------------------
/browserslist:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # You can see what browsers were selected by your queries by running:
6 | # npx browserslist
7 |
8 | > 0.5%
9 | last 2 versions
10 | Firefox ESR
11 | not dead
12 | not IE 9-11 # For IE 9-11 support, remove 'not'.
13 |
--------------------------------------------------------------------------------
/src/app/order/order-detail/order-detail.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule } from '@angular/router';
3 | import { SharedModule } from '../../shared';
4 | import { OrderDetailPage } from './order-detail.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([{ path: '', component: OrderDetailPage }])
10 | ],
11 | declarations: [OrderDetailPage]
12 | })
13 | export class OrderDetailPageModule {}
14 |
15 |
--------------------------------------------------------------------------------
/src/app/shared/components/back/back-header.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'back-header',
5 | template: `
6 |
7 |
8 | {{hTitle}}
9 |
10 | `,
11 | styles: [`
12 | .back-icon {
13 | margin: 0 -5px 0 -4px;
14 | }
15 | `]
16 | })
17 | export class BackHeaderComponent {
18 | @Input() hTitle: string;
19 | }
20 |
--------------------------------------------------------------------------------
/src/app/confirm-order/remark/remark.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { RemarkPage } from './remark.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '', component: RemarkPage
12 | }
13 | ])
14 | ],
15 | declarations: [RemarkPage]
16 | })
17 | export class RemarkPageModule { }
18 |
19 |
--------------------------------------------------------------------------------
/src/app/order/order.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule } from '@angular/router';
3 | import { SharedModule } from '../shared';
4 | import { OrderPage } from './order.page';
5 | import { TimeLastPipe } from './time-last.pipe';
6 |
7 | @NgModule({
8 | imports: [
9 | SharedModule,
10 | RouterModule.forChild([
11 | { path: '', component: OrderPage }
12 | ])
13 | ],
14 | declarations: [OrderPage, TimeLastPipe]
15 | })
16 | export class OrderPageModule {}
17 |
--------------------------------------------------------------------------------
/src/app/address/add-address/add-address.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { AddAddressPage } from './add-address.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '', component: AddAddressPage
12 | }
13 | ])
14 | ],
15 | declarations: [AddAddressPage]
16 | })
17 | export class AddAddressPageModule { }
18 |
19 |
--------------------------------------------------------------------------------
/src/assets/rem.js:
--------------------------------------------------------------------------------
1 | (function (doc, win) {
2 | var docEl = doc.documentElement,
3 | resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
4 | recalc = function () {
5 | var clientWidth = docEl.clientWidth;
6 | if (!clientWidth) return;
7 | docEl.style.fontSize = 12 * (clientWidth / 320) + 'px';
8 | };
9 | if (!doc.addEventListener) return;
10 | win.addEventListener(resizeEvt, recalc, false);
11 | doc.addEventListener('DOMContentLoaded', recalc, false);
12 | })(document, window);
--------------------------------------------------------------------------------
/src/app/address/search-address/search-address.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { SearchAddressPage } from './search-address.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '', component: SearchAddressPage
12 | }
13 | ])
14 | ],
15 | declarations: [SearchAddressPage]
16 | })
17 | export class SearchAddressPageModule { }
18 |
19 |
--------------------------------------------------------------------------------
/src/app/confirm-order/choose-address/choose-address.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { ChooseAddressPage } from './choose-address.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '', component: ChooseAddressPage
12 | }
13 | ])
14 | ],
15 | declarations: [ChooseAddressPage]
16 | })
17 | export class ChooseAddressPageModule { }
18 |
19 |
--------------------------------------------------------------------------------
/src/app/confirm-order/payment/payment.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../../shared';
4 | import { PaymentPage } from './payment.page';
5 | import { TimeLastPipe } from './time-last.pipe';
6 |
7 | @NgModule({
8 | imports: [
9 | SharedModule,
10 | RouterModule.forChild([
11 | {
12 | path: '', component: PaymentPage
13 | }
14 | ])
15 | ],
16 | declarations: [PaymentPage, TimeLastPipe]
17 | })
18 | export class PaymentPageModule { }
19 |
20 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnDestroy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'loading',
5 | templateUrl: 'loading.html',
6 | styleUrls: ['loading.scss']
7 | })
8 | export class LoadingComponent implements OnDestroy {
9 | timer: any;
10 | positionY: number;
11 | constructor() {
12 | this.positionY = 0;
13 | this.timer = setInterval(() => {
14 | this.positionY++;
15 | }, 600);
16 | }
17 | ngOnDestroy() {
18 | if (this.timer) {
19 | clearInterval(this.timer);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/confirm-order/payment/time-last.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({ name: 'timeLast' })
4 | export class TimeLastPipe implements PipeTransform {
5 | transform(value: number, ...args: any[]): string {
6 | let minute: any = parseInt((value / 60).toString(), 10);
7 | if (minute < 10) {
8 | minute = '0' + minute;
9 | }
10 | let second: any = parseInt((value % 60).toString(), 10);
11 | if (second < 10) {
12 | second = '0' + second;
13 | }
14 | return '00 : ' + minute + ' : ' + second;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "importHelpers": true,
13 | "target": "es2015",
14 | "lib": [
15 | "es2018",
16 | "dom"
17 | ]
18 | },
19 | "angularCompilerOptions": {
20 | "fullTemplateTypeCheck": true,
21 | "strictInjectionParameters": true
22 | }
23 | }
--------------------------------------------------------------------------------
/src/app/shop/evaluate/evaluate.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 |
4 |
5 | @Component({
6 | selector: 'page-shop-evaluate',
7 | templateUrl: 'evaluate.page.html'
8 | })
9 | export class ShopEvaluatePage {
10 | shopId: string;
11 | rating: string;
12 | title: string;
13 | constructor(public route: ActivatedRoute) {
14 | this.shopId = this.route.snapshot.paramMap.get('id');
15 | this.rating = this.route.snapshot.queryParamMap.get('rating');
16 | this.title = this.route.snapshot.queryParamMap.get('title');
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/shared/components/rating-star/rating-star.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../style/mixin.scss";
2 | .rating_container{
3 | position: relative;
4 | top: .334rem;
5 | @include wh(3.34rem, .668rem);
6 | .star_overflow{
7 | overflow: hidden;
8 | position: relative;
9 | height: 100%;
10 | }
11 | .star_container{
12 | position: absolute;
13 | display: flex;
14 | width: 3.34rem;
15 | height: 0.668rem;
16 | top: -0.0334rem;
17 | left: -0.0334rem;
18 | .grey_fill{
19 | fill: #d1d1d1;
20 | }
21 | .orange_fill{
22 | fill: #ff9a0d;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/shared/shared.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { IonicModule } from '@ionic/angular';
5 | import { ComponentsModule } from './components';
6 |
7 | @NgModule({
8 | imports: [
9 | CommonModule,
10 | FormsModule,
11 | IonicModule.forRoot(),
12 | ],
13 | declarations: [
14 | ],
15 | exports: [
16 | CommonModule,
17 | FormsModule,
18 | IonicModule,
19 | ComponentsModule
20 | ],
21 | entryComponents: [],
22 | })
23 | export class SharedModule {}
24 |
--------------------------------------------------------------------------------
/src/app/shared/components/rating-star/rating-star.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | *.log
7 | *.tmp
8 | *.tmp.*
9 | log.txt
10 | *.sublime-project
11 | *.sublime-workspace
12 | .vscode/
13 | npm-debug.log*
14 |
15 | .idea/
16 | .sourcemaps/
17 | ionic-elm/
18 | ionic-ng-elm/
19 | .sass-cache/
20 | .tmp/
21 | .versions/
22 | coverage/
23 | dist/
24 | node_modules/
25 | tmp/
26 | temp/
27 | hooks/
28 | platforms/
29 | plugins/
30 | plugins/android.json
31 | plugins/ios.json
32 | www/
33 | $RECYCLE.BIN/
34 |
35 | .DS_Store
36 | Thumbs.db
37 | UserInterfaceState.xcuserstate
38 |
--------------------------------------------------------------------------------
/src/app/service/convert-request.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 | import { environment } from '../../environments/environment';
5 |
6 | @Injectable({
7 | providedIn: 'root'
8 | })
9 | export class ConvertRequestService implements HttpInterceptor {
10 |
11 | intercept(req: HttpRequest, next: HttpHandler): Observable> {
12 | const convertReq = req.clone({
13 | url: environment.apiUrl + req.url
14 | });
15 | return next.handle(convertReq);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/shared/components/back/back-icon.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'back-icon',
5 | template: ``,
6 | styles: [`
7 | ion-icon {
8 | font-size: 1.4rem;
9 | margin: auto 0;
10 | }
11 | `]
12 | })
13 | export class BackIconComponent {
14 | _size: number = 2;
15 | @Input() set size(val: string) {
16 | if (val === 'md') {
17 | this._size = 2;
18 | } else if (val === 'sm') {
19 | this._size = 1.4;
20 | }
21 | }
22 | back() {
23 | window.history.back();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/list/shop-list.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
13 | -
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { Platform } from '@ionic/angular';
4 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
5 | import { StatusBar } from '@ionic-native/status-bar/ngx';
6 |
7 | @Component({
8 | selector: 'app-root',
9 | templateUrl: 'app.component.html'
10 | })
11 | export class AppComponent {
12 | constructor(
13 | private platform: Platform,
14 | private splashScreen: SplashScreen,
15 | private statusBar: StatusBar
16 | ) {
17 | this.initializeApp();
18 | }
19 |
20 | initializeApp() {
21 | this.platform.ready().then(() => {
22 | this.statusBar.styleDefault();
23 | this.splashScreen.hide();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/app/service/localstorage.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 |
7 | export class LocalStorageService {
8 |
9 | getStore(name: string) {
10 | if (!name) {
11 | return;
12 | }
13 | return window.localStorage.getItem(name);
14 | }
15 |
16 | setStore(name: string, content: any) {
17 | if (!name) {
18 | return;
19 | }
20 | if (typeof content !== 'string') {
21 | content = JSON.stringify(content);
22 | }
23 | window.localStorage.setItem(name, content);
24 | }
25 |
26 | removeStore(name: string) {
27 | if (!name) {
28 | return;
29 | }
30 | window.localStorage.removeItem(name);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/shared/components/login-header/login-header.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { AppService, LocalStorageService } from '../../../service';
4 | import { UserInfo } from '../../../class';
5 |
6 | @Component({
7 | selector: 'login-header',
8 | templateUrl: 'login-header.html',
9 | styleUrls: ['login-header.scss']
10 | })
11 | export class LoginHeaderComponent extends UserInfo {
12 | constructor(public router: Router,
13 | public localStorageService: LocalStorageService,
14 | public appService: AppService) {
15 | super(appService, localStorageService);
16 | }
17 |
18 | public toProfile() {
19 | this.router.navigateByUrl('/tabs/profile');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/app/tabs/tabs.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 外卖
6 |
7 |
8 |
9 |
10 | 搜索
11 |
12 |
13 |
14 |
15 | 订单
16 |
17 |
18 |
19 |
20 | 我的
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/app/tabs/tabs.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { SharedModule } from '../shared';
3 |
4 | import { TabsPageRoutingModule } from './tabs.router.module';
5 |
6 | import { TabsPage } from './tabs.page';
7 | import { MsitePageModule } from '../msite/msite.module';
8 | import { SearchPageModule } from '../search/search.module';
9 | import { ProfilePageModule } from '../profile/profile.module';
10 | import { OrderPageModule } from '../order/order.module';
11 |
12 | @NgModule({
13 | imports: [
14 | SharedModule,
15 | TabsPageRoutingModule,
16 | MsitePageModule,
17 | SearchPageModule,
18 | ProfilePageModule,
19 | OrderPageModule
20 | ],
21 | declarations: [TabsPage]
22 | })
23 | export class TabsPageModule {}
24 |
--------------------------------------------------------------------------------
/src/app/service/shop.service.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter, Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 |
7 | export class ShopService {
8 | shopDetailData: any;
9 | ratingScoresData: any;
10 | ratingList: any;
11 | updateData: EventEmitter = new EventEmitter();
12 | loaderMoreRatings: EventEmitter = new EventEmitter();
13 |
14 | setShopDetailData(data: any) {
15 | this.shopDetailData = data;
16 | this.updateData.emit('update');
17 | }
18 |
19 | setRatingScoresData(data: any) {
20 | this.ratingScoresData = data;
21 | this.updateData.emit('update');
22 | }
23 |
24 | setRatingList(data: any) {
25 | this.ratingList = data;
26 | this.updateData.emit('update');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/app/address/address.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { AddressPage } from './address.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '',
12 | component: AddressPage,
13 | },
14 | {
15 | path: 'add',
16 | loadChildren: () => import('./add-address/add-address.module').then(m => m.AddAddressPageModule)
17 | },
18 | {
19 | path: 'search',
20 | loadChildren: () => import('./search-address/search-address.module').then(m => m.SearchAddressPageModule)
21 | }
22 | ])
23 | ],
24 | declarations: [AddressPage]
25 | })
26 | export class AddressPageModule { }
27 |
--------------------------------------------------------------------------------
/src/app/service/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, EventEmitter } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 |
7 | export class AppService {
8 | public userInfoEvent: EventEmitter = new EventEmitter();
9 | public notify: EventEmitter = new EventEmitter();
10 | public geohash: string = '';
11 | public shopId: string = '';
12 | public searchAddress: any;
13 | public choosedAddress: { address: string, index: number } = { address: '', index: 0 };
14 | public confirmRemark: { remarkText: string, inputText: string } = { remarkText: '', inputText: '' };
15 | public orderDetail: any;
16 |
17 | getTabPagesIndex(pageName) {
18 | const tabPagesIndex: any = { MsitePage: 0, SearchPage: 1, OrderPage: 2, ProfilePage: 3 };
19 | return tabPagesIndex[pageName];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/assets/imgs/shopback.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/class/userinfo.ts:
--------------------------------------------------------------------------------
1 | import { Directive, OnDestroy, OnInit } from '@angular/core';
2 | import { AppService, LocalStorageService } from '../service';
3 | import { Subscription } from 'rxjs';
4 | @Directive()
5 | export class UserInfo implements OnInit, OnDestroy {
6 | public userId: string;
7 | unSubEvent: Subscription;
8 | constructor(public appService: AppService,
9 | public localStorageService: LocalStorageService) {
10 | this.userId = this.localStorageService.getStore('userId');
11 | this.unSubEvent = this.appService.userInfoEvent.subscribe(res => {
12 | this.userId = this.localStorageService.getStore('userId');
13 | this.ngOnInit();
14 | });
15 | }
16 | ngOnInit() {}
17 |
18 | ngOnDestroy() {
19 | if (this.unSubEvent) {
20 | this.unSubEvent.unsubscribe();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 | export const environment = {
6 | production: false,
7 | apiUrl: ''
8 | };
9 |
10 | /*
11 | * In development mode, to ignore zone related error stack frames such as
12 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
13 | * import the following file, but please comment it out in production mode
14 | * because it will have performance impact when throw error
15 | */
16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/src/app/shop/shop.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { ShopPage } from './shop.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | { path: '', redirectTo: ':id', pathMatch: 'full' },
11 | {
12 | path: ':id',
13 | children: [
14 | { path: '', component: ShopPage },
15 | { path: 'detail', loadChildren: () => import('./detail/shop-detail.module').then(m => m.ShopDetailPageModule) },
16 | { path: 'evaluate', loadChildren: () => import('./evaluate/evaluate.module').then(m => m.ShopEvaluatePageModule) }
17 | ]
18 | }
19 | ])
20 | ],
21 | declarations: [ShopPage]
22 | })
23 | export class ShopPageModule { }
24 |
--------------------------------------------------------------------------------
/src/app/order/time-last.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({ name: 'timeLast', pure: false })
4 | export class TimeLastPipe implements PipeTransform {
5 | timer: any;
6 | countNum: number = 900;
7 | constructor() {
8 | setInterval(() => {
9 | this.countNum--;
10 | if (this.countNum === 0) {
11 | clearInterval(this.timer);
12 | }
13 | }, 1000);
14 | }
15 | transform(value: number, ...args: any[]): string {
16 | const time = this.countNum - value;
17 | let minute: any = parseInt((time / 60).toString(), 10);
18 | let second: any = parseInt((time % 60).toString(), 10);
19 | if (minute < 10) {
20 | minute = '0' + minute;
21 | }
22 | if (second < 10) {
23 | second = '0' + second;
24 | }
25 | return '去支付(还剩' + minute + '分' + second + '秒)';
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/app/address/search-address/search-address.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 | -
13 |
{{item.name}}
14 | {{item.address}}
15 |
16 |
17 |
18 |
找不到地址?
19 |
尝试输入小区、写字楼或学校名
20 |
详细地址(如门牌号等)可稍后输入哦
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | elm
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/app/address/search-address/search-address.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { DataService, AppService} from '../../service';
4 |
5 | @Component({
6 | selector: 'page-search-address',
7 | templateUrl: 'search-address.page.html',
8 | styleUrls: ['search-address.page.scss']
9 | })
10 | export class SearchAddressPage {
11 | searchData: any;
12 | searchValue: string = '';
13 | constructor(
14 | public router: Router,
15 | public appService: AppService,
16 | public dataService: DataService) {
17 | }
18 |
19 | searchPlace() {
20 | if (this.searchValue) {
21 | this.dataService.searchNearby(this.searchValue).subscribe(res => {
22 | this.searchData = res;
23 | });
24 | }
25 | }
26 | choooedAddress(item: any) {
27 | this.appService.searchAddress = item;
28 | this.router.navigate(['/address', 'add']);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/app/address/address.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { AppService, DataService, LocalStorageService } from '../service';
3 | import { UserInfo } from '../class';
4 | @Component({
5 | selector: 'page-address',
6 | templateUrl: 'address.page.html',
7 | styleUrls: ['address.page.scss']
8 | })
9 | export class AddressPage extends UserInfo implements OnInit, OnDestroy {
10 | addressList: any[];
11 | iconColor: any = {'公司': '#4cd964', '学校': '#3190e8', '家': '#ff5722'};
12 | constructor(
13 | public appService: AppService,
14 | public localStorageService: LocalStorageService,
15 | public dataService: DataService) {
16 | super(appService, localStorageService);
17 | }
18 |
19 | ngOnInit() {
20 | this.addressList = [];
21 | if (this.userId) {
22 | this.dataService.getAddressList(this.userId).subscribe(res => {
23 | this.addressList = res;
24 | });
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../style/mixin.scss";
2 | @keyframes load{
3 | 0% {transform: translateY(0px);}
4 | 50% {transform: translateY(-50px);}
5 | 100% {transform: translateY(0px);}
6 | }
7 | @keyframes ellipse{
8 | 0% {transform: scale(1);}
9 | 50% {transform: scale(0.3);}
10 | 100% {transform: scale(1);}
11 | }
12 | .loading_container{
13 | position: fixed;
14 | top: 50%;
15 | left: 50%;
16 | transform: translate(-50%, -50%);
17 | @include wh(2.5rem, 2.5rem);
18 | }
19 | .load_img{
20 | @include wh(100%, 100%);
21 | background: url(../../../../assets/imgs/icon_loading.png) no-repeat 0 0;
22 | background-size: 2.5rem auto;
23 | transform: translateY(0px);
24 | animation: load .6s infinite ease-in-out;
25 | position: relative;
26 | z-index: 11;
27 | }
28 | .load_ellipse{
29 | position: absolute;
30 | @include wh(2.6rem, 2rem);
31 | top: 2.2rem;
32 | left: 0.2rem;
33 | z-index: 10;
34 | animation: ellipse .6s infinite ease-in-out;
35 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/confirm-order.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { NgModule } from '@angular/core';
3 | import { SharedModule } from '../shared';
4 | import { ConfirmOrderPage } from './confirm-order.page';
5 |
6 | @NgModule({
7 | imports: [
8 | SharedModule,
9 | RouterModule.forChild([
10 | {
11 | path: '',
12 | component: ConfirmOrderPage,
13 | },
14 | {
15 | path: 'chooseAddress',
16 | loadChildren: () => import('./choose-address/choose-address.module').then(m => m.ChooseAddressPageModule)
17 | },
18 | {
19 | path: 'remark',
20 | loadChildren: () => import('./remark/remark.module').then(m => m.RemarkPageModule)
21 | },
22 | {
23 | path: 'payment',
24 | loadChildren: () => import('./payment/payment.module').then(m => m.PaymentPageModule)
25 | }
26 | ])
27 | ],
28 | declarations: [ConfirmOrderPage]
29 | })
30 | export class ConfirmOrderPageModule { }
31 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/msite/shop-msite.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { ImgBaseUrl } from '../../../../config/env';
3 |
4 | @Component({
5 | selector: 'shop-msite',
6 | templateUrl: 'shop-msite.html',
7 | styleUrls: ['shop-msite.scss']
8 | })
9 | export class ShopMsiteComponent {
10 | distance: number;
11 | _shop: any;
12 | @Input()
13 | set shop(val: any) {
14 | this._shop = val;
15 | if (val && val.distance) {
16 | this.distance = Number(val);
17 | }
18 | }
19 | get shop() {
20 | return this._shop;
21 | }
22 | @Input() geohash: string;
23 | imgBaseUrl = ImgBaseUrl;
24 |
25 | zhunShi(supports) {
26 | let zhunStatus;
27 | if ((supports instanceof Array) && supports.length) {
28 | supports.forEach(item => {
29 | if (item.icon_name === '准') {
30 | zhunStatus = true;
31 | }
32 | });
33 | } else {
34 | zhunStatus = false;
35 | }
36 | return zhunStatus;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | // Protractor configuration file, see link for more information
3 | // https://github.com/angular/protractor/blob/master/lib/config.ts
4 |
5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
6 |
7 | /**
8 | * @type { import("protractor").Config }
9 | */
10 | exports.config = {
11 | allScriptsTimeout: 11000,
12 | specs: [
13 | './src/**/*.e2e-spec.ts'
14 | ],
15 | capabilities: {
16 | browserName: 'chrome'
17 | },
18 | directConnect: true,
19 | baseUrl: 'http://localhost:4200/',
20 | framework: 'jasmine',
21 | jasmineNodeOpts: {
22 | showColors: true,
23 | defaultTimeoutInterval: 30000,
24 | print: function() {}
25 | },
26 | onPrepare() {
27 | require('ts-node').register({
28 | project: require('path').join(__dirname, './tsconfig.json')
29 | });
30 | jasmine.getEnv().addReporter(new SpecReporter({
31 | spec: {
32 | displayStacktrace: StacktraceOption.PRETTY
33 | }
34 | }));
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/src/app/address/address.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
24 |
28 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../coverage'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/src/assets/shapes.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/app/city/city.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{guessCity}}
5 | 切换城市
6 |
7 |
8 |
9 |
10 |
18 |
19 |
20 | -
21 |
{{place?.name}}
22 | {{place?.address}}
23 |
24 |
25 |
26 | 很抱歉!无搜索结果
27 |
--------------------------------------------------------------------------------
/src/app/tabs/tabs.router.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | import { TabsPage } from './tabs.page';
5 |
6 |
7 | const routes: Routes = [
8 | {
9 | path: '',
10 | component: TabsPage,
11 | children: [
12 | {
13 | path: '',
14 | redirectTo: '/msite',
15 | pathMatch: 'full'
16 | },
17 | {
18 | path: 'msite',
19 | loadChildren: () => import('../msite/msite.module').then(m => m.MsitePageModule)
20 | },
21 | {
22 | path: 'search',
23 | loadChildren: () => import('../search/search.module').then(m => m.SearchPageModule)
24 | },
25 | {
26 | path: 'order',
27 | loadChildren: () => import('../order/order.module').then(m => m.OrderPageModule)
28 | },
29 | {
30 | path: 'profile',
31 | loadChildren: () => import('../profile/profile.module').then(m => m.ProfilePageModule)
32 | }
33 | ]
34 | }
35 | ];
36 |
37 | @NgModule({
38 | imports: [RouterModule.forChild(routes)],
39 | exports: [RouterModule]
40 | })
41 | export class TabsPageRoutingModule { }
42 |
--------------------------------------------------------------------------------
/src/global.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * App Global CSS
3 | * ----------------------------------------------------------------------------
4 | * Put style rules here that you want to apply globally. These styles are for
5 | * the entire app and not just one component. Additionally, this file can be
6 | * used as an entry point to import other CSS/Sass files to be included in the
7 | * output CSS.
8 | * For more information on global stylesheets, visit the documentation:
9 | * https://ionicframework.com/docs/layout/global-stylesheets
10 | */
11 |
12 | /* Core CSS required for Ionic components to work properly */
13 | @import "~@ionic/angular/css/core.css";
14 |
15 | /* Basic CSS for apps built with Ionic */
16 | @import "~@ionic/angular/css/normalize.css";
17 | @import "~@ionic/angular/css/structure.css";
18 | @import "~@ionic/angular/css/typography.css";
19 | @import '~@ionic/angular/css/display.css';
20 |
21 | /* Optional CSS utils that can be commented out */
22 | @import "~@ionic/angular/css/padding.css";
23 | @import "~@ionic/angular/css/float-elements.css";
24 | @import "~@ionic/angular/css/text-alignment.css";
25 | @import "~@ionic/angular/css/text-transformation.css";
26 | @import "~@ionic/angular/css/flex-utils.css";
27 |
--------------------------------------------------------------------------------
/src/app/address/search-address/search-address.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | ion-content {
3 | background-color: #fff;
4 | }
5 | .search_address_page{
6 | overflow-y: auto;
7 | }
8 | .search_form{
9 | display: flex;
10 | padding: 1.16rem;
11 | input{
12 | @include sc(1.1rem, #999);
13 | flex: 4;
14 | background-color: #f1f1f1;
15 | margin-right: 1rem;
16 | height: 2.5rem;
17 | border-radius: 0.25rem;
18 | padding: 0 .67rem;
19 | }
20 | button{
21 | flex: 1;
22 | @include sc(1.1rem, #fff);
23 | background-color: $blue;
24 | border-radius: 0.25rem;
25 | }
26 | }
27 | .address_list{
28 | padding: 1.16rem;
29 | li{
30 | padding: 1.16rem 0;
31 | border-bottom: 0.041rem solid #f5f5f5;
32 | line-height: 1.6rem;
33 | h4{
34 | @include sc(1.25rem, #555);
35 | }
36 | p{
37 | @include sc(1.1rem, #999);
38 | }
39 | }
40 | }
41 | .empty_tips{
42 | @include center;
43 | width: 100%;
44 | p{
45 | @include sc(0.83rem, #aaa);
46 | line-height: 1.16rem;
47 | text-align: center;
48 |
49 | }
50 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/remark/remark.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
24 |
--------------------------------------------------------------------------------
/src/app/shop/detail/shop-detail.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { ShopService } from '../../service';
3 | import { ImgBaseUrl } from '../../config/env';
4 |
5 | @Component({
6 | selector: 'page-shop-detail',
7 | templateUrl: 'shop-detail.page.html',
8 | styleUrls: ['shop-detail.page.scss']
9 | })
10 | export class ShopDetailPage {
11 | shopDetailData: any;
12 | ratingScoresData: any;
13 | rating: any;
14 | imgBaseUrl: string = ImgBaseUrl;
15 | ratingParams: any;
16 | constructor(public shopService: ShopService) {
17 | this.shopDetailData = this.shopService.shopDetailData;
18 | this.ratingScoresData = this.shopService.ratingScoresData;
19 | this.rating = this.shopService.ratingList[0];
20 | this.ratingParams = {rating: this.shopDetailData.rating, title: this.shopDetailData.name};
21 | }
22 |
23 | getImgPath(path) {
24 | let suffix;
25 | if (!path) {
26 | return 'http://test.fe.ptdev.cn/elm/elmlogo.jpeg';
27 | }
28 | if (path.indexOf('jpeg') !== -1) {
29 | suffix = '.jpeg';
30 | } else {
31 | suffix = '.png';
32 | }
33 | const url = '/' + path.substr(0, 1) + '/' + path.substr(1, 2) + '/' + path.substr(3) + suffix;
34 | return 'https://fuss10.elemecdn.com' + url;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/style/common.scss:
--------------------------------------------------------------------------------
1 | a, article, aside, b, body, button, dd, div, dl, dt, figcaption, figure, footer, h1, h2, h3, h4, h5, h6, header, i, input, li, nav, p, section, select, span, textarea, ul {
2 | padding: 0;
3 | margin: 0;
4 | list-style: none;
5 | font-style: normal;
6 | text-decoration: none;
7 | border: none;
8 | outline: none;
9 | font-weight: 400;
10 | font-family: Microsoft Yahei;
11 | box-sizing: border-box;
12 | -webkit-tap-highlight-color: transparent;
13 | -webkit-font-smoothing: antialiased;
14 | }
15 |
16 | html {
17 | font-size: 14px;
18 | }
19 |
20 | .clear:after {
21 | content: '';
22 | display: block;
23 | clear: both;
24 | }
25 |
26 | @keyframes backOpacity{
27 | 0% { opacity: 1 }
28 | 25% { opacity: .5 }
29 | 50% { opacity: 1 }
30 | 75% { opacity: .5 }
31 | 100% { opacity: 1 }
32 | }
33 |
34 | .animation_opactiy{
35 | animation: backOpacity 2s ease-in-out infinite;
36 | }
37 |
38 | input:-webkit-autofill,
39 | input:-webkit-autofill:hover,
40 | input:-webkit-autofill:focus {
41 | box-shadow:0 0 0 60px #fff inset !important;
42 | -webkit-text-fill-color: #666 !important;
43 | }
44 |
45 | .ellipsis {
46 | overflow: hidden;
47 | text-overflow: ellipsis;
48 | white-space: nowrap;
49 | }
--------------------------------------------------------------------------------
/src/app/msite/msite.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 | ion-icon {
4 | font-size: 2rem;
5 | vertical-align: middle;
6 | }
7 | .msite_nav{
8 | background-color: #fff;
9 | border-bottom: .041rem solid $bc;
10 | height: 15.6rem;
11 | .swiper-container{
12 | @include wh(100%, 100%);
13 | position: relative;
14 | }
15 | .fl_back{
16 | @include wh(100%, 100%);
17 | }
18 | }
19 | .food_types_container{
20 | height: 100%;
21 | .swiper-slide {
22 | flex-wrap: wrap;
23 | }
24 | .link_to_food{
25 | width: 25%;
26 | padding: .5rem 0rem;
27 | @include ifj(center);
28 | figure{
29 | img{
30 | margin-bottom: .83rem;
31 | @include wh(3rem, 3rem);
32 | }
33 | figcaption{
34 | text-align: center;
35 | @include sc(.37rem, #666);
36 | }
37 | }
38 | }
39 | }
40 | .shop_list_container{
41 | margin-top: .668rem;
42 | border-top: .041rem solid $bc;
43 | background-color: #fff;
44 | .shop_header{
45 | .shop_icon{
46 | fill: #999;
47 | margin-left: 1rem;
48 | vertical-align: middle;
49 | @include wh(1rem, 1rem);
50 | }
51 | .shop_header_title{
52 | color: #999;
53 | @include font(.92rem, 2.7rem);
54 | }
55 | }
56 | }
57 | .empty_data{
58 | @include sc(0.835rem, #666);
59 | text-align: center;
60 | line-height: 3.34rem;
61 | }
--------------------------------------------------------------------------------
/src/app/shared/components/shop/search/shop-search.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{shop.name}}
9 |
14 |
15 |
月售 {{shop.month_sales||shop.recent_order_num}} 单
16 |
{{shop.delivery_fee||shop.float_minimum_order_amount}} 元起送 / 距离{{shop.distance}}
17 |
18 |
19 | -
20 | {{activity?.icon_name}}
21 | {{activity?.name}}
22 | (手机客户端专享)
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | const routes: Routes = [
5 | { path: '', redirectTo: 'home', pathMatch: 'full' },
6 | { path: 'address', loadChildren: () => import('./address/address.module').then(m => m.AddressPageModule) },
7 | { path: 'tabs', loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) },
8 | { path: 'city/:id', loadChildren: () => import('./city/city.module').then(m => m.CityPageModule) },
9 | { path: 'confirmOrder', loadChildren: () => import('./confirm-order/confirm-order.module').then(m => m.ConfirmOrderPageModule) },
10 | { path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) },
11 | { path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginPageModule) },
12 | { path: 'food', loadChildren: () => import('./food/food.module').then(m => m.FoodPageModule) },
13 | { path: 'order/detail', loadChildren: () => import('./order/order-detail/order-detail.module').then(m => m.OrderDetailPageModule) },
14 | { path: 'shop', loadChildren: () => import('./shop/shop.module').then(m => m.ShopPageModule) }
15 | ];
16 | @NgModule({
17 | imports: [RouterModule.forRoot(routes, { useHash: true })],
18 | exports: [RouterModule]
19 | })
20 | export class AppRoutingModule { }
21 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4 | import { RouteReuseStrategy } from '@angular/router';
5 |
6 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
7 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
8 | import { StatusBar } from '@ionic-native/status-bar/ngx';
9 |
10 | import { AppRoutingModule } from './app-routing.module';
11 | import { AppComponent } from './app.component';
12 |
13 | import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
14 |
15 | import { SharedModule } from './shared';
16 | import { CoreModule } from './core';
17 | import { ConvertRequestService } from './service/convert-request.service';
18 |
19 | @NgModule({
20 | declarations: [AppComponent],
21 | entryComponents: [],
22 | imports: [
23 | BrowserModule,
24 | BrowserAnimationsModule,
25 | IonicModule.forRoot(),
26 | AppRoutingModule,
27 | HttpClientModule,
28 | SharedModule,
29 | CoreModule
30 | ],
31 | providers: [
32 | StatusBar,
33 | SplashScreen,
34 | { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
35 | { provide: HTTP_INTERCEPTORS, useClass: ConvertRequestService, multi: true },
36 | ],
37 | bootstrap: [AppComponent]
38 | })
39 | export class AppModule { }
40 |
--------------------------------------------------------------------------------
/src/app/search/search.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
14 |
15 | 搜索历史
16 |
17 | -
18 | {{item}}
19 |
23 |
24 |
25 |
26 |
27 | 很抱歉!无搜索结果
28 |
--------------------------------------------------------------------------------
/src/app/home/home.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ele.me
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 | 热门城市
23 |
24 | -
25 | {{hotCity?.name}}
26 |
27 |
28 |
29 |
30 |
31 | -
32 |
{{group?.letter}}(按字母排序)
33 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/app/home/home.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { DataService } from '../service';
3 |
4 | @Component({
5 | selector: 'page-home',
6 | templateUrl: 'home.page.html',
7 | styleUrls: ['home.page.scss']
8 | })
9 |
10 | export class HomePage implements OnInit {
11 | guessCity: string;
12 | guessCityId: string;
13 | hotCities: any[];
14 | groupCities: any;
15 | constructor(public dataService: DataService) {
16 | this.guessCity = '';
17 | this.hotCities = [];
18 | }
19 |
20 | ngOnInit() {
21 | this.getCurrentCity();
22 | this.getHotCity();
23 | this.getGroupCity();
24 | }
25 |
26 | getCurrentCity() {
27 | this.dataService.getGuessCity().subscribe(res => {
28 | this.guessCity = res.name;
29 | this.guessCityId = res.id;
30 | }, err => {
31 | this.guessCity = '无数据';
32 | this.guessCityId = '';
33 | });
34 | }
35 |
36 | getHotCity() {
37 | this.dataService.getHotCity().subscribe(res => {
38 | if (Array.isArray(res)) {
39 | this.hotCities = res.map((city) => {
40 | return { name: city.name, id: city.id };
41 | });
42 | }
43 | }, err => {
44 | this.hotCities = [];
45 | });
46 | }
47 |
48 | getGroupCity() {
49 | this.dataService.getGroupCity().subscribe(res => {
50 | this.groupCities = res;
51 | }, err => {
52 | this.groupCities = [];
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/assets/imgs/fl.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/style/ionic.scss:
--------------------------------------------------------------------------------
1 | /** ion-toolbar **/
2 | ion-toolbar {
3 | min-height: 3.3rem;
4 | --background: #108ee9;
5 | --border-color: #108ee9;
6 | }
7 |
8 | /** ion-title **/
9 | ion-title {
10 | text-align: center;
11 | font-size: 1.4rem;
12 | }
13 |
14 | /** ion-back-button **/
15 | .back-button-native {
16 | font-size: 1.2rem !important;
17 | }
18 | ion-back-button {
19 | position: absolute;
20 | }
21 | .back-button-native[data-ion-back-button-md] {
22 | margin-left: -1rem;
23 | }
24 |
25 | /** ion-content **/
26 | ion-content {
27 | background-color: #f5f5f5;
28 | }
29 |
30 | /** toast **/
31 | ion-toast {
32 | --background: rgba(58, 58, 58, 0.9);
33 | --color: #fff;
34 | text-align: center;
35 | }
36 |
37 | .toast-container {
38 | text-align: center;
39 | background-color: #333;
40 | border-radius: .2rem;
41 | }
42 |
43 | .toast-ios .toast-wrapper,
44 | .toast-md .toast-wrapper {
45 | left: 1rem;
46 | right: 1rem;
47 | border-radius: 0.65rem;
48 | width: auto;
49 | }
50 |
51 | .toast-ios .toast-message,
52 | .toast-md .toast-message {
53 | font-size: 1rem;
54 | color: #fff;
55 | padding: .6rem;
56 | }
57 |
58 | /** infinite sroll **/
59 | ion-infinite-scroll-content {
60 | min-height: 1px;
61 | }
62 |
63 | .infinite-loading {
64 | margin-bottom: 0;
65 | }
66 |
67 | /** ion header **/
68 | .header-md back-icon {
69 | position: absolute;
70 | }
71 |
72 | /** ion slides **/
73 | .swiper-pagination-bullet {
74 | opacity: 1;
75 | }
--------------------------------------------------------------------------------
/src/app/login/login.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
28 |
29 | 温馨提示:未注册过的账号,登录时将自动注册
30 |
31 |
32 | 注册过的用户可凭账号密码登录
33 |
34 |
35 |
36 | 登录
37 |
38 |
--------------------------------------------------------------------------------
/src/app/order/order-detail/order-detail.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { AppService, DataService, LocalStorageService } from '../../service';
4 | import { ImgBaseUrl } from '../../config/env';
5 | import { UserInfo } from '../../class';
6 |
7 | @Component({
8 | selector: 'page-order-detail',
9 | templateUrl: 'order-detail.page.html',
10 | styleUrls: ['order-detail.page.scss']
11 | })
12 | export class OrderDetailPage extends UserInfo implements OnInit {
13 | orderData: any;
14 | orderDetail: any;
15 | showLoading: boolean = true;
16 | imgBaseUrl: string = ImgBaseUrl;
17 | shopId: string;
18 | params: {geohash: string};
19 | constructor(public router: Router,
20 | public appService: AppService,
21 | public dataService: DataService,
22 | public localStorageService: LocalStorageService) {
23 | super(appService, localStorageService);
24 | }
25 |
26 | ngOnInit() {
27 | this.shopId = this.appService.orderDetail.restaurant_id;
28 | this.params = { geohash: this.appService.geohash };
29 | this.orderDetail = this.appService.orderDetail;
30 | if (this.userId && this.appService.orderDetail) {
31 | this.dataService.getOrderDetail(this.userId, this.appService.orderDetail.unique_id).subscribe(res => {
32 | this.orderData = res;
33 | this.showLoading = false;
34 | });
35 | } else {
36 | this.router.navigate(['/login']);
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/app/confirm-order/remark/remark.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { AppService, DataService, LocalStorageService } from '../../service';
4 |
5 | @Component({
6 | selector: 'page-remark',
7 | templateUrl: 'remark.page.html',
8 | styleUrls: ['remark.page.scss']
9 | })
10 | export class RemarkPage implements OnInit {
11 | showLoading: boolean = true;
12 | remarkList: any;
13 | remarkText: any = {};
14 | inputText: string = '';
15 | id: string;
16 | sig: any;
17 | constructor(
18 | public route: ActivatedRoute,
19 | public router: Router,
20 | public localStorageService: LocalStorageService,
21 | public appService: AppService,
22 | public dataService: DataService) {
23 | this.id = this.route.snapshot.queryParamMap.get('id');
24 | this.sig = this.route.snapshot.queryParamMap.get('sig');
25 | }
26 |
27 | ngOnInit() {
28 | this.remarkList = this.dataService.getRemark(this.id, this.sig).subscribe(res => {
29 | this.remarkList = res;
30 | this.showLoading = false;
31 | });
32 | }
33 |
34 | chooseRemark(index: number, remarkIndex: string, text: string) {
35 | this.remarkText[index] = [remarkIndex, text];
36 | this.remarkText = Object.assign({}, this.remarkText);
37 | }
38 |
39 | confirmRemark() {
40 | this.appService.confirmRemark = { remarkText: this.remarkText, inputText: this.inputText };
41 | window.history.back();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/app/shared/components/buy-cart/buy-cart.html:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
19 | {{foodNum()}}
20 | 选规格
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/style/mixin.scss:
--------------------------------------------------------------------------------
1 | $blue: #3190e8;
2 | $bc: #e4e4e4;
3 | $fc:#fff;
4 |
5 | // 背景图片地址和大小
6 | @mixin bis($url) {
7 | background-image: url($url);
8 | background-repeat: no-repeat;
9 | background-size: 100% 100%;
10 | }
11 |
12 | @mixin borderRadius($radius) {
13 | -webkit-border-radius: $radius;
14 | -moz-border-radius: $radius;
15 | -ms-border-radius: $radius;
16 | -o-border-radius: $radius;
17 | border-radius: $radius;
18 | }
19 | // 定位全屏
20 | @mixin allcover{
21 | position:absolute;
22 | top:0;
23 | right:0;
24 | }
25 |
26 | // 定位上下左右居中
27 | @mixin center {
28 | position: absolute;
29 | top: 50%;
30 | left: 50%;
31 | transform: translate(-50%, -50%);
32 | }
33 |
34 | // 定位上下居中
35 | @mixin ct {
36 | position: absolute;
37 | top: 50%;
38 | transform: translateY(-50%);
39 | }
40 |
41 | // 定位上下居中
42 | @mixin cl {
43 | position: absolute;
44 | left: 50%;
45 | transform: translateX(-50%);
46 | }
47 |
48 | // 宽高
49 | @mixin wh($width, $height){
50 | width: $width;
51 | height: $height;
52 | }
53 |
54 | // 字体大小、行高、字体
55 | @mixin font($size, $line-height, $family: 'Microsoft YaHei') {
56 | font: #{$size}/#{$line-height} $family;
57 | }
58 |
59 | // 字体大小,颜色
60 | @mixin sc($size, $color){
61 | font-size: $size;
62 | color: $color;
63 | }
64 |
65 | // flex 布局和 子元素 对其方式
66 | @mixin fj($type: space-between){
67 | display: flex;
68 | justify-content: $type;
69 |
70 | }
71 |
72 | // inline-flex 布局和 子元素 对其方式
73 | @mixin ifj($type: space-between){
74 | display: inline-flex;
75 | justify-content: $type;
76 |
77 | }
--------------------------------------------------------------------------------
/src/app/login/login.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 |
3 | ion-toggle {
4 | position: absolute;
5 | top: .3rem;
6 | right: 1rem;
7 | }
8 | ion-button {
9 | font-size: 1.2rem;
10 | }
11 | .login_content {
12 | padding-top: 1rem;
13 | }
14 | .login_form {
15 | background-color: #fff;
16 | .input_container{
17 | display: flex;
18 | justify-content: space-between;
19 | padding: 1rem 1.33rem;
20 | border-bottom: 1px solid #f1f1f1;
21 | input{
22 | @include sc(1.16rem, #666);
23 | outline: none;
24 | }
25 | }
26 | .input_pwd {
27 | position: relative;
28 | }
29 | .captcha_code_container{
30 | height: 3.6rem;
31 | .img_change_img{
32 | display: flex;
33 | align-items: center;
34 | margin-right: 1rem;
35 | img{
36 | @include wh(5.8rem, 2.5rem);
37 | margin-right: .34rem;
38 | }
39 | .change_img{
40 | display: flex;
41 | flex-direction: 'column';
42 | flex-wrap: wrap;
43 | width: 3.34rem;
44 | justify-content: center;
45 | p{
46 | @include sc(.92rem, #666);
47 | }
48 | p:nth-of-type(2){
49 | color: #3b95e9;
50 | margin-top: .34rem;
51 | }
52 | }
53 | }
54 | }
55 | }
56 | .login_tips{
57 | @include sc(.8rem, red);
58 | padding: .7rem 1rem;
59 | line-height: .8rem;
60 | }
61 | .button_login {
62 | text-align: center;
63 | margin: 1rem;
64 | span {
65 | color: #fff;
66 | }
67 | }
68 | .show_pwd {
69 | display: none;
70 | }
71 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/search/shop-search.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../../style/mixin.scss";
2 | .list_li{
3 | display: flex;
4 | justify-content: 'center';
5 | padding: 0.835rem;
6 | border-bottom: 0.041rem solid $bc;
7 | .shop_left{
8 | margin-right: 0.41rem;
9 | .restaurant_img{
10 | @include wh(2.839rem, 2.839rem);
11 | }
12 | }
13 | .shop_right{
14 | font-size: 0.92rem;
15 | flex: 1;
16 | .shop_right_text{
17 | padding-bottom: 0.41rem;
18 | border-bottom: 0.041rem solid $bc;
19 | p{
20 | line-height: 1.502rem;
21 | }
22 | .pay_icon{
23 | margin-bottom: -0.13rem;
24 | }
25 | }
26 | .shop_right_detail{
27 | margin-top: 0.41rem;
28 | li{
29 | font-size: 0;
30 | span{
31 | font-size: .835rem;
32 | vertical-align: middle;
33 | display: inline-block;
34 | margin-bottom: 0.134rem;
35 | }
36 | .activity_icon{
37 | @include sc(.835rem, #fff);
38 | font-weight: bold;
39 | padding: .067rem;
40 | border-radius: 0.25rem;
41 | margin-right: 0.21rem;
42 | }
43 | .only_phone{
44 | color: #FF6000;
45 | }
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/assets/icon/mine.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnDestroy, OnInit } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { AppService, DataService, LocalStorageService } from '../service';
4 | import { UserInfo } from '../class';
5 | import { ImgBaseUrl } from '../config/env';
6 |
7 | @Component({
8 | selector: 'page-profile',
9 | templateUrl: 'profile.page.html',
10 | styleUrls: ['profile.page.scss']
11 | })
12 | export class ProfilePage extends UserInfo implements OnDestroy, OnInit {
13 | userId: string;
14 | userInfo: any;
15 | mobile: string;
16 | imgBaseUrl: string = ImgBaseUrl;
17 |
18 | constructor(public appService: AppService,
19 | public dataService: DataService,
20 | public localStorageService: LocalStorageService,
21 | public router: Router) {
22 | super(appService, localStorageService);
23 | }
24 |
25 | ngOnInit() {
26 | this.userId = this.localStorageService.getStore('userId');
27 | if (this.userId) {
28 | this.getUserInfo(this.userId);
29 | } else {
30 | this.mobile = '暂无绑定手机号';
31 | }
32 | }
33 |
34 | public getUserInfo(userId: string) {
35 | this.dataService.getUserInfo(userId).subscribe(res => {
36 | this.userInfo = res;
37 | this.mobile = this.userInfo.mobile || '暂无绑定手机号';
38 | });
39 | }
40 |
41 | public exit() {
42 | this.localStorageService.removeStore('userId');
43 | this.userInfo = {};
44 | this.appService.userInfoEvent.emit('update');
45 | }
46 |
47 | public toOrderPage() {
48 | this.router.navigateByUrl('/tabs/order');
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/app/shared/components/components.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 | import { IonicModule } from '@ionic/angular';
5 | import { RouterModule } from '@angular/router';
6 |
7 | import { BackHeaderComponent } from './back/back-header';
8 | import { BackIconComponent } from './back/back-icon';
9 | import { BuyCartComponent } from './buy-cart/buy-cart';
10 | import { ElmSvgComponent } from './svg/svg';
11 | import { LoginHeaderComponent } from './login-header/login-header';
12 | import { LoadingComponent } from './loading/loading';
13 | import { RatingStarComponent } from './rating-star/rating-star';
14 | import { ShoplistComponent } from './shop/list/shop-list';
15 | import { ShopSearchComponent } from './shop/search/shop-search';
16 | import { ShopMsiteComponent } from './shop/msite/shop-msite';
17 | import { ShopEvaluateComponent } from './shop/evaluate/evaluate';
18 |
19 | // import { DirectivesModule } from '../directives';
20 | const coms: any[] = [
21 | BackHeaderComponent,
22 | BackIconComponent,
23 | BuyCartComponent,
24 | ElmSvgComponent,
25 | LoginHeaderComponent,
26 | LoadingComponent,
27 | RatingStarComponent,
28 | ShoplistComponent,
29 | ShopSearchComponent,
30 | ShopMsiteComponent,
31 | ShopEvaluateComponent
32 | ];
33 |
34 | @NgModule({
35 | imports: [
36 | CommonModule,
37 | FormsModule,
38 | RouterModule,
39 | IonicModule.forRoot(),
40 | ],
41 | declarations: [
42 | coms
43 | ],
44 | exports: [
45 | coms
46 | ],
47 | entryComponents: [],
48 | })
49 | export class ComponentsModule { }
50 |
--------------------------------------------------------------------------------
/src/app/search/search.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 |
4 | .seller_form {
5 | background-color: #fff;
6 | padding: .8rem;
7 | display: flex;
8 | }
9 |
10 | ion-input {
11 | background-color: #f2f2f2;
12 | --padding-start: .5rem;
13 | --padding-end: .5rem;
14 | border: 1px solid #e4e4e4;
15 | color: #333;
16 | font-size: 1.1rem;
17 | height: 2.5rem;
18 | flex: 4;
19 | }
20 |
21 | ion-button {
22 | --border-radius: 3px;
23 | --height:2.5rem;
24 | --margin-top: 0;
25 | --margin-start: 0;
26 | --margin-end: 0;
27 | --margin-bottom: 0;
28 | float: right;
29 | flex:1;
30 | }
31 |
32 | .title_restaurant{
33 | font-size: 1rem;
34 | line-height: 3.3rem;
35 | text-indent: 0.835rem;
36 | font-weight: bold;
37 | color: #666;
38 | }
39 | .list_container{
40 | background-color: #fff;
41 | }
42 | .search_history{
43 | .history_list{
44 | background-color: #fff;
45 | border-bottom: 0.041rem solid $bc;
46 | @include font(1.16rem, 3.34rem);
47 | padding: 0 0.5rem;
48 | display: flex;
49 | justify-content: space-between;
50 | align-items: center;
51 | .history_text{
52 | display: inline-block;
53 | width: 80%;
54 | }
55 | .delete_icon{
56 | @include wh(1.67rem, 1.67rem);
57 | }
58 | }
59 | .clear_history{
60 | background-color: #fff;
61 | color: $blue;
62 | @include font(1.169rem, 3.34rem);
63 | font-weight: bold;
64 | text-align: center;
65 | }
66 | }
67 | .search_none{
68 | margin: 0 auto;
69 | @include font(1.1rem, 2.9rem);
70 | color: #333;
71 | background-color: #fff;
72 | text-align: center;
73 | margin-top: 0.21rem;
74 | }
--------------------------------------------------------------------------------
/src/app/city/city.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 |
4 | ion-input {
5 | background-color: #fff;
6 | --padding-start: .5rem;
7 | --padding-end: .5rem;
8 | border: 1px solid #e4e4e4;
9 | color: #333;
10 | font-size: 1.1rem;
11 | height: 2.34rem;
12 | }
13 |
14 | .change_city {
15 | font-size: 1rem;
16 | position: absolute;
17 | top: 0;
18 | bottom: 0;
19 | right: .6rem;
20 | margin: auto 0;
21 | height: 1.4rem;
22 | }
23 |
24 | .city_form {
25 | background-color: #fff;
26 | border-top: 1px solid #e4e4e4;
27 | border-bottom: 1px solid #e4e4e4;
28 | padding-top: .65rem;
29 | .city_search {
30 | margin: 0 auto .65rem auto;
31 | width: 90%;
32 | }
33 | }
34 |
35 | .button_submit {
36 | width: 100%;
37 | padding: 0 1.28rem .669rem 1.28rem;
38 | background-color: #fff;
39 | border-bottom: 1px solid #e4e4e4;
40 | }
41 | .getpois_ul {
42 | background-color: #fff;
43 | border-top: 1px solid #e4e4e4;
44 | li {
45 | padding-top: 1.088rem;
46 | padding-bottom: .92rem;
47 | border-bottom: 1px solid #e4e4e4;
48 | .pois_name {
49 | font-size: 1.088rem;
50 | width: 90%;
51 | margin: 0 auto .586rem;
52 | }
53 | .pois_address {
54 | font-size: .857rem;
55 | width: 90%;
56 | margin: 0 auto;
57 | color: #999;
58 | }
59 | }
60 | }
61 | .pois_search_history {
62 | font-size: .8rem;
63 | padding-left: .8rem;
64 |
65 | }
66 | .search_none_place, .clear_all_history {
67 | line-height: 3rem;
68 | font-size: 1.1rem;
69 | background-color: #fff;
70 | }
71 | .search_none_place {
72 | text-indent: .85rem;
73 | }
74 | .clear_all_history {
75 | text-align: center;
76 | }
77 |
--------------------------------------------------------------------------------
/src/app/confirm-order/remark/remark.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | .header_style{
3 | @include sc(1.1rem, #333);
4 | line-height: 3.3rem;
5 | }
6 | .quick_remark{
7 | background-color: #fff;
8 | margin-top: .67rem;
9 | padding: 0 1rem 1.67rem;
10 | ul{
11 | display: flex;
12 | flex-wrap: wrap;
13 | li{
14 | margin-right: 1rem;
15 | margin-bottom: 2rem;
16 | span{
17 | @include sc(1rem, #333);
18 | padding: .5rem 1rem;
19 | border: 0.061rem solid #3190e8;
20 | border-left: 0;
21 | }
22 | .first{
23 | border-left: 0.061em solid #3190e8;
24 | border-top-left-radius: .33rem;
25 | border-bottom-left-radius: .33rem;
26 | }
27 | .last{
28 | border-top-right-radius: .33rem;
29 | border-bottom-right-radius: .33rem;
30 | }
31 | .choosed{
32 | color: #fff;
33 | background-color: #3190e8;
34 | }
35 | }
36 | }
37 | }
38 | .input_remark{
39 | background-color: #fff;
40 | .input_text{
41 | width: 100%;
42 | background-color: #f9f9f9;
43 | border: 0.041rem solid #eee;
44 | resize: none;
45 | min-height: 7.5rem;
46 | border-radius: .33rem;
47 | @include sc(1rem, #666);
48 | padding: .83rem;
49 | }
50 | }
51 | .determine{
52 | background-color: #4cd964;
53 | @include sc(1.16rem, #fff);
54 | text-align: center;
55 | margin: 0 1.16rem;
56 | line-height: 3rem;
57 | border-radius: 0.33rem;
58 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/payment/payment.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{countNum | timeLast}}
9 |
13 |
14 |
15 | 选择支付方式
16 |
17 |
18 |
19 |
20 |
21 |
22 |
支付宝
23 |
24 |
27 |
28 |
29 |
30 |
33 | 微信
34 |
35 |
38 |
39 |
40 | 确认支付
41 |
42 |
--------------------------------------------------------------------------------
/src/app/shared/components/buy-cart/buy-cart.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../style/mixin.scss";
2 | .cart_module{
3 | .add_icon{
4 | position: relative;
5 | // z-index: 999;
6 | }
7 | .cart_button{
8 | display: flex;
9 | align-items: center;
10 | }
11 | svg{
12 | @include wh(1.5rem, 1.5rem);
13 | fill: #3190e8;
14 | }
15 | .cart_num{
16 | @include sc(1.1rem, #666);
17 | min-width: 1rem;
18 | text-align: center;
19 | font-family: Helvetica Neue,Tahoma;
20 | margin-right: .2rem;
21 | }
22 | .choose_specification{
23 | .choose_icon_container{
24 | display: flex;
25 | align-items: center;
26 | .show_chooselist{
27 | display: block;
28 | @include sc(.92rem, #fff);
29 | padding: .16rem .33rem;
30 | background-color: $blue;
31 | border-radius: 0.33rem;
32 | border: 1px solid $blue;
33 | }
34 | }
35 | }
36 | }
37 | .showReduce-enter-active, .showReduce-leave-active {
38 | transition: all .3s ease-out;
39 | }
40 | .showReduce-enter, .showReduce-leave-active {
41 | opacity: 0;
42 | transform: translateX(1rem);
43 | }
44 | .fade-enter-active, .fade-leave-active {
45 | transition: all .3s;
46 | }
47 | .fade-enter, .fade-leave-active {
48 | opacity: 0;
49 | }
50 | .fadeBounce-enter-active, .fadeBounce-leave-active {
51 | transition: all .3s;
52 | }
53 | .fadeBounce-enter, .fadeBounce-leave-active {
54 | opacity: 0;
55 | transform: scale(.7);
56 | }
--------------------------------------------------------------------------------
/src/app/msite/msite.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{addressTitle}}
5 |
6 |
7 |
8 |
9 |
26 |
27 |
33 |
34 |
没有更多了
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myapp",
3 | "version": "0.0.1",
4 | "author": "nuonuoge",
5 | "homepage": "https://github.com/nuonuoge/ionic4_angular6_elm",
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve --port 5555",
9 | "build": "ng build --prod --aot",
10 | "test": "ng test",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e"
13 | },
14 | "private": true,
15 | "dependencies": {
16 | "@angular/animations": "~10.0.0",
17 | "@angular/common": "~10.0.0",
18 | "@angular/core": "~10.0.0",
19 | "@angular/forms": "~10.0.0",
20 | "@angular/platform-browser": "~10.0.0",
21 | "@angular/platform-browser-dynamic": "~10.0.0",
22 | "@angular/router": "~10.0.0",
23 | "@ionic-native/core": "^5.0.0",
24 | "@ionic-native/splash-screen": "^5.0.0",
25 | "@ionic-native/status-bar": "^5.0.0",
26 | "@ionic/angular": "^5.0.0",
27 | "rxjs": "~6.5.5",
28 | "tslib": "^2.0.0",
29 | "zone.js": "~0.10.3"
30 | },
31 | "devDependencies": {
32 | "@angular-devkit/build-angular": "~0.1000.0",
33 | "@angular/cli": "~10.0.5",
34 | "@angular/compiler": "~10.0.0",
35 | "@angular/compiler-cli": "~10.0.0",
36 | "@angular/language-service": "~10.0.0",
37 | "@ionic/angular-toolkit": "^2.3.0",
38 | "@types/node": "^12.11.1",
39 | "@types/jasmine": "~3.5.0",
40 | "@types/jasminewd2": "~2.0.3",
41 | "codelyzer": "^6.0.0",
42 | "jasmine-core": "~3.5.0",
43 | "jasmine-spec-reporter": "~5.0.0",
44 | "karma": "~5.0.0",
45 | "karma-chrome-launcher": "~3.1.0",
46 | "karma-coverage-istanbul-reporter": "~3.0.2",
47 | "karma-jasmine": "~3.3.0",
48 | "karma-jasmine-html-reporter": "^1.5.0",
49 | "protractor": "~7.0.0",
50 | "ts-node": "~8.3.0",
51 | "tslint": "~6.1.0",
52 | "typescript": "~3.9.5"
53 | },
54 | "description": "An Ionic project"
55 | }
56 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/msite/shop-msite.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
14 |
15 |
16 | {{shop.rating}}
17 |
18 |
19 | 月售{{shop.recent_order_num}}单
20 |
21 |
22 |
23 | {{shop.delivery_mode.text}}
24 | 准时达
25 |
26 |
27 |
28 |
29 | ¥{{shop.float_minimum_order_amount}}起送
30 | / {{shop.piecewise_agent_fee.tips}}
31 |
32 |
33 | {{shop.distance > 1000? (shop.distance/1000).toFixed(2) + 'km': shop.distance + 'm'}}
34 | /
35 |
36 | {{shop.distance}}
37 | /
38 | {{shop.order_lead_time}}
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/app/address/address.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | .scroll_container{
3 | height: calc(100% - 4.1rem);
4 | overflow-y: auto;
5 | }
6 | .list_cotainer {
7 | padding-bottom: 10px;
8 | }
9 | .deliverable_address{
10 | background-color: #fff;
11 | li{
12 | display: flex;
13 | align-items: center;
14 | border-bottom: 0.041rem solid #f5f5f5;
15 | padding: 1.16rem;
16 | line-height: 1.67rem;
17 | .choosed_address{
18 | @include wh(1.33rem, 1.33rem);
19 | fill: #4cd964;
20 | margin-right: .67rem;
21 | opacity: 0;
22 | }
23 | .default_address{
24 | opacity: 1;
25 | }
26 | header{
27 | @include sc(1.16rem, #333);
28 | span:nth-of-type(1){
29 | font-size: 1.33rem;
30 | font-weight: bold;
31 | }
32 | }
33 | .address_detail{
34 | width: 100%;
35 | display: flex;
36 | align-items: center;
37 | span{
38 | font-size: .83rem;
39 | line-height: 1.1rem;
40 | padding: .15rem;
41 | margin-right: .5rem;
42 | border: 0.05rem solid;
43 | }
44 | p{
45 | @include sc(1rem, #777);
46 | }
47 | }
48 | }
49 | }
50 | #out_delivery{
51 | .out_header{
52 | @include sc(1rem, #666);
53 | line-height: 2.5rem;
54 | padding-left: .83rem;
55 | background-color: #f5f5f5;
56 | }
57 | *{
58 | color: #ccc;
59 | }
60 | }
61 | .add_icon_footer{
62 | height: 4.1rem;
63 | border-top: 1px solid f5f5f5;
64 | background-color: #fff;
65 | display: flex;
66 | justify-content: center;
67 | align-items: center;
68 | span{
69 | @include sc(1.16rem, $blue);
70 | margin-left: .5rem;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/payment/payment.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { AlertController} from '@ionic/angular';
4 | import { AppService, CartService, DataService, LocalStorageService } from '../../service';
5 |
6 | @Component({
7 | selector: 'page-payment',
8 | templateUrl: 'payment.page.html',
9 | styleUrls: ['payment.page.scss']
10 | })
11 | export class PaymentPage implements OnInit {
12 | cartPrice: any;
13 | payDetail: any = {};
14 | showAlert: boolean = false;
15 | alertText: string = '';
16 | payWay: number = 1;
17 | countNum: number = 900; // 倒计时15分钟
18 | gotoOrders: boolean = false;
19 | timer: any;
20 | constructor(
21 | public router: Router,
22 | public alertCtrl: AlertController,
23 | public localStorageService: LocalStorageService,
24 | public appService: AppService,
25 | public cartService: CartService,
26 | public dataService: DataService) {
27 | }
28 |
29 | ngOnInit() {
30 | // 清除购物车中当前商铺的信息
31 | if (this.appService.shopId) {
32 | this.cartService.clearCart(this.appService.shopId);
33 | }
34 | this.remainingTime();
35 | }
36 |
37 | async presentConfirm(message: string) {
38 | const alert = await this.alertCtrl.create({
39 | header: '确认支付',
40 | message: message,
41 | cssClass: 'confirm',
42 | buttons: [
43 | {
44 | text: '确认',
45 | handler: () => {
46 | this.router.navigateByUrl('/tabs/order');
47 | }
48 | }
49 | ]
50 | });
51 | alert.present();
52 | }
53 |
54 | // 倒计时
55 | remainingTime() {
56 | clearInterval(this.timer);
57 | this.timer = setInterval(() => {
58 | this.countNum--;
59 | if (this.countNum === 0) {
60 | clearInterval(this.timer);
61 | }
62 | }, 1000);
63 | }
64 | // 确认付款
65 | confirmPay() {
66 | this.presentConfirm('当前环境无法支付,请打开官方APP进行付款?');
67 | this.gotoOrders = true;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/app/login/login.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Location } from '@angular/common';
3 | import { ToastController } from '@ionic/angular';
4 | import { AppService, DataService, LocalStorageService } from '../service';
5 |
6 | @Component({
7 | selector: 'page-login',
8 | templateUrl: 'login.page.html',
9 | styleUrls: ['login.page.scss']
10 | })
11 | export class LoginPage implements OnInit {
12 | userName: string;
13 | userPwd: string;
14 | showPwd: boolean;
15 | captchaCodeImg: string;
16 | codeNumber: string;
17 | constructor(
18 | public location: Location,
19 | public appService: AppService,
20 | public dataService: DataService,
21 | public storageService: LocalStorageService,
22 | public toastCtrl: ToastController) {
23 | }
24 |
25 | ngOnInit() {
26 | this.userName = '';
27 | this.userPwd = '';
28 | this.showPwd = false;
29 | this.getCaptchaCode();
30 | }
31 |
32 | // 获取验证码
33 | getCaptchaCode() {
34 | this.dataService.getCaptchas().subscribe(res => {
35 | this.captchaCodeImg = res.code;
36 | });
37 | }
38 |
39 | async toastTip(message: string) {
40 | const toast = await this.toastCtrl.create({
41 | message,
42 | duration: 2000,
43 | position: 'middle'
44 | });
45 | toast.present();
46 | }
47 |
48 | logIn() {
49 | if (!this.userName) {
50 | this.toastTip('请填写用户名');
51 | return;
52 | }
53 | if (!this.userPwd) {
54 | this.toastTip('请填写密码');
55 | return;
56 | }
57 | if (!this.codeNumber) {
58 | this.toastTip('请填写验证码');
59 | return;
60 | }
61 | this.dataService.accountLogin(this.userName, this.userPwd, this.codeNumber).subscribe(res => {
62 | if (!res.user_id) {
63 | this.getCaptchaCode();
64 | this.toastTip(res.message);
65 | } else {
66 | this.storageService.setStore('userId', res.user_id);
67 | this.appService.userInfoEvent.emit('update');
68 | this.location.back();
69 | }
70 | });
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/app/confirm-order/choose-address/choose-address.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | .rating_page{
3 | height: 100%;
4 | }
5 | .scroll_container{
6 | height: calc(100% - 4.1rem);
7 | overflow-y: auto;
8 | }
9 | .list_cotainer{
10 | padding-bottom: 10px;
11 | }
12 | ion-checkbox {
13 | --size: 1.33rem;
14 | }
15 | .deliverable_address{
16 | background-color: #fff;
17 | li{
18 | display: flex;
19 | align-items: center;
20 | border-bottom: 0.041rem solid #f5f5f5;
21 | padding: 1.16rem;
22 | line-height: 1.67rem;
23 | .choosed_address{
24 | @include wh(1.33rem, 1.33rem);
25 | fill: #4cd964;
26 | margin-right: .67rem;
27 | opacity: 0;
28 | }
29 | .default_address{
30 | opacity: 1;
31 | }
32 | header{
33 | @include sc(1.16rem, #333);
34 | span:nth-of-type(1){
35 | font-size: 1.33rem;
36 | font-weight: bold;
37 | }
38 | span + span {
39 | margin-left: .3rem;
40 | }
41 | }
42 | .address_detail{
43 | width: 100%;
44 | display: flex;
45 | align-items: center;
46 | span{
47 | font-size: .83rem;
48 | line-height: 1.1rem;
49 | padding: .15rem;
50 | margin-right: .5rem;
51 | border: 0.05rem solid;
52 | }
53 | p{
54 | @include sc(1rem, #777);
55 | }
56 | }
57 | }
58 | }
59 | #out_delivery{
60 | .out_header{
61 | @include sc(1rem, #666);
62 | line-height: 2.5rem;
63 | padding-left: .83rem;
64 | background-color: #f5f5f5;
65 | }
66 | *{
67 | color: #ccc;
68 | }
69 | }
70 | .add_icon_footer{
71 | height: 4.1rem;
72 | background-color: #fff;
73 | display: flex;
74 | justify-content: center;
75 | align-items: center;
76 | z-index: 204;
77 | span{
78 | @include sc(1.16rem, $blue);
79 | margin-left: .5rem;
80 | }
81 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/payment/payment.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | .show_time_amount{
3 | background-color: #fff;
4 | padding: 1.16rem;
5 | text-align: center;
6 | .time_last{
7 | @include sc(1rem, #666);
8 | margin-top: 1rem;
9 | }
10 | .time{
11 | @include sc(2.5rem, #333);
12 | margin: .5rem 0 1.67rem;
13 | }
14 | .order_detail{
15 | @include fj;
16 | span{
17 | @include sc(1.1rem, #666);
18 | }
19 | span:nth-of-type(2){
20 | color: #ff6000;
21 | font-weight: bold;
22 | }
23 | }
24 | }
25 | .pay_way{
26 | background-color: #f1f1f1;
27 | padding: 0 1.16rem;
28 | @include sc(1.16rem, #666);
29 | line-height: 3rem;
30 | }
31 | .pay_way_list{
32 | background-color: #fff;
33 | .pay_item{
34 | padding: .67rem 1.16rem;
35 | @include fj;
36 | align-items: center;
37 | line-height: 4.3rem;
38 | border-bottom: 0.041rem solid #f5f5f5;
39 | .pay_icon_contaienr{
40 | @include fj;
41 | align-items: center;
42 | .zhifubao{
43 | @include wh(3.3rem, 3.3rem);
44 | background: url(../../../assets/imgs/zhifubao.png) no-repeat;
45 | background-size: 100% 100%;
46 | margin-right: .33rem;
47 | }
48 | svg{
49 | @include wh(3.3rem, 3.3rem);
50 | margin-right: .5rem;
51 | }
52 | span{
53 | @include sc(1.16rem, #666);
54 | }
55 | }
56 | .choose_icon{
57 | @include wh(1.67rem, 1.67rem);
58 | fill: #ccc;
59 | }
60 | .choosed_way{
61 | fill: #4cd964;
62 | }
63 | }
64 | }
65 | .determine{
66 | background-color: #4cd964;
67 | @include sc(1.16rem, #fff);
68 | text-align: center;
69 | margin: 0 1.16rem;
70 | line-height: 3rem;
71 | border-radius: 0.33rem;
72 | margin-top: 0.83rem;
73 | font-weight: bold;
74 | }
75 | .confirm {
76 | background-color: #4cd964;
77 | }
--------------------------------------------------------------------------------
/src/app/confirm-order/choose-address/choose-address.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { Subscription } from 'rxjs';
3 | import { AppService, DataService, LocalStorageService, CartService, ShopService } from '../../service';
4 | import { UserInfo } from '../../class';
5 |
6 | @Component({
7 | selector: 'page-choose-address',
8 | templateUrl: 'choose-address.page.html',
9 | styleUrls: ['choose-address.page.scss']
10 | })
11 | export class ChooseAddressPage extends UserInfo implements OnInit, OnDestroy {
12 | addressList: any[];
13 | deliverable: any[];
14 | deliverdisable: any[];
15 | iconColor: any = {'公司': '#4cd964', '学校': '#3190e8', '家': '#ff5722'};
16 | unSub: Subscription;
17 | constructor(
18 | public appService: AppService,
19 | public localStorageService: LocalStorageService,
20 | public cartService: CartService,
21 | public shopService: ShopService,
22 | public dataService: DataService) {
23 | super(appService, localStorageService);
24 | this.unSub = this.appService.notify.subscribe(res => {
25 | this.ngOnInit();
26 | });
27 | }
28 |
29 | ngOnInit() {
30 | this.addressList = [];
31 | this.deliverable = [];
32 | this.deliverdisable = [];
33 | if (this.userId) {
34 | this.dataService.getAddressList(this.userId).subscribe(res => {
35 | this.addressList = res;
36 | this.addressList.forEach(item => {
37 | if (item.is_deliverable) {
38 | this.deliverable.push(item);
39 | } else {
40 | this.deliverdisable.push(item);
41 | }
42 | });
43 | this.setFirstIndex();
44 | });
45 | }
46 | }
47 | setFirstIndex() {
48 | if (this.deliverable.length === 1) {
49 | this.appService.choosedAddress = {address: this.deliverable[0], index: 0};
50 | }
51 | }
52 | defaultIndex() {
53 | if (this.appService.choosedAddress.index) {
54 | return this.appService.choosedAddress.index;
55 | } else {
56 | return 0;
57 | }
58 | }
59 | chooseAddress(address, index) {
60 | this.appService.choosedAddress = {address, index};
61 | window.history.back();
62 | }
63 |
64 | ngOndestory() {
65 | if (this.unSub) {
66 | this.unSub.unsubscribe();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/app/home/home.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 | .head_logo {
4 | margin-left: .8rem;
5 | color: #fff;
6 | font-size: 1.2rem;
7 | }
8 | .city_nav {
9 | background-color: #fff;
10 | line-height: 2.75rem;
11 | margin-bottom: .66rem;
12 | .city_tip{
13 | line-height: 3rem;
14 | display: -webkit-box;
15 | display: -ms-flexbox;
16 | display: flex;
17 | -webkit-box-pack: justify;
18 | -ms-flex-pack: justify;
19 | justify-content: space-between;
20 | padding: 0 .88rem;
21 | }
22 | .city_tip{
23 | span:first-of-type {
24 | color: #666;
25 | font-size: .9rem;
26 | }
27 | span:nth-of-type(2) {
28 | font-size: 1rem;
29 | font-weight: 900;
30 | font-size: .475rem;
31 | color: #9f9f9f;
32 | }
33 | }
34 | }
35 | .guess_city {
36 | height: 3rem;
37 | display: -webkit-box;
38 | display: -ms-flexbox;
39 | display: flex;
40 | -webkit-box-pack: justify;
41 | -ms-flex-pack: justify;
42 | justify-content: space-between;
43 | -webkit-box-align: center;
44 | -ms-flex-align: center;
45 | align-items: center;
46 | font-size: 1.25rem;
47 | background-color: #fff;
48 | border-top: 1px solid #e4e4e4;
49 | border-bottom: 2px solid #e4e4e4;
50 | padding: 0 .88rem;
51 | span {
52 | color: $blue;
53 | }
54 | .arrow_right {
55 | width: 1rem;
56 | height: 1rem;
57 | fill: #999;
58 | }
59 | }
60 | .hot_city_container {
61 | background-color: #fff;
62 | margin-bottom: .66rem;
63 | }
64 | .citylistul li {
65 | text-align: center;
66 | color: $blue;
67 | border-bottom: .004rem solid #e4e4e4;
68 | border-right: .004rem solid #e4e4e4;
69 | width: 25%;
70 | height: 2.93rem;
71 | line-height: 2.93rem;
72 | font-size: 1rem;
73 | float: left;
74 | }
75 | .city_title {
76 | line-height: 2.57rem;
77 | color: #666;
78 | border-top: 2px solid #e4e4e4;
79 | border-bottom: 1px solid #e4e4e4;
80 | font-size: .92rem;
81 | text-indent: .75rem;
82 | }
83 | .letter_classify_li {
84 | margin-bottom: .66rem;
85 | background-color: #fff;
86 | border-bottom: 1px solid #e4e4e4;
87 | }
88 | .letter_classify_li .groupcity_name_container li {
89 | color: #666;
90 | }
91 | .ellipsis {
92 | overflow: hidden;
93 | text-overflow: ellipsis;
94 | white-space: nowrap;
95 | }
96 |
--------------------------------------------------------------------------------
/src/app/shared/components/shop/evaluate/evaluate.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { DataService, ShopService } from '../../../../service';
3 |
4 | @Component({
5 | selector: 'shop-evaluate',
6 | templateUrl: 'evaluate.html',
7 | styleUrls: ['evaluate.scss']
8 | })
9 | export class ShopEvaluateComponent {
10 | @Input() shopId: string;
11 | @Input() rating: string;
12 | ratingList: any; // 评价列表
13 | ratingOffset: number = 0; // 评价获取数据offset值
14 | ratingScoresData: any; // 评价总体分数
15 | showLoading: boolean = false;
16 | items: any[] = [];
17 | touchEnd: boolean = false;
18 | preventRepeatReuqest: boolean = false; // 到达底部加载数据,防止重复加载
19 | constructor(public dataService: DataService,
20 | public shopService: ShopService) {
21 | this.ratingList = this.shopService.ratingList;
22 | this.ratingScoresData = this.shopService.ratingScoresData;
23 | this.shopService.updateData.subscribe(res => {
24 | this.ratingList = this.shopService.ratingList;
25 | this.ratingScoresData = this.shopService.ratingScoresData;
26 | });
27 | }
28 | loaderMore(event: any) {
29 | if (this.preventRepeatReuqest) {
30 | return;
31 | }
32 | if (this.touchEnd) {
33 | event.target.disabled = true;
34 | return;
35 | }
36 | this.preventRepeatReuqest = true;
37 | this.ratingOffset += 10;
38 | this.showLoading = true;
39 | this.dataService.getRatingList(this.shopId, this.ratingOffset).subscribe(res => {
40 | this.preventRepeatReuqest = false;
41 | if (res.length < 10) {
42 | this.touchEnd = true;
43 | }
44 | event.target.complete();
45 | this.ratingList = [...this.ratingList, ...res];
46 | });
47 | }
48 |
49 | getRatingList(ratingOffset: number, name?: string) {
50 | this.dataService.getRatingList(this.shopId, ratingOffset, name).subscribe(res => {
51 | this.ratingList = this.shopService.ratingList;
52 | });
53 | }
54 |
55 | getImgPath(path) {
56 | let suffix;
57 | if (!path) {
58 | return 'http://test.fe.ptdev.cn/elm/elmlogo.jpeg';
59 | }
60 | if (path.indexOf('jpeg') !== -1) {
61 | suffix = '.jpeg';
62 | } else {
63 | suffix = '.png';
64 | }
65 | const url = '/' + path.substr(0, 1) + '/' + path.substr(1, 2) + '/' + path.substr(3) + suffix;
66 | return 'https://fuss10.elemecdn.com' + url;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/assets/icon/elm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/confirm-order/choose-address/choose-address.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
54 |
--------------------------------------------------------------------------------
/src/app/order/order.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | 订单
4 |
5 |
6 |
7 |
8 | 0">
9 |
10 |

11 |
您最近没有订单
12 |
13 | 0">
14 | -
15 |
16 |
17 |
18 |
32 |
33 | {{item.basket.group[0][0].name}}{{item.basket.group[0].length > 1 ? ' 等' + item.basket.group[0].length + '件商品'
34 | : ''}}
35 | ¥{{item.total_amount.toFixed(2)}}
36 |
37 |
38 |
39 |
40 | {{item.time_pass|timeLast}}
41 |
42 |
再来一单
43 |
44 |
45 |
46 |
47 |
48 |
49 | 没有更多了
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/app/address/add-address/add-address.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | .address_page{
3 | .page_text_container{
4 | background-color: #fff;
5 | padding: 0 1.16rem;
6 | }
7 | .section_list{
8 | display: flex;
9 | border-bottom: 0.041rem solid #f5f5f5;
10 | .section_left{
11 | @include sc(1.16rem, #333);
12 | flex: 2;
13 | line-height: 4.1rem;
14 | }
15 | .section_right{
16 | flex: 5;
17 | .input_style{
18 | width: 100%;
19 | height: 4.1rem;
20 | @include sc(1.16rem, #999);
21 | }
22 | .phone_bk{
23 | border-top: 0.041rem solid #f5f5f5;
24 | }
25 | .phone_add{
26 | @include fj;
27 | align-items: center;
28 | .phone_add_bk {
29 | @include wh(1.5rem, 1.5rem);
30 | }
31 | }
32 | .choose_sex, .choose_tag {
33 | display: flex;
34 | height: 4.1rem;
35 | border-top: 0.041rem solid #f5f5f5;
36 | align-items: center;
37 | .choose_option{
38 | @include sc(1rem, #333);
39 | margin-right: 1.33rem;
40 | width: 4rem;
41 | height: 2rem;
42 | line-height: 1.9rem;
43 | text-align: center;
44 | display: inline-block;
45 | border-radius: .1rem;
46 | border: 1px solid #d9d9d9;
47 | }
48 | .choosed{
49 | color: $blue;
50 | border-color: $blue;
51 | }
52 | }
53 |
54 | .choose_address{
55 | @include sc(1.16rem, #999);
56 | line-height: 4.1rem;
57 | border-bottom: 0.041rem solid #f5f5f5;
58 | display: flex;
59 | justify-content: space-between;
60 | align-items: center;
61 | .address_name {
62 | color: #999;
63 | }
64 | }
65 | .address_search{
66 | @include wh(1rem, 1rem);
67 | fill: #999;
68 | }
69 | }
70 | }
71 | .determine{
72 | background-color: #4cd964;
73 | @include sc(1.16rem, #fff);
74 | text-align: center;
75 | margin: 0 1.16rem;
76 | line-height: 3rem;
77 | border-radius: 0.33rem;
78 | margin-top: 1rem;
79 | }
80 | }
--------------------------------------------------------------------------------
/src/app/shared/components/shop/evaluate/evaluate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
27 |
28 | -
29 |
30 |
31 |
41 |
42 | -
43 |
44 |
45 |
46 |
47 | -
48 | {{item.food_name}}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 没有更多了
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/app/address/add-address/add-address.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
27 |
39 |
40 | 标签
41 |
42 |
43 | 家
44 | 学校
45 | 公司
46 |
47 |
48 |
49 |
50 |
确定
51 |
52 |
--------------------------------------------------------------------------------
/src/app/city/city.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { AppService, DataService, LocalStorageService } from '../service';
4 |
5 | @Component({
6 | selector: 'page-city',
7 | templateUrl: 'city.page.html',
8 | styleUrls: ['city.page.scss']
9 | })
10 | export class CityPage implements OnInit {
11 | search: string;
12 | guessCity: string;
13 | guessCityId: string;
14 | placeList: any[];
15 | placeNone: boolean;
16 | placeHistory: any[];
17 | historyTitle: boolean;
18 | constructor(
19 | public router: Router,
20 | public route: ActivatedRoute,
21 | public appService: AppService,
22 | public dataService: DataService,
23 | public storageService: LocalStorageService) {
24 | this.guessCityId = this.route.snapshot.paramMap.get('id');
25 | this.guessCity = '';
26 | this.search = '';
27 | this.placeList = [];
28 | this.placeHistory = [];
29 | this.historyTitle = true;
30 | this.getCityById(this.guessCityId);
31 | }
32 |
33 | ngOnInit() {
34 | if (this.storageService.getStore('placeHistory')) {
35 | this.placeList = JSON.parse(this.storageService.getStore('placeHistory'));
36 | } else {
37 | this.placeList = [];
38 | }
39 | }
40 |
41 | getCityById(id: string) {
42 | this.dataService.getCityById(id).subscribe(res => {
43 | this.guessCity = res.name;
44 | });
45 | }
46 |
47 | setSearchStorage(place: any) {
48 | const history = this.storageService.getStore('placeHistory');
49 | const choosePlace = place;
50 | if (history) {
51 | let checkrepeat = false;
52 | this.placeHistory = JSON.parse(history);
53 | this.placeHistory.forEach(item => {
54 | if (item.geohash === place.geohash) {
55 | checkrepeat = true;
56 | }
57 | });
58 | if (!checkrepeat) {
59 | this.placeHistory.push(choosePlace);
60 | }
61 | } else {
62 | this.placeHistory.push(choosePlace);
63 | }
64 | this.storageService.setStore('placeHistory', this.placeHistory);
65 | }
66 |
67 | searchPlace() {
68 | if (!this.search) {
69 | return;
70 | }
71 | this.historyTitle = false;
72 | this.dataService.searchPlace(this.guessCityId, this.search).subscribe(res => {
73 | this.placeList = res;
74 | this.placeNone = res.length ? false : true;
75 | });
76 | }
77 |
78 | clearAll() {
79 | this.storageService.removeStore('placeHistory');
80 | this.placeList = [];
81 | }
82 |
83 | toMiste(place: any) {
84 | this.setSearchStorage(place);
85 | this.appService.geohash = place.geohash;
86 | this.router.navigateByUrl('/tabs/msite?geohash=' + place.geohash);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/app/order/order.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { AlertController } from '@ionic/angular';
4 | import { AppService, DataService, LocalStorageService } from '../service';
5 | import { ImgBaseUrl } from '../config/env';
6 | import { UserInfo } from '../class';
7 |
8 | @Component({
9 | selector: 'page-order',
10 | templateUrl: 'order.page.html',
11 | styleUrls: ['order.page.scss']
12 | })
13 | export class OrderPage extends UserInfo implements OnInit, OnDestroy {
14 | orderList: any;
15 | showLoading: boolean = true;
16 | offset: number = 0;
17 | imgBaseUrl: string = ImgBaseUrl;
18 | touchEnd: boolean = false;
19 | preventRepeatReuqest: boolean = false; // 到达底部加载数据,防止重复加载
20 | params: {geohash: string};
21 | constructor(
22 | public route: ActivatedRoute,
23 | public router: Router,
24 | public appService: AppService,
25 | public dataService: DataService,
26 | public localStorageService: LocalStorageService,
27 | public alertCtrl: AlertController) {
28 | super(appService, localStorageService);
29 | }
30 |
31 | ngOnInit() {
32 | this.params = { geohash: this.appService.geohash };
33 | this.orderList = [];
34 | if (this.userId) {
35 | this.dataService.getOrderList(this.userId, this.offset).subscribe(res => {
36 | this.orderList = [...res];
37 | this.showLoading = false;
38 | });
39 | } else {
40 | this.showLoading = false;
41 | }
42 | }
43 |
44 | loaderMore(event: any) {
45 | this.offset += 10;
46 | this.preventRepeatReuqest = true;
47 | this.showLoading = true;
48 | const userId = this.localStorageService.getStore('userId');
49 | this.dataService.getOrderList(userId, this.offset).subscribe(res => {
50 | if (res.length < 10) {
51 | this.touchEnd = true;
52 | event.target.disabled = true;
53 | }
54 | this.orderList = [...this.orderList, ...res];
55 | this.showLoading = false;
56 | this.preventRepeatReuqest = false;
57 | });
58 | event.target.complete();
59 | }
60 | // 显示详情页
61 | showDetail(item: any) {
62 | this.appService.orderDetail = item;
63 | this.preventRepeatReuqest = false;
64 | this.router.navigateByUrl('/order/detail');
65 | }
66 |
67 | async presentConfirm(message: string) {
68 | const alert = await this.alertCtrl.create({
69 | header: '确认支付',
70 | message: message,
71 | cssClass: 'confirm',
72 | buttons: [
73 | {
74 | text: '确认',
75 | handler: () => {
76 | this.router.navigateByUrl('/tabs/order');
77 | }
78 | }
79 | ]
80 | });
81 | alert.present();
82 | }
83 |
84 | toPay() {
85 | this.presentConfirm('付款功能未开放');
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ionic6_angular10_elm
2 | 基于ionic6 + ng10构建一个具有 30+ 页面的大型单页面应用(master必须使用ionic v6,已升级到v6正式版)
3 |
4 | [阿里移动端组件库ng-zorro-antd-mobile开源地址](https://github.com/NG-ZORRO/ng-zorro-antd-mobile),将在zorro分支逐步使用zorro-antd-mobile组件替换重构,感兴趣的可以直接使用zorro分支(重构中,未完成)
5 |
6 | 基于ionic5 + ng8 构建一个具有 30+ 页面的大型单页面应用(请使用ionic5-ng8分支)
7 |
8 | 基于ionic3 + ng5 构建一个具有 30+ 页面的大型单页面应用(请使用v3分支,必须使用ionic v3才能启动)
9 | 借鉴了[@bailicangdu](https://github.com/bailicangdu/vue2-elm) vue-elm项目,已征得其本人同意,[后台传送地址](https://github.com/bailicangdu/node-elm)
10 |
11 |
12 |
13 | ## 项目运行
14 |
15 | #### 注意:由于涉及大量的 ES6/7 等新属性,node 需要 6.0 以上版本
16 |
17 | ```
18 | npm install -g cordova ionic // 需要全局安装cordova ionic
19 |
20 | git clone https://github.com/nuonuoge/ionic4_angular6_elm.git
21 |
22 | cd ionic4_angular6_elm
23 |
24 | npm install
25 |
26 | npm start
27 |
28 | ```
29 |
30 | ## 另外
31 | 此项目有配套的后台系统,如果想体验前后台同时开发,可以下载对应的后台系统:[后台项目传送地址](https://github.com/bailicangdu/node-elm)。
32 |
33 | 如果只做前端开发,请忽略这句话。
34 |
35 |
36 | # 说明
37 |
38 | > 暂时没有体验地址,待所有功能完成后再发布,可以去[vue-elm发布地址体验](http://cangdu.org/elm/)(请用chrome手机模式预览)
39 |
40 | > 如果对您有帮助,您可以点右上角 "Star" 支持一下 谢谢! ^_^
41 |
42 | > 或者您可以 "follow" 一下,我会不断开源更多的有趣的项目
43 |
44 | > 如有问题请直接在 Issues 中提,或者您发现问题并有非常好的解决方案,欢迎 PR 👍
45 |
46 | > 推荐一个 react + redux 开源项目,对react感兴趣的朋友赶紧去看看。[地址在这里](https://github.com/bailicangdu/react-pxq)
47 |
48 | > 另外一个 vue2 + vuex 的elm项目。[地址在这里](https://github.com/bailicangdu/vue2-elm)
49 |
50 | # 部分展示
51 | ### 登录页
52 |
53 |
54 | ### 搜索页
55 |
56 |
57 | ### tabs
58 |
59 |
60 | ### 商铺列表页
61 |
62 |
63 | ### 商铺页
64 |
65 |
66 | # 目标功能
67 | - [x] 定位功能 -- 完成
68 | - [x] 选择城市 -- 完成
69 | - [x] 搜索地址 -- 完成
70 | - [x] 展示所选地址附近商家列表 -- 完成
71 | - [x] 搜索美食,餐馆 -- 完成
72 | - [x] 根据距离、销量、评分、特色菜、配送方式等进行排序和筛选 -- 完成
73 | - [x] 餐馆食品列表页 -- 完成
74 | - [x] 购物车功能 -- 完成
75 | - [x] 店铺评价页面 -- 完成
76 | - [x] 单个食品详情页面 -- 完成
77 | - [x] 商家详情页 -- 完成
78 | - [x] 登录、注册 -- 完成
79 | - [x] 个人中心 -- 完成
80 | - [x] 下单功能 -- 完成
81 | - [x] 订单列表 -- 完成
82 | - [x] 订单详情 -- 完成
83 |
84 | # License
85 |
86 | GPL
87 |
--------------------------------------------------------------------------------
/src/app/shared/components/buy-cart/buy-cart.ts:
--------------------------------------------------------------------------------
1 | import { Component, EventEmitter, Input, Output } from '@angular/core';
2 | import { ToastController } from '@ionic/angular';
3 | import { LocalStorageService, CartService } from '../../../service';
4 |
5 | @Component({
6 | selector: 'buy-cart',
7 | templateUrl: 'buy-cart.html',
8 | styleUrls: ['buy-cart.scss']
9 | })
10 | export class BuyCartComponent {
11 | @Input() foods: any;
12 | @Input() shopId: string;
13 | @Output() onCartChange: EventEmitter = new EventEmitter();
14 | @Output() onShowChooseList: EventEmitter = new EventEmitter();
15 | @Output() onShowMoveDot: EventEmitter = new EventEmitter();
16 | showMoveDot: any = [];
17 | constructor(public storageService: LocalStorageService, public cartService: CartService, public toastCtrl: ToastController) {
18 |
19 | }
20 | shopCart() {
21 | return Object.assign({}, this.cartService.cartList[this.shopId]);
22 | }
23 | // shopCart变化的时候重新计算当前商品的数量
24 | foodNum() {
25 | const category_id = this.foods.category_id;
26 | const item_id = this.foods.item_id;
27 | if (this.shopCart() && this.shopCart()[category_id] && this.shopCart()[category_id][item_id]) {
28 | let num = 0;
29 | const values = [];
30 | Object.keys(this.shopCart()[category_id][item_id]).forEach(item => {
31 | values.push(this.shopCart()[category_id][item_id][item]);
32 | });
33 | values.forEach((item, index) => {
34 | num += item.num;
35 | });
36 | return num;
37 | } else {
38 | return 0;
39 | }
40 | }
41 | // 移出购物车
42 | removeOutCart(category_id, item_id, food_id, name, price, specs, packing_fee, sku_id, stock) {
43 | if (this.foodNum() > 0) {
44 | this.cartService.reduceCart({ shopid: this.shopId, category_id, item_id, food_id, name, price, specs, packing_fee, sku_id, stock });
45 | this.onCartChange.emit(null);
46 | }
47 | }
48 | // 加入购物车,计算按钮位置。
49 | addToCart(category_id, item_id, food_id, name, price, specs, packing_fee, sku_id, stock, event) {
50 | this.cartService.addCart({ shopid: this.shopId, category_id, item_id, food_id, name, price, specs, packing_fee, sku_id, stock });
51 | this.onCartChange.emit(null);
52 | const elLeft = event.target.getBoundingClientRect().left;
53 | const elBottom = event.target.getBoundingClientRect().bottom;
54 | this.showMoveDot.push(true);
55 | this.onShowMoveDot.emit({ 'showMoveDot': this.showMoveDot, 'elLeft': elLeft, 'elBottom': elBottom });
56 |
57 | }
58 | // 显示规格列表
59 | showChooseList(foods) {
60 | this.onShowChooseList.emit(foods);
61 | }
62 | // 点击多规格商品的减按钮,弹出提示
63 | async showReduceTip() {
64 | const toast = await this.toastCtrl.create({
65 | message: '多规格商品只能去购物车删除哦',
66 | duration: 2000,
67 | position: 'middle',
68 | cssClass: 'specs_reduce_tip'
69 | });
70 | toast.present();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/app/service/cart.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { LocalStorageService } from './localstorage.service';
3 |
4 | @Injectable({
5 | providedIn: 'root'
6 | })
7 |
8 | export class CartService {
9 | public cartList: any;
10 | constructor(public storageService: LocalStorageService) {
11 | this.cartList = {};
12 | }
13 |
14 | // 加入购物车
15 | addCart(cartObject: {
16 | shopid?: string,
17 | category_id?: string,
18 | item_id?: string,
19 | food_id?: string,
20 | name?: string,
21 | price?: any,
22 | specs?: any,
23 | packing_fee?: any,
24 | sku_id?: string,
25 | stock?: any
26 | }) {
27 | const cart = this.cartList;
28 | const shop = cart[cartObject.shopid] = (cart[cartObject.shopid] || {});
29 | const category = shop[cartObject.category_id] = (shop[cartObject.category_id] || {});
30 | const item = category[cartObject.item_id] = (category[cartObject.item_id] || {});
31 | if (item[cartObject.food_id]) {
32 | item[cartObject.food_id]['num']++;
33 | } else {
34 | item[cartObject.food_id] = {
35 | 'num': 1,
36 | 'id': cartObject.food_id,
37 | 'name': cartObject.name,
38 | 'price': cartObject.price,
39 | 'specs': cartObject.specs,
40 | 'packing_fee': cartObject.packing_fee,
41 | 'sku_id': cartObject.sku_id,
42 | 'stock': cartObject.stock
43 | };
44 | }
45 | this.cartList = { ...cart };
46 | // 存入localStorage
47 | this.storageService.setStore('buyCart', this.cartList);
48 | }
49 | // 移出购物车
50 | reduceCart(cartObject: {
51 | shopid?: string,
52 | category_id?: string,
53 | item_id?: string,
54 | food_id?: string,
55 | name?: string,
56 | price?: any,
57 | specs?: any,
58 | packing_fee?: any,
59 | sku_id?: string,
60 | stock?: any
61 | }) {
62 | const cart = this.cartList;
63 | const shop = (cart[cartObject.shopid] || {});
64 | const category = (shop[cartObject.category_id] || {});
65 | const item = (category[cartObject.item_id] || {});
66 | if (item && item[cartObject.food_id]) {
67 | if (item[cartObject.food_id]['num'] > 0) {
68 | item[cartObject.food_id]['num']--;
69 | this.cartList = { ...cart };
70 | // 存入localStorage
71 | this.storageService.setStore('buyCart', this.cartList);
72 | } else {
73 | // 商品数量为0,则清空当前商品的信息
74 | item[cartObject.food_id] = null;
75 | }
76 | }
77 | }
78 | // 网页初始化时从本地缓存获取购物车数据
79 | initBuyCart() {
80 | const initCart = this.storageService.getStore('buyCart');
81 | if (initCart) {
82 | this.cartList = JSON.parse(initCart);
83 | }
84 | }
85 | // 清空当前商品的购物车信息
86 | clearCart(shopId) {
87 | this.cartList[shopId] = null;
88 | this.cartList = { ...this.cartList };
89 | this.storageService.setStore('buyCart', this.cartList);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/app/search/search.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { DataService, LocalStorageService } from '../service';
4 |
5 | @Component({
6 | selector: 'page-search',
7 | templateUrl: 'search.page.html',
8 | styleUrls: ['./search.page.scss']
9 | })
10 | export class SearchPage implements OnInit {
11 | searchValue: string;
12 | geohash: string;
13 | restaurantList: any[];
14 | emptyResult: boolean;
15 | searchHistory: any[];
16 | showHistory: boolean;
17 |
18 | constructor(public route: ActivatedRoute,
19 | public router: Router,
20 | public dataService: DataService,
21 | public storageService: LocalStorageService) {
22 | this.geohash = this.route.snapshot.queryParamMap.get('geohash');
23 | this.searchValue = '';
24 | this.restaurantList = [];
25 | this.searchHistory = [];
26 | this.showHistory = true;
27 | }
28 |
29 | ngOnInit() {
30 | if (this.storageService.getStore('searchHistory')) {
31 | this.searchHistory = JSON.parse(this.storageService.getStore('searchHistory'));
32 | } else {
33 | this.searchHistory = [];
34 | }
35 | }
36 |
37 | setSearchStorage() {
38 | const history = this.storageService.getStore('searchHistory');
39 | if (history) {
40 | let checkrepeat = false;
41 | this.searchHistory = JSON.parse(history);
42 | this.searchHistory.forEach(item => {
43 | if (item === this.searchValue) {
44 | checkrepeat = true;
45 | }
46 | });
47 | if (!checkrepeat) {
48 | this.searchHistory.push(this.searchValue);
49 | }
50 | } else {
51 | this.searchHistory.push(this.searchValue);
52 | }
53 | this.storageService.setStore('searchHistory', this.searchHistory);
54 | }
55 |
56 | searchRestaurants(value?: string) {
57 | if (value) {
58 | this.searchValue = value;
59 | } else if (!this.searchValue) {
60 | return;
61 | }
62 | this.showHistory = false;
63 | this.dataService.searchRestaurant(this.geohash, this.searchValue).subscribe((res: any) => {
64 | this.restaurantList = res;
65 | this.emptyResult = res.length ? false : true;
66 | });
67 | this.setSearchStorage();
68 | }
69 |
70 | checkInput() {
71 | if (this.searchValue === '') {
72 | this.showHistory = true; // 显示历史记录
73 | this.restaurantList = []; // 清空搜索结果
74 | this.emptyResult = false; // 隐藏搜索为空提示
75 | }
76 | }
77 |
78 | deleteHistory(index: number) {
79 | this.searchHistory.splice(index, 1);
80 | this.storageService.setStore('searchHistory', this.searchHistory);
81 | }
82 |
83 | clearAll() {
84 | this.storageService.removeStore('searchHistory');
85 | this.searchHistory = [];
86 | this.restaurantList = [];
87 | }
88 |
89 | toShop(place: any) {
90 | this.router.navigate(['msite'], { queryParams: { geohash: place.geohash } });
91 | }
92 |
93 | back() {
94 | window.history.back();
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/app/order/order.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 |
4 | .order_empty {
5 | height: 100%;
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | justify-content: center;
10 | .order_empty_icon {
11 | background-repeat: no-repeat;
12 | height: 6rem;
13 | width: 6rem;
14 | }
15 | .order_empty_text {
16 | font-size: 1rem;
17 | color: #999;
18 | margin-top: .5rem;
19 | }
20 | }
21 | .order_list_ul{
22 | .order_list_li{
23 | background-color: #fff;
24 | display: flex;
25 | margin-bottom: 0.83rem;
26 | padding: 1rem 1rem 0;
27 | .restaurant_image{
28 | @include wh(3.3rem, 3.3rem);
29 | margin-right: 0.67rem;
30 | }
31 | .order_item_right{
32 | flex: 5;
33 | .order_item_right_header{
34 | border-bottom: 0.041rem solid #f5f5f5;
35 | padding-bottom: .5rem;
36 | padding-right: 1rem;
37 | @include fj;
38 | .order_header{
39 | h4{
40 | display: flex;
41 | align-items: center;
42 | justify-content: flex-start;
43 | @include sc(1.25rem, #333);
44 | line-height: 1.67rem;
45 | width: 15rem;
46 | .arrow_right{
47 | @include wh(.67rem, .67rem);
48 | fill: #ccc;
49 | margin-right: .33rem;
50 | }
51 | }
52 | .order_time{
53 | @include sc(.92rem, #999);
54 | line-height: 1.33rem;
55 | }
56 | }
57 | .order_status{
58 | @include sc(1rem, #333);
59 | }
60 | }
61 | .order_basket{
62 | @include fj;
63 | padding-right: 1rem;
64 | line-height: 3.3rem;
65 | border-bottom: 0.041rem solid #f5f5f5;
66 | .order_name{
67 | @include sc(1rem, #666);
68 | width: 15rem;
69 | }
70 | .order_amount{
71 | @include sc(1rem, #f60);
72 | font-weight: bold;
73 | }
74 | }
75 | .order_again{
76 | text-align: right;
77 | line-height: 2.6rem;
78 | margin-right: 1rem;
79 | .buy_again{
80 | @include sc(.92rem, #3190e8);
81 | border: 0.055rem solid #3190e8;
82 | padding: .26rem .33rem;
83 | border-radius: .25rem;
84 | }
85 | .page{
86 | display: inline-block;
87 | .wait_pay {
88 | font-size: .92rem;
89 | color: orange;
90 | border: 1px solid orange;
91 | border-radius: .15rem;
92 | padding: .1rem .2rem;
93 | }
94 | .rem_time{
95 | @include sc(.92rem, orange);
96 | padding: .16rem .33rem;
97 | border-radius: .25rem;
98 | }
99 | }
100 | }
101 | }
102 | }
103 | }
104 | .empty_data{
105 | @include sc(0.82rem, #666);
106 | text-align: center;
107 | line-height: 3.34rem;
108 | }
--------------------------------------------------------------------------------
/src/assets/icon/find.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags.ts';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | import './zone-flags';
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 |
61 | import 'zone.js/dist/zone'; // Included with Angular CLI.
62 |
63 |
64 | /***************************************************************************************************
65 | * APPLICATION IMPORTS
66 | */
67 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 我的
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
{{userInfo?.username}}
18 |
登录|注册
19 |
20 |
21 |
24 |
25 | {{mobile}}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | -
35 | {{userInfo?.balance}}元
36 | 我的余额
37 |
38 | -
39 | {{userInfo?.gift_amount}}个
40 | 我的优惠
41 |
42 | -
43 | {{userInfo?.point}}分
44 | 我的积分
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 | 我的订单
58 |
59 |
62 |
63 |
64 |
65 |
66 |
67 |
72 |
73 | 收货地址
74 |
75 |
78 |
79 |
80 |
81 |
82 |
85 |
--------------------------------------------------------------------------------
/src/app/order/order-detail/order-detail.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
82 |
83 |
--------------------------------------------------------------------------------
/src/app/shop/detail/shop-detail.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
24 |
25 | 配送费: 配送费¥{{shopDetailData.float_delivery_fee}}
26 | 公告: {{shopDetailData.promotion_info}}
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
37 | {{rating.username}}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | 0||shopDetailData.supports?.length>0">
47 |
48 |
49 | {{item.icon_name}}
50 | {{item.description}}
51 |
52 |
53 | {{item.icon_name}}
54 | {{item.description}}
55 |
56 |
57 |
58 |
59 | 叫外卖,上饿了么
60 | 地址:{{shopDetailData.address}}
61 | 营业时间:{{time}}
62 |
63 |
--------------------------------------------------------------------------------
/src/app/order/order-detail/order-detail.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../../style/mixin.scss";
2 | @import "../../../style/common.scss";
3 |
4 | .order_title{
5 | display: flex;
6 | flex-direction: column;
7 | align-items: center;
8 | padding: 1.16rem;
9 | background-color: #fff;
10 | margin-bottom: 0.83rem;
11 | img{
12 | border: 0.08rem solid $blue;
13 | border-radius: 50%;
14 | @include wh(5rem, 5rem);
15 | }
16 | p:nth-of-type(1){
17 | @include sc(1.5rem, #333);
18 | font-weight: bold;
19 | margin-top: .67rem;
20 | }
21 | p:nth-of-type(2){
22 | @include sc(.92rem, #999);
23 | width: 16.7rem;
24 | margin-top: .5rem;
25 | text-align: center;
26 | }
27 | .order_again{
28 | @include sc(1rem, $blue);
29 | margin-top: .83rem;
30 | border: 0.041rem solid $blue;
31 | padding: .25rem .67rem;
32 | border-radius: .16rem;
33 | }
34 | }
35 | .food_list{
36 | background-color: #fff;
37 | .food_list_header{
38 | @include fj;
39 | align-items: center;
40 | padding: .33rem .83rem;
41 | border-bottom: 1px solid #f5f5f5;
42 | .shop_name{
43 | img{
44 | @include wh(2rem, 2rem);
45 | vertical-align: middle;
46 | margin-right: .33rem;
47 | }
48 | span{
49 | @include sc(1.25rem, #333);
50 | font-weight: bold;
51 | }
52 | }
53 | svg{
54 | @include wh(1rem, 1rem);
55 | fill: #666;
56 | }
57 | }
58 | .food_list_ul{
59 | li{
60 | @include fj;
61 | align-items: center;
62 | padding: 0 .83rem;
63 | line-height: 3.3rem;
64 | .food_name{
65 | @include sc(1rem, #666);
66 | flex: 4;
67 | }
68 | .quantity_price{
69 | flex: 1;
70 | @include fj;
71 | align-items: center;
72 | span:nth-of-type(1){
73 | @include sc(1rem, #ccc);
74 | }
75 | span:nth-of-type(2){
76 | @include sc(1rem, #666);
77 | }
78 | }
79 | }
80 | }
81 | .deliver_fee{
82 | @include fj;
83 | align-items: center;
84 | padding: 0 .83rem;
85 | line-height: 3.3rem;
86 | border-top: 1px solid #f5f5f5;
87 | span{
88 | @include sc(1rem, #666);
89 | }
90 | }
91 | .pay_ment{
92 | @include sc(1rem, #fb6b23);
93 | border-top: 1px solid #f5f5f5;
94 | font-weight: bold;
95 | line-height: 3.3rem;
96 | text-align: right;
97 | padding-right: .83rem;
98 | }
99 | }
100 | .order_detail_style{
101 | background-color: #fff;
102 | margin-top: 0.83rem;
103 | header{
104 | @include sc(1.25rem, #333);
105 | padding: .83rem;
106 | border-bottom: 1px solid #f5f5f5;
107 | }
108 | .item_style{
109 | display: flex;
110 | padding: .83rem;
111 | p{
112 | @include sc(1.1rem, #666);
113 | line-height: 1.67rem;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/src/app/shared/components/shop/msite/shop-msite.scss:
--------------------------------------------------------------------------------
1 | @import "../../../../../style/mixin.scss";
2 | .shoplist_container{
3 | background-color: #fff;
4 | margin-bottom: 3.34rem;
5 | }
6 | .shop_li{
7 | display: flex;
8 | border-bottom: 0.06rem solid #f1f1f1;
9 | padding: 1.16rem 0.668rem;
10 | }
11 | .shop_img{
12 | @include wh(4.5rem, 4.5rem);
13 | display: block;
14 | margin-right: 0.668rem;
15 | }
16 | .list_back_li{
17 | height: 8.1rem;
18 | .list_back_svg{
19 | @include wh(100%, 100%)
20 | }
21 | }
22 | .shop_right{
23 | flex: auto;
24 | .shop_detail_header{
25 | @include fj;
26 | align-items: center;
27 | .shop_title{
28 | width: 14.2rem;
29 | color: #333;
30 | padding-top: .016rem;
31 | @include font(1.08rem, 1.08rem, 'PingFangSC-Regular');
32 | font-weight: 700;
33 | }
34 | .premium::before{
35 | content: '品牌';
36 | display: inline-block;
37 | font-size: 0.83rem;
38 | line-height: 1rem;
39 | color: #333;
40 | background-color: #ffd930;
41 | padding: 0 0.16rem;
42 | border-radius: 0.16rem;
43 | margin-right: 0.33rem;
44 | }
45 | .shop_detail_ul{
46 | display: flex;
47 | transform: scale(.8);
48 | margin-right: -0.5rem;
49 | .supports{
50 | @include sc(0.835rem, #999);
51 | border: 0.06rem solid #f1f1f1;
52 | padding: 0 0.0668rem;
53 | border-radius: 0.13rem;
54 | margin-left: 0.083rem;
55 | }
56 | }
57 | }
58 | .rating_order_num{
59 | @include fj(space-between);
60 | height: 1rem;
61 | margin-top: 0.87rem;
62 | .rating_order_num_left{
63 | @include fj(flex-start);
64 | .rating_section{
65 | display: flex;
66 | .rating_num{
67 | @include sc(0.668rem, #ff6000);
68 | margin: 0 0.334rem;
69 | }
70 | }
71 | .order_section{
72 | transform: scale(.8);
73 | margin-left: -0.334rem;
74 | @include sc(0.668rem, #666);
75 | }
76 | }
77 | .rating_order_num_right{
78 | display: flex;
79 | align-items: center;
80 | transform: scale(.7);
81 | min-width: 8.35rem;
82 | justify-content: flex-end;
83 | margin-right: -1.336rem;
84 | .delivery_style{
85 | font-size: 0.668rem;
86 | padding: 0.0668rem 0.13rem 0;
87 | border-radius: 0.13rem;
88 | margin-left: 0.13rem;
89 | border: 1px;
90 | }
91 | .delivery_left{
92 | color: #fff;
93 | background-color: $blue;
94 | border: 0.06rem solid $blue;
95 | }
96 | .delivery_right{
97 | color: $blue;
98 | border: 0.06rem solid $blue;
99 | }
100 | }
101 | }
102 | .fee_distance{
103 | margin-top: 0.87rem;
104 | @include fj;
105 | @include sc(0.835rem, #333);
106 | .fee{
107 | transform: scale(.9);
108 | @include sc(0.835rem, #666);
109 | }
110 | .distance_time{
111 | transform: scale(.9);
112 | span{
113 | color: #999;
114 | }
115 | .order_time{
116 | color: $blue;
117 | }
118 | .segmentation{
119 | color: #ccc;
120 | }
121 | }
122 | }
123 | }
124 | .loader_more{
125 | @include font(1rem, 3);
126 | text-align: center;
127 | color: #999;
128 | }
129 | .return_top{
130 | position: fixed;
131 | bottom: 5rem;
132 | right: 1.67rem;
133 | .back_top_svg{
134 | @include wh(3.34rem, 3.34rem);
135 | }
136 | }
137 | .loading-enter-active, .loading-leave-active {
138 | transition: opacity 1s
139 | }
140 | .loading-enter, .loading-leave-active {
141 | opacity: 0
142 | }
--------------------------------------------------------------------------------
/src/app/address/add-address/add-address.page.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { ToastController } from '@ionic/angular';
4 | import { DataService, LocalStorageService, AppService } from '../../service';
5 | import { UserInfo } from '../../class';
6 |
7 | @Component({
8 | selector: 'page-add-address',
9 | templateUrl: 'add-address.page.html',
10 | styleUrls: ['./add-address.page.scss']
11 | })
12 | export class AddAddressPage extends UserInfo {
13 | name: string = null; // 姓名
14 | sex: number = 1; // 性别
15 | phone: string = null; // 电话
16 | phoneBk: boolean = false; // 备用电话
17 | addressDetail: string = null; // 详细地址
18 | tag: string = ''; // 备注
19 | tagType: number = 1; // 备注类型
20 | phone_bk: boolean = false; // 是否选择备注电话
21 | anntherPhoneNumber: string = ''; // 备注电话
22 | showAlert: boolean = false; // 弹出框
23 | fromWhere: string;
24 | constructor(
25 | public route: ActivatedRoute,
26 | public router: Router,
27 | public localStorageService: LocalStorageService,
28 | public appService: AppService,
29 | public dataService: DataService,
30 | public toastCtrl: ToastController) {
31 | super(appService, localStorageService);
32 | this.fromWhere = this.route.snapshot.queryParamMap.get('from');
33 | }
34 |
35 | searchAddress(): any {
36 | return this.appService.searchAddress;
37 | }
38 |
39 | // 选择性别
40 | chooseSex(sex) {
41 | this.sex = sex;
42 | }
43 | // 选择标签
44 | chooseTag(tag) {
45 | this.tag = tag;
46 | }
47 |
48 | async toastTip(message: string) {
49 | const toast = await this.toastCtrl.create({
50 | message: message,
51 | duration: 2000,
52 | position: 'bottom'
53 | });
54 | toast.present();
55 | }
56 |
57 | // 保存地址信息
58 | addAddress() {
59 | let alertText = '';
60 | if (!this.userId) {
61 | alertText = '请登录';
62 | } else if (!this.name) {
63 | this.showAlert = true;
64 | alertText = '请输入姓名';
65 | } else if (!this.phone) {
66 | this.showAlert = true;
67 | alertText = '请输入电话号码';
68 | } else if (!this.searchAddress()) {
69 | this.showAlert = true;
70 | alertText = '请选择地址';
71 | } else if (!this.addressDetail) {
72 | this.showAlert = true;
73 | alertText = '请输入详细地址';
74 | }
75 | if (alertText) {
76 | this.toastTip(alertText);
77 | return;
78 | }
79 | if (this.tag === '家') {
80 | this.tagType = 2;
81 | } else if (this.tag === '学校') {
82 | this.tagType = 3;
83 | } else if (this.tag === '公司') {
84 | this.tagType = 4;
85 | }
86 | this.dataService.postAddAddress(this.userId, this.searchAddress().name, this.addressDetail,
87 | this.appService.geohash, this.name, this.phone, this.anntherPhoneNumber, 0,
88 | this.sex, this.tag, this.tagType)
89 | .subscribe(res => {
90 | // 保存成功返沪上一页,否则弹出提示框
91 | if (res.message) {
92 | this.toastTip(res.message);
93 | } else {
94 | this.appService.searchAddress = '';
95 | this.appService.notify.emit('refresh');
96 | if (this.fromWhere === 'searchAddress') {
97 | this.router.navigate(['/confirmOrder', 'chooseAddress']);
98 | } else {
99 | this.router.navigate(['/address']);
100 | }
101 | }
102 | });
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rules": {
4 | "align": {
5 | "options": [
6 | "statements"
7 | ]
8 | },
9 | "array-type": false,
10 | "arrow-return-shorthand": true,
11 | "curly": true,
12 | "deprecation": {
13 | "severity": "warning"
14 | },
15 | "component-class-suffix": [true, "Page", "Component"],
16 | "contextual-lifecycle": true,
17 | "directive-class-suffix": true,
18 | "directive-selector": [
19 | true,
20 | "attribute",
21 | "app",
22 | "camelCase"
23 | ],
24 | "component-selector": [
25 | true,
26 | "element",
27 | "kebab-case"
28 | ],
29 | "eofline": true,
30 | "import-blacklist": [
31 | true,
32 | "rxjs/Rx"
33 | ],
34 | "import-spacing": true,
35 | "indent": {
36 | "options": [
37 | "spaces"
38 | ]
39 | },
40 | "max-classes-per-file": false,
41 | "max-line-length": [
42 | true,
43 | 140
44 | ],
45 | "member-ordering": [
46 | true,
47 | {
48 | "order": [
49 | "static-field",
50 | "instance-field",
51 | "static-method",
52 | "instance-method"
53 | ]
54 | }
55 | ],
56 | "no-console": [
57 | true,
58 | "debug",
59 | "info",
60 | "time",
61 | "timeEnd",
62 | "trace"
63 | ],
64 | "no-empty": false,
65 | "no-inferrable-types": false,
66 | "no-non-null-assertion": true,
67 | "no-redundant-jsdoc": true,
68 | "no-switch-case-fall-through": true,
69 | "no-var-requires": false,
70 | "object-literal-key-quotes": [
71 | true,
72 | "as-needed"
73 | ],
74 | "quotemark": [
75 | true,
76 | "single"
77 | ],
78 | "semicolon": {
79 | "options": [
80 | "always"
81 | ]
82 | },
83 | "space-before-function-paren": {
84 | "options": {
85 | "anonymous": "never",
86 | "asyncArrow": "always",
87 | "constructor": "never",
88 | "method": "never",
89 | "named": "never"
90 | }
91 | },
92 | "typedef-whitespace": {
93 | "options": [
94 | {
95 | "call-signature": "nospace",
96 | "index-signature": "nospace",
97 | "parameter": "nospace",
98 | "property-declaration": "nospace",
99 | "variable-declaration": "nospace"
100 | },
101 | {
102 | "call-signature": "onespace",
103 | "index-signature": "onespace",
104 | "parameter": "onespace",
105 | "property-declaration": "onespace",
106 | "variable-declaration": "onespace"
107 | }
108 | ]
109 | },
110 | "variable-name": {
111 | "options": [
112 | "ban-keywords",
113 | "check-format",
114 | "allow-pascal-case",
115 | "allow-snake-case"
116 | ]
117 | },
118 | "whitespace": {
119 | "options": [
120 | "check-branch",
121 | "check-decl",
122 | "check-operator",
123 | "check-separator",
124 | "check-type",
125 | "check-typecast"
126 | ]
127 | },
128 | "no-conflicting-lifecycle": true,
129 | "no-host-metadata-property": true,
130 | "no-input-rename": true,
131 | "no-inputs-metadata-property": true,
132 | "no-output-native": true,
133 | "no-output-on-prefix": true,
134 | "no-output-rename": true,
135 | "no-outputs-metadata-property": true,
136 | "template-banana-in-box": true,
137 | "template-no-negated-async": true,
138 | "use-lifecycle-interface": true,
139 | "use-pipe-transform-interface": true,
140 | "object-literal-sort-keys": false
141 | },
142 | "rulesDirectory": [
143 | "codelyzer"
144 | ]
145 | }
--------------------------------------------------------------------------------
/src/app/msite/msite.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { AppService, DataService } from '../service';
4 |
5 |
6 | @Component({
7 | selector: 'page-msite',
8 | templateUrl: 'msite.page.html',
9 | styleUrls: ['msite.page.scss']
10 | })
11 | export class MsitePage implements OnInit {
12 | geohash: string;
13 | addressTitle: string;
14 | foodTypes: any[];
15 | slideActive: boolean;
16 | imgBaseUrl = 'https://fuss10.elemecdn.com';
17 | params: any;
18 | foodParams: any;
19 | hasGetData: boolean;
20 |
21 | shopList: any[];
22 | latitude: string;
23 | longitude: string;
24 | offset: number;
25 | restaurantCategoryId: string;
26 | touchend: boolean;
27 | showLoading: boolean;
28 | preventRepeatReuqest: boolean = false; // 到达底部加载数据,防止重复加载
29 |
30 | constructor(
31 | public route: ActivatedRoute,
32 | public router: Router,
33 | public appService: AppService,
34 | public dataService: DataService) {
35 | this.geohash = this.route.snapshot.queryParamMap.get('geohash');
36 | this.offset = 0;
37 | this.shopList = [];
38 | this.touchend = false;
39 | this.showLoading = true;
40 |
41 | }
42 |
43 | ngOnInit() {
44 | if (this.geohash) {
45 | this.latitude = this.geohash.split(',')[0];
46 | this.longitude = this.geohash.split(',')[1];
47 | this.params = { geohash: this.geohash };
48 | this.getPoisGeohash();
49 | this.getMsiteFoodTypes();
50 | this.getShopList();
51 | } else {
52 | this.dataService.getGuessCity().subscribe(res => {
53 | this.latitude = res.latitude;
54 | this.longitude = res.longitude;
55 | this.geohash = res.latitude + ',' + res.longitude;
56 | this.params = { geohash: this.geohash };
57 | this.getPoisGeohash();
58 | this.getMsiteFoodTypes();
59 | this.getShopList();
60 | });
61 | }
62 | }
63 |
64 | getCategoryId(url) {
65 | const urlData = decodeURIComponent(url.split('=')[1].replace('&target_name', ''));
66 | if (/restaurant_category_id/gi.test(urlData)) {
67 | return JSON.parse(urlData).restaurant_category_id.id;
68 | } else {
69 | return '';
70 | }
71 | }
72 |
73 | getPoisGeohash() {
74 | this.dataService.getPoisGeohash(this.geohash).subscribe(res => {
75 | this.addressTitle = res.name;
76 | this.hasGetData = true;
77 | });
78 | }
79 |
80 | getMsiteFoodTypes() {
81 | this.dataService.getMsiteFoodTypes(this.geohash).subscribe(res => {
82 | const resArr = [...res];
83 | this.foodTypes = this.spliceArray(resArr, 8);
84 | });
85 | }
86 | getShopList() {
87 | this.dataService.getShopList(this.latitude, this.longitude, this.offset, this.restaurantCategoryId).subscribe(res => {
88 | if (res.length < 20) {
89 | this.touchend = true;
90 | }
91 | this.shopList = [...this.shopList, ...res];
92 | this.showLoading = false;
93 | this.preventRepeatReuqest = false;
94 | });
95 | }
96 | spliceArray(array: any[], spliceLength: number) {
97 | const length: number = array.length;
98 | const foodArr: any[] = [];
99 | for (let i = 0, j = 0; i < length; i += spliceLength, j++) {
100 | foodArr[j] = array.splice(0, spliceLength);
101 | }
102 | return foodArr;
103 | }
104 |
105 | toSearch() {
106 | this.router.navigateByUrl('/tabs/search?geohash=' + this.geohash);
107 | }
108 |
109 | loaderMore(event: any) {
110 | if (this.touchend) {
111 | event.target.disabled = true;
112 | return;
113 | }
114 | if (this.preventRepeatReuqest) {
115 | return;
116 | }
117 | this.offset += 20;
118 | this.showLoading = true;
119 | this.preventRepeatReuqest = true;
120 | this.getShopList();
121 | event.target.complete();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.scss:
--------------------------------------------------------------------------------
1 | @import "../../style/mixin.scss";
2 | @import "../../style/common.scss";
3 | .profile-number{
4 | display:flex;
5 | align-items: center;
6 | background:$blue;
7 | padding: .8rem 1rem;
8 | .privateImage{
9 | display:inline-block;
10 | @include wh(4.1rem,4.1rem);
11 | border-radius:50%;
12 | vertical-align:middle;
13 | .privateImage-svg{
14 | background:$fc;
15 | border-radius:50%;
16 | @include wh(4.1rem,4.1rem);
17 | }
18 | }
19 | .user-info{
20 | margin-left:.8rem;
21 | -webkit-box-flex: 1;
22 | -ms-flex-positive: 1;
23 | flex-grow: 1;
24 | p{
25 | font-weight:700;
26 | @include sc(1rem,$fc);
27 | .user-icon{
28 | @include wh(0.83rem,1.25rem);
29 | display:inline-block;
30 | vertical-align:middle;
31 | line-height:1.25rem;
32 | .icon-mobile{
33 | @include wh(100%,100%);
34 | }
35 | }
36 | .icon-mobile-number{
37 | display:inline-block;
38 | @include sc(.9rem,$fc);
39 | margin-left: .5rem;
40 | vertical-align: middle;
41 | }
42 | }
43 |
44 | }
45 | }
46 | .info-data{
47 | width:100%;
48 | background:$fc;
49 | box-sizing: border-box;
50 | ul{
51 | .info-data-link{
52 | float:left;
53 | width:33.33%;
54 | border-right:1px solid #f1f1f1;
55 | span{
56 | display:block;
57 | width:100%;
58 | text-align:center;
59 | }
60 | .info-data-top{
61 | @include sc(.92rem,#333);
62 | padding: 1.5rem 0 .75rem;
63 | b{
64 | display:inline-block;
65 | @include sc(2rem,#f90);
66 | font-weight:700;
67 | line-height:1.67rem;
68 | font-family: Helvetica Neue,Tahoma;
69 | }
70 | }
71 | .info-data-bottom{
72 | @include sc(.95rem,#666);
73 | font-weight:400;
74 | padding-bottom:.453333rem;
75 |
76 | }
77 | }
78 | .info-data-link:nth-of-type(2){
79 | .info-data-top{
80 | b{
81 | color:#ff5f3e;
82 | }
83 | }
84 |
85 | }
86 | .info-data-link:nth-of-type(3){
87 | border:0;
88 | .info-data-top{
89 | b{
90 | color:#6ac20b;
91 | }
92 | }
93 | }
94 | }
95 | }
96 | .profile-1reTe{
97 | margin-top:.67rem;
98 | background:$fc;
99 | .myorder{
100 | padding-left:1rem;
101 | display:flex;
102 | align-items: center;
103 | aside{
104 | @include wh(1.16rem,1.16rem);
105 | margin-right:1.5rem;
106 | display:flex;
107 | align-items: center;
108 | svg{
109 | @include wh(100%,100%);
110 | }
111 | }
112 | .myorder-div{
113 | width:100%;
114 | border-bottom:1px solid #f1f1f1;
115 | padding: .8rem .5rem .8rem 0;
116 | @include sc(1.16rem,#333);
117 | display:flex;
118 | justify-content:space-between;
119 | span{
120 | display:block;
121 | }
122 | .myorder-divsvg{
123 | @include wh(.78rem,.78rem);
124 | svg{
125 | @include wh(100%,100%);
126 | }
127 | }
128 | }
129 | }
130 | .myorder:nth-of-type(3) .myorder-div{
131 | border:0;
132 | }
133 | }
134 | .profile-exit {
135 | line-height: 3rem;
136 | text-align: center;
137 | background-color: #fff;
138 | margin-top: 1.5rem;
139 | font-size: 1rem;
140 | .btn-exit {
141 | color: #ff5f3e;
142 | }
143 | }
--------------------------------------------------------------------------------