dreamnight 5 лет назад
Сommit
d1a64ac3bb
79 измененных файлов с 21865 добавлено и 0 удалено
  1. 4 0
      .eslintignore
  2. 33 0
      .eslintrc.js
  3. 25 0
      .gitignore
  4. 22 0
      README.md
  5. 63 0
      babel.config.js
  6. 17768 0
      package-lock.json
  7. 104 0
      package.json
  8. 22 0
      postcss.config.js
  9. 28 0
      public/index.html
  10. 35 0
      src/App.vue
  11. 33 0
      src/api/activityApi.js
  12. 41 0
      src/api/app.js
  13. 62 0
      src/api/request.js
  14. 34 0
      src/api/userApi.js
  15. 119 0
      src/components/activityCard.vue
  16. 66 0
      src/components/activityFlow.vue
  17. 55 0
      src/components/defContent.vue
  18. 34 0
      src/components/fixedBottom.vue
  19. 39 0
      src/components/imgText.vue
  20. 8 0
      src/components/networkError.vue
  21. 140 0
      src/components/orderCard.vue
  22. 17 0
      src/components/uploadImg.vue
  23. 34 0
      src/main.js
  24. 87 0
      src/manifest.json
  25. 151 0
      src/pages.json
  26. 223 0
      src/pages/classification.vue
  27. 356 0
      src/pages/index.vue
  28. 137 0
      src/pages/my.vue
  29. 233 0
      src/pages/order.vue
  30. 519 0
      src/pagesSub/activity/activityDetail.vue
  31. 110 0
      src/pagesSub/activity/signUpOutcome.vue
  32. 42 0
      src/pagesSub/my/about.vue
  33. 69 0
      src/pagesSub/my/commonProblem.vue
  34. 86 0
      src/pagesSub/my/userDetail.vue
  35. 68 0
      src/pagesSub/order/rule.vue
  36. 274 0
      src/pagesSub/order/submitOrder.vue
  37. 128 0
      src/pagesSub/order/submitOutcome.vue
  38. 58 0
      src/pagesSub/other/login.vue
  39. 123 0
      src/pagesSub/other/noviceStrategy.vue
  40. 19 0
      src/pagesSub/other/webView.vue
  41. BIN
      src/static/common/bg_sy.png
  42. BIN
      src/static/common/def_location.png
  43. BIN
      src/static/common/def_network_err.png
  44. BIN
      src/static/common/def_order.png
  45. BIN
      src/static/common/icon_bq_ybm.png
  46. BIN
      src/static/common/icon_bq_yqg.png
  47. BIN
      src/static/common/icon_lc_fgx.png
  48. BIN
      src/static/common/icon_numbei_1.png
  49. BIN
      src/static/common/icon_numbei_2.png
  50. BIN
      src/static/common/icon_numbei_3.png
  51. BIN
      src/static/common/icon_numbei_4.png
  52. BIN
      src/static/icon/aboutour.png
  53. BIN
      src/static/icon/avatar.png
  54. BIN
      src/static/icon/icon_bt.png
  55. BIN
      src/static/icon/icon_dingwei.png
  56. BIN
      src/static/icon/icon_dp.png
  57. BIN
      src/static/icon/icon_pp_elm.png
  58. BIN
      src/static/icon/icon_pp_lxsj.png
  59. BIN
      src/static/icon/icon_pp_mt.png
  60. BIN
      src/static/icon/icon_pz_close.png
  61. BIN
      src/static/icon/icon_success.png
  62. BIN
      src/static/icon/icon_zujian_sctp.png
  63. BIN
      src/static/icon/jiantou.png
  64. BIN
      src/static/icon/order.png
  65. BIN
      src/static/icon/problem.png
  66. BIN
      src/static/tabber/icon_db_dingdan.png
  67. BIN
      src/static/tabber/icon_db_dingdan2.png
  68. BIN
      src/static/tabber/icon_db_fenl.png
  69. BIN
      src/static/tabber/icon_db_fenl2.png
  70. BIN
      src/static/tabber/icon_db_home.png
  71. BIN
      src/static/tabber/icon_db_home2.png
  72. BIN
      src/static/tabber/icon_db_my.png
  73. BIN
      src/static/tabber/icon_db_my2.png
  74. 140 0
      src/store/index.js
  75. 5 0
      src/store/storageKeys.js
  76. 141 0
      src/uni.scss
  77. 1 0
      src/utils/dayjs.min.js
  78. 38 0
      src/utils/dealImgUrl.js
  79. 71 0
      src/utils/uploadImg.js

+ 4 - 0
.eslintignore

@@ -0,0 +1,4 @@
+/dist/
+/src/components/vender
+/src/common/vender
+*.json

+ 33 - 0
.eslintrc.js

@@ -0,0 +1,33 @@
+// https://eslint.org/docs/user-guide/configuring
+
+module.exports = {
+  root: true,
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  env: {
+    browser: true
+  },
+  extends: [
+    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
+    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
+    'plugin:vue/essential',
+    // https://github.com/standard/standard/blob/master/docs/RULES-en.md
+    'standard'
+  ],
+  // required to lint *.vue files
+  plugins: [
+    'vue'
+  ],
+  // add your custom rules here
+  rules: {
+    // allow async-await
+    'generator-star-spacing': 'off',
+    // allow debugger during development
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
+    'no-tabs': 'off',
+    indent: ['warn', 2],
+    'no-async-promise-executor': 'off',
+    'no-undef': 'off'
+  }
+}

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+.DS_Store
+node_modules/
+unpackage/
+dist/
+
+loginTipsDialog.vue
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.project
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw*

+ 22 - 0
README.md

@@ -0,0 +1,22 @@
+# overlord-meal-applets
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
+
+### UI框架 - uView 多平台快速开发的UI框架
+See [uView](https://uviewui.com/components/topTips.html)

+ 63 - 0
babel.config.js

@@ -0,0 +1,63 @@
+const plugins = []
+
+if (process.env.UNI_OPT_TREESHAKINGNG) {
+  plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'))
+}
+
+if (
+  (
+    process.env.UNI_PLATFORM === 'app-plus' &&
+    process.env.UNI_USING_V8
+  ) ||
+  (
+    process.env.UNI_PLATFORM === 'h5' &&
+    process.env.UNI_H5_BROWSER === 'builtin'
+  )
+) {
+  const path = require('path')
+
+  const isWin = /^win/.test(process.platform)
+
+  const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
+
+  const input = normalizePath(process.env.UNI_INPUT_DIR)
+  try {
+    plugins.push([
+      require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
+      {
+        file (file) {
+          file = normalizePath(file)
+          if (file.indexOf(input) === 0) {
+            return path.relative(input, file)
+          }
+          return false
+        }
+      }
+    ])
+  } catch (e) {}
+}
+
+process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']
+process.UNI_LIBRARIES.forEach(libraryName => {
+  plugins.push([
+    'import',
+    {
+      'libraryName': libraryName,
+      'customName': (name) => {
+        return `${libraryName}/lib/${name}/${name}`
+      }
+    }
+  ])
+})
+module.exports = {
+  presets: [
+    [
+      '@vue/app',
+      {
+        modules: 'commonjs',
+        useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry'
+      }
+    ]
+  ],
+  plugins
+}

Разница между файлами не показана из-за своего большого размера
+ 17768 - 0
package-lock.json


+ 104 - 0
package.json

@@ -0,0 +1,104 @@
+{
+  "name": "overlord-meal-applets",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "npm run dev:h5",
+    "build": "npm run build:h5",
+    "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
+    "build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
+    "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
+    "build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
+    "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
+    "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
+    "build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
+    "build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
+    "build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
+    "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
+    "build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
+    "build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
+    "build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
+    "build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
+    "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
+    "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
+    "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
+    "dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
+    "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
+    "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
+    "dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
+    "dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
+    "dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
+    "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
+    "dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
+    "dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
+    "dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
+    "dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
+    "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
+    "serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
+    "test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
+    "test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
+    "test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
+    "test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
+    "test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@dcloudio/uni-app-plus": "^2.0.0-29820201110001",
+    "@dcloudio/uni-h5": "^2.0.0-29820201110001",
+    "@dcloudio/uni-helper-json": "*",
+    "@dcloudio/uni-mp-360": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-alipay": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-baidu": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-qq": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-toutiao": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-vue": "^2.0.0-29820201110001",
+    "@dcloudio/uni-mp-weixin": "^2.0.0-29820201110001",
+    "@dcloudio/uni-quickapp-native": "^2.0.0-29820201110001",
+    "@dcloudio/uni-quickapp-webview": "^2.0.0-29820201110001",
+    "@dcloudio/uni-stat": "^2.0.0-29820201110001",
+    "@vue/shared": "^3.0.0",
+    "core-js": "^3.6.5",
+    "flyio": "^0.6.2",
+    "regenerator-runtime": "^0.12.1",
+    "uview-ui": "^1.8.2",
+    "vue": "^2.6.11",
+    "vuex": "^3.2.0"
+  },
+  "devDependencies": {
+    "@dcloudio/types": "*",
+    "@dcloudio/uni-automator": "^2.0.0-29820201110001",
+    "@dcloudio/uni-cli-shared": "^2.0.0-29820201110001",
+    "@dcloudio/uni-migration": "^2.0.0-29820201110001",
+    "@dcloudio/uni-template-compiler": "^2.0.0-29820201110001",
+    "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-29820201110001",
+    "@dcloudio/vue-cli-plugin-uni": "^2.0.0-29820201110001",
+    "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-29820201110001",
+    "@dcloudio/webpack-uni-mp-loader": "^2.0.0-29820201110001",
+    "@dcloudio/webpack-uni-pages-loader": "^2.0.0-29820201110001",
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "babel-eslint": "^10.1.0",
+    "babel-plugin-import": "^1.11.0",
+    "cross-env": "^7.0.2",
+    "eslint-config-standard": "^16.0.2",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-vue": "^7.0.0-beta.4",
+    "jest": "^25.4.0",
+    "mini-types": "*",
+    "miniprogram-api-typings": "*",
+    "node-sass": "^5.0.0",
+    "postcss-comment": "^2.0.0",
+    "sass-loader": "^10.1.0",
+    "standard": "^16.0.3",
+    "vue-template-compiler": "^2.6.11"
+  },
+  "browserslist": [
+    "Android >= 4",
+    "ios >= 8"
+  ],
+  "uni-app": {
+    "scripts": {}
+  }
+}

+ 22 - 0
postcss.config.js

@@ -0,0 +1,22 @@
+const path = require('path')
+module.exports = {
+  parser: require('postcss-comment'),
+  plugins: [
+    require('postcss-import')({
+      resolve (id, basedir, importOptions) {
+        if (id.startsWith('~@/')) {
+          return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3))
+        } else if (id.startsWith('@/')) {
+          return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2))
+        } else if (id.startsWith('/') && !id.startsWith('//')) {
+          return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1))
+        }
+        return id
+      }
+    }),
+    require('autoprefixer')({
+      remove: process.env.UNI_PLATFORM !== 'h5'
+    }),
+    require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
+  ]
+}

+ 28 - 0
public/index.html

@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <title>
+            <%= htmlWebpackPlugin.options.title %>
+        </title>
+        <script>
+            document.addEventListener('DOMContentLoaded', function() {
+                document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
+            })
+            var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
+            document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+        </script>
+        <link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
+    </head>
+
+    <body>
+        <noscript>
+            <strong>Please enable JavaScript to continue.</strong>
+        </noscript>
+        <div id="app"></div>
+        <!-- built files will be auto injected -->
+    </body>
+
+</html>

+ 35 - 0
src/App.vue

@@ -0,0 +1,35 @@
+<script>
+import { getSystemConfig } from '@/api/app'
+export default {
+  onLaunch: function () {
+    console.log('App Launch')
+    this.getConfig()
+  },
+  onShow: function () {
+    console.log('App Show')
+  },
+  onHide: function () {
+    console.log('App Hide')
+  },
+  methods: {
+    async getConfig () {
+      const { code, data } = await getSystemConfig()
+      if (code === 200) {
+        this.$store.state.ossImgResize = data.oss_img_resize
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+  /*每个页面公共css */
+  @import "uview-ui/index.scss";
+  page {
+    min-height: 100vh;
+    font-size: 24px;
+    font-family: PingFangSC-Regular, PingFang SC;
+    color: $u-main-color;
+    background-color: $bg-color;
+  }
+</style>

+ 33 - 0
src/api/activityApi.js

@@ -0,0 +1,33 @@
+import ajax from './request'
+
+// 获取banner列表
+export const getActivityBannerList = (data) => {
+  return ajax.get({
+    url: 'mobile/activity/bannerList',
+    data
+  })
+}
+
+// 获取活动分类
+export const getActivityCategoryList = (data) => {
+  return ajax.get({
+    url: 'mobile/activity/categoryList',
+    data
+  })
+}
+
+// 获取活动列表
+export const getActivityList = (data) => {
+  return ajax.get({
+    url: 'mobile/activity/getList',
+    data
+  })
+}
+
+// 获取活动详情
+export const getActivityDetail = (data) => {
+  return ajax.get({
+    url: 'mobile/activity/detail',
+    data
+  })
+}

+ 41 - 0
src/api/app.js

@@ -0,0 +1,41 @@
+import ajax from './request'
+
+// 微信code换取openid
+export const bindWxCode = (data) => {
+  return ajax.post({
+    url: 'mobile/user/bindWxCode',
+    data
+  })
+}
+
+// 微信登录
+export const wxLogin = (data) => {
+  return ajax.post({
+    url: 'mobile/user/wxLogin',
+    data
+  })
+}
+
+// 获取阿里云oss配置
+export const getCdnToken = (data) => {
+  return ajax.get({
+    url: 'mobile/index/cdn/token',
+    data
+  })
+}
+
+// 获取常见问题
+export const getQaList = (data) => {
+  return ajax.get({
+    url: 'mobile/index/qaList',
+    data
+  })
+}
+
+// 获取常见问题
+export const getSystemConfig = (data) => {
+  return ajax.get({
+    url: 'mobile/index/systemConfig',
+    data
+  })
+}

+ 62 - 0
src/api/request.js

@@ -0,0 +1,62 @@
+/**
+ * 通用uni-app网络请求
+ * 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
+ */
+import { USER_TOKEN } from '../store/storageKeys'
+
+export default {
+  config: {
+    baseUrl: process.env.NODE_ENV === 'development' ? 'https://cmsapi2.angrypizza.cn/rrr/' : '',
+    data: '',
+    header: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    method: 'GET',
+    timeout: 60000,
+    dataType: 'json',
+    responseType: '',
+    success: () => {},
+    fail: () => {},
+    complete: () => {}
+  },
+  request (options = {}) {
+    options = Object.assign({}, this.config, options)
+
+    options.url = options.baseUrl + options.url
+
+    if (uni.getStorageSync(USER_TOKEN)) {
+      options.header.token = uni.getStorageSync(USER_TOKEN)
+    }
+
+    return new Promise((resolve) => {
+      options.complete = ({ statusCode, data }) => {
+        if (statusCode !== 200) {
+          uni.showToast({
+            title: '系统异常',
+            icon: 'none'
+          })
+          return
+        }
+        data.code = data.code * 1
+        if (data.code === 200) {
+          resolve(data)
+        } else if (data.code === 1000) {
+          uni.navigateTo({
+            url: '/pagesSub/login/login'
+          })
+        } else {
+          resolve(data)
+        }
+      }
+      uni.request(options)
+    })
+  },
+  get (options) {
+    options.method = 'GET'
+    return this.request(options)
+  },
+  post (options) {
+    options.method = 'POST'
+    return this.request(options)
+  }
+}

+ 34 - 0
src/api/userApi.js

@@ -0,0 +1,34 @@
+import ajax from './request'
+
+// 编辑用户信息
+export const editUserInfo = (data) => {
+  return ajax.post({
+    url: 'mobile/user/editUserInfo',
+    data
+  })
+}
+
+// 参与活动
+export const editJoinActivity = (data) => {
+  return ajax.post({
+    url: 'mobile/user/joinActivity',
+    data
+  })
+}
+
+// 提交订单信息
+export const submitOrderInfo = (data) => {
+  return ajax.post({
+    header: { 'Content-Type': 'application/json' },
+    url: 'mobile/user/submitOrderInfo',
+    data
+  })
+}
+
+//  获取订单列表
+export const getOrderList = (data) => {
+  return ajax.get({
+    url: 'mobile/user/getOrderList',
+    data
+  })
+}

+ 119 - 0
src/components/activityCard.vue

@@ -0,0 +1,119 @@
+<template>
+  <view class="activity-card-main u-flex u-col-bottom" @click.stop="clickCard">
+    <image class="card-image" lazy-load :src="value.imgs | imgFilter(2)" mode="aspectFill"></image>
+    <view class="u-flex-1 u-m-l-16">
+      <view class="card-title u-font-28 bold u-line-1">{{value.title}}</view>
+      <view class="card-desc u-flex u-content-color u-m-t-4 u-m-b-12">
+        <view>平台:{{value.plat_type | platFilter}}</view>
+        <view class="u-font-22 line-32 u-flex-1">({{value.start_time | timeFilter(this)}}---{{value.end_time | timeFilter(this)}})</view>
+        <view v-if="value.distance">{{(value.distance / 1000).toFixed(1)}}km</view>
+        <view v-else>距离&gt;99km</view>
+      </view>
+      <view class="card-footer u-flex u-col-bottom">
+        <view class="u-flex u-flex-1 u-col-bottom">
+          <view class="u-content-color line-34">返利</view>
+          <block v-if="value.activity_type * 1 === 1">
+            <view class="u-m-l-8 u-primary-color u-font-32 line-44 bold">实付全返</view>
+          </block>
+          <block v-if="value.activity_type * 1 === 2">
+            <view class="u-m-l-8 u-flex u-col-bottom">
+              <text class="u-primary-color u-font-24 line-34 bold">¥</text>
+              <text class="u-primary-color u-font-36 line-44 bold">{{(value.rebate_amount / 100).toFixed(2)}}</text>
+            </view>
+          </block>
+        </view>
+        <view>
+          <block v-if="status * 1 === 1">
+            <view class="u-primary-color u-text-center u-font-20 line-28">剩余{{value.join_count - value.join_number}}</view>
+            <button class="join-btn u-m-t-2 u-font-22 line-32" @click.stop="signUp">参与报名</button>
+          </block>
+          <block v-if="status * 1 === 2">
+            <image class="already-img" src="../static/common/icon_bq_ybm.png" @click.stop="clickYBM"></image>
+          </block>
+          <block v-if="status * 1 === 3">
+            <image class="already-img" src="../static/common/icon_bq_yqg.png" @click.stop="clickYQG"></image>
+          </block>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  computed: {
+    status () {
+      if (this.value.join_status === 1) {
+        return 2
+      } else if (this.value.join_count === this.value.join_number) {
+        return 3
+      } else {
+        return 1
+      }
+    }
+  },
+  methods: {
+    clickCard () {
+      this.$emit('click-card', this.value)
+    },
+    signUp () {
+      this.$emit('sign-up', this.value)
+    },
+    clickYBM () {
+      this.$emit('click-ybm', this.value)
+    },
+    clickYQG () {
+      this.$emit('click-yqg', this.value)
+    }
+  },
+  filters: {
+    platFilter (e) {
+      const platText = {
+        8: '饿了么',
+        9: '美团'
+      }
+      return platText[e]
+    },
+    timeFilter (time, el) {
+      return el.$dayjs(`${el.$dayjs().format('YYYY-MM-DD')} ${time}`).format('HH:mm')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .activity-card-main {
+    .card-image {
+      width: 180px;
+      height: 180px;
+      border-radius: 12px;
+    }
+    .card-title {
+      max-width: 498px;
+      @include lineHeight(20px)
+    }
+    .card-desc {
+      @include lineHeight(17px)
+    }
+    .join-btn {
+      box-sizing: border-box;
+      padding: 10px 16px;
+      width: 120px;
+      height: 50px;
+      border-radius: 26px;
+      color: #fff;
+      background-color: $u-type-primary;
+    }
+    .already-img {
+      width: 76px;
+      height: 76px;
+      vertical-align: bottom;
+    }
+  }
+</style>

+ 66 - 0
src/components/activityFlow.vue

@@ -0,0 +1,66 @@
+<template>
+  <view class="activity-flow-main">
+    <view class="u-main-color bold u-font-34">活动流程</view>
+    <view class="flow-body u-flex u-m-t-18 u-m-l-14">
+      <view class="flow-item u-flex">
+        <image class="flow-image" src="../static/common/icon_numbei_1.png"/>
+        <view class="flow-text u-main-color">
+          <view class="u-m-b-4">免费</view>
+          <view>报名</view>
+        </view>
+      </view>
+      <view class="flow-line"></view>
+      <view class="flow-item u-flex">
+        <image class="flow-image" src="../static/common/icon_numbei_2.png"/>
+        <view class="flow-text u-main-color">
+          <view class="u-m-b-4">进入店铺</view>
+          <view>下单</view>
+        </view>
+      </view>
+      <view class="flow-line"></view>
+      <view class="flow-item u-flex">
+        <image class="flow-image" src="../static/common/icon_numbei_3.png"/>
+        <view class="flow-text u-main-color">
+          <view class="u-m-b-4">提交活动</view>
+          <view>资料确认</view>
+        </view>
+      </view>
+      <view class="flow-line"></view>
+      <view class="flow-item u-flex">
+        <image class="flow-image" src="../static/common/icon_numbei_4.png"/>
+        <view class="flow-text u-main-color">
+          <view class="u-m-b-4">获取</view>
+          <view>返利</view>
+        </view>
+      </view>
+    </view>
+    <view class="u-m-t-16 u-m-l-14 u-font-22">
+      <text class="u-content-color">提示:返利金额将在</text>
+      <text class="u-primary-color">提交活动资料后的1天内</text>
+      <text class="u-content-color">到账</text>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.activity-flow-main {
+  padding: 40px 40px 20px 28px;
+  background-color: #fff;
+  .flow-item {
+    .flow-image {
+      width: 36px;
+      height: 86px;
+    }
+    .flow-text {
+      @include lineHeight(13px)
+    }
+  }
+  .flow-line {
+    width: 30px;
+    margin: 0 20px;
+    height: 2px;
+    background: url('~@/static/common/icon_lc_fgx.png') no-repeat center center;
+    background-size: contain;
+  }
+}
+</style>

+ 55 - 0
src/components/defContent.vue

@@ -0,0 +1,55 @@
+<template>
+  <view class="def-content-main">
+    <block v-if="type * 1 === 1">
+      <image class="def-image" src="@/static/common/def_order.png"></image>
+      <view class="u-m-t-40 u-content-color line-34">暂无内容</view>
+    </block>
+    <block v-if="type * 1 === 2">
+      <image class="def-image" src="@/static/common/def_location.png"></image>
+      <view class="u-m-t-40 u-content-color line-34">定位失败,请先授权地理位置信息</view>
+    </block>
+  </view>
+</template>
+<script>
+
+export default {
+  props: {
+    type: {
+      type: Number,
+      default: 1
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.def-content-main {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .def-image {
+    width: 300px;
+    height: 288px;
+  }
+  .location-btn {
+    margin-top: 40px;
+    padding: 16px 40px;
+    width: 192px;
+    height: 72px;
+    border-radius: 36px;
+    color: $u-type-primary;
+    &::after {
+      content: "";
+      display: flex;
+      align-items: center;
+      width: 200%;
+      height: 200%;
+      border: 2px solid $u-type-primary;
+      border-radius: 72px;
+      box-sizing: border-box;
+      pointer-events: none;
+      transform-origin: 0 0;
+    }
+  }
+}
+</style>

+ 34 - 0
src/components/fixedBottom.vue

@@ -0,0 +1,34 @@
+<template>
+  <view :id="elId" class="fixed-btn-main">
+    <slot/>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      elId: this.$u.guid()
+    }
+  },
+  mounted () {
+    this.$nextTick(() => {
+      const node = uni.createSelectorQuery().in(this)
+      if (!node) { return }
+      node.select(`#${this.elId}`).boundingClientRect()
+      node.exec(res => {
+        if (res[0].height) this.$emit('get-height', res[0].height || 0)
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .fixed-btn-main {
+    position: fixed;
+    bottom: env(safe-area-inset-bottom);
+    width: 100%;
+    box-shadow: 0 0 8px 0 rgba($color: #000000, $alpha: 0.1);
+  }
+</style>

+ 39 - 0
src/components/imgText.vue

@@ -0,0 +1,39 @@
+<template>
+  <view>
+    <block v-if="type * 1 === 1">
+      <text class="u-m-b-16 u-font-24 u-content-color line-40">{{value}}</text>
+    </block>
+    <block v-if="type * 1 === 2">
+      <image class="u-m-b-16" :src="value | imgFilter" mode="aspectFit" @click="lookImg(value)"></image>
+    </block>
+  </view>
+</template>
+
+<script>
+import dealImgUrl from '@/utils/dealImgUrl'
+export default {
+  props: {
+    value: {
+      type: String,
+      default: ''
+    },
+    type: {
+      type: Number,
+      default: 1
+    }
+  },
+  methods: {
+    lookImg (e) {
+      const value = dealImgUrl(e)
+      uni.previewImage({
+        urls: [value],
+        current: 0
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 8 - 0
src/components/networkError.vue

@@ -0,0 +1,8 @@
+<template>
+  <view>
+    <u-no-network
+      tips="网络连接失败,请检查您的网络设置"
+      :image="'/static/common/def_network_err.png'"
+    ></u-no-network>
+  </view>
+</template>

+ 140 - 0
src/components/orderCard.vue

@@ -0,0 +1,140 @@
+<template>
+  <view class="order-card-main" @click.stop="clickCard">
+    <view class="u-flex">
+      <view class="icon-shop-wh icon-shop"></view>
+      <view class="shop-name u-m-l-8 u-line-1 line-34">{{value.shop_name}}</view>
+      <view class="u-flex-1 u-text-right u-primary-color line-34">{{value.join_status | statusFilter}}</view>
+    </view>
+    <view class="u-flex u-m-t-16 u-p-b-24">
+      <image class="order-img" :src="value.imgs | imgFilter(3)" lazy-load mode="aspectFill"></image>
+      <view class="u-flex-1 u-m-l-16">
+        <block v-if="value.activity_type * 1 === 1">
+          <view class="u-font-28 line-40 bold">返利:实付全返</view>
+        </block>
+        <block v-if="value.activity_type * 1 === 2">
+          <view class="u-font-28 line-40 bold">返利:¥{{(value.rebate_amount / 100).toFixed(2)}}</view>
+        </block>
+        <view class="u-font-22 u-m-t-8 line-32 u-content-color">平台:{{value.plat_type | platTypeFilter}}</view>
+        <block v-if="value.join_status * 1 === 4">
+          <view class="reson-text u-m-t-8 u-font-22 line-32 u-other-color u-line-1">驳回原因:{{value.reject_reason}}</view>
+        </block>
+      </view>
+    </view>
+    <view class="u-border-top u-p-t-16 u-p-b-16" v-if="value.join_status * 1 === 1 || value.join_status * 1 === 4">
+      <block v-if="value.join_status * 1 === 1">
+        <view class="u-flex u-row-right">
+          <button class="cancel-btn u-font-24 line-34" @click.stop="cancelSignUp">取消报名</button>
+          <button class="submit-btn u-font-24 line-34 u-m-l-24" @click.stop="submitResult">提交结果</button>
+        </view>
+      </block>
+      <block v-if="value.join_status * 1 === 4">
+        <view class="u-flex u-row-right">
+          <button class="cancel-btn u-font-24 line-34" open-type="contact" @click.stop>联系客服</button>
+        </view>
+      </block>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  methods: {
+    clickCard () {
+      this.$emit('click-card', this.value)
+    },
+    cancelSignUp () {
+      this.$emit('cancel-sign-up', this.value)
+    },
+    submitResult () {
+      this.$emit('submit-result', this.value)
+    }
+  },
+  filters: {
+    statusFilter (e) {
+      const statusText = {
+        1: '已报名',
+        2: '已提交',
+        3: '已结算',
+        4: '已驳回',
+        5: '已取消',
+        6: '已过期'
+      }
+      return statusText[e] || ''
+    },
+    platTypeFilter (e) {
+      const playType = {
+        8: '饿了么',
+        9: '美团'
+      }
+      return playType[e]
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.order-card-main {
+  padding: 24px 24px 0;
+  border-radius: 12px;
+  background-color: #fff;
+  .icon-shop-wh {
+    width: 30px;
+    height: 30px;
+  }
+  .shop-name {
+    max-width: 512px;
+  }
+  .order-img {
+    width: 108px;
+    height: 108px;
+    border-radius: 4px;
+  }
+  .reson-text {
+    max-width: 426px;
+  }
+  .cancel-btn, .submit-btn {
+    margin: 0;
+    padding: 6px 24px;
+    width: 144px;
+    height: 48px;
+    border-radius: 24px;
+    background-color: #fff;
+  }
+  .cancel-btn {
+    color: $u-main-color;
+    &::after {
+      content: "";
+      display: flex;
+      align-items: center;
+      width: 200%;
+      height: 200%;
+      border: 2px solid $u-light-color;
+      border-radius: 48px;
+      box-sizing: border-box;
+      pointer-events: none;
+      transform-origin: 0 0;
+    }
+  }
+  .submit-btn {
+    color: $u-type-primary;
+    &::after {
+      content: "";
+      display: flex;
+      align-items: center;
+      width: 200%;
+      height: 200%;
+      border: 2px solid $u-type-primary;
+      border-radius: 48px;
+      box-sizing: border-box;
+      pointer-events: none;
+      transform-origin: 0 0;
+    }
+  }
+}
+</style>

+ 17 - 0
src/components/uploadImg.vue

@@ -0,0 +1,17 @@
+<template>
+  <view>uploadImg</view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {}
+  },
+  mounted () {},
+  methods: {}
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 34 - 0
src/main.js

@@ -0,0 +1,34 @@
+import Vue from 'vue'
+import App from './App'
+import store from './store/index'
+import uView from 'uview-ui'
+import dayjs from './utils/dayjs.min.js'
+import dealImgUrl from '@/utils/dealImgUrl'
+import networkError from '@/components/networkError'
+
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+
+Vue.prototype.$store = store
+Vue.prototype.$dayjs = dayjs
+
+Vue.use(uView)
+
+Vue.filter('imgFilter', (fileItem, type) => {
+  return dealImgUrl(fileItem, type)
+})
+
+Vue.filter('imgListFilter', (fileList, type) => {
+  fileList.forEach(item => {
+    item.url = dealImgUrl(item, type)
+  })
+  return fileList
+})
+
+Vue.component('network-error', networkError)
+
+const app = new Vue({
+  ...App
+})
+app.$mount()

+ 87 - 0
src/manifest.json

@@ -0,0 +1,87 @@
+{
+	"name": "",
+	"appid": "",
+	"description": "",
+	"versionName": "1.0.0",
+	"versionCode": "100",
+	"transformPx": true,
+	"app-plus": { /* 5+App特有相关 */
+		"usingComponents": true,
+		"splashscreen": {
+			"alwaysShowBeforeRender": true,
+			"waiting": true,
+			"autoclose": true,
+			"delay": 0
+		},
+		"modules": { /* 模块配置 */
+
+		},
+		"distribute": { /* 应用发布信息 */
+			"android": { /* android打包配置 */
+				"permissions": ["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
+					"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+					"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+					"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+					"<uses-feature android:name=\"android.hardware.camera\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+				]
+			},
+			"ios": { /* ios打包配置 */
+
+			},
+			"sdkConfigs": { /* SDK配置 */
+
+			}
+		}
+	},
+	"quickapp": { /* 快应用特有相关 */
+
+	},
+	"mp-weixin": { /* 微信小程序特有相关 */
+		"appid": "wx268dbc0f5dd92c92",
+		"setting": {
+			"urlCheck": false
+		},
+    "permission": {
+      "scope.userLocation": {
+        "desc": "你的位置信息将用于获取附近活动"
+      }
+    },
+    "navigateToMiniProgramAppIdList": [
+      "wxece3a9a4c82f58c9",
+      "wx2c348cf579062e56"
+    ],
+		"optimization": {
+			"subPackages": true
+		},
+		"usingComponents": true
+	},
+	"mp-alipay" : {
+    "usingComponents" : true
+  },
+  "mp-baidu" : {
+    "usingComponents" : true
+  },
+  "mp-toutiao" : {
+    "usingComponents" : true
+  },
+  "mp-qq" : {
+    "usingComponents" : true
+	}
+}

+ 151 - 0
src/pages.json

@@ -0,0 +1,151 @@
+{
+	"easycom": {
+		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
+	},
+	"pages": [
+		{
+			"path": "pages/index",
+			"style": {
+				"navigationStyle": "custom",
+				"enablePullDownRefresh": true
+			}
+		},
+		{
+			"path": "pages/classification",
+			"style": {
+				"navigationBarTitleText": "分类",
+				"enablePullDownRefresh": true
+			}
+		},
+		{
+			"path": "pages/order",
+			"style": {
+				"navigationBarTitleText": "订单",
+				"enablePullDownRefresh": true
+			}
+		},
+		{
+			"path": "pages/my",
+			"style": {
+				"navigationBarTitleText": "个人中心"
+			}
+		}
+	],
+	"subPackages": [{
+		"root": "pagesSub/activity",
+		"pages": [{
+			"path": "activityDetail",
+			"style": {
+				"navigationBarTitleText": "免费吃活动详情",
+				"enablePullDownRefresh": true
+			}
+		}, {
+			"path": "signUpOutcome",
+			"style": {
+				"navigationBarTitleText": "报名结果"
+			}
+		}]
+	}, {
+		"root": "pagesSub/my",
+		"pages": [{
+			"path": "about",
+			"style": {
+				"navigationBarTitleText": "关于我们"
+			}
+		}, {
+			"path": "commonProblem",
+			"style": {
+				"navigationBarTitleText": "常见问题"
+			}
+		}, {
+			"path": "userDetail",
+			"style": {
+				"navigationBarTitleText": "个人信息"
+			}
+		}]
+	}, {
+		"root": "pagesSub/order",
+		"pages": [{
+			"path": "submitOrder",
+			"style": {
+				"navigationBarTitleText": "提交订单"
+			}
+		}, {
+			"path": "submitOutcome",
+			"style": {
+				"navigationBarTitleText": "提交结果"
+			}
+		}, {
+			"path": "rule",
+			"style": {
+				"navigationBarTitleText": "评价规则"
+			}
+		}]
+	}, {
+		"root": "pagesSub/other",
+		"pages": [{
+			"path": "login",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+		}, {
+			"path": "webView"
+		}, {
+			"path": "noviceStrategy",
+			"style": {
+				"navigationBarTitleText": "新手攻略"
+			}
+		}]
+	}],
+	"preloadRule": {
+		"pages/index": {
+			"network": "all",
+			"packages": ["pagesSub/activity"]
+		},
+		"pages/classification": {
+			"network": "all",
+			"packages": ["pagesSub/activity"]
+		},
+		"pages/order": {
+			"network": "all",
+			"packages": ["pagesSub/order"]
+		},
+		"pages/my": {
+			"network": "wifi",
+			"packages": ["pagesSub/my"]
+		}
+	},
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "趣吃",
+		"navigationBarBackgroundColor": "#FFFFFF",
+		"backgroundColor": "#F4F5F9"
+	},
+	"tabBar": {
+    "color": "#999999",
+    "selectedColor": "#FF6632",
+    "borderStyle": "black",
+    "backgroundColor": "#ffffff",
+    "list": [{
+			"pagePath": "pages/index",
+			"iconPath": "static/tabber/icon_db_home.png",
+			"selectedIconPath": "static/tabber/icon_db_home2.png",
+			"text": "首页"
+    }, {
+			"pagePath": "pages/classification",
+			"iconPath": "static/tabber/icon_db_fenl.png",
+			"selectedIconPath": "static/tabber/icon_db_fenl2.png",
+			"text": "分类"
+    }, {
+			"pagePath": "pages/order",
+			"iconPath": "static/tabber/icon_db_dingdan.png",
+			"selectedIconPath": "static/tabber/icon_db_dingdan2.png",
+			"text": "订单"
+		}, {
+			"pagePath": "pages/my",
+			"iconPath": "static/tabber/icon_db_my.png",
+			"selectedIconPath": "static/tabber/icon_db_my2.png",
+			"text": "我的"
+		}]
+	}
+}

+ 223 - 0
src/pages/classification.vue

@@ -0,0 +1,223 @@
+<template>
+  <view class="class-main">
+    <network-error />
+    <u-sticky
+      :enable="enable"
+      offset-top="0"
+      h5-nav-height="0"
+      @fixed="stickyFixed"
+      @unfixed="unStickyFixed"
+    >
+      <view class="class-tabs">
+        <u-tabs
+          is-scroll
+          :list="list"
+          name="category_name"
+          :current="currentTab"
+          height="72"
+          font-size="28"
+          active-color="#111111"
+          inactive-color="#111111"
+          :gutter="32"
+          :bar-style="{
+            bottom: '16rpx',
+            marginLeft: '-8rpx',
+            width: '56rpx',
+            height: '10rpx',
+            borderRadius: 0,
+            backgroundColor: '#FD5B36',
+            boxShadow: '0px 1px 1px 0px rgba(255, 102, 50, 0.3)'
+          }"
+          @change="changeTab"
+        >
+        </u-tabs>
+      </view>
+    </u-sticky>
+    <block v-if="isLocation">
+      <view class="activity-list" :style="{marginTop: `${activityListMT}rpx`}">
+        <block v-if="activityList.length !== 0">
+          <view class="activity-card u-border-bottom" v-for="(item, index) in activityList" :key="index">
+            <activity-card
+              :value="item"
+              @sign-up="toActivityDetail"
+              @click-ybm="toActivityDetail"
+              @click-yqg="toActivityDetail"
+            >
+            </activity-card>
+          </view>
+          <view class="touch-bottom u-font-22 line-32 u-text-center">{{isLoadMore ? '加载中...' : '到底了~'}}</view>
+        </block>
+        <block v-else>
+          <view class="no-location def-content">
+            <def-content type="1"></def-content>
+          </view>
+        </block>
+      </view>
+    </block>
+    <block v-else>
+      <view class="def-content">
+        <def-content type="2"></def-content>
+      </view>
+    </block>
+  </view>
+</template>
+
+<script>
+import defContent from '@/components/defContent'
+import activityCard from '@/components/activityCard'
+import { getActivityCategoryList, getActivityList } from '@/api/activityApi.js'
+export default {
+  components: { defContent, activityCard },
+  data () {
+    return {
+      isLocation: false,
+      enable: true,
+      currentTab: 0,
+      activityListMT: 16,
+      list: [],
+      isLoadMore: false,
+      searchForm: {
+        page_no: 1,
+        page_size: 10,
+        category_id: 0
+      },
+      activityList: [],
+      total: -1
+    }
+  },
+  computed: {
+    cateId () {
+      return this.$store.state.cateId
+    }
+  },
+  async onShow () {
+    await this.getCategoryData()
+    if (this.cateId) {
+      this.currentTab = this.list.findIndex(item => {
+        return item.id === this.cateId * 1
+      })
+    } else {
+      this.currentTab = 0
+    }
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.activityList = []
+    this.getActivityData()
+    this.enable = true
+    this.$store.commit('changeCateId', '')
+  },
+  onHide () {
+    this.enable = true
+  },
+  onPullDownRefresh () {
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.activityList = []
+    this.getActivityData()
+  },
+  onReachBottom () {
+    if (this.isLoadMore) {
+      this.searchForm.page_no += 1
+      this.getActivityData()
+    }
+  },
+  methods: {
+    // 获取用户经纬度
+    getLocation () {
+      return new Promise((resolve, reject) => {
+        uni.getLocation({
+          type: 'wgs84',
+          success: (res) => {
+            this.isLocation = true
+            resolve(res)
+          },
+          fail: () => {
+            this.isLocation = false
+            resolve(false)
+          }
+        })
+      })
+    },
+    // 获取分类标签
+    async getCategoryData () {
+      const { code, data } = await getActivityCategoryList()
+      if (code === 200) {
+        this.list = data
+      }
+    },
+    // 获取活动列表
+    async getActivityData () {
+      const location = await this.getLocation()
+      if (!location) { return }
+      const params = {
+        lng: location.longitude,
+        lat: location.latitude,
+        page_no: this.searchForm.page_no,
+        page_size: this.searchForm.page_size,
+        category_id: this.searchForm.category_id
+      }
+      const { code, data } = await getActivityList(params)
+      if (code === 200) {
+        this.total = data.total_count
+        this.activityList = this.activityList.concat(data.rows)
+        this.isLoadMore = this.total !== this.activityList.length
+      }
+    },
+    changeTab (index) {
+      this.currentTab = index
+      this.searchForm.category_id = this.list[index].id
+      this.searchForm.page_no = 1
+      this.total = -1
+      this.activityList = []
+      this.getActivityData()
+    },
+    toActivityDetail (e) {
+      uni.navigateTo({
+        url: `/pagesSub/activity/activityDetail?id=${e.id}`
+      })
+    },
+    stickyFixed () {
+      this.activityListMT = 64
+    },
+    unStickyFixed () {
+      this.activityListMT = 16
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.class-main {
+  .class-tabs {
+    width: 100%;
+    padding: 0;
+    background-color: #fff;
+  }
+  .no-location, .activity-list {
+    padding: 0 28px;
+    min-height: 100vh;
+    background-color: #fff;
+    .activity-card {
+      padding: 32px 0;
+    }
+    .touch-bottom {
+      padding: 30px 0;
+      color: #BABBBC;
+    }
+  }
+  .back-color {
+    height: 16px;
+    background-color: #fff;
+  }
+  .def-content {
+    padding-top: 252px;
+  }
+}
+
+</style>
+
+<style >
+  .class-tabs >>> .u-tab-item {
+    z-index: 10;
+  }
+</style>

+ 356 - 0
src/pages/index.vue

@@ -0,0 +1,356 @@
+<template>
+  <view class="index-main">
+    <network-error />
+    <view class="first" :style="{height: `${firstHeight}rpx`}">
+      <view class="index-header">
+        <view class="index-banner" v-if="bannerList.length" v-show="!isSticky">
+          <u-swiper
+            mode="dot"
+            img-mode="scaleToFill"
+            :list="bannerList | bannerListFilter | imgListFilter(1)"
+            name="url"
+            height="176"
+            border-radius="20"
+            @click="bannerClick"
+          >
+          </u-swiper>
+        </view>
+      </view>
+      <view class="activity-flow u-p-t-34" v-show="!isSticky">
+        <activity-flow></activity-flow>
+      </view>
+    </view>
+    <view class="index-body u-m-t-16">
+      <u-sticky
+        :enable="enable"
+        offset-top="0"
+        h5-nav-height="0"
+        @fixed="stickyFixed"
+        @unfixed="unStickyFixed"
+      >
+        <!-- 只能有一个根元素 -->
+        <view class="sticky">
+          <view
+            class="nav-title u-font-32 bold line-44 u-text-center"
+            :style="{
+              paddingTop: `${navTitleStyle.paddingTop}rpx`,
+              paddingBottom: `${navTitleStyle.paddingBottom}rpx`,
+              lineHeight: `${navTitleStyle.lineHeight}rpx`,
+              fontSize: `${navTitleStyle.fontSize}rpx`
+            }"
+          >
+            首页
+          </view>
+          <view class="index-tabs u-flex u-col-bottom u-row-between">
+            <u-tabs
+              :is-scroll="false"
+              :list="tabList"
+              :current="currentTab"
+              height="44"
+              font-size="34"
+              active-color="#111111"
+              inactive-color="#111111"
+              :gutter="0"
+              :bar-style="{
+                bottom: '-10rpx',
+                marginLeft: '-34rpx',
+                width: '104rpx',
+                height: '10rpx',
+                borderRadius: 0,
+                backgroundColor: '#FD6D4E',
+                boxShadow: '0px 1px 1px 0px rgba(255, 102, 50, 0.3)'
+              }"
+              @change="tabsChange"
+            >
+            </u-tabs>
+            <view class="u-font-22 u-content-color">单平台每天只能报名1次</view>
+          </view>
+        </view>
+      </u-sticky>
+      <block v-if="isLocation">
+        <view class="activity-list" :style="{paddingTop: `${activityListPT}rpx`}">
+          <block v-if="activityList.length !== 0">
+            <view class="activity-card u-border-bottom" v-for="(item, index) in activityList" :key="index">
+              <activity-card
+                :value="item"
+                @signUp="toActivityDetail"
+                @clickYBM="toActivityDetail"
+                @clickYQG="toActivityDetail"
+              >
+              </activity-card>
+            </view>
+            <view class="touch-bottom u-font-22 line-32 u-text-center">{{isLoadMore ? '加载中...' : '到底了~'}}</view>
+          </block>
+          <block v-else>
+            <view class="def-content">
+              <def-content type="1"></def-content>
+            </view>
+          </block>
+        </view>
+      </block>
+      <block v-else>
+        <view class="no-location def-content">
+          <def-content type="2"></def-content>
+        </view>
+      </block>
+    </view>
+  </view>
+</template>
+
+<script>
+import defContent from '@/components/defContent'
+import activityFlow from '@/components/activityFlow'
+import activityCard from '@/components/activityCard'
+import { getActivityBannerList, getActivityList } from '@/api/activityApi'
+
+export default {
+  components: { defContent, activityFlow, activityCard },
+  data () {
+    return {
+      isLocation: false,
+      enable: true,
+      isSticky: false,
+      firstHeight: 542,
+      navTitleStyle: {
+        paddingTop: 0,
+        paddingBottom: 0,
+        lineHeight: 0,
+        fontSize: 0
+      },
+      activityListPT: 0,
+      bannerList: [],
+      isLoadMore: false,
+      tabList: [{ name: '免费吃' }, { name: '返利餐' }],
+      searchForm: {
+        page_no: 1,
+        page_size: 10,
+        activity_type: 1
+      },
+      total: -1,
+      currentTab: 0,
+      activityList: []
+    }
+  },
+  computed: {
+    navHeight () {
+      return (uni.getSystemInfoSync().statusBarHeight * 2) + 16
+    }
+  },
+  onShow () {
+    this.getLocation()
+    this.getBannerData()
+    this.isLoadMore = false
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.activityList = []
+    this.getActivityData()
+    this.enable = true
+  },
+  onHide () {
+    this.enable = true
+  },
+  onPullDownRefresh () {
+    this.getBannerData()
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.activityList = []
+    this.getActivityData()
+  },
+  onReachBottom () {
+    if (this.isLoadMore) {
+      this.searchForm.page_no += 1
+      this.getActivityData()
+    }
+  },
+  methods: {
+    // 获取用户经纬度
+    getLocation () {
+      return new Promise((resolve, reject) => {
+        uni.getLocation({
+          type: 'wgs84',
+          success: (res) => {
+            this.isLocation = true
+            resolve(res)
+          },
+          fail: () => {
+            this.isLocation = false
+            resolve(false)
+          }
+        })
+      })
+    },
+    // 获取banner列表
+    async getBannerData () {
+      const { code, data } = await getActivityBannerList()
+      if (code === 200) {
+        this.bannerList = data
+      }
+    },
+    // 获取活动列表
+    async getActivityData () {
+      const location = await this.getLocation()
+      if (!location) { return }
+      const params = {
+        lng: location.longitude,
+        lat: location.latitude,
+        page_no: this.searchForm.page_no,
+        page_size: this.searchForm.page_size,
+        activity_type: this.searchForm.activity_type
+      }
+      const { code, data } = await getActivityList(params)
+      if (code === 200) {
+        this.total = data.total_count
+        this.activityList = this.activityList.concat(data.rows)
+        this.isLoadMore = this.total !== this.activityList.length
+      }
+    },
+    // 活动类型切换
+    tabsChange (index) {
+      this.currentTab = index
+      this.searchForm.activity_type = index + 1
+      this.searchForm.page_no = 1
+      this.total = -1
+      this.activityList = []
+      this.getActivityData()
+    },
+    stickyFixed () {
+      this.isSticky = true
+      this.firstHeight = 0
+      this.navTitleStyle = {
+        paddingTop: this.navHeight,
+        paddingBottom: 30,
+        lineHeight: 44,
+        fontSize: 32
+      }
+      this.activityListPT = this.navHeight + 82
+    },
+    unStickyFixed () {
+      this.isSticky = false
+      this.firstHeight = 542
+      this.navTitleStyle = {
+        paddingTop: 0,
+        paddingBottom: 0,
+        lineHeight: 0,
+        fontSize: 0
+      }
+      this.activityListPT = 0
+    },
+    toActivityDetail (e) {
+      uni.navigateTo({
+        url: `../pagesSub/activity/activityDetail?id=${e.id}`
+      })
+    },
+    // 点击banner事件
+    bannerClick (index) {
+      const banner = this.bannerList[index]
+      console.log(banner)
+      switch (banner.jump_type * 1) {
+      case 1:
+        uni.navigateTo({
+          url: `/pagesSub/other/webView?url=${banner.jump_content}`
+        })
+        break
+      case 2:
+        this.$store.dispatch('toOtherApplte', banner.jump_content)
+        break
+      case 3:
+        uni.navigateTo({
+          url: `/pagesSub/activity/activityDetail?id=${banner.jump_content}`
+        })
+        break
+      case 4:
+        console.log('jump_content', banner.jump_content)
+        this.$store.commit('changeCateId', banner.jump_content)
+        uni.switchTab({
+          url: '/pages/classification'
+        })
+        break
+      case 5:
+        this.$store.commit('changeCateId', banner.jump_content)
+        uni.navigateTo({
+          url: '/pagesSub/other/noviceStrategy'
+        })
+        break
+      default:
+      }
+    }
+  },
+  filters: {
+    bannerListFilter (e) {
+      return e.map(item => {
+        item.url = item.imgs
+        return item
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.index-main {
+  .first {
+    height: 540px;
+    opacity: 1;
+    transition: all 1s;
+  }
+  .hidden-first {
+    height: 0;
+    opacity: 0;
+  }
+  .index-header {
+    height: 254px;
+    background: url('~@/static/common/bg_sy.png') no-repeat center top;
+    background-size: contain;
+    transition: height 2s;
+    .index-banner {
+      position: relative;
+      top: 112px;
+      margin: 0 auto;
+      width: 694px;
+      transition: width 2s;
+    }
+  }
+  .activity-flow {
+    background-color: #fff;
+  }
+  .index-tabs {
+    padding: 24px 28px 16px;
+  }
+  .index-body {
+    background-color: #fff;
+    .sticky {
+      background-color: #fff;
+      .nav-title {
+        box-sizing: border-box;
+        padding-bottom: 30px;
+        transition: padding 1s;
+      }
+    }
+    .no-location, .activity-list {
+      padding: 0 28px;
+      min-height: 100vh;
+      background-color: #fff;
+      .activity-card {
+        padding: 32px 0;
+      }
+    }
+    .touch-bottom {
+      padding: 30px 0;
+      color: #BABBBC;
+    }
+  }
+  .def-content {
+    margin-top: 212px;
+  }
+}
+</style>
+
+<style >
+  .index-tabs >>> .u-tab-item {
+    z-index: 10;
+    font-weight: bold!important;
+  }
+  .index-tabs >>> .u-tab-item + .u-tab-item {
+    margin-left: 42px;
+  }
+</style>

+ 137 - 0
src/pages/my.vue

@@ -0,0 +1,137 @@
+<template>
+  <view class="pensonal">
+    <network-error />
+    <view class="login u-flex" @click="login">
+      <block v-if="!userInfo.nick_name">
+      <image class="avatar" src="~@/static/icon/avatar.png"></image>
+        <text class="name u-content-color line-50 ml-16 u-flex-1 bold">点击登录</text>
+      </block>
+      <block v-else>
+      <image class="avatar" :src="userInfo.head_url"></image>
+        <view class="name line-50 ml-16 u-flex-1 u-line-1 bold">{{userInfo.nick_name}}</view>
+      </block>
+      <block v-if="userInfo.id">
+        <view class="info u-font-22" @click.stop="toUserDetail">个人信息<u-icon name="arrow-right"></u-icon></view>
+      </block>
+    </view>
+    <view class="item-list">
+      <view class="item u-flex u-border-bottom" @click="toDetail(1)">
+        <view class="icon-wh icon-problem"></view>
+        <view class="u-font-28 ml-28 u-flex-1 title">常见问题</view>
+        <view class="jiantou-wh icon-jiantou "></view>
+      </view>
+      <view class="item u-flex u-border-bottom" @click="toDetail(2)">
+        <view class="icon-wh icon-aboutour"></view>
+        <view class="u-font-28 ml-28 u-flex-1 title">关于我们</view>
+        <view class="jiantou-wh icon-jiantou "></view>
+      </view>
+      <view class="item u-flex" @click="toDetail(3)">
+        <view class="icon-wh icon-order"></view>
+        <view class="u-font-28 ml-28 u-flex-1 title">订单</view>
+        <view class="jiantou-wh icon-jiantou"></view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {}
+  },
+  computed: {
+    userInfo () {
+      return this.$store.state.userInfo
+    }
+  },
+  methods: {
+    toDetail (type) {
+      let url
+      if (type === 1 || type === 2) {
+        url = type === 1 ? '/pagesSub/my/commonProblem' : '/pagesSub/my/about'
+        uni.navigateTo({
+          url: url
+        })
+      }
+      if (type === 3) {
+        uni.switchTab({
+          url: 'order'
+        })
+      }
+    },
+    // 登录
+    login () {
+      if (this.userInfo.id) { return }
+      uni.navigateTo({
+        url: '/pagesSub/other/login'
+      })
+    },
+    // 个人信息
+    toUserDetail () {
+      uni.navigateTo({
+        url: '/pagesSub/my/userDetail'
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .pensonal {
+    width: 750px;
+    background: #FFF;
+  }
+  .login {
+    width: 100%;
+    height: 156px;
+    align-items: center;
+    padding: 8px 0 40px 40px;
+  }
+  .info {
+    width: 124px;
+    height: 48px;
+    line-height: 48px;
+    background: $bg-personl-info-color;
+    color: #FFFFFF;
+    text-align: right;
+    border-radius: 100px 0px 0px 100px;
+  }
+  .avatar {
+    width: 108px;
+    height: 108px;
+    border-radius: 54px;
+  }
+  .name {
+    width: 414px;
+    height: 50px;
+    font-size: 36px;
+    margin-left: 16px;
+  }
+  .item-list {
+    width: 100%;
+    background: #FFF;
+    box-sizing: border-box;
+    padding: 0 32px 0 40px;
+    .item {
+      width: 100%;
+      height: 96px;
+      .title {
+        color: $u-main-color;
+      }
+    }
+  }
+  // .border-bottom {
+  //   border-bottom: 1px solid $u-border-color;
+  // }
+  .icon-wh {
+    width: 36px;
+    height: 36px;
+  }
+  .jiantou-wh {
+    width: 14px;
+    height: 24px;
+  }
+  .ml-28 {
+    margin-left: 28px;
+  }
+</style>

+ 233 - 0
src/pages/order.vue

@@ -0,0 +1,233 @@
+<template>
+  <view class="order-main">
+    <network-error />
+    <u-sticky
+      :enable="enable"
+      offset-top="0"
+      h5-nav-height="0"
+    >
+      <view class="order-tabs">
+        <u-tabs
+          :is-scroll="false"
+          :list="tabList"
+          :current="currentTab"
+          height="72"
+          font-size="28"
+          active-color="#111111"
+          inactive-color="#111111"
+          :gutter="32"
+          :bar-style="{
+            bottom: '8rpx',
+            marginLeft: '-8rpx',
+            width: '56rpx',
+            height: '10rpx',
+            borderRadius: 0,
+            backgroundColor: '#FD5B36',
+            boxShadow: '0px 1px 1px 0px rgba(255, 102, 50, 0.3)'
+          }"
+          @change="changeTab"
+        >
+        </u-tabs>
+      </view>
+    </u-sticky>
+    <view class="order-list">
+      <block v-if="orderList.length !== 0">
+        <view class="u-m-b-16" v-for="(item, index) in orderList" :key="index">
+          <order-card
+            :value="item"
+            @click-card="toActivityDetail"
+            @submit-result="toSubmitOrder"
+            @cancel-sign-up="cancelSignUp"
+          >
+          </order-card>
+        </view>
+        <view class="touch-bottom u-font-22 line-32 u-text-center">{{isLoadMore ? '加载中...' : '到底了~'}}</view>
+      </block>
+      <block v-else>
+        <view class="def-content">
+          <def-content type="1"></def-content>
+        </view>
+      </block>
+    </view>
+  </view>
+</template>
+
+<script>
+import defContent from '@/components/defContent'
+import orderCard from '@/components/orderCard'
+import { getOrderList, editJoinActivity } from '@/api/userApi'
+
+export default {
+  components: { defContent, orderCard },
+  data () {
+    return {
+      enable: true,
+      tabList: [
+        {
+          status: -1,
+          name: '全部'
+        }, {
+          status: 1,
+          name: '已报名'
+        }, {
+          status: 2,
+          name: '已提交'
+        }, {
+          status: 3,
+          name: '已完成'
+        }, {
+          status: 4,
+          name: '已取消'
+        }
+      ],
+      currentTab: 0,
+      isLoadMore: false,
+      searchForm: {
+        page_no: 1,
+        page_size: 10,
+        status: -1
+      },
+      orderList: [],
+      total: -1
+    }
+  },
+  computed: {
+    userId () {
+      return this.$store.state.userInfo.id
+    }
+  },
+  watch: {
+    userId (e) {
+      if (!e) {
+        uni.navigateTo({
+          url: '/pagesSub/other/login'
+        })
+      }
+    }
+  },
+  onShow () {
+    if (!this.userId) {
+      uni.navigateTo({
+        url: '/pagesSub/other/login'
+      })
+      return
+    }
+    this.enable = true
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.orderList = []
+    this.getOrderData()
+  },
+  onHide () {
+    this.enable = true
+  },
+  onPullDownRefresh () {
+    this.searchForm.page_no = 1
+    this.total = -1
+    this.activityList = []
+    this.getOrderData()
+  },
+  onReachBottom () {
+    if (this.isLoadMore) {
+      this.searchForm.page_no += 1
+      this.getOrderData()
+    }
+  },
+  methods: {
+    // 获取订单列表
+    async getOrderData () {
+      const params = {
+        page_no: this.searchForm.page_no,
+        page_size: this.searchForm.page_size,
+        status: this.searchForm.status
+      }
+      const { code, data } = await getOrderList(params)
+      if (code === 200) {
+        this.orderList = this.orderList.concat(data.rows)
+        this.total = data.total_count
+        this.isLoadMore = this.total !== this.orderList.length
+      }
+    },
+    // 取消报名
+    async joinActivity (id) {
+      const params = {
+        id: id,
+        type: 2
+      }
+      const { code, msg } = await editJoinActivity(params)
+      if (code === 200) {
+        this.searchForm.page_no = 1
+        this.total = -1
+        this.orderList = []
+        this.getOrderData()
+        uni.showToast({
+          title: '取消成功',
+          icon: 'none'
+        })
+      } else {
+        uni.showToast({
+          title: msg,
+          icon: 'none'
+        })
+      }
+    },
+    changeTab (index) {
+      this.currentTab = index
+      this.searchForm.status = this.tabList[index].status
+      this.searchForm.page_no = 1
+      this.total = -1
+      this.orderList = []
+      this.getOrderData()
+    },
+    cancelSignUp (e) {
+      uni.showModal({
+        title: '提示',
+        content: '确定取消报名',
+        confirmColor: '#1677FF',
+        cancelColor: '#1677FF',
+        success: (res) => {
+          if (res.confirm) {
+            this.joinActivity(e.id)
+          }
+        }
+      })
+    },
+    toActivityDetail (e) {
+      uni.navigateTo({
+        url: `/pagesSub/activity/activityDetail?id=${e.activity_id}`
+      })
+    },
+    toSubmitOrder (e) {
+      uni.navigateTo({
+        url: `/pagesSub/order/submitOrder?activityId=${e.activity_id}&userActivityId=${e.user_activity_id}`
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.order-main {
+  .order-tabs {
+    width: 100%;
+    padding: 0;
+    background-color: #fff;
+  }
+  .order-list {
+    padding: 24px 16px 0 16px;
+  }
+  .def-content {
+    padding-top: 252px;
+  }
+  .touch-bottom {
+    padding: 16px 0;
+    color: #BABBBC;
+  }
+}
+</style>
+
+<style >
+  .order-tabs >>> .u-tab-item {
+    z-index: 10;
+  }
+</style>

+ 519 - 0
src/pagesSub/activity/activityDetail.vue

@@ -0,0 +1,519 @@
+<template>
+  <view class="act-deltail-main" :style="{paddingBottom: `${footerHeight}rpx`}">
+    <network-error />
+    <view class="over-view">
+      <image class="detail-img" :src="detail.imgs" mode="aspectFill"></image>
+      <view class="detail-over">
+        <text class="detail-title u-line-2 u-font-40 line-56 u-tips-color bold">【{{detail.activity_type | activityTyepFilter}}】{{detail.title}}</text>
+        <view class="u-flex u-col-bottom u-p-t-24 u-p-b-14 u-border-bottom">
+          <text class="u-primary-color u-font-28 line-40">返利:</text>
+          <block v-if="detail.activity_type === 1">
+            <text class="u-flex-1 u-primary-color u-font-36 line-50 bold">实付全返</text>
+          </block>
+          <block v-if="detail.activity_type === 2">
+            <view class="u-flex-1 u-primary-color bold">
+              <text class="u-font-28 line-40">¥</text>
+              <text class="u-font-36 line-50">{{(detail.rebate_amount / 100).toFixed(2)}}</text>
+            </view>
+          </block>
+          <text class="u-primary-color u-font-24 line-34">{{detail.join_count - detail.join_number}}</text>
+          <text class="u-content-color u-font-24 line-34">剩余名额</text>
+        </view>
+        <view class="u-flex u-row-between u-p-t-22 line-34">
+          <text class="u-content-color">{{detail.join_number}}已参与</text>
+          <button class="share-btn u-primary-color u-font-24 line-34" open-type="share">分享活动</button>
+        </view>
+      </view>
+    </view>
+    <view class="shop-info u-m-t-16">
+      <view class="u-font-36 line-50 u-tips-color bold">店铺信息</view>
+      <view class="u-flex">
+        <view class="u-flex-1 u-p-r-32">
+          <text class="shop-name u-font-28 u-tips-color line-40 u-line-1">【{{detail.plat_type | platFilter}}】{{detail.shop_name}}</text>
+          <view class="u-flex" @click="openMap">
+            <view class="icon-map-wh icon-map"></view>
+            <view class="u-content-color u-m-l-8 u-m-r-16">{{(detail.distance / 1000).toFixed(1)}}km</view>
+            <text class="shop-address u-flex-1 u-content-color u-line-1">{{detail.shop_address}}</text>
+          </view>
+        </view>
+        <view class="divider-right"></view>
+        <block v-if="detail.plat_type === 8">
+          <view class="to-btn u-p-l-28" @click="openOtherApplte(8)">
+            <view class="icon-mt-wh icon-elm"></view>
+            <view class="u-m-t-2 u-font-22 u-content-color line-32">打开饿了么</view>
+          </view>
+        </block>
+        <block v-if="detail.plat_type === 9">
+          <view class="to-btn u-p-l-28" @click="openOtherApplte(9)">
+            <view class="icon-mt-wh icon-mt"></view>
+            <view class="u-m-t-2 u-font-22 u-content-color line-32">打开美团</view>
+          </view>
+        </block>
+      </view>
+    </view>
+    <view class="act-able-time u-m-t-16">
+      <view class="u-font-36 line-50 u-tips-color bold">活动可用时间</view>
+      <view class="u-flex">
+        <text class="u-flex-1 u-content-color line-40 u-line-2 u-p-r-32">{{businessHours}}营业时间可用(当天参与报名,需当天提交资料才能有效返款)</text>
+        <view class="divider-right"></view>
+        <button class="to-btn contact-btn u-p-l-28" open-type="contact">
+          <view class="icon-phone-wh icon-phone"></view>
+          <view class="u-m-t-2 u-font-22 u-content-color line-32">联系客服</view>
+        </button>
+      </view>
+    </view>
+    <view class="act-desc u-m-t-16">
+      <view class="act-tabs u-border-bottom">
+        <u-tabs
+          :is-scroll="false"
+          :list="[{name: '活动规则'}, {name: '评价要求'}]"
+          :current="currentTab"
+          height="104"
+          font-size="30"
+          active-color="#FF6632"
+          inactive-color="#111111"
+          :bar-style="{
+            bottom: '-4rpx',
+            marginLeft: '-40rpx',
+            width: '120rpx',
+            height: '6rpx',
+            borderRadius: 0,
+            backgroundColor: 'linear-gradient(270deg, #FFB76B 0%, #FE4028 100%)'
+          }"
+          @change="changeTab"
+        >
+        </u-tabs>
+      </view>
+      <view class="u-m-b-18 u-p-t-32 u-p-b-32">
+        <block v-if="currentTab === 0">
+          <block v-for="(item, index) in detail.content" :key="index">
+            <img-text :value="item.content" :type="item.contentType"></img-text>
+          </block>
+        </block>
+        <block v-else>
+          <img-text :value="detail.requirement" type="1"></img-text>
+        </block>
+      </view>
+    </view>
+    <block v-if="status">
+      <fixed-bottom @get-height="getFooterHeight">
+        <view class="bottom-footer u-flex">
+          <block v-if="status * 1 === 1 || status * 1 === 2">
+            <view class="u-flex-1">
+              <view class="line-34 bold">距活动结束还有:</view>
+              <view class="u-font-20 u-content-color line-28">{{remainingTime}}</view>
+            </view>
+            <block v-if="status * 1 === 1">
+              <button class="sign-up-btn u-font-30 bold line-42" @click="join">我要报名</button>
+            </block>
+            <block v-if="status * 1 === 2">
+              <view class="u-flex">
+                <button class="canel-btn u-font-28 line-40" @click="cancelJoin">取消报名</button>
+                <button class="submit-btn u-font-28 line-40 u-m-l-16" @click="toSubmiteOrder">提交结果</button>
+              </view>
+            </block>
+          </block>
+          <block v-if="status * 1 === 3 || status * 1 === 4">
+            <block v-if="status * 1 === 3">
+              <view class="u-flex-1">
+                <view class="line-34 bold">等待审核:</view>
+                <view class="u-font-20 u-content-color line-28">审核通过后将获得返利金额</view>
+              </view>
+            </block>
+            <block v-if="status * 1 === 4">
+              <view class="u-flex-1">
+                <view class="line-34 bold">审核通过:</view>
+                <view class="u-font-20 u-content-color line-28">返利金额将在第二日到账</view>
+              </view>
+            </block>
+            <button class="sign-up-btn u-font-30 bold line-42" disabled>已提交</button>
+          </block>
+          <block v-if="status * 1 === 5">
+            <view class="u-flex-1">
+              <view class="line-34 bold">审核驳回:</view>
+              <view class="u-font-20 u-content-color line-28">审核驳回理由审核驳回理由审核驳回理由</view>
+            </view>
+          </block>
+          <block v-if="status * 1 === 6">
+            <button class="end-btn u-m-l-12" disabled>已结束</button>
+          </block>
+          <block v-if="status * 1 === 7">
+            <button class="end-btn u-m-l-12" disabled>已抢光</button>
+          </block>
+        </view>
+      </fixed-bottom>
+    </block>
+  </view>
+</template>
+
+<script>
+import fixedBottom from '@/components/fixedBottom'
+import imgText from '@/components/imgText'
+import { getActivityDetail } from '@/api/activityApi'
+import { editJoinActivity } from '@/api/userApi'
+export default {
+  components: { fixedBottom, imgText },
+  data () {
+    return {
+      showErr: false,
+      errMsg: '',
+      nowTime: '',
+      timer: null,
+      footerHeight: 0,
+      currentTab: 0,
+      activityId: '',
+      detail: {
+        imgs: '',
+        activity_type: '',
+        title: '',
+        rebate_amount: '',
+        join_count: 0,
+        join_number: 0,
+        plat_type: '',
+        shop_name: '',
+        distance: 0,
+        shop_address: '',
+        join_status: '',
+        start_time: '',
+        end_time: ''
+      }
+    }
+  },
+  computed: {
+    userId () {
+      return this.$store.state.userInfo.id
+    },
+    businessHours () {
+      const date = this.$dayjs().format('YYYY年MM月DD日')
+      const start = this.$dayjs(`${this.$dayjs().format('YYYY-MM-DD')} ${this.detail.start_time}`).format('HH:mm')
+      const end = this.$dayjs(`${this.$dayjs().format('YYYY-MM-DD')} ${this.detail.end_time}`).format('HH:mm')
+      return `${date} ${start}-${end}`
+    },
+    status () {
+      if (this.detail.join_status === 1) {
+        return 2
+      } else if (this.detail.join_status === 2) {
+        return 3
+      } else if (this.detail.join_status === 3) {
+        return 4
+      } else if (this.detail.join_status === 4) {
+        return 5
+      } else if (this.detail.join_status === 5) {
+        return 1
+      } else if (this.detail.join_status === 6) {
+        return 6
+      } else if (this.remainingTime === 0) {
+        return 6
+      } else if (this.detail.join_count === this.detail.join_number && this.detail.join_count) {
+        return 7
+      } else if (this.detail.join_status === 0) {
+        return 1
+      } else {
+        return 0
+      }
+    },
+    remainingTime () {
+      if (!this.detail.end_time) { return }
+      const endTime = this.$dayjs(`${this.$dayjs().format('YYYY-MM-DD')} ${this.detail.end_time}`)
+      if (isNaN(endTime.diff(this.nowTime, 's'))) { return }
+      if (!isNaN(endTime.diff(this.nowTime, 's')) && endTime.diff(this.nowTime, 's') === 0) {
+        clearTimeout(this.timer)
+        return 0
+      }
+      return this.$dayjs(endTime.diff(this.nowTime)).subtract(8, 'h').format('HH小时mm分ss秒')
+    }
+  },
+  watch: {
+    userId (e) {
+      if (!e) {
+        uni.navigateTo({
+          url: '/pagesSub/other/login'
+        })
+      }
+    }
+  },
+  onLoad (options) {
+    this.activityId = options.id
+  },
+  onShow () {
+    if (!this.userId) {
+      uni.navigateTo({
+        url: '/pagesSub/other/login'
+      })
+      return
+    }
+    this.getDetailData()
+    this.reNowTime()
+  },
+  onHide () {
+    clearTimeout(this.timer)
+  },
+  onError () {
+    clearTimeout(this.timer)
+  },
+  onPullDownRefresh () {
+    clearTimeout(this.timer)
+    this.getDetailData()
+    this.reNowTime()
+  },
+  onPageNotFound () {
+    clearTimeout(this.timer)
+  },
+  onShareAppMessage (res) {
+    const title = `${this.detail.activity_type === 1 ? '【免费吃】' : '【返利餐】'}${this.detail.title}`
+    return {
+      title: title,
+      path: `/pagesSub/activity/activityDetail?id=${this.detail.id}`,
+      imageUrl: this.detail.imgs
+    }
+  },
+  methods: {
+    reNowTime () {
+      clearTimeout(this.timer)
+      this.timer = setTimeout(() => {
+        this.nowTime = this.$dayjs()
+        this.reNowTime()
+      }, 1000)
+    },
+    // 获取用户经纬度
+    getLocation () {
+      return new Promise((resolve, reject) => {
+        uni.getLocation({
+          type: 'wgs84',
+          success: (res) => {
+            resolve(res)
+          },
+          fail: () => {
+            resolve(false)
+          }
+        })
+      })
+    },
+    // 获取活动详情
+    async getDetailData () {
+      const location = await this.getLocation()
+      if (!location) { return }
+      const params = {
+        id: this.activityId,
+        lng: location.longitude,
+        lat: location.latitude
+      }
+      const { code, data } = await getActivityDetail(params)
+      if (code === 200) {
+        this.detail = data
+      }
+    },
+    // 报名活动/取消报名
+    async joinActivity (type) {
+      const params = {
+        id: this.detail.id,
+        type: type
+      }
+      const { code, msg } = await editJoinActivity(params)
+      if (code === 200) {
+        if (type === 1) {
+          uni.navigateTo({
+            url: `/pagesSub/activity/signUpOutcome?endTime=${this.detail.end_time}&platType=${this.detail.plat_type}`
+          })
+        } else {
+          this.getDetailData()
+        }
+      } else {
+        uni.showToast({
+          title: msg,
+          icon: 'none'
+        })
+      }
+    },
+    getFooterHeight (h) {
+      this.footerHeight = h * 2
+    },
+    changeTab (index) {
+      this.currentTab = index
+    },
+    openMap () {
+      uni.openLocation({
+        latitude: this.detail.shop_lat,
+        longitude: this.detail.shop_lng
+      })
+    },
+    // 我要报名
+    join () {
+      // uni.requestSubscribeMessage({
+      //   tmplIds: [''],
+      //   success: (res) => {
+      //     this.joinActivity(1)
+      //   }
+      // })
+      this.joinActivity(1)
+    },
+    // 取消报名
+    cancelJoin () {
+      uni.showModal({
+        title: '提示',
+        content: '确定取消报名',
+        confirmColor: '#1677FF',
+        cancelColor: '#1677FF',
+        success: (res) => {
+          if (res.confirm) {
+            this.joinActivity(2)
+          }
+        }
+      })
+    },
+    // 提交结果
+    toSubmiteOrder () {
+      uni.navigateTo({
+        url: `/pagesSub/order/submitOrder?activityId=${this.detail.id}&userActivityId=${this.detail.user_activity_id}`
+      })
+    },
+    openOtherApplte (platType) {
+      this.$store.dispatch('toOtherApplte', platType)
+    }
+  },
+  filters: {
+    activityTyepFilter (e) {
+      const typeList = {
+        1: '免费吃',
+        2: '返利餐'
+      }
+      return typeList[e] || ''
+    },
+    platFilter (e) {
+      const platList = {
+        8: '饿了么',
+        9: '美团'
+      }
+      return platList[e] || ''
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.act-deltail-main {
+  .over-view {
+    .detail-img {
+      width: 100%;
+      height: 424px;
+      font-size: 0;
+    }
+    .detail-over {
+      padding: 24px 40px 28px;
+      background-color: #fff;
+    }
+    .detail-title {
+      max-width: 670px;
+    }
+    .share-btn {
+      margin: 0;
+      padding-right: 0;
+      background-color: #fff;
+      &::after {
+        border-color: transparent;
+      }
+    }
+  }
+  .act-able-time, .shop-info {
+    padding: 32px 40px 28px;
+    background-color: #fff;
+    .shop-name {
+      display: inline-block;
+      margin: 16px 0;
+      max-width: 510px;
+    }
+    .shop-address {
+      display: inline-block;
+      max-width: 396px;
+    }
+    .to-btn {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+    .contact-btn {
+      padding-right: 0;
+      background-color: #fff;
+      &::after {
+        border-color: transparent;
+      }
+    }
+    .icon-map-wh {
+      width: 20px;
+      height: 24px;
+    }
+    .icon-phone-wh, .icon-elm-wh, .icon-mt-wh {
+      width: 56px;
+      height: 56px;
+    }
+    .divider-right {
+      width: 2px;
+      height: 54px;
+      background-color: $u-border-color;
+    }
+  }
+  .act-desc {
+    padding: 0 40px;
+    background-color: #fff;
+  }
+  .bottom-footer {
+    padding: 16px 40px 16px 28px;
+    width: 100%;
+    background-color: #fff;
+    .sign-up-btn {
+      padding: 24px 128px;
+      width: 374px;
+      height: 88px;
+      border-radius: 44px;
+      color: #fff;
+      background-color: $u-type-primary;
+      white-space: nowrap;
+    }
+    .canel-btn, .submit-btn {
+      padding: 16px 40px;
+      width: 192px;
+      height: 72px;
+      border-radius: 36px;
+    }
+    .canel-btn {
+      position: relative;
+      color: $u-type-primary;
+      background-color: #fff;
+      &::after {
+        content: "";
+        display: flex;
+        align-items: center;
+        width: 200%;
+        height: 200%;
+        border: 2px solid $u-type-primary;
+        border-radius: 72px;
+        box-sizing: border-box;
+        pointer-events: none;
+        transform-origin: 0 0;
+      }
+    }
+    .submit-btn {
+      color: #fff;
+      background-color: $u-type-primary;
+    }
+    .end-btn {
+      width: 670px;
+      height: 88px;
+      border-radius: 44px;
+    }
+  }
+}
+button[disabled] {
+  color: #fff!important;
+  background-color: #D3D4D5!important;
+}
+button[disabled]::after {
+  border-color: transparent;
+}
+</style>
+
+<style >
+  .act-tabs >>> .u-tab-item + .u-tab-item {
+    margin-left: 42px;
+  }
+</style>

+ 110 - 0
src/pagesSub/activity/signUpOutcome.vue

@@ -0,0 +1,110 @@
+<template>
+  <view class="main">
+    <network-error />
+    <view class="success u-flex u-row-center">
+      <view class="icon-success-wh icon-success"></view>
+      <view class="u-font-36 line-50">报名成功</view>
+    </view>
+    <view class="date">
+      <view class="mtb">截止日期:{{endTime}}</view>
+      <view>参与结果可在【首页底部导航栏-订单】中查看</view>
+    </view>
+    <view class="u-flex u-row-center">
+      <view class="message">
+        <view class="title u-font-24 line-28">返利规则</view>
+        <view class="content u-font-24 line-34">点餐后需按要求提交订单信息,当天报名当天提交才可获得<span class="money">返利金额</span></view>
+      </view>
+    </view>
+    <view class="btn u-flex u-row-center">
+      <button @click="toOrderList">查看订单</button>
+      <button class="active" @click="toOrderMeal">去点餐</button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      platType: '',
+      endTime: ''
+    }
+  },
+  onLoad (options) {
+    this.platType = options.platType
+    this.endTime = this.$dayjs(`${this.$dayjs().format('YYYY-MM-DD')} ${options.endTime}`).format('YYYY-MM-DD HH:mm:ss')
+  },
+  methods: {
+    toOrderList () {
+      uni.switchTab({
+        url: '/pages/order'
+      })
+    },
+    toOrderMeal () {
+      this.$store.dispatch('toOtherApplte', this.platType)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    background-color: #FFF;
+    padding-top: 15px;
+  }
+  .success {
+    color:$u-main-color;
+    font-weight: 1000;
+    margin: 48px 0;
+  }
+  .icon-success-wh {
+    width: 92px;
+    height: 92px;
+    margin-right: 16px;
+  }
+  .date {
+    font-size: 26px;
+    color:$u-main-color;
+    line-height: 36px;
+    margin: 16px 0 40px 32px;
+    .mtb {
+      margin: 16px 0;
+    }
+  }
+  .message {
+    width: 686px;
+    height: 156px;
+    color:$u-main-color;
+    background-color: #F7F8F9;
+    padding: 24px;
+    border-radius: 8px;
+    .title {
+      font-family: Helvetica;
+      margin-bottom: 8px;
+    }
+    .money {
+      color: #4A6D8D;
+    }
+  }
+  .btn {
+    button {
+      width: 280px;
+      height: 84px;
+      border: 1px solid #D3D4D5;
+      border-radius: 42px;
+      font-size: 28px;
+      line-height: 40px;
+      color:$u-main-color;
+      background-color: #FFF;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin: 40px 0;
+    }
+    .active {
+      border: 1px solid #FF6632;
+      color: #FF6632;
+      margin-left: 30px;
+    }
+  }
+</style>

+ 42 - 0
src/pagesSub/my/about.vue

@@ -0,0 +1,42 @@
+<template>
+  <view class="main">
+    <network-error />
+    <view class="logo">
+      <iamge></iamge>
+    </view>
+    <view class="info u-font-26 line-36">
+      描述文案描述文案描述文案描述文案描述文案描述文案描述文案描述文案
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {}
+  },
+  mounted () {},
+  methods: {}
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    width: 100%;
+    height: 100vh;
+    background-color: #fff;
+    box-sizing: border-box;
+    padding: 64px 48px 0;
+  }
+  .logo {
+    width: 128px;
+    height: 128px;
+    border-radius: 8px;
+    background-color: $u-light-color;
+    margin: 0 auto 32px;
+  }
+  .info {
+    color: #999999;
+    text-align: center;
+  }
+</style>

+ 69 - 0
src/pagesSub/my/commonProblem.vue

@@ -0,0 +1,69 @@
+<template>
+  <view>
+    <network-error />
+    <view class="main">
+      <view class="title u-font-36 line-50 bold">常见问题</view>
+      <u-collapse class="collapse">
+        <block v-for="(item, index) in proList" :key="index">
+          <u-collapse-item :title="item.question" >
+            <view class="content-item u-font-24 line-34 u-border-bottom">{{item.answer}}</view>
+          </u-collapse-item>
+        </block>
+      </u-collapse>
+    </view>
+    <view class="tips line-34 u-other-color">以上内容最终解释权归本公司所有。</view>
+  </view>
+</template>
+
+<script>
+import { getQaList } from '@/api/app'
+export default {
+  data () {
+    return {
+      proList: []
+    }
+  },
+  onLoad () {
+    this.getProList()
+  },
+  methods: {
+    async getProList () {
+      const { code, data } = await getQaList()
+      if (code === 200) {
+        this.proList = data
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    background-color: #FFF;
+    width: 100%;
+    .title {
+      color: $u-main-color;
+      box-sizing: border-box;
+      padding: 24px 0 0 32px;
+      margin-bottom: 30px;
+    }
+    .content-item {
+      padding: 32px;
+      color: #98999A;
+    }
+  }
+  .tips {
+    padding: 32px 0;
+    text-align: center;
+  }
+</style>
+
+<style>
+   .collapse >>> u-collapse-item .u-collapse-item .u-collapse-head {
+     font-size: 28px;
+     color: #111111;
+     line-height: 40px;
+     padding: 32px 0 32px 32px;
+     border-bottom: 1px solid #EAEBEC;
+   }
+</style>

+ 86 - 0
src/pagesSub/my/userDetail.vue

@@ -0,0 +1,86 @@
+<template>
+  <view class="main">
+    <network-error />
+    <view class="item border-bottom u-flex">
+      <view class="title bold u-flex-1">头像</view>
+      <image class="avatar" :src="newHead" @click="changeHead"></image>
+      <u-icon name="arrow-right" color="#98999A" size="20"></u-icon>
+    </view>
+    <view class="item border-bottom u-flex u-row-between">
+      <view class="title bold">昵称</view>
+      <input class="info u-text-right" v-model="nickName" placeholder="昵称限11字" @change="submit" />
+    </view>
+  </view>
+</template>
+
+<script>
+import upload from '@/utils/uploadImg'
+import { editUserInfo } from '@/api/userApi'
+export default {
+  data () {
+    return {
+      newHead: '',
+      nickName: ''
+    }
+  },
+  computed: {
+    userInfo () {
+      return this.$store.state.userInfo
+    },
+    imgPrefix () {
+      return this.$store.state.imgPrefix
+    }
+  },
+  onLoad () {
+    this.newHead = this.userInfo.head_url
+    this.nickName = this.userInfo.nick_name
+  },
+  methods: {
+    async submit () {
+      const params = {
+        head_url: this.newHead,
+        nick_name: this.nickName
+      }
+      const { code } = await editUserInfo(params)
+      if (code === 200) {
+        this.$store.commit('changeHeadOrNickName', params)
+        uni.showToast({
+          title: '修改成功',
+          icon: 'none'
+        })
+      }
+    },
+    async changeHead () {
+      const imgs = await upload(9)
+      this.newHead = this.imgPrefix + imgs[0].url
+      this.submit()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    background-color: #FFF;
+    padding: 30px 32px 0 32px;
+  }
+  .item {
+    padding: 40px 0;
+    font-size: 28px;
+    line-height: 40px;
+    .title {
+      color: $u-tips-color;
+    }
+  }
+  .avatar {
+    width: 108px;
+    height: 108px;
+    border-radius: 54px;
+  }
+  .border-bottom {
+    border-bottom: 1px solid #EAEBEC;
+  }
+  .title {
+    font-weight: 1000;
+  }
+</style>

+ 68 - 0
src/pagesSub/order/rule.vue

@@ -0,0 +1,68 @@
+<template>
+  <view class="rule-main">
+    <network-error />
+    <view class="u-font-32 line-44 bold color-212121">符合活动的评价要求,需满足:</view>
+    <view class="u-m-t-16 u-font-28 line-20 color-333">{{detail.requirement}}</view>
+  </view>
+</template>
+
+<script>
+import { getActivityDetail } from '@/api/activityApi'
+export default {
+  data () {
+    return {
+      activityId: '',
+      detail: {}
+    }
+  },
+  onLoad (options) {
+    this.activityId = options.id
+    this.getDetailData()
+  },
+  methods: {
+    // 获取用户经纬度
+    getLocation () {
+      return new Promise((resolve, reject) => {
+        uni.getLocation({
+          type: 'wgs84',
+          success: (res) => {
+            resolve(res)
+          },
+          fail: () => {
+            resolve(false)
+          }
+        })
+      })
+    },
+    // 获取活动详情
+    async getDetailData () {
+      const location = await this.getLocation()
+      if (!location) { return }
+      const params = {
+        id: this.activityId,
+        lng: location.longitude,
+        lat: location.latitude
+      }
+      const { code, data } = await getActivityDetail(params)
+      if (code === 200) {
+        this.detail = data
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .rule-main {
+    box-sizing: border-box;
+    padding: 48px 32px 0;
+    height: 100vh;
+    background-color: #fff;
+    .color-212121 {
+      color: #212121;
+    }
+    .color-333 {
+      color: #333;
+    }
+  }
+</style>

+ 274 - 0
src/pagesSub/order/submitOrder.vue

@@ -0,0 +1,274 @@
+<template>
+  <view>
+    <network-error />
+    <u-notice-bar mode="horizontal" :list="['虚假填写信息将被列入黑名单,永久不得参加活动']"></u-notice-bar>
+    <view class="main">
+      <view class="item u-flex u-row-left u-border-bottom">
+        <view class="label u-flex label-w">
+          <view class="icon-bt"></view>
+          <view>外卖订单编号</view>
+        </view>
+        <input v-model="form.ordersn" placeholder="请输入订单编号"/>
+      </view>
+      <view class="item u-flex u-row-left u-border-bottom">
+        <view class="label u-flex label-w">
+          <view class="icon-bt"></view>
+          <view>实际支付金额</view>
+        </view>
+        <input v-model="form.real_pay_price" type="digit" placeholder="请输入实际支付金额"/>
+      </view>
+      <view class="item u-flex u-row-left u-border-bottom">
+        <view class="label u-flex label-w">
+          <view class="icon-bt"></view>
+          <view>手机号</view>
+        </view>
+        <input v-model="form.contact_phone" type="number" placeholder="请输入手机号"/>
+      </view>
+      <view class="item u-border-bottom">
+        <view class="label u-flex">
+          <view class="icon-bt"></view>
+          <view>订单截图<span class="u-content-color u-font-30 line-42">(含店名与实付金额)</span></view>
+        </view>
+        <view class="u-flex u-flex-wrap u-p-t-40">
+          <block v-for="(item, index) in imgList1" :key="index">
+            <view class="u-rela img-item">
+              <image :src="item.url | imgFilter(4)" mode="aspectFill" @click="lookImg(imgList2, index)"></image>
+              <view class="icon-del-red-wh icon-del-red" @click="delImg(index, 1)"></view>
+            </view>
+          </block>
+          <view class="upload icon-upload-bg" @click="uploadImg(1)"></view>
+        </view>
+      </view>
+      <view class="item u-border-bottom">
+        <view class="label u-flex">
+          <view class="icon-bt"></view>
+          <view>订单截图<span class="u-content-color u-font-30 line-42">(含下单时间与订单号)</span></view>
+        </view>
+        <view class="u-flex u-flex-wrap u-p-t-40">
+          <block v-for="(item, index) in imgList2" :key="index">
+            <view class="u-rela img-item">
+              <image :src="item.url | imgFilter(4)" mode="aspectFill" @click="lookImg(imgList2, index)"></image>
+              <view class="icon-del-red-wh icon-del-red" @click="delImg(index, 2)"></view>
+            </view>
+          </block>
+          <view class="upload icon-upload-bg" @click="uploadImg(2)"></view>
+        </view>
+      </view>
+      <view class="item u-border-bottom">
+        <view class="label u-flex">
+          <view class="icon-bt"></view>
+          <view>评价截图<span class="u-content-color u-font-30 line-42">(需上传评价截图)</span>
+            <span class="rule u-m-l-32" @click="toRule">评价规则</span>
+          </view>
+        </view>
+        <view class="u-flex u-flex-wrap u-p-t-40">
+          <block v-for="(item, index) in imgList3" :key="index">
+            <view class="u-rela img-item">
+              <image :src="item.url | imgFilter(4)" mode="aspectFill" @click="lookImg(imgList2, index)"></image>
+              <view class="icon-del-red-wh icon-del-red" @click="delImg(index, 3)"></view>
+            </view>
+          </block>
+          <view class="upload icon-upload-bg" @click="uploadImg(3)"></view>
+        </view>
+      </view>
+    </view>
+    <button class="sub u-m-t-12" :disabled="disabledBtn" @click="submit">提交</button >
+  </view>
+</template>
+
+<script>
+import upload from '@/utils/uploadImg'
+import dealImgUrl from '@/utils/dealImgUrl'
+import { submitOrderInfo } from '@/api/userApi'
+export default {
+  data () {
+    return {
+      activityId: '',
+      form: {
+        id: '',
+        ordersn: '',
+        contact_phone: '',
+        real_pay_price: '',
+        img_items: []
+      },
+      imgList1: [], // 订单截图(含店名与实付金额)
+      imgList2: [], // 订单截图(含下单时间与订单号)
+      imgList3: [] // 评价截图(需上传评价截图)
+    }
+  },
+  computed: {
+    disabledBtn () {
+      if (!this.imgList3.length) {
+        return true
+      } else if (!this.imgList2.length) {
+        return true
+      } else if (!this.imgList1.length) {
+        return true
+      } else if (!this.form.real_pay_price) {
+        return true
+      } else if (!this.form.contact_phone) {
+        return true
+      } else if (!this.form.ordersn) {
+        return true
+      } else {
+        return false
+      }
+    }
+  },
+  onLoad (options) {
+    this.activityId = options.activityId
+    this.form.id = options.userActivityId
+  },
+  methods: {
+    // 提交订单信息
+    async submitForm () {
+      const params = JSON.parse(JSON.stringify(this.form))
+      const { code, msg } = await submitOrderInfo(params)
+      if (code === 200) {
+        uni.navigateTo({
+          url: `/pagesSub/order/submitOutcome?id=${this.activityId}`
+        })
+      } else {
+        uni.showToast({
+          title: msg,
+          icon: 'none'
+        })
+      }
+    },
+    // 上传图片
+    async uploadImg (type) {
+      const imgs = await upload(9)
+      if (type === 1) {
+        this.imgList1 = this.imgList1.concat(imgs)
+      } else if (type === 2) {
+        this.imgList2 = this.imgList2.concat(imgs)
+      } else {
+        this.imgList3 = this.imgList3.concat(imgs)
+      }
+    },
+    delImg (index, type) {
+      if (type === 1) {
+        this.imgList1.splice(index, 1)
+      } else if (type === 2) {
+        this.imgList2.splice(index, 1)
+      } else {
+        this.imgList3.splice(index, 1)
+      }
+    },
+    // 点击提交
+    submit () {
+      const is = /^1(3|4|5|6|7|8|9)\d{9}$/.test(this.form.contact_phone)
+      if (!is) {
+        uni.showToast({
+          title: '请输入正确的手机号!',
+          icon: 'none'
+        })
+        return
+      }
+      const imgList1 = this.dealImg(this.imgList1, 1)
+      const imgList2 = this.dealImg(this.imgList2, 2)
+      const imgList3 = this.dealImg(this.imgList3, 3)
+      this.form.img_items = this.form.img_items.concat(imgList1, imgList2, imgList3)
+      this.submitForm()
+    },
+    // 处理上传图片
+    dealImg (arr, type) {
+      const imgs = []
+      arr.forEach(item => {
+        const imgItem = {
+          url: item.url,
+          res_type: type
+        }
+        imgs.push(imgItem)
+      })
+      return imgs
+    },
+    toRule () {
+      uni.navigateTo({
+        url: `/pagesSub/order/rule?id=${this.activityId}`
+      })
+    },
+    lookImg (list, index) {
+      const imgs = list.map(item => {
+        item.url = dealImgUrl(item.url)
+        return item.url
+      })
+      uni.previewImage({
+        urls: imgs,
+        current: index
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    background-color: #FFF;
+  }
+  .icon-bt {
+    width: 14px;
+    height: 14px;
+    margin-right: 4px;
+  }
+  .item {
+    padding: 32px 32px 32px 24px;
+  }
+  .label {
+    font-size: 30px;
+    color: $u-main-color;
+    line-height: 42px;
+  }
+  .label-w {
+    width: 200px;
+    margin-right: 78px;
+  }
+  .sub {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 116px;
+    border-radius: 0;
+    background-color: $u-type-primary;
+    color: #FFF;
+    font-size: 36px;
+    line-height: 50px;
+    &::after {
+      border-color: transparent;
+    }
+  }
+  .img-item image, .upload {
+    width: 160px;
+    height: 160px;
+    border-radius: 4px;
+    font-size: 0;
+  }
+  .upload {
+    margin-bottom: 16px;
+  }
+  .img-item {
+    margin-right: 14px;
+    margin-bottom: 10px;
+  }
+  .icon-del-red-wh {
+    position: absolute;
+    top: 8px;
+    right: 8px;
+    width: 28px;
+    height: 28px;
+  }
+  .rule {
+    color: $u-type-other;
+  }
+  button[disabled] {
+    color: #F8F9FB;
+    background-color: #F8BCA9;
+  }
+</style>
+
+<style scoped>
+  .u-notice-bar >>> .u-notice-text {
+    font-size: 26px;
+  }
+</style>

+ 128 - 0
src/pagesSub/order/submitOutcome.vue

@@ -0,0 +1,128 @@
+<template>
+  <view class="main">
+    <network-error />
+    <view class="success u-flex u-row-center">
+      <view class="icon-success-wh icon-success"></view>
+      <view class="u-font-36 line-50">提交成功</view>
+    </view>
+    <view class="u-flex u-row-center">
+      <view class="message">
+        <view class="title u-font-24 line-28">返利时间</view>
+        <view class="content u-font-24 line-34">审核通过后,返利金额将在第二天的12点——24点打入您的微信红包</view>
+      </view>
+    </view>
+    <view class="btn u-flex u-row-center">
+      <button @click="toIndex">回到首页</button>
+      <button class="active" open-type="share">分享活动</button>
+    </view>
+  </view>
+</template>
+
+<script>
+import { getActivityDetail } from '@/api/activityApi'
+export default {
+  data () {
+    return {
+      activityId: '',
+      detail: {}
+    }
+  },
+  onLoad (options) {
+    this.activityId = options.id
+    this.getDetailData()
+  },
+  onShareAppMessage (res) {
+    const title = `${this.detail.activity_type === 1 ? '【免费吃】' : '【返利餐】'}${this.detail.title}`
+    return {
+      title: title,
+      path: `/pagesSub/activity/activityDetail?id=${this.detail.id}`,
+      imageUrl: this.detail.imgs
+    }
+  },
+  methods: {
+    // 获取用户经纬度
+    getLocation () {
+      return new Promise((resolve, reject) => {
+        uni.getLocation({
+          type: 'wgs84',
+          success: (res) => {
+            resolve(res)
+          },
+          fail: () => {
+            resolve(false)
+          }
+        })
+      })
+    },
+    // 获取活动详情
+    async getDetailData () {
+      const location = await this.getLocation()
+      if (!location) { return }
+      const params = {
+        id: this.activityId,
+        lng: location.longitude,
+        lat: location.latitude
+      }
+      const { code, data } = await getActivityDetail(params)
+      if (code === 200) {
+        this.detail = data
+      }
+    },
+    toIndex () {
+      uni.switchTab({
+        url: '/pages/index'
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .main {
+    background-color: #FFF;
+    padding-top: 15px;
+  }
+  .success {
+    color: $u-main-color;
+    font-weight: 1000;
+    margin: 48px 0;
+  }
+  .icon-success-wh {
+    width: 92px;
+    height: 92px;
+    margin-right: 16px;
+  }
+  .message {
+    width: 686px;
+    height: 156px;
+    color: $u-main-color;
+    background-color: #F7F8F9;
+    padding: 24px;
+    border-radius: 8px;
+    .title {
+      font-family: Helvetica;
+      margin-bottom: 8px;
+    }
+  }
+  .btn {
+    button {
+      width: 280px;
+      height: 84px;
+      border: 1px solid #D3D4D5;
+      border-radius: 42px;
+      font-size: 28px;
+      line-height: 40px;
+      color: $u-main-color;
+      background-color: #FFF;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin: 40px 0;
+    }
+    .active {
+      border: 1px solid #FF6632;
+      color: $u-type-primary;
+      margin-left: 30px;
+    }
+  }
+</style>

+ 58 - 0
src/pagesSub/other/login.vue

@@ -0,0 +1,58 @@
+<template>
+  <view class="login-main">
+    <network-error />
+    <view class="header-image"><open-data type="userAvatarUrl"></open-data></view>
+    <view class="u-m-t-30 u-font-40 line-56 bold">您好,<open-data type="userNickName"></open-data></view>
+    <view class="u-m-t-32 u-font-28 line-40 u-content-color">登录小程序,请先授权微信信息</view>
+    <button class="login-btn u-font-32 line-44 bold" open-type="getUserInfo" @getuserinfo="changeUserInfo">
+      <u-icon class="u-m-r-16" name="weixin-fill" color="#FFF" size="32"></u-icon>
+      微信登录授权
+    </button>
+  </view>
+</template>
+
+<script>
+export default {
+  methods: {
+    async changeUserInfo (data) {
+      if (data.detail.errMsg === 'getUserInfo:ok') {
+        uni.showLoading({
+          title: '正在登录...'
+        })
+        const is = await this.$store.dispatch('getUserInfo')
+        uni.hideLoading()
+        if (is) {
+          uni.navigateBack({
+            delta: 1
+          })
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.login-main {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding-top: 16%;
+  height: 100vh;
+  background-color: #fff;
+  .header-image {
+    width: 148px;
+    height: 148px;
+    border-radius: 74px;
+  }
+  .login-btn {
+    box-sizing: border-box;
+    margin-top: 206px;
+    padding: 24px 210px;
+    width: 668px;
+    border-radius: 42px;
+    color: #fff;
+    background-color: $u-type-primary;
+  }
+}
+</style>

+ 123 - 0
src/pagesSub/other/noviceStrategy.vue

@@ -0,0 +1,123 @@
+<template>
+  <view class="novice-main">
+    <view class="content">
+      <view class="title">
+        <view class="z-index-10">活动类型有哪些?</view>
+        <view class="title-bg"></view>
+      </view>
+      <view class="desc u-m-t-8 line-34">霸王餐主要活动类型有两种:</view>
+      <view class="item">
+        <view class="line-40 bold">1.免费吃(实付全返)</view>
+        <view class="desc line-34 u-m-t-8">该类型活动只要订单存在且符合要求就会按照实付全返。</view>
+      </view>
+      <view class="item">
+        <view class="line-40 bold">2.返利餐(部分返利)</view>
+        <view class="desc line-34 u-m-t-8">该类型活动需满足实付金额大于规定金额的订单,才可以返对应的返利金额。</view>
+      </view>
+    </view>
+    <view class="content">
+      <view class="title">
+        <view class="z-index-10">如何参与活动?</view>
+        <view class="title-bg"></view>
+      </view>
+      <view class="desc u-m-t-8 line-34">参与活动共有4个步骤:</view>
+      <view class="item">
+        <view class="line-40 bold">1.免费报名</view>
+        <view class="u-m-t-8 u-new-color line-34">进入首页选择活动,进行报名。</view>
+        <view class="desc line-34">具体报名方法:首先进入小程序首页,并找到需要参与的活动,点击对应活动右边的“参与报名”按钮,或在该活动详情页下点击“我要报名” 按钮,即可成功报名。</view>
+      </view>
+      <view class="item">
+        <view class="line-40  bold">2.进入店铺下单</view>
+        <view class="u-m-t-8 u-new-color line-34">报名之后,需到对应平台找到对应商家和活动商品,进行下单。</view>
+        <view class="desc line-34">具体下单方法:成功报名后,点击活动详情页的“复制店名”按钮,并前往美团/饿了么平台进行搜索店铺并下单。</view>
+      </view>
+      <view class="item">
+        <view class="line-40  bold">3.提交活动资料,并提交审核</view>
+        <view class="u-m-t-8 u-new-color line-34">用户根据活动要求提交相应资料,等待审核。</view>
+        <view class="desc line-34">具体提交资料方法:完成下单后,在活动详情页内,点击下方“提交结果”按钮,并按照要求填写对应凭证,提交审核。</view>
+      </view>
+      <view class="item">
+        <view class="line-40  bold">4.获取返利</view>
+        <view class="u-m-t-8 u-new-color line-34">审核通过后,返利金额将直接打入用户微信支付账户。</view>
+        <view class="desc line-34">审核相关事宜:当成功提交资料后,系统会对提交结果的信息进行审核,若参与订单存在且符合要求,则会在第二天的12点-24点之间进行返款。若审核不通过,无法获得返利金额。</view>
+      </view>
+    </view>
+    <view class="content">
+      <view class="title">
+        <view class="z-index-10">活动规则悉知</view>
+        <view class="title-bg"></view>
+      </view>
+      <view class="desc u-m-t-8 line-34">参与活动共有4个步骤:</view>
+      <view class="item">
+        <view class="line-40 bold">1.报名规则</view>
+        <view class="u-m-t-8 u-new-color line-34">用户定位10km范围以外活动不能够报名。 同平台(例如美团、饿了么)单用户每天只能报名一次。</view>
+        <view class="desc line-34">霸王餐与返利餐均为限时限量活动,当活动时间过期或参与名额为零时,则无法报名。</view>
+      </view>
+      <view class="item">
+        <view class="line-40 bold">2.下单规则</view>
+        <view class="u-m-t-8 u-new-color line-34">用户报名后,需按对应商家、商品的要求进行下单,否则无效。</view>
+      </view>
+      <view class="item">
+        <view class="line-40 bold">3.提交资料、审核规则</view>
+        <view class="desc u-m-t-8 line-34">当天报名、当天提交资料为有效提交。</view>
+        <view class="desc line-34">提交的资料需包含:外卖订单编号、实际支付金额、订单截图(需要包含店名、实付金额、下单时间、订单号)、评价截图(符合评价要求)、手机号。</view>
+        <view class="desc line-34"> 提交的资料内容需符合要求、且订单真实存在。</view>
+        <view class="desc line-34">用户有黑名单机制,如用户出现一些违规问题会被加入黑名单永久不能参加活动,例如参加了活动还找商家私下再要返利者。</view>
+      </view>
+      <view class="item">
+        <view class="line-40 bold">4.返利规则</view>
+        <view class="desc line-34 u-m-t-8">当资料通过审核后,即可拿到返利,且返款时间为第二天的12点-24点之间。</view>
+      </view>
+    </view>
+    <view class="tips line-34 u-other-color">以上内容最终解释权归本公司所有。</view>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {}
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .novice-main {
+    .z-index-10 {
+      z-index: 10;
+      position: relative;
+    }
+    .content {
+      margin-top: 16px;
+      padding: 32px;
+      background-color: #fff;
+      .title {
+        font-size: 36px;
+        line-height: 50px;
+        font-weight: bold;
+        .title-bg {
+          position: relative;
+          &::before {
+            position: absolute;
+            left: 0;
+            bottom: 0;
+            content: "";
+            width: 262px;
+            height: 14px;
+            background: linear-gradient(90deg, #FEB268 0%, rgba(254, 176, 104, 0) 100%);
+          }
+        }
+      }
+      .desc {
+        color: $u-other-color;
+      }
+      .item {
+        margin-top: 24px;
+      }
+    }
+    .tips {
+      padding: 32px 0;
+      text-align: center;
+    }
+  }
+</style>

+ 19 - 0
src/pagesSub/other/webView.vue

@@ -0,0 +1,19 @@
+<template>
+  <view>
+    <network-error />
+    <web-view :src="url"></web-view>
+  </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      url: ''
+    }
+  },
+  onLoad (options) {
+    this.url = options.url
+  }
+}
+</script>

BIN
src/static/common/bg_sy.png


BIN
src/static/common/def_location.png


BIN
src/static/common/def_network_err.png


BIN
src/static/common/def_order.png


BIN
src/static/common/icon_bq_ybm.png


BIN
src/static/common/icon_bq_yqg.png


BIN
src/static/common/icon_lc_fgx.png


BIN
src/static/common/icon_numbei_1.png


BIN
src/static/common/icon_numbei_2.png


BIN
src/static/common/icon_numbei_3.png


BIN
src/static/common/icon_numbei_4.png


BIN
src/static/icon/aboutour.png


BIN
src/static/icon/avatar.png


BIN
src/static/icon/icon_bt.png


BIN
src/static/icon/icon_dingwei.png


BIN
src/static/icon/icon_dp.png


BIN
src/static/icon/icon_pp_elm.png


BIN
src/static/icon/icon_pp_lxsj.png


BIN
src/static/icon/icon_pp_mt.png


BIN
src/static/icon/icon_pz_close.png


BIN
src/static/icon/icon_success.png


BIN
src/static/icon/icon_zujian_sctp.png


BIN
src/static/icon/jiantou.png


BIN
src/static/icon/order.png


BIN
src/static/icon/problem.png


BIN
src/static/tabber/icon_db_dingdan.png


BIN
src/static/tabber/icon_db_dingdan2.png


BIN
src/static/tabber/icon_db_fenl.png


BIN
src/static/tabber/icon_db_fenl2.png


BIN
src/static/tabber/icon_db_home.png


BIN
src/static/tabber/icon_db_home2.png


BIN
src/static/tabber/icon_db_my.png


BIN
src/static/tabber/icon_db_my2.png


+ 140 - 0
src/store/index.js

@@ -0,0 +1,140 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import * as storageKeys from './storageKeys'
+import { bindWxCode, wxLogin } from '@/api/app'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+  state: {
+    imgPrefix: 'https://image.4008737773.com/',
+    ossImgResize: {},
+    openid: uni.getStorageSync(storageKeys.OPENIDID) || '', // 微信code换取openid
+    userInfo: uni.getStorageSync(storageKeys.USER_INFO) || {}, // 用户信息
+    cateId: ''
+  },
+  mutations: {
+    changeOssImgResize (state, data) {
+      state.ossImgResize = data
+    },
+    changeOpenId (state, data) {
+      if (!data) data = ''
+      state.openid = data
+      uni.setStorageSync(storageKeys.OPENIDID, data)
+    },
+    updateUserInfo (state, info) {
+      state.userInfo = info
+      if (!state.userInfo.token) {
+        uni.setStorageSync(storageKeys.USER_TOKEN, state.userInfo.token)
+      }
+      uni.setStorageSync(storageKeys.USER_INFO, state.userInfo)
+    },
+    changeHeadOrNickName (state, data) {
+      state.userInfo.head_url = data.head_url
+      state.userInfo.nick_name = data.nick_name
+      uni.setStorageSync(storageKeys.USER_INFO, state.userInfo)
+    },
+    changeCateId (state, data) {
+      state.cateId = data
+    }
+  },
+  actions: {
+    async getUserInfo ({ commit, state, dispatch }) {
+      return new Promise(async (resolve) => {
+        const sessionInfo = await new Promise(resolve => {
+          uni.checkSession({
+            success: res => resolve(res),
+            fail: err => {
+              // console.error('检查登陆状态失败', err)
+              resolve(err)
+            }
+          })
+        })
+        let userData = {}
+        let params = {}
+        if (state.openid === '' || sessionInfo.errMsg !== 'checkSession:ok') {
+          const openid = await dispatch('getUserCode')
+          if (!openid) { return }
+          userData = await uni.getUserInfo({ withCredentials: true })
+        }
+        if (!Array.isArray(userData) && !userData.userInfo) {
+          resolve(false)
+          return
+        }
+        if (Array.isArray(userData)) {
+          if (userData[1].errMsg !== 'getUserInfo:ok') {
+            resolve(false)
+            return
+          }
+          params = {
+            openid: state.openid,
+            iv: userData[1].iv,
+            encryptedData: userData[1].encryptedData
+          }
+        } else {
+          if (userData.errMsg !== 'getUserInfo:ok') {
+            resolve(false)
+            return
+          }
+          params = {
+            openid: state.openid,
+            iv: userData.iv,
+            encryptedData: userData.encryptedData
+          }
+        }
+        const userInfo = await wxLogin(params)
+        if (userInfo.data) {
+          userInfo.data.openid = state.openid
+          uni.setStorageSync(storageKeys.USER_TOKEN, userInfo.data.token)
+          commit('updateUserInfo', userInfo.data)
+          resolve(true)
+        } else {
+          resolve(false)
+        }
+      })
+    },
+    getUserCode ({ commit }) {
+      return new Promise(async (resolve, reject) => {
+        try {
+          const loginData = await new Promise((resolve) => {
+            uni.login({
+              success: res => resolve(res),
+              fail: err => {
+                console.error('登录失败', err)
+                resolve(false)
+              }
+            })
+          })
+          const { code, data, msg } = await bindWxCode({ code: loginData.code })
+          if (code === 200) {
+            commit('changeOpenId', data.openid)
+            resolve(data.openid)
+          } else {
+            uni.showToast({
+              icon: 'none',
+              title: msg
+            })
+            resolve(false)
+          }
+        } catch (err) {
+          console.error('获取用户信息失败', err)
+          resolve(false)
+        }
+      })
+    },
+    toOtherApplte ({ commit, state, dispatch }, platType) {
+      let appId = ''
+      if (platType * 1 === 8) {
+        appId = 'wxece3a9a4c82f58c9'
+      } else if (platType * 1 === 9) {
+        appId = 'wx2c348cf579062e56'
+      }
+      uni.navigateToMiniProgram({
+        appId: appId,
+        path: ''
+      })
+    }
+  }
+})
+
+export default store

+ 5 - 0
src/store/storageKeys.js

@@ -0,0 +1,5 @@
+export const OPENIDID = 'OPENIDID' // openid
+
+export const USER_TOKEN = 'USER_TOKEN'
+
+export const USER_INFO = 'USER_INFO'

+ 141 - 0
src/uni.scss

@@ -0,0 +1,141 @@
+@import 'uview-ui/theme.scss';
+
+
+$u-type-primary: #FF6632;
+$u-type-other: #FF7445;
+
+$u-main-color: #111111;
+$u-content-color: #767778;
+$u-tips-color: #212121;
+$u-light-color: #D3D4D5;
+$u-other-color: #98999A;
+$u-new-color: #FA6400;
+
+$bg-color: #F4F5F9;
+$bg-personl-info-color: linear-gradient(90deg, #FC744B 0%, #FE4035 100%, #FE4035 100%);
+
+$u-border-color: #EAEBEC;
+
+@mixin lineHeight ($line) {
+  line-height: $line * 2;
+}
+
+.u-primary-color {
+  color: $u-type-primary;
+}
+.u-other-color {
+  color: $u-other-color;
+}
+.u-new-color {
+  color: $u-new-color;
+}
+
+.bg-color {
+  background-color: #F4F5F9;
+}
+
+.bold {
+  font-weight: bold;
+}
+
+.line-20 {
+  line-height: 20px;
+}
+.line-22 {
+  line-height: 22px;
+}
+.line-24 {
+  line-height: 24px;
+}
+.line-26 {
+  line-height: 26px;
+}
+.line-28 {
+  line-height: 28px;
+}
+.line-30 {
+  line-height: 30px;
+}
+.line-32 {
+  line-height: 32px;
+}
+.line-33 {
+  line-height: 33px;
+}
+.line-34 {
+  line-height: 34px;
+}
+.line-36 {
+  line-height: 36px;
+}
+.line-38 {
+  line-height: 38px;
+}
+.line-40 {
+  line-height: 40px;
+}
+.line-42 {
+  line-height: 42px;
+}
+.line-44 {
+  line-height: 44px;
+}
+.line-50 {
+  line-height: 50px;
+}
+.line-56 {
+  line-height: 56px;
+}
+
+.icon-map {
+  background: url('~@/static/icon/icon_dingwei.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-mt {
+  background: url('~@/static/icon/icon_pp_mt.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-elm {
+  background: url('~@/static/icon/icon_pp_elm.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-phone {
+  background: url('~@/static/icon/icon_pp_lxsj.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-shop {
+  background: url('~@/static/icon/icon_dp.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-problem {
+  background: url('~@/static/icon/problem.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-aboutour {
+  background: url('~@/static/icon/aboutour.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-order {
+  background: url('~@/static/icon/order.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-jiantou {
+  background: url('~@/static/icon/jiantou.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-bt {
+  background: url('~@/static/icon/icon_bt.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-success {
+  background: url('~@/static/icon/icon_success.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-del-red {
+  background: url('~@/static/icon/icon_pz_close.png') no-repeat center center;
+  background-size: contain;
+}
+.icon-upload-bg {
+  background: url('~@/static/icon/icon_zujian_sctp.png') no-repeat center center;
+  background-size: contain;
+}

Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/utils/dayjs.min.js


+ 38 - 0
src/utils/dealImgUrl.js

@@ -0,0 +1,38 @@
+import store from '@/store/index'
+
+export default function (fileItem, type) {
+  let url = fileItem
+  if (!url) { return '' }
+  if (fileItem instanceof Object) {
+    url = fileItem.url
+  }
+  if (url.indexOf('http') < 0) {
+    /**
+     * type
+     * 1: 首页banner缩放参数
+     * 2: 活动列表缩放参数
+     * 3: 订单列表缩放参数
+     * 4: 提交订单截图缩放参数
+    */
+    switch (type) {
+    case 1: url = store.state.ossImgResize.banner_list
+      ? store.state.imgPrefix + url + store.state.ossImgResize.banner_list
+      : store.state.imgPrefix + url
+      break
+    case 2: url = store.state.ossImgResize.activity_list
+      ? store.state.imgPrefix + url + store.state.ossImgResize.activity_list
+      : store.state.imgPrefix + url
+      break
+    case 3: url = store.state.ossImgResize.order_list
+      ? store.state.imgPrefix + url + store.state.ossImgResize.order_list
+      : store.state.imgPrefix + url
+      break
+    case 4: url = store.state.ossImgResize.order_submit
+      ? store.state.imgPrefix + url + store.state.ossImgResize.order_submit
+      : store.state.ossImgResize.order_submit
+      break
+    default: url = store.state.imgPrefix + url
+    }
+  }
+  return url
+}

+ 71 - 0
src/utils/uploadImg.js

@@ -0,0 +1,71 @@
+import { getCdnToken } from '@/api/app'
+
+function S4 () {
+  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
+}
+
+function v4 () {
+  return S4() + '' + S4() + '' + S4() + '' + S4() + '' + S4() + '' + S4() + '' + S4() + '' + S4()
+}
+
+function uploadF (file) {
+  return new Promise(async resolve => {
+    const { data } = await getCdnToken({ dir: 'interest-eat-imgs' })
+    const newFilePath = v4() + '.' + file.split('.')[file.split('.').length - 1]
+    const uploadInfo = await new Promise(resolve => {
+      uni.showLoading({ title: '上传中...', mask: true })
+      uni.uploadFile({
+        url: (data.host.indexOf('https') === -1 ? 'https://' : '') + data.host,
+        filePath: file,
+        name: 'file',
+        formData: {
+          key: data.dir + '/' + newFilePath,
+          policy: data.policy,
+          OSSAccessKeyId: data.accessid,
+          signature: data.signature
+        },
+        complete: res => {
+          uni.hideLoading()
+          resolve(res)
+        }
+      })
+    })
+    let url = ''
+    if (uploadInfo.errMsg === 'uploadFile:ok') {
+      url = data.dir + '/' + newFilePath
+    } else {
+      console.log(uploadInfo.errMsg)
+      uni.showToast({
+        title: '上传失败',
+        icon: 'none'
+      })
+    }
+    resolve(url)
+  })
+}
+
+const upload = async function (count = 1) {
+  return new Promise(resolve => {
+    uni.chooseImage({
+      count,
+      success: async res => {
+        if (res.errMsg === 'chooseImage:ok') {
+          const urlArr = []
+          console.log(res)
+          for (const file of res.tempFilePaths) {
+            const url = await uploadF(file)
+            if (!url) { return }
+            urlArr.push({
+              url: url
+            })
+          }
+          resolve(urlArr)
+        } else {
+          resolve(false)
+        }
+      }
+    })
+  })
+}
+
+export default upload