refactor: 移动端代码合并

This commit is contained in:
fit2cloud-chenyw 2022-01-03 21:13:45 +08:00
parent a50c94fbd5
commit 9b15f26ccb
113 changed files with 8013 additions and 2 deletions

View File

@ -410,13 +410,13 @@
</move>
<copy todir="src/main/resources/static/de-app">
<fileset dir="../../dataease-app/dist/build/h5">
<fileset dir="../mobile/dist/build/h5">
<exclude name="*.html"/>
</fileset>
</copy>
<copy file="../../dataease-app/dist/build/h5/index.html" tofile="src/main/resources/templates/app.html" />
<copy file="../mobile/dist/build/h5/index.html" tofile="src/main/resources/templates/app.html" />
</target>

13
mobile/.env.development Normal file
View File

@ -0,0 +1,13 @@
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = 'http://localhost:8081/'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true

7
mobile/.env.production Normal file
View File

@ -0,0 +1,7 @@
# just a flag
ENV = 'production'
# base api
# VUE_APP_BASE_API = 'http://localhost:8081/'
VUE_APP_BASE_API = '/'

19
mobile/README.md Normal file
View File

@ -0,0 +1,19 @@
# dataease-mobile
## 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/).

63
mobile/babel.config.js Normal file
View File

@ -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
}

View File

5
mobile/dist/build/h5/index.html vendored Normal file
View File

@ -0,0 +1,5 @@
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><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="/de-app/static/index.a5c69d49.css"></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id="app"></div><script src="/de-app/static/js/chunk-vendors.2822c2ee.js"></script><script src="/de-app/static/js/index.12bd8b7a.js"></script></body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
mobile/dist/build/h5/static/about.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
mobile/dist/build/h5/static/dir.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
mobile/dist/build/h5/static/folder.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

BIN
mobile/dist/build/h5/static/home.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-index-index"],{"022a":function(t,n,a){"use strict";var e;a.d(n,"b",(function(){return i})),a.d(n,"c",(function(){return o})),a.d(n,"a",(function(){return e}));var i=function(){var t=this,n=t.$createElement,a=t._self._c||n;return a("v-uni-view",{staticClass:"content"},[a("v-uni-image",{staticClass:"logo",attrs:{src:"/static/logo.png"}}),a("v-uni-view",[a("v-uni-text",{staticClass:"title"},[t._v(t._s(t.title))])],1)],1)},o=[]},"0d9b":function(t,n,a){"use strict";a("7a82"),Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var e={data:function(){return{title:"Hello"}},onLoad:function(){},methods:{}};n.default=e},"10e7":function(t,n,a){var e=a("f40c");"string"===typeof e&&(e=[[t.i,e,""]]),e.locals&&(t.exports=e.locals);var i=a("4f06").default;i("096e183a",e,!0,{sourceMap:!1,shadowMode:!1})},"4cfc":function(t,n,a){"use strict";var e=a("10e7"),i=a.n(e);i.a},8069:function(t,n,a){"use strict";a.r(n);var e=a("0d9b"),i=a.n(e);for(var o in e)["default"].indexOf(o)<0&&function(t){a.d(n,t,(function(){return e[t]}))}(o);n["default"]=i.a},f40c:function(t,n,a){var e=a("4bad");n=e(!1),n.push([t.i,".content[data-v-3da995af]{display:flex;flex-direction:column;align-items:center;justify-content:center}.logo[data-v-3da995af]{height:%?200?%;width:%?200?%;margin:%?200?% auto %?50?% auto}.text-area[data-v-3da995af]{display:flex;justify-content:center}.title[data-v-3da995af]{font-size:%?36?%;color:#8f8f94}",""]),t.exports=n},f75a:function(t,n,a){"use strict";a.r(n);var e=a("022a"),i=a("8069");for(var o in i)["default"].indexOf(o)<0&&function(t){a.d(n,t,(function(){return i[t]}))}(o);a("4cfc");var c,r=a("f0c5"),u=Object(r["a"])(i["default"],e["b"],e["c"],!1,null,"3da995af",null,!1,e["a"],c);n["default"]=u.exports}}]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-dir-folder"],{"0336":function(t,e,i){"use strict";var n=i("2842"),a=i.n(n);a.a},"0878":function(t,e,i){var n=i("4bad");e=n(!1),e.push([t.i,"uni-image[data-v-7e90865b],\nuni-swiper[data-v-7e90865b],\n.img-view[data-v-7e90865b]{width:%?750?%;width:100%;height:%?500?%}.page-section-title[data-v-7e90865b]{margin-top:%?50?%}.dataease-main[data-v-7e90865b]{position:fixed;left:var(--window-left);right:var(--window-right);padding:5px;height:calc(100vh - 10px)}.swiper-box[data-v-7e90865b]{flex:1;margin-top:5px;background-color:#fff;height:calc(100vh - 60px)}.swiper-item[data-v-7e90865b]{flex:1;flex-direction:row}.person-title[data-v-7e90865b]{font-weight:700;font-size:15px;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.uni-list[data-v-7e90865b]{overflow-y:scroll;height:100%}",""]),t.exports=e},2842:function(t,e,i){var n=i("0878");"string"===typeof n&&(n=[[t.i,n,""]]),n.locals&&(t.exports=n.locals);var a=i("4f06").default;a("5e77a576",n,!0,{sourceMap:!1,shadowMode:!1})},"5cc7":function(t,e,i){"use strict";i.r(e);var n=i("c1d1"),a=i.n(n);for(var r in n)["default"].indexOf(r)<0&&function(t){i.d(e,t,(function(){return n[t]}))}(r);e["default"]=a.a},9247:function(t,e,i){"use strict";i.r(e);var n=i("af80"),a=i("5cc7");for(var r in a)["default"].indexOf(r)<0&&function(t){i.d(e,t,(function(){return a[t]}))}(r);i("0336");var o,u=i("f0c5"),s=Object(u["a"])(a["default"],n["b"],n["c"],!1,null,"7e90865b",null,!1,n["a"],o);e["default"]=s.exports},af80:function(t,e,i){"use strict";i.d(e,"b",(function(){return a})),i.d(e,"c",(function(){return r})),i.d(e,"a",(function(){return n}));var n={uniListItem:i("4c2b").default,uniList:i("7f33").default},a=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("v-uni-view",{staticClass:"page dataease-main"},[i("v-uni-view",[i("uni-list-item",{staticClass:"person-title",attrs:{title:t.banner.title}})],1),i("v-uni-swiper",{staticClass:"swiper-box",staticStyle:{flex:"1"},attrs:{duration:300}},[i("v-uni-swiper-item",{staticClass:"swiper-item"},[i("uni-list",t._l(t.nodes,(function(e,n){return i("uni-list-item",{key:n,attrs:{title:e.text,showArrow:"folder"===e.type,thumb:"folder"===e.type?"../../../static/folder.png":"../../../static/yibiaobans.png","thumb-size":"base",clickable:!0,rightText:""},on:{click:function(i){arguments[0]=i=t.$handleEvent(i),t.clickHandler(e)}}})})),1)],1)],1)],1)},r=[]},c1d1:function(t,e,i){"use strict";i("7a82"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,i("e9c4");var n=i("caf0"),a={data:function(){return{showSwiper:!1,imgUrls:["https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b4b60b10-5168-11eb-bd01-97bc1429a9ff.jpg","https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b1dcfa70-5168-11eb-bd01-97bc1429a9ff.jpg"],nodes:[],banner:{}}},onLoad:function(t){var e=this,i=t.detailDate||t.payload;try{this.banner=JSON.parse(decodeURIComponent(i))}catch(n){this.banner=JSON.parse(i)}uni.setNavigationBarTitle({title:this.banner.title}),setTimeout((function(){e.loadData(e.banner.id)}),350)},methods:{loadData:function(t){var e=this;t=t||"panel_list";var i={pid:t};(0,n.requestDir)(i).then((function(t){e.nodes=t.data})).catch((function(t){}))},clickHandler:function(t){var e={id:t.id,title:t.text,index:4};"panel"!==t.type?uni.navigateTo({url:"./folder?detailDate="+encodeURIComponent(JSON.stringify(e))}):uni.navigateTo({url:"../home/detail?detailDate="+encodeURIComponent(JSON.stringify(e))})}}};e.default=a},caf0:function(t,e,i){"use strict";i("7a82");var n=i("4ea4");Object.defineProperty(e,"__esModule",{value:!0}),e.linkInfo=s,e.requestDir=o,e.requestHome=r,e.requestMe=u,e.star=l,e.starStatus=f,e.switchLink=d,e.unstar=c;var a=n(i("6cbd"));function r(t){return(0,a.default)({url:"/mobile/home/query",method:"post",loading:!0,data:t})}function o(t){return(0,a.default)({url:"/mobile/dir/query",method:"post",loading:!0,data:t})}function u(){return(0,a.default)({url:"/mobile/me/query",method:"post",loading:!0})}function s(t){return(0,a.default)({url:"/api/link/currentGenerate/"+t,method:"post",loading:!0})}function d(t){return(0,a.default)({url:"/api/link/switchLink",method:"post",loading:!0,data:t})}function l(t){return(0,a.default)({url:"/api/store/"+t,method:"post",loading:!0})}function c(t){return(0,a.default)({url:"/api/store/remove/"+t,method:"post",loading:!0})}function f(t){return(0,a.default)({url:"/api/store/status/"+t,method:"post",loading:!0})}}}]);

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-dir-index"],{"1bd1":function(t,e,a){"use strict";a("7a82"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,a("e9c4");var n=a("caf0"),i={data:function(){return{showSwiper:!1,imgUrls:["https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b4b60b10-5168-11eb-bd01-97bc1429a9ff.jpg","https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b1dcfa70-5168-11eb-bd01-97bc1429a9ff.jpg"],nodes:[]}},onLoad:function(){var t=this;setTimeout((function(){t.loadData("panel_list")}),350)},onNavigationBarSearchInputClicked:function(t){uni.navigateTo({url:"./search"})},onPullDownRefresh:function(){this.loadData("panel_list")},methods:{loadData:function(t){var e=this;t=t||"panel_list";var a={pid:t};(0,n.requestDir)(a).then((function(t){e.nodes=t.data,uni.stopPullDownRefresh()})).catch((function(t){uni.stopPullDownRefresh()}))},clickHandler:function(t){var e={id:t.id,title:t.text,index:4};"panel"!==t.type?uni.navigateTo({url:"./folder?detailDate="+encodeURIComponent(JSON.stringify(e))}):uni.navigateTo({url:"../home/detail?detailDate="+encodeURIComponent(JSON.stringify(e))})}}};e.default=i},"3a57":function(t,e,a){"use strict";a.r(e);var n=a("ae5d"),i=a("dd01");for(var o in i)["default"].indexOf(o)<0&&function(t){a.d(e,t,(function(){return i[t]}))}(o);a("4ffa");var r,u=a("f0c5"),d=Object(u["a"])(i["default"],n["b"],n["c"],!1,null,"773a4c5a",null,!1,n["a"],r);e["default"]=d.exports},"4ffa":function(t,e,a){"use strict";var n=a("9884"),i=a.n(n);i.a},9884:function(t,e,a){var n=a("caa6");"string"===typeof n&&(n=[[t.i,n,""]]),n.locals&&(t.exports=n.locals);var i=a("4f06").default;i("781e9be4",n,!0,{sourceMap:!1,shadowMode:!1})},ae5d:function(t,e,a){"use strict";a.d(e,"b",(function(){return i})),a.d(e,"c",(function(){return o})),a.d(e,"a",(function(){return n}));var n={uniList:a("7f33").default,uniListItem:a("4c2b").default},i=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("v-uni-view",{staticClass:"page dataease-main"},[a("v-uni-swiper",{staticClass:"swiper-box",staticStyle:{flex:"1"},attrs:{duration:300}},[a("v-uni-swiper-item",{staticClass:"swiper-item"},[a("uni-list",t._l(t.nodes,(function(e,n){return a("uni-list-item",{key:n,attrs:{title:e.text,showArrow:"folder"===e.type,thumb:"folder"===e.type?"../../../static/folder.png":"../../../static/yibiaobans.png","thumb-size":"base",clickable:!0,rightText:""},on:{click:function(a){arguments[0]=a=t.$handleEvent(a),t.clickHandler(e)}}})})),1)],1)],1)],1)},o=[]},caa6:function(t,e,a){var n=a("4bad");e=n(!1),e.push([t.i,"uni-image[data-v-773a4c5a],\nuni-swiper[data-v-773a4c5a],\n.img-view[data-v-773a4c5a]{width:%?750?%;width:100%;height:%?500?%}.page-section-title[data-v-773a4c5a]{margin-top:%?50?%}.dataease-main[data-v-773a4c5a]{position:fixed;left:var(--window-left);right:var(--window-right);top:40px;padding:5px;height:calc(100vh - 90px)}.swiper-box[data-v-773a4c5a]{flex:1;background-color:#fff;height:calc(100vh - 100px)}.swiper-item[data-v-773a4c5a]{flex:1;flex-direction:row}.uni-list[data-v-773a4c5a]{overflow-y:scroll;height:calc(100vh - 100px)}",""]),t.exports=e},caf0:function(t,e,a){"use strict";a("7a82");var n=a("4ea4");Object.defineProperty(e,"__esModule",{value:!0}),e.linkInfo=d,e.requestDir=r,e.requestHome=o,e.requestMe=u,e.star=l,e.starStatus=f,e.switchLink=c,e.unstar=s;var i=n(a("6cbd"));function o(t){return(0,i.default)({url:"/mobile/home/query",method:"post",loading:!0,data:t})}function r(t){return(0,i.default)({url:"/mobile/dir/query",method:"post",loading:!0,data:t})}function u(){return(0,i.default)({url:"/mobile/me/query",method:"post",loading:!0})}function d(t){return(0,i.default)({url:"/api/link/currentGenerate/"+t,method:"post",loading:!0})}function c(t){return(0,i.default)({url:"/api/link/switchLink",method:"post",loading:!0,data:t})}function l(t){return(0,i.default)({url:"/api/store/"+t,method:"post",loading:!0})}function s(t){return(0,i.default)({url:"/api/store/remove/"+t,method:"post",loading:!0})}function f(t){return(0,i.default)({url:"/api/store/status/"+t,method:"post",loading:!0})}},dd01:function(t,e,a){"use strict";a.r(e);var n=a("1bd1"),i=a.n(n);for(var o in n)["default"].indexOf(o)<0&&function(t){a.d(e,t,(function(){return n[t]}))}(o);e["default"]=i.a}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-me-about"],{"0d5b":function(t,e,i){"use strict";i.d(e,"b",(function(){return a})),i.d(e,"c",(function(){return o})),i.d(e,"a",(function(){return n}));var n={uniList:i("7f33").default,uniListItem:i("4c2b").default},a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("v-uni-view",{staticClass:"page dataease-main"},[n("uni-list",[n("uni-list-item",{staticClass:"person-title",attrs:{title:t.$t("navigate.about")}})],1),n("v-uni-swiper",{staticClass:"swiper-box",staticStyle:{flex:"1"},attrs:{duration:300}},[n("v-uni-swiper-item",{staticClass:"swiper-item"},[n("v-uni-view",{staticClass:"uni-center",staticStyle:{"font-size":"0",padding:"40px 40px 20px"}},[n("v-uni-image",{staticClass:"image",attrs:{mode:"widthFix",src:i("2456")}})],1),n("v-uni-view",{staticClass:"person-lic"},["Enterprise"===t.license.edition?n("span",[t._v(t._s(t.$t("me.enterprise")))]):n("span",[t._v(t._s(t.$t("me.standard")))])]),n("v-uni-view",{staticClass:"person-lic"},[n("span",[t._v(t._s(t.build))])]),n("uni-list",[n("uni-list-item",{attrs:{clickable:!0,showArrow:!0,"thumb-size":"base",title:t.$t("me.userManual")},on:{click:function(e){arguments[0]=e=t.$handleEvent(e),t.toUserManual.apply(void 0,arguments)}}}),n("uni-list-item",{attrs:{clickable:!0,showArrow:!0,"thumb-size":"base",title:t.$t("me.community")},on:{click:function(e){arguments[0]=e=t.$handleEvent(e),t.toGithub.apply(void 0,arguments)}}})],1)],1)],1)],1)},o=[]},2456:function(t,e,i){t.exports=i.p+"static/img/DataEase-01.b9bf8897.png"},3786:function(t,e,i){"use strict";i("7a82");var n=i("4ea4");Object.defineProperty(e,"__esModule",{value:!0}),e.buildVersion=l,e.getInfo=s,e.getPublicKey=u,e.login=o,e.logout=r,e.validate=c;var a=n(i("6cbd"));function o(t){return(0,a.default)({url:"/api/auth/login",method:"post",data:t})}function s(){return(0,a.default)({url:"/api/auth/userInfo",method:"post"})}function r(){return(0,a.default)({url:"/api/auth/logout",method:"post"})}function u(){return(0,a.default)({url:"/api/auth/getPublicKey",method:"get"})}function l(){return(0,a.default)({url:"/about/build/version",method:"get"})}function c(t){return(0,a.default)({url:"/about/license/validate",method:"post",data:t})}},"4ba4":function(t,e,i){var n=i("4bad");e=n(!1),e.push([t.i,".dataease-main[data-v-d8a35a0a]{position:fixed;left:var(--window-left);right:var(--window-right);padding:5px;height:calc(100vh - 90px)}.swiper-box[data-v-d8a35a0a]{flex:1;margin-top:5px;background-color:#fff;height:calc(100vh - 60px)}.swiper-item[data-v-d8a35a0a]{flex:1;flex-direction:row}.person-title[data-v-d8a35a0a]{font-weight:700;font-size:15px;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.person-lic[data-v-d8a35a0a]{font-weight:500;font-size:15px;text-align:center;overflow:hidden;white-space:nowrap;height:50px;text-overflow:ellipsis;display:flex;align-items:center;justify-content:center}.image[data-v-d8a35a0a]{width:185px}",""]),t.exports=e},"56bb":function(t,e,i){"use strict";i("7a82"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,i("e9c4");var n=i("3786"),a={data:function(){return{build:null,license:{}}},onLoad:function(t){this.initVersion()},methods:{toGithub:function(){window.location.href="https://github.com/dataease/dataease"},toUserManual:function(){var t={linkIndex:1};uni.navigateTo({url:"./outlink?detailDate="+encodeURIComponent(JSON.stringify(t))})},initVersion:function(){var t=this;(0,n.buildVersion)().then((function(e){t.build=e.data}))},getLicenseInfo:function(){var t=this;this.validateHandler({},(function(e){t.license=t.getLicense(e.data)}))},validateHandler:function(t,e){(0,n.validate)(t).then(e)},getLicense:function(t){return{status:t.status,corporation:t.license?t.license.corporation:"",expired:t.license?t.license.expired:"",count:t.license?t.license.count:"",version:t.license?t.license.version:"",edition:t.license?t.license.edition:""}}}};e.default=a},"8f07":function(t,e,i){"use strict";var n=i("adad"),a=i.n(n);a.a},adad:function(t,e,i){var n=i("4ba4");"string"===typeof n&&(n=[[t.i,n,""]]),n.locals&&(t.exports=n.locals);var a=i("4f06").default;a("7fc56c93",n,!0,{sourceMap:!1,shadowMode:!1})},c835:function(t,e,i){"use strict";i.r(e);var n=i("0d5b"),a=i("c92e");for(var o in a)["default"].indexOf(o)<0&&function(t){i.d(e,t,(function(){return a[t]}))}(o);i("8f07");var s,r=i("f0c5"),u=Object(r["a"])(a["default"],n["b"],n["c"],!1,null,"d8a35a0a",null,!1,n["a"],s);e["default"]=u.exports},c92e:function(t,e,i){"use strict";i.r(e);var n=i("56bb"),a=i.n(n);for(var o in n)["default"].indexOf(o)<0&&function(t){i.d(e,t,(function(){return n[t]}))}(o);e["default"]=a.a}}]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-me-language"],{"42fd":function(t,e,a){"use strict";a.r(e);var i=a("d3ae"),n=a("bd01");for(var s in n)["default"].indexOf(s)<0&&function(t){a.d(e,t,(function(){return n[t]}))}(s);a("dcb9");var u,l=a("f0c5"),o=Object(l["a"])(n["default"],i["b"],i["c"],!1,null,"60aad5f0",null,!1,i["a"],u);e["default"]=o.exports},b09b:function(t,e,a){var i=a("cfe5");"string"===typeof i&&(i=[[t.i,i,""]]),i.locals&&(t.exports=i.locals);var n=a("4f06").default;n("f7311c76",i,!0,{sourceMap:!1,shadowMode:!1})},bd01:function(t,e,a){"use strict";a.r(e);var i=a("f1c6"),n=a.n(i);for(var s in i)["default"].indexOf(s)<0&&function(t){a.d(e,t,(function(){return i[t]}))}(s);e["default"]=n.a},cfe5:function(t,e,a){var i=a("4bad");e=i(!1),e.push([t.i,".dataease-main[data-v-60aad5f0]{position:fixed;left:var(--window-left);right:var(--window-right);padding:5px;height:calc(100vh - 90px)}.swiper-box[data-v-60aad5f0]{flex:1;margin-top:5px;background-color:#fff;height:calc(100vh - 60px)}.swiper-item[data-v-60aad5f0]{flex:1;flex-direction:row}.person-title[data-v-60aad5f0]{font-weight:700;font-size:15px;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}",""]),t.exports=e},d3ae:function(t,e,a){"use strict";a.d(e,"b",(function(){return n})),a.d(e,"c",(function(){return s})),a.d(e,"a",(function(){return i}));var i={uniList:a("7f33").default,uniListItem:a("4c2b").default},n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("v-uni-view",{staticClass:"page dataease-main"},[a("uni-list",[a("uni-list-item",{staticClass:"person-title",attrs:{title:t.$t("navigate.language")}})],1),a("v-uni-swiper",{staticClass:"swiper-box",staticStyle:{flex:"1"},attrs:{duration:300}},[a("v-uni-swiper-item",{staticClass:"swiper-item"},[a("v-uni-radio-group",{on:{change:function(e){arguments[0]=e=t.$handleEvent(e),t.radioChange.apply(void 0,arguments)}}},t._l(t.items,(function(e,i){return a("v-uni-label",{key:i,staticClass:"uni-list-cell uni-list-cell-pd"},[a("v-uni-view",[t._v(t._s(e.text))]),a("v-uni-view",[a("v-uni-radio",{attrs:{value:e.value,checked:e.value===t.language}})],1)],1)})),1)],1)],1)],1)},s=[]},dcb9:function(t,e,a){"use strict";var i=a("b09b"),n=a.n(i);n.a},f1c6:function(t,e,a){"use strict";a("7a82"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i=a("90b9"),n={data:function(){return{language:"sys"}},computed:{items:function(){return[{value:"sys",text:this.$t("commons.sysLanguage")},{value:"zh-Hans",text:this.$t("commons.zh")},{value:"zh-Hant",text:this.$t("commons.tw")},{value:"en",text:this.$t("commons.en")}]}},onLoad:function(t){this.language=(0,i.getLanguage)()},methods:{radioChange:function(t){if(this.language=t.detail.value,"sys"===t.detail.value){var e=uni.getLocale();uni.setLocale(e),this.$i18n.locale=e}else uni.setLocale(t.detail.value),this.$i18n.locale=t.detail.value;(0,i.setLanguage)(t.detail.value)}}};e.default=n}}]);

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-me-outlink"],{"240f":function(n,t,e){"use strict";var a;e.d(t,"b",(function(){return r})),e.d(t,"c",(function(){return u})),e.d(t,"a",(function(){return a}));var r=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("v-uni-view",[e("v-uni-web-view",{attrs:{src:n.urls[n.banner.linkIndex]}})],1)},u=[]},"4f58":function(n,t,e){"use strict";e.r(t);var a=e("240f"),r=e("d830");for(var u in r)["default"].indexOf(u)<0&&function(n){e.d(t,n,(function(){return r[n]}))}(u);var i,c=e("f0c5"),o=Object(c["a"])(r["default"],a["b"],a["c"],!1,null,null,null,!1,a["a"],i);t["default"]=o.exports},"90c3":function(n,t,e){"use strict";e("7a82"),Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a={data:function(){return{urls:["https://github.com/dataease/dataease","https://dataease.io/docs/user_manual/general/"],banner:{}}},onLoad:function(n){var t=n.detailDate||n.payload;try{this.banner=JSON.parse(decodeURIComponent(t))}catch(e){this.banner=JSON.parse(t)}}};t.default=a},d830:function(n,t,e){"use strict";e.r(t);var a=e("90c3"),r=e.n(a);for(var u in a)["default"].indexOf(u)<0&&function(n){e.d(t,n,(function(){return a[n]}))}(u);t["default"]=r.a}}]);

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-tabBar-me-person"],{"0121":function(t,e,i){"use strict";i.d(e,"b",(function(){return n})),i.d(e,"c",(function(){return r})),i.d(e,"a",(function(){return a}));var a={uniList:i("7f33").default,uniListItem:i("4c2b").default},n=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("v-uni-view",{staticClass:"page dataease-main"},[i("uni-list",[i("uni-list-item",{staticClass:"person-title",attrs:{title:t.$t("navigate.personInfo")}})],1),i("v-uni-swiper",{staticClass:"swiper-box",staticStyle:{flex:"1"},attrs:{duration:300}},[i("v-uni-swiper-item",{staticClass:"swiper-item"},[i("uni-list",[i("uni-list-item",{attrs:{title:t.$t("me.organization"),rightText:t.me.deptName}}),i("uni-list-item",{attrs:{title:t.$t("me.email"),rightText:t.user.email}}),i("uni-list-item",{attrs:{title:t.$t("me.createTime"),rightText:t.me.timeStr}})],1)],1)],1)],1)},r=[]},"293c":function(t,e,i){"use strict";i.r(e);var a=i("ba3d"),n=i.n(a);for(var r in a)["default"].indexOf(r)<0&&function(t){i.d(e,t,(function(){return a[t]}))}(r);e["default"]=n.a},"4f04":function(t,e,i){"use strict";i.r(e);var a=i("0121"),n=i("293c");for(var r in n)["default"].indexOf(r)<0&&function(t){i.d(e,t,(function(){return n[t]}))}(r);i("c386");var o,u=i("f0c5"),s=Object(u["a"])(n["default"],a["b"],a["c"],!1,null,"f14bf0c6",null,!1,a["a"],o);e["default"]=s.exports},5407:function(t,e,i){var a=i("4bad");e=a(!1),e.push([t.i,".dataease-main[data-v-f14bf0c6]{position:fixed;left:var(--window-left);right:var(--window-right);padding:5px;height:calc(100vh - 90px)}.swiper-box[data-v-f14bf0c6]{flex:1;margin-top:5px;background-color:#fff;height:calc(100vh - 60px)}.swiper-item[data-v-f14bf0c6]{flex:1;flex-direction:row}.person-title[data-v-f14bf0c6]{font-weight:700;font-size:15px;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}",""]),t.exports=e},"5d90":function(t,e,i){var a=i("5407");"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var n=i("4f06").default;n("7d4cbda6",a,!0,{sourceMap:!1,shadowMode:!1})},ba3d:function(t,e,i){"use strict";i("7a82"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var a=i("90b9"),n=i("caf0"),r={data:function(){return{user:null,me:{}}},created:function(){this.user=(0,a.getUserInfo)(),this.load()},onLoad:function(t){},methods:{load:function(){var t=this;(0,n.requestMe)().then((function(e){e.success&&e.data&&(t.me=e.data),t.me.createTime&&(t.me.timeStr=new Date(t.me.createTime).format("yyyy-MM-dd"))}))}}};e.default=r},c386:function(t,e,i){"use strict";var a=i("5d90"),n=i.n(a);n.a},caf0:function(t,e,i){"use strict";i("7a82");var a=i("4ea4");Object.defineProperty(e,"__esModule",{value:!0}),e.linkInfo=s,e.requestDir=o,e.requestHome=r,e.requestMe=u,e.star=d,e.starStatus=c,e.switchLink=l,e.unstar=f;var n=a(i("6cbd"));function r(t){return(0,n.default)({url:"/mobile/home/query",method:"post",loading:!0,data:t})}function o(t){return(0,n.default)({url:"/mobile/dir/query",method:"post",loading:!0,data:t})}function u(){return(0,n.default)({url:"/mobile/me/query",method:"post",loading:!0})}function s(t){return(0,n.default)({url:"/api/link/currentGenerate/"+t,method:"post",loading:!0})}function l(t){return(0,n.default)({url:"/api/link/switchLink",method:"post",loading:!0,data:t})}function d(t){return(0,n.default)({url:"/api/store/"+t,method:"post",loading:!0})}function f(t){return(0,n.default)({url:"/api/store/remove/"+t,method:"post",loading:!0})}function c(t){return(0,n.default)({url:"/api/store/status/"+t,method:"post",loading:!0})}}}]);

BIN
mobile/dist/build/h5/static/language.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

BIN
mobile/dist/build/h5/static/logo-bg.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

BIN
mobile/dist/build/h5/static/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
mobile/dist/build/h5/static/me.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
mobile/dist/build/h5/static/msg.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
mobile/dist/build/h5/static/uni.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
mobile/dist/build/h5/static/uni.ttf vendored Normal file

Binary file not shown.

BIN
mobile/dist/build/h5/static/user.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

102
mobile/package.json Normal file
View File

@ -0,0 +1,102 @@
{
"name": "dataease-mobile",
"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"
},
"dependencies": {
"@dcloudio/uni-app-plus": "^2.0.0-32920211029001",
"@dcloudio/uni-h5": "^2.0.0-32920211029001",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-i18n": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-360": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-alipay": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-baidu": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-kuaishou": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-qq": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-toutiao": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-vue": "^2.0.0-32920211029001",
"@dcloudio/uni-mp-weixin": "^2.0.0-32920211029001",
"@dcloudio/uni-quickapp-native": "^2.0.0-32920211029001",
"@dcloudio/uni-quickapp-webview": "^2.0.0-32920211029001",
"@dcloudio/uni-stat": "^2.0.0-32920211029001",
"@dcloudio/uni-ui": "^1.4.6",
"@vue/shared": "^3.0.0",
"axios": "^0.24.0",
"core-js": "^3.6.5",
"flyio": "^0.6.2",
"jsencrypt": "^3.2.1",
"regenerator-runtime": "^0.12.1",
"vue": "^2.6.11",
"vue-i18n": "^8.26.7",
"vuex": "^3.2.0"
},
"devDependencies": {
"@babel/runtime": "~7.12.0",
"@dcloudio/types": "*",
"@dcloudio/uni-automator": "^2.0.0-32920211029001",
"@dcloudio/uni-cli-i18n": "^2.0.0-32920211029001",
"@dcloudio/uni-cli-shared": "^2.0.0-32920211029001",
"@dcloudio/uni-migration": "^2.0.0-32920211029001",
"@dcloudio/uni-template-compiler": "^2.0.0-32920211029001",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-32920211029001",
"@dcloudio/vue-cli-plugin-uni": "^2.0.0-32920211029001",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-32920211029001",
"@dcloudio/webpack-uni-mp-loader": "^2.0.0-32920211029001",
"@dcloudio/webpack-uni-pages-loader": "^2.0.0-32920211029001",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.43.4",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"uni-app": {
"scripts": {}
}
}

64
mobile/pom.xml Normal file
View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dataease-server</artifactId>
<groupId>io.dataease</groupId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mobile</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<frontend-maven-plugin.version>1.9.1</frontend-maven-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<!-- See https://nodejs.org/en/download/ for latest node and npm (lts) versions -->
<nodeVersion>v15.12.0</nodeVersion>
<npmVersion>7.6.3</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<!-- Optional configuration which provides for running any npm command -->
<configuration>
<arguments>install --force</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

22
mobile/postcss.config.js Normal file
View File

@ -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
mobile/public/index.html Normal file
View File

@ -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>

17
mobile/src/App.vue Normal file
View File

@ -0,0 +1,17 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
</style>

45
mobile/src/api/auth.js Normal file
View File

@ -0,0 +1,45 @@
import request from '@/common/js/request'
export function login(data) {
return request({
url: '/api/auth/login',
method: 'post',
data
})
}
export function getInfo() {
return request({
url: '/api/auth/userInfo',
method: 'post'
})
}
export function logout() {
return request({
url: '/api/auth/logout',
method: 'post'
})
}
export function getPublicKey() {
return request({
url: '/api/auth/getPublicKey',
method: 'get'
})
}
export function buildVersion() {
return request({
url: '/about/build/version',
method: 'get'
})
}
export function validate(data) {
return request({
url: '/about/license/validate',
method: 'post',
data
})
}

69
mobile/src/api/panel.js Normal file
View File

@ -0,0 +1,69 @@
import request from '@/common/js/request'
export function requestHome(data) {
return request({
url: '/mobile/home/query',
method: 'post',
loading: true,
data
})
}
export function requestDir(data) {
return request({
url: '/mobile/dir/query',
method: 'post',
loading: true,
data
})
}
export function requestMe() {
return request({
url: '/mobile/me/query',
method: 'post',
loading: true
})
}
export function linkInfo(panelId) {
return request({
url: '/api/link/currentGenerate/'+panelId,
method: 'post',
loading: true
})
}
export function switchLink(data) {
return request({
url: '/api/link/switchLink',
method: 'post',
loading: true,
data
})
}
export function star(panelId) {
return request({
url: '/api/store/'+panelId,
method: 'post',
loading: true
})
}
export function unstar(panelId) {
return request({
url: '/api/store/remove/'+panelId,
method: 'post',
loading: true
})
}
export function starStatus(panelId) {
return request({
url: '/api/store/status/' + panelId,
method: 'post',
loading: true
})
}

View File

@ -0,0 +1,92 @@
import axios from 'axios'
import Config from '@/settings'
import { getToken, setToken, setUserInfo } from '@/common/utils'
const TokenKey = Config.TokenKey
const RefreshTokenKey = Config.RefreshTokenKey
const white_list = Config.WHITE_LIST
let service = axios.create({
// baseURL: 'http://localhost:8081',
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
// request interceptor
service.interceptors.request.use(
config => {
if (white_list.includes(config.url)) {
return config
}
let token = getToken()
if (token) {
config.headers[TokenKey] = token
}
else {
logout()
}
return config
},
error => {
return Promise.reject(error)
}
)
// 请根据实际需求修改
service.interceptors.response.use(response => {
checkAuth(response)
return response.data
}, error => {
checkAuth(error.response)
let msg
if (error.response) {
checkAuth(error.response)
msg = error.response.data.message || error.response.data
} else {
msg = error.message
}
uni.showToast({
icon: 'error',
title: msg
});
return Promise.reject(error)
})
const logout = () => {
setToken(null)
setUserInfo(null)
uni.reLaunch({
url: '/'
});
}
const checkAuth = response => {
if (response.headers['authentication-status'] === 'login_expire') {
uni.showToast({
icon: 'none',
title: 'token超时'
});
logout()
}
if (response.headers['authentication-status'] === 'invalid') {
uni.showToast({
icon: 'none',
title: 'token错误'
});
logout()
}
// token到期后自动续命 刷新token
// if (response.headers[RefreshTokenKey] && !interruptTokenContineUrls.some(item => response.config.url.indexOf(item) >= 0)) {
if (response.headers[RefreshTokenKey]) {
const refreshToken = response.headers[RefreshTokenKey]
setToken(refreshToken)
}
}
export default service

View File

@ -0,0 +1,2 @@
@import './uni.css';
@import './uni-nvue.css';

View File

@ -0,0 +1,135 @@
/* #ifndef APP-PLUS-NVUE */
page {
min-height: 100%;
height: auto;
}
/* #endif */
/* 解决头条小程序字体图标不显示问题因为头条运行时自动插入了span标签且有全局字体 */
/* #ifdef MP-TOUTIAO */
/* text :not(view) {
font-family: uniicons;
} */
/* #endif */
.uni-icon {
font-family: uniicons;
font-weight: normal;
}
.uni-header-logo {
/* #ifdef H5 */
display: flex;
/* #endif */
padding: 15px 15px;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 10rpx;
}
.uni-header-image {
width: 80px;
height: 80px;
}
.uni-hello-text {
margin-bottom: 20px;
}
.hello-text {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.hello-link {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.uni-panel {
margin-bottom: 12px;
}
.uni-panel-h {
/* #ifdef H5 */
display: flex;
/* #endif */
background-color: #ffffff;
flex-direction: row !important;
/* justify-content: space-between !important; */
align-items: center !important;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
/*
.uni-panel-h:active {
background-color: #efeff4;
}
*/
.uni-panel-h-on {
background-color: #f0f0f0;
}
.uni-panel-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-panel-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
transform: rotate(0deg);
transition-duration: 0s;
transition-property: transform;
}
.uni-panel-icon-on {
transform: rotate(180deg);
}
.uni-navigate-item {
/* #ifdef H5 */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
background-color: #FFFFFF;
border-top-style: solid;
border-top-color: #f0f0f0;
border-top-width: 1px;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navigate-item:active {
background-color: #efeff4;
}
.uni-navigate-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-navigate-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
}

File diff suppressed because it is too large Load Diff

145
mobile/src/common/utils.js Normal file
View File

@ -0,0 +1,145 @@
/* eslint-disable no-extend-native */
Date.prototype.format = function(fmt) {
var o = {
'M+': this.getMonth() + 1, // 月份
'd+': this.getDate(), // 日
'h+': this.getHours(), // 小时
'm+': this.getMinutes(), // 分
's+': this.getSeconds(), // 秒
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
'S': this.getMilliseconds() // 毫秒
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
}
}
return fmt
}
import Config from 'settings'
import JSEncrypt from 'jsencrypt/bin/jsencrypt'
export function getDeviceUUID() {
let deviceId = uni.getStorageSync('uni_deviceId') ||
uni.getSystemInfoSync().deviceId ||
uni.getSystemInfoSync().system + '_' + Math.random().toString(36).substr(2);
uni.setStorageSync('uni_deviceId', deviceId)
return deviceId;
}
export function encrypt(txt) {
const publicKey = getLocalPK()
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对需要加密的数据进行加密
}
export function getToken() {
return uni.getStorageSync(Config.TokenKey);
}
export function setToken(token) {
uni.setStorageSync(Config.TokenKey, token);
}
export function setLocalPK(data) {
uni.setStorageSync(Config.PUBLICKEY, data)
}
export function getLocalPK() {
return uni.getStorageSync(Config.PUBLICKEY)
}
export function getUserInfo() {
return uni.getStorageSync(Config.USER_INFO_KEY)
}
export function setUserInfo(data) {
return uni.setStorageSync(Config.USER_INFO_KEY, data)
}
export function addRecent(data) {
const userInfo = getUserInfo()
const key = Config.RECENT_KEY
const list = getRecent(key + userInfo.userId)
const len = list.length
let index = len
while(index-- > 0) {
if (list[index].id === data.id) {
list.splice(index, 1)
}
}
data.time = Date.now()
list.splice(0, 0, data)
list.splice(10, 100)
uni.setStorageSync(key + userInfo.userId, list);
}
export function getRecent() {
const userInfo = getUserInfo()
const key = Config.RECENT_KEY
const list = uni.getStorageSync(key + userInfo.userId)
return list || []
}
function isToday(time) {
return (new Date()).toDateString() === (new Date(time)).toDateString()
}
function isYestday(time) {
const date = new Date(time)
const yestday = new Date(Date.now() - 24 * 60 * 60 * 1000)
return date.getYear() === yestday.getYear() && date.getMonth() === yestday.getMonth() && date.getDate() === yestday.getDate()
}
function isCurrentYear(time) {
const date = new Date(time)
const cur = new Date()
return date.getYear() === cur.getYear()
}
export function formatHistoryDate(time) {
if(isToday(time)) {
return (new Date(time)).format('hh:mm')
}
if(isYestday(time)) {
return '昨天'
}
if (isCurrentYear(time)) {
return (new Date(time)).format('MM月dd日')
}
return (new Date(time)).format('yyyy年MM月dd日')
}
export function setLanguage(val) {
const userInfo = getUserInfo()
const key = 'my-language-'
uni.setStorageSync(key + userInfo.userId, val)
}
export function getLanguage() {
const userInfo = getUserInfo()
if(!userInfo || !userInfo.userId) return 'sys'
const key = 'my-language-'
const result = uni.getStorageSync(key + userInfo.userId)
if(!result) {
return 'sys'
}
return result
}
export function parseLanguage() {
const language = getLanguage()
if(language === 'sys') return uni.getLocale()
return language
}

View File

@ -0,0 +1,74 @@
<template>
<view class="uni-flex uni-column dataease-container uni-container">
<view class="text dataease-head">
<slot name="header"></slot>
</view>
<view class="text dataease-main">
<slot></slot>
</view>
</view>
</template>
<script>
// TODO 修复Android v3 加载过慢问题
// #ifdef APP-PLUS
var domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('/static/uni.ttf')"
});
// #endif
export default {
props: {
},
data() {
return {
}
},
onShareAppMessage() {
return {
title: '欢迎体验dataease-mobile',
path: '/pages/tabBar/home/index'
}
},
onNavigationBarButtonTap(e) {
uni.navigateTo({
url: '/pages/about/about'
});
},
// #ifdef H5
watch: {
},
// #endif
methods: {
}
}
</script>
<style>
.dataease-container {
position: relative;
height: 100%;
}
.dataease-head {
width: 100%;
height: 45px;
left: var(--window-left);
right: var(--window-right);
padding: 5px 5px 0;
border-radius: 6px;
}
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
top: 45px;
padding: 5px;
height: calc(100vh - 90px);
}
</style>

View File

@ -0,0 +1,181 @@
import amap from '@/components/amap-wx/lib/amap-wx.js';
// 地铁颜色图
const line = {
'1号线': '#C43B33',
'2号线': '#016299',
'4号线/大兴线': '#008E9C',
'5号线': '#A42380',
'6号线': '#D09900',
'7号线': '#F2C172',
'8号线': '#009D6A',
'9号线': '#8FC41E',
'10号线': '#009DBE',
'13号线': '#F9E701',
'14号线东段': '#D4A7A2',
'14号线西段': '#D4A7A2',
'15号线': '#5D2D69',
'八通线': '#C33A32',
'昌平线': '#DE82B1',
'亦庄线': '#E40177',
'房山线': '#E66021',
'机场线': '#A29BBC',
}
// 150500:地铁站 ,150700:公交站 , 190700:地名地址
const typecode = [{
id: '150500',
icon: 'icon-ditie'
}, {
id: '150700',
icon: 'icon-gongjiao'
}, {
id: '190700',
icon: 'icon-gonglu'
}];
const util = {
key:'b526b09b86cd2996e7732be8ab8c4430',
/**
* 初始化高德地图api
*/
mapInit() {
return new amap.AMapWX({
key: this.key
});
},
// 服务状态吗
typecode,
/**
* 获取地图颜色
*/
lineColor(name) {
if (line[name]) {
return line[name];
} else {
return '#ccc';
}
},
/**
* 关键字颜色变化
*/
serachNmme(val, name) {
let namestr = new RegExp(val);
let nameresult =
`<div style="font-size: 14px;color: #333;line-height: 1.5;">
${name.replace(namestr, "<span style='color:#66ccff;'>" + val + '</span>')}
</div>`
.trim();
return nameresult;
},
/**
* 地址转地铁线路
*/
addressToLine(address, type) {
let addr = address.split(';');
let dt = '';
addr.forEach(elm => {
let color = '#cccccc';
if (type === typecode[0].id) {
color = this.lineColor(elm)
} else if (type === typecode[1].id) {
color = '#4075cb'
}
let style = 'margin:5px 0;margin-right:5px;padding:0 5px;background:' + color +
';font-size:12px;color:#fff;border-radius:3px;';
dt += `<div style=\'${style}\'>${elm}</div>`;
});
return `<div style="display:flex;flex-wrap: wrap;">${dt}</div>`;
},
/**
* 数据处理
*/
dataHandle(item, val) {
// 改变字体颜色
if (val) {
item.nameNodes = util.serachNmme(val, item.name);
} else {
item.nameNodes = `<div style="font-size: 14px;color: #333;line-height: 1.5;">${item.name}</div>`;
}
// 地址解析 地铁
/* if (
item.typecode === util.typecode[0].id ||
item.typecode === util.typecode[1].id
) {
item.addressNodes = util.addressToLine(item.address, item.typecode);
if (item.typecode === util.typecode[0].id) {
item.icon = util.typecode[0].icon;
} else if (item.typecode === util.typecode[1].id) {
item.icon = util.typecode[1].icon;
}
} else {
item.addressNodes = `<span>${item.district}${
item.address.length > 0 ? '·' + item.address : ''
}</span>`.trim();
item.icon = 'icon-weizhi';
}
if (item.location && item.location.length === 0) {
item.icon = 'icon-sousuo';
} */
item.icon = 'icon-weizhi'
return item;
},
/**
* 存储历史数据
* val [string | object]需要存储的内容
*/
setHistory(val) {
let searchHistory = uni.getStorageSync('search:history');
if (!searchHistory) searchHistory = [];
let serachData = {};
if (typeof(val) === 'string') {
serachData = {
adcode: [],
address: [],
city: [],
district: [],
id: [],
location: [],
name: val,
typecode: []
};
} else {
serachData = val
}
// 判断数组是否存在,如果存在,那么将放到最前面
for (var i = 0; i < searchHistory.length; i++) {
if (searchHistory[i].name === serachData.name) {
searchHistory.splice(i, 1);
break;
}
}
searchHistory.unshift(util.dataHandle(serachData));
uni.setStorage({
key: 'search:history',
data: searchHistory,
success: function() {
// console.log('success');
}
});
},
getHistory() {
},
removeHistory() {
uni.removeStorage({
key: 'search:history',
success: function(res) {
console.log('success');
}
});
return []
}
}
export default util;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,378 @@
@font-face {
font-family: uniicons;
font-weight: normal;
font-style: normal;
src: url('/static/uni.ttf') format('truetype');
}
.m-icon {
font-family: uniicons;
/* font-size: 24px; */
margin-left: 20px;
font-weight: normal;
font-style: normal;
line-height: 1;
display: inline-block;
text-decoration: none;
-webkit-font-smoothing: antialiased;
}
.m-icon.uni-active {
color: #007aff;
}
.m-icon-contact:before {
content: '\e100';
}
.m-icon-person:before {
content: '\e101';
}
.m-icon-personadd:before {
content: '\e102';
}
.m-icon-contact-filled:before {
content: '\e130';
}
.m-icon-person-filled:before {
content: '\e131';
}
.m-icon-personadd-filled:before {
content: '\e132';
}
.m-icon-phone:before {
content: '\e200';
}
.m-icon-email:before {
content: '\e201';
}
.m-icon-chatbubble:before {
content: '\e202';
}
.m-icon-chatboxes:before {
content: '\e203';
}
.m-icon-phone-filled:before {
content: '\e230';
}
.m-icon-email-filled:before {
content: '\e231';
}
.m-icon-chatbubble-filled:before {
content: '\e232';
}
.m-icon-chatboxes-filled:before {
content: '\e233';
}
.m-icon-weibo:before {
content: '\e260';
}
.m-icon-weixin:before {
content: '\e261';
}
.m-icon-pengyouquan:before {
content: '\e262';
}
.m-icon-chat:before {
content: '\e263';
}
.m-icon-qq:before {
content: '\e264';
}
.m-icon-videocam:before {
content: '\e300';
}
.m-icon-camera:before {
content: '\e301';
}
.m-icon-mic:before {
content: '\e302';
}
.m-icon-location:before {
content: '\e303';
}
.m-icon-mic-filled:before,
.m-icon-speech:before {
content: '\e332';
}
.m-icon-location-filled:before {
content: '\e333';
}
.m-icon-micoff:before {
content: '\e360';
}
.m-icon-image:before {
content: '\e363';
}
.m-icon-map:before {
content: '\e364';
}
.m-icon-compose:before {
content: '\e400';
}
.m-icon-trash:before {
content: '\e401';
}
.m-icon-upload:before {
content: '\e402';
}
.m-icon-download:before {
content: '\e403';
}
.m-icon-close:before {
content: '\e404';
}
.m-icon-redo:before {
content: '\e405';
}
.m-icon-undo:before {
content: '\e406';
}
.m-icon-refresh:before {
content: '\e407';
}
.m-icon-star:before {
content: '\e408';
}
.m-icon-plus:before {
content: '\e409';
}
.m-icon-minus:before {
content: '\e410';
}
.m-icon-circle:before,
.m-icon-checkbox:before {
content: '\e411';
}
.m-icon-close-filled:before,
.m-icon-clear:before {
content: '\e434';
}
.m-icon-refresh-filled:before {
content: '\e437';
}
.m-icon-star-filled:before {
content: '\e438';
}
.m-icon-plus-filled:before {
content: '\e439';
}
.m-icon-minus-filled:before {
content: '\e440';
}
.m-icon-circle-filled:before {
content: '\e441';
}
.m-icon-checkbox-filled:before {
content: '\e442';
}
.m-icon-closeempty:before {
content: '\e460';
}
.m-icon-refreshempty:before {
content: '\e461';
}
.m-icon-reload:before {
content: '\e462';
}
.m-icon-starhalf:before {
content: '\e463';
}
.m-icon-spinner:before {
content: '\e464';
}
.m-icon-spinner-cycle:before {
content: '\e465';
}
.m-icon-search:before {
content: '\e466';
}
.m-icon-plusempty:before {
content: '\e468';
}
.m-icon-forward:before {
content: '\e470';
}
.m-icon-back:before,
.m-icon-left-nav:before {
content: '\e471';
}
.m-icon-checkmarkempty:before {
content: '\e472';
}
.m-icon-home:before {
content: '\e500';
}
.m-icon-navigate:before {
content: '\e501';
}
.m-icon-gear:before {
content: '\e502';
}
.m-icon-paperplane:before {
content: '\e503';
}
.m-icon-info:before {
content: '\e504';
}
.m-icon-help:before {
content: '\e505';
}
.m-icon-locked:before {
content: '\e506';
}
.m-icon-more:before {
content: '\e507';
}
.m-icon-flag:before {
content: '\e508';
}
.m-icon-home-filled:before {
content: '\e530';
}
.m-icon-gear-filled:before {
content: '\e532';
}
.m-icon-info-filled:before {
content: '\e534';
}
.m-icon-help-filled:before {
content: '\e535';
}
.m-icon-more-filled:before {
content: '\e537';
}
.m-icon-settings:before {
content: '\e560';
}
.m-icon-list:before {
content: '\e562';
}
.m-icon-bars:before {
content: '\e563';
}
.m-icon-loop:before {
content: '\e565';
}
.m-icon-paperclip:before {
content: '\e567';
}
.m-icon-eye:before {
content: '\e568';
}
.m-icon-arrowup:before {
content: '\e580';
}
.m-icon-arrowdown:before {
content: '\e581';
}
.m-icon-arrowleft:before {
content: '\e582';
}
.m-icon-arrowright:before {
content: '\e583';
}
.m-icon-arrowthinup:before {
content: '\e584';
}
.m-icon-arrowthindown:before {
content: '\e585';
}
.m-icon-arrowthinleft:before {
content: '\e586';
}
.m-icon-arrowthinright:before {
content: '\e587';
}
.m-icon-pulldown:before {
content: '\e588';
}
.m-icon-scan:before {
content: "\e612";
}

View File

@ -0,0 +1,23 @@
<template>
<view class="m-icon" :class="['m-icon-'+type]" @click="onClick()"></view>
</template>
<script>
export default {
props: {
/**
* 图标类型
*/
type: String
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style>
@import "./m-icon.css";
</style>

View File

@ -0,0 +1,125 @@
<template>
<view class="m-input-view">
<input :focus="focus" :type="inputType" :value="value" @input="onInput" class="m-input-input" :placeholder="placeholder"
:password="type==='password'&&!showPassword" @focus="onFocus" @blur="onBlur" />
<!-- 优先显示密码可见按钮 -->
<view v-if="clearable&&!displayable&&value.length" class="m-input-icon">
<m-icon color="#666666" type="clear" @click="clear"></m-icon>
</view>
<view v-if="displayable" class="m-input-icon">
<m-icon :style="{color:showPassword?'#666666':'#cccccc'}" type="eye" @click="display"></m-icon>
</view>
</view>
</template>
<script>
import mIcon from './m-icon/m-icon.vue'
export default {
components: {
mIcon
},
props: {
/**
* 输入类型
*/
type: String,
/**
*
*/
value: String,
/**
* 占位符
*/
placeholder: String,
/**
* 是否显示清除按钮
*/
clearable: {
type: [Boolean, String],
default: false
},
/**
* 是否显示密码可见按钮
*/
displayable: {
type: [Boolean, String],
default: false
},
/**
* 自动获取焦点
*/
focus: {
type: [Boolean, String],
default: false
}
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
/**
* 显示密码明文
*/
showPassword: false,
/**
* 是否获取焦点
*/
isFocus: false
}
},
computed: {
inputType() {
const type = this.type
return type === 'password' ? 'text' : type
}
},
methods: {
clear() {
this.$emit('input', '')
},
display() {
this.showPassword = !this.showPassword
},
onFocus() {
this.isFocus = true
},
onBlur() {
this.$nextTick(() => {
this.isFocus = false
})
},
onInput(e) {
this.$emit('input', e.detail.value)
}
}
}
</script>
<style>
.m-input-view {
display: inline-flex;
flex-direction: row;
align-items: center;
/* width: 100%; */
flex: 1;
padding: 0 10px;
}
.m-input-input {
flex: 1;
width: 100%;
height: 20px;
line-height: 20px;
background-color: rgba(0, 0, 0, 0);
}
.m-input-icon {
/* width: 20px; */
font-size: 20px;
line-height: 20px;
color: #666666;
}
</style>

View File

@ -0,0 +1,420 @@
<template>
<view class="uni-card uni-border" :class="{ 'uni-card--full': isFull === true || isFull === 'true', 'uni-card--shadow': isShadow === true || isShadow === 'true'}">
<!-- 基础 -->
<view v-if="mode === 'basic' && title" @click.stop="onClick" class="uni-card__head-padding">
<view class="uni-card__header uni-border-bottom">
<slot name="header">
<view v-if="thumbnail" class="uni-card__header-extra-img-view">
<image :src="thumbnail" class="uni-card__header-extra-img" />
</view>
<text class="uni-card__header-title-text">{{ title }}</text>
<text v-if="extra" class="uni-card__header-extra-text">{{ extra }}</text>
</slot>
</view>
</view>
<!-- 标题 -->
<view v-if="mode === 'title'" @click.stop="onClick" class="uni-card__head-padding">
<view class="uni-card__title uni-border-bottom">
<slot name="header">
<view class="uni-card__title-box">
<view v-if="thumbnail" class="uni-card__title-header">
<image class="uni-card__title-header-image" :src="thumbnail" mode="scaleToFill" />
</view>
<view class="uni-card__title-content">
<text class="uni-card__title-content-title uni-ellipsis">{{ title }}</text>
<text class="uni-card__title-content-extra uni-ellipsis">{{ subTitle }}</text>
</view>
</view>
<view v-if="extra">
<text class="uni-card__header-extra-text">{{ extra }}</text>
</view>
</slot>
</view>
</view>
<!-- 图文 -->
<view v-if="mode === 'style'" class="uni-card__thumbnailimage" @click.stop="onClick">
<view class="uni-card__thumbnailimage-box">
<image v-if="thumbnail" class="uni-card__thumbnailimage-image" :src="thumbnail" mode="aspectFill" />
<uni-icons v-if="!thumbnail" type="image" size="30" color="#999" />
</view>
<view v-if="title" class="uni-card__thumbnailimage-title">
<text class="uni-card__thumbnailimage-title-text">{{ title }}</text>
</view>
</view>
<!-- 内容 -->
<view class="uni-card__content uni-card__content--pd" @click.stop="onClick">
<view v-if="mode === 'style' && extra" class=""><text class="uni-card__content-extra">{{ extra }}</text>
</view>
<slot />
</view>
<!-- 底部 -->
<view v-if="note" class="uni-card__footer uni-border-top">
<slot name="footer">
<text class="uni-card__footer-text">{{ note }}</text>
</slot>
</view>
</view>
</template>
<script>
/**
* Card 卡片
* @description 卡片视图组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=22
* @property {String} title 标题文字
* @property {String} subTitle 副标题仅仅mode=title下生效
* @property {String} extra 标题额外信息
* @property {String} note 底部信息
* @property {String} thumbnail 标题左侧缩略图
* @property {String} mode = [basic|style|title] 卡片模式
* @value basic 基础卡片
* @value style 图文卡片
* @value title 标题卡片
* @property {Boolean} isFull = [true | false] 卡片内容是否通栏 true 时将去除padding值
* @property {Boolean} isShadow = [true | false] 卡片内容是否开启阴影
* @event {Function} click 点击 Card 触发事件
* @example <uni-card title="标题文字" thumbnail="xxx.jpg" extra="额外信息" note="Tips">内容主体可自定义内容及样式</uni-card>
*/
export default {
name: 'UniCard',
emits: ['click'],
props: {
title: {
type: String,
default: ''
},
subTitle: {
type: String,
default: ''
},
extra: {
type: String,
default: ''
},
note: {
type: String,
default: ''
},
thumbnail: {
type: String,
default: ''
},
mode: {
type: String,
default: 'basic'
},
isFull: {
//
type: Boolean,
default: false
},
isShadow: {
//
type: [Boolean, String],
default: false
}
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style scoped>
.uni-card {
/* #ifndef APP-NVUE */
display: flex;
flex: 1;
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
/* #endif */
margin: 12px 15px;
background-color: #ffffff;
position: relative;
flex-direction: column;
border-radius: 5px;
overflow: hidden;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-border {
position: relative;
/* #ifdef APP-NVUE */
border-color: #e5e5e5;
border-style: solid;
border-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border: 1px solid #e5e5e5;
border-radius: 10px;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-bottom {
position: relative;
/* #ifdef APP-NVUE */
border-bottom-color: #e5e5e5;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border-bottom:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-bottom: 1px solid #e5e5e5;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-border-top {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: #e5e5e5;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
z-index: 1;
}
/* #ifndef APP-NVUE */
.uni-border-top:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
border-top: 1px solid #e5e5e5;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
z-index: -1;
}
/* #endif */
.uni-card__thumbnailimage {
position: relative;
/* #ifndef APP-NVUE */
/* #endif */
flex-direction: column;
justify-content: center;
height: 150px;
background-color: #F1F1F1;
overflow: hidden;
}
.uni-card__thumbnailimage-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
height: 150px;
flex-direction: row;
justify-content: center;
align-items: center;
overflow: hidden;
}
.uni-card__thumbnailimage-image {
flex: 1;
}
.uni-card__thumbnailimage-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
position: absolute;
bottom: 0;
left: 0;
right: 0;
flex-direction: row;
padding: 8px 12px;
background-color: rgba(0, 0, 0, 0.4);
}
.uni-card__thumbnailimage-title-text {
flex: 1;
font-size: 14px;
color: #fff;
}
.uni-card__title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px;
}
.uni-card__title-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
overflow: hidden;
}
.uni-card__title-header {
width: 40px;
height: 40px;
overflow: hidden;
border-radius: 5px;
padding-right: 10px;
}
.uni-card__title-header-image {
width: 40px;
height: 40px;
}
.uni-card__title-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
flex: 1;
height: 40px;
overflow: hidden;
}
.uni-card__title-content-title {
font-size: 14px;
line-height: 22px;
}
.uni-card__title-content-extra {
font-size: 12px;
line-height: 27px;
color: #999;
}
.uni-card__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
position: relative;
flex-direction: row;
padding: 12px;
align-items: center;
}
.uni-card__header-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
margin-right: 8px;
justify-content: flex-start;
align-items: center;
}
.uni-card__header-title-text {
font-size: 16px;
flex: 1;
color: #333;
}
.uni-card__header-extra-img {
height: 20px;
width: 20px;
margin-right: 8px;
}
.uni-card__header-extra-text {
flex: 1;
margin-left: 8px;
font-size: 12px;
text-align: right;
color: #999;
}
.uni-card__content {
color: #333;
}
.uni-card__content--pd {
padding: 12px;
}
.uni-card__content-extra {
font-size: 14px;
padding-bottom: 10px;
color: #999;
}
.uni-card__footer {
justify-content: space-between;
padding: 12px;
}
.uni-card__footer-text {
color: #999;
font-size: 12px;
}
.uni-card--shadow {
position: relative;
/* #ifndef APP-NVUE */
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1);
/* #endif */
}
.uni-card--full {
margin: 0;
border-radius: 0;
}
/* #ifndef APP-NVUE */
.uni-card--full:after {
border-radius: 0;
}
/* #endif */
.uni-ellipsis {
/* #ifndef APP-NVUE */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
}
</style>

View File

@ -0,0 +1,132 @@
export default {
"pulldown": "\ue588",
"refreshempty": "\ue461",
"back": "\ue471",
"forward": "\ue470",
"more": "\ue507",
"more-filled": "\ue537",
"scan": "\ue612",
"qq": "\ue264",
"weibo": "\ue260",
"weixin": "\ue261",
"pengyouquan": "\ue262",
"loop": "\ue565",
"refresh": "\ue407",
"refresh-filled": "\ue437",
"arrowthindown": "\ue585",
"arrowthinleft": "\ue586",
"arrowthinright": "\ue587",
"arrowthinup": "\ue584",
"undo-filled": "\ue7d6",
"undo": "\ue406",
"redo": "\ue405",
"redo-filled": "\ue7d9",
"bars": "\ue563",
"chatboxes": "\ue203",
"camera": "\ue301",
"chatboxes-filled": "\ue233",
"camera-filled": "\ue7ef",
"cart-filled": "\ue7f4",
"cart": "\ue7f5",
"checkbox-filled": "\ue442",
"checkbox": "\ue7fa",
"arrowleft": "\ue582",
"arrowdown": "\ue581",
"arrowright": "\ue583",
"smallcircle-filled": "\ue801",
"arrowup": "\ue580",
"circle": "\ue411",
"eye-filled": "\ue568",
"eye-slash-filled": "\ue822",
"eye-slash": "\ue823",
"eye": "\ue824",
"flag-filled": "\ue825",
"flag": "\ue508",
"gear-filled": "\ue532",
"reload": "\ue462",
"gear": "\ue502",
"hand-thumbsdown-filled": "\ue83b",
"hand-thumbsdown": "\ue83c",
"hand-thumbsup-filled": "\ue83d",
"heart-filled": "\ue83e",
"hand-thumbsup": "\ue83f",
"heart": "\ue840",
"home": "\ue500",
"info": "\ue504",
"home-filled": "\ue530",
"info-filled": "\ue534",
"circle-filled": "\ue441",
"chat-filled": "\ue847",
"chat": "\ue263",
"mail-open-filled": "\ue84d",
"email-filled": "\ue231",
"mail-open": "\ue84e",
"email": "\ue201",
"checkmarkempty": "\ue472",
"list": "\ue562",
"locked-filled": "\ue856",
"locked": "\ue506",
"map-filled": "\ue85c",
"map-pin": "\ue85e",
"map-pin-ellipse": "\ue864",
"map": "\ue364",
"minus-filled": "\ue440",
"mic-filled": "\ue332",
"minus": "\ue410",
"micoff": "\ue360",
"mic": "\ue302",
"clear": "\ue434",
"smallcircle": "\ue868",
"close": "\ue404",
"closeempty": "\ue460",
"paperclip": "\ue567",
"paperplane": "\ue503",
"paperplane-filled": "\ue86e",
"person-filled": "\ue131",
"contact-filled": "\ue130",
"person": "\ue101",
"contact": "\ue100",
"images-filled": "\ue87a",
"phone": "\ue200",
"images": "\ue87b",
"image": "\ue363",
"image-filled": "\ue877",
"location-filled": "\ue333",
"location": "\ue303",
"plus-filled": "\ue439",
"plus": "\ue409",
"plusempty": "\ue468",
"help-filled": "\ue535",
"help": "\ue505",
"navigate-filled": "\ue884",
"navigate": "\ue501",
"mic-slash-filled": "\ue892",
"search": "\ue466",
"settings": "\ue560",
"sound": "\ue590",
"sound-filled": "\ue8a1",
"spinner-cycle": "\ue465",
"download-filled": "\ue8a4",
"personadd-filled": "\ue132",
"videocam-filled": "\ue8af",
"personadd": "\ue102",
"upload": "\ue402",
"upload-filled": "\ue8b1",
"starhalf": "\ue463",
"star-filled": "\ue438",
"star": "\ue408",
"trash": "\ue401",
"phone-filled": "\ue230",
"compose": "\ue400",
"videocam": "\ue300",
"trash-filled": "\ue8dc",
"download": "\ue403",
"chatbubble-filled": "\ue232",
"chatbubble": "\ue202",
"cloud-download": "\ue8e4",
"cloud-upload-filled": "\ue8e5",
"cloud-upload": "\ue8e6",
"cloud-download-filled": "\ue8e9",
"headphones":"\ue8bf",
"shop":"\ue609"
}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,128 @@
<template>
<a v-if="isShowA" class="uni-link" :href="href"
:class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" :download="download">
<slot>{{text}}</slot>
</a>
<!-- #ifndef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
<slot>{{text}}</slot>
</text>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
{{text}}
</text>
<!-- #endif -->
</template>
<script>
/**
* Link 外部网页超链接组件
* @description uni-link是一个外部网页超链接组件在小程序内复制url在app内打开外部浏览器在h5端打开新网页
* @tutorial https://ext.dcloud.net.cn/plugin?id=1182
* @property {String} href 点击后打开的外部网页url
* @property {String} text 显示的文字
* @property {String} downlaod H5平台下载文件名
* @property {Boolean} showUnderLine 是否显示下划线
* @property {String} copyTips 在小程序端复制链接时显示的提示语
* @property {String} color 链接文字颜色
* @property {String} fontSize 链接文字大小
* @example * <uni-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn"></uni-link>
*/
export default {
name: 'uniLink',
props: {
href: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
download: {
type: String,
default: ''
},
showUnderLine: {
type: [Boolean, String],
default: true
},
copyTips: {
type: String,
default: '已自动复制网址,请在手机浏览器里粘贴该网址'
},
color: {
type: String,
default: '#999999'
},
fontSize: {
type: [Number, String],
default: 14
}
},
computed: {
isShowA() {
// #ifdef H5
this._isH5 = true;
// #endif
if ((this.isMail() || this.isTel()) && this._isH5 === true) {
return true;
}
return false;
}
},
created() {
this._isH5 = null;
},
methods: {
isMail() {
return this.href.startsWith('mailto:');
},
isTel() {
return this.href.startsWith('tel:');
},
openURL() {
// #ifdef APP-PLUS
if (this.isTel()) {
this.makePhoneCall(this.href.replace('tel:', ''));
} else {
plus.runtime.openURL(this.href);
}
// #endif
// #ifdef H5
window.open(this.href)
// #endif
// #ifdef MP
uni.setClipboardData({
data: this.href
});
uni.showModal({
content: this.copyTips,
showCancel: false
});
// #endif
},
makePhoneCall(phoneNumber) {
uni.makePhoneCall({
phoneNumber
})
}
}
}
</script>
<style>
/* #ifndef APP-NVUE */
.uni-link {
cursor: pointer;
}
/* #endif */
.uni-link--withline {
text-decoration: underline;
}
</style>

View File

@ -0,0 +1,443 @@
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view :class="{ 'uni-list-item--disabled': disabled }" :hover-class="(!clickable && !link) || disabled || showSwitch ? '' : 'uni-list-item--hover'" class="uni-list-item" @click="onClick">
<view v-if="!isFirstChild" class="border--left" :class="{ 'uni-list--border': border }"></view>
<view class="uni-list-item__container" :class="{ 'container--right': showArrow || link, 'flex--direction': direction === 'column' }">
<slot name="header">
<view class="uni-list-item__header">
<view v-if="thumb" class="uni-list-item__icon">
<image :src="thumb" class="uni-list-item__icon-img" :class="['uni-list--' + thumbSize]" />
</view>
<view v-else-if="showExtraIcon" class="uni-list-item__icon">
<uni-icons :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" />
</view>
</view>
</slot>
<slot name="body">
<view class="uni-list-item__content" :class="{ 'uni-list-item__content--center': thumb || showExtraIcon || showBadge || showSwitch }">
<text v-if="title" class="uni-list-item__content-title" :class="[ellipsis !== 0 && ellipsis <= 2 ? 'uni-ellipsis-' + ellipsis : '']">{{ title }}</text>
<text v-if="note" class="uni-list-item__content-note">{{ note }}</text>
</view>
</slot>
<slot name="footer">
<view v-if="rightText || showBadge || showSwitch" class="uni-list-item__extra" :class="{ 'flex--justify': direction === 'column' }">
<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text>
<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" />
<switch v-if="showSwitch" :disabled="disabled" :checked="switchChecked" @change="onSwitchChange" />
</view>
</slot>
</view>
<uni-icons v-if="showArrow || link" :size="16" class="uni-icon-wrapper" color="#bbb" type="arrowright" />
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
/**
* ListItem 列表子组件
* @description 列表子组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} title 标题
* @property {String} note 描述
* @property {String} thumb 左侧缩略图若thumb有值则不会显示扩展图标
* @property {String} thumbSize = [lg|base|sm] 略缩图大小
* @value lg 大图
* @value base 一般
* @value sm 小图
* @property {String} badgeText 数字角标内容
* @property {String} badgeType 数字角标类型参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
* @property {String} rightText 右侧文字内容
* @property {Boolean} disabled = [true|false] 是否禁用
* @property {Boolean} clickable = [true|false] 是否开启点击反馈
* @property {String} link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈
* @value navigateTo uni.navigateTo()
* @value redirectTo uni.redirectTo()
* @value reLaunch uni.reLaunch()
* @value switchTab uni.switchTab()
* @property {String | PageURIString} to 跳转目标页面
* @property {Boolean} showBadge = [true|false] 是否显示数字角标
* @property {Boolean} showSwitch = [true|false] 是否显示Switch
* @property {Boolean} switchChecked = [true|false] Switch是否被选中
* @property {Boolean} showExtraIcon = [true|false] 左侧是否显示扩展图标
* @property {Object} extraIcon 扩展图标参数格式为 {color: '#4cd964',size: '22',type: 'spinner'}
* @property {String} direction = [row|column] 排版方向
* @value row 水平排列
* @value column 垂直排列
* @event {Function} click 点击 uniListItem 触发事件
* @event {Function} switchChange 点击切换 Switch 时触发
*/
export default {
name: 'UniListItem',
emits: ['click', 'switchChange'],
props: {
direction: {
type: String,
default: 'row'
},
title: {
type: String,
default: ''
},
note: {
type: String,
default: ''
},
ellipsis: {
type: [Number],
default: 0
},
disabled: {
type: [Boolean, String],
default: false
},
clickable: {
type: Boolean,
default: false
},
showArrow: {
type: [Boolean, String],
default: false
},
link: {
type: [Boolean, String],
default: false
},
to: {
type: String,
default: ''
},
showBadge: {
type: [Boolean, String],
default: false
},
showSwitch: {
type: [Boolean, String],
default: false
},
switchChecked: {
type: [Boolean, String],
default: false
},
badgeText: {
type: String,
default: ''
},
badgeType: {
type: String,
default: 'success'
},
rightText: {
type: String,
default: ''
},
thumb: {
type: String,
default: ''
},
thumbSize: {
type: String,
default: 'base'
},
showExtraIcon: {
type: [Boolean, String],
default: false
},
extraIcon: {
type: Object,
default () {
return {
type: 'contact',
color: '#000000',
size: 20
};
}
},
border: {
type: Boolean,
default: true
}
},
// inject: ['list'],
data() {
return {
isFirstChild: false
};
},
mounted() {
this.list = this.getForm()
// uni-list
if (this.list) {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true;
this.isFirstChild = true;
}
}
},
methods: {
/**
* 获取父元素实例
*/
getForm(name = 'uniList') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
onClick() {
if (this.to !== '') {
this.openPage();
return;
}
if (this.clickable || this.link) {
this.$emit('click', {
data: {}
});
}
},
onSwitchChange(e) {
this.$emit('switchChange', e.detail);
},
openPage() {
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
this.pageApi(this.link);
} else {
this.pageApi('navigateTo');
}
},
pageApi(api) {
let callback = {
url: this.to,
success: res => {
this.$emit('click', {
data: res
});
},
fail: err => {
this.$emit('click', {
data: err
});
}
}
switch (api) {
case 'navigateTo':
uni.navigateTo(callback)
break
case 'redirectTo':
uni.redirectTo(callback)
break
case 'reLaunch':
uni.reLaunch(callback)
break
case 'switchTab':
uni.switchTab(callback)
break
default:
uni.navigateTo(callback)
}
}
}
};
</script>
<style scoped>
.uni-list-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
font-size: 16px;
position: relative;
justify-content: space-between;
align-items: center;
background-color: #fff;
flex-direction: row;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-list-item--disabled {
opacity: 0.3;
}
.uni-list-item--hover {
background-color: #f1f1f1;
}
.uni-list-item__container {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 12px 15px;
padding-left: 15px;
flex: 1;
overflow: hidden;
}
.container--right {
padding-right: 0;
}
.uni-list--border {
position: absolute;
top: 0;
right: 0;
left: 0;
/* #ifdef APP-NVUE */
border-top-color: #e5e5e5;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
}
/* #ifndef APP-NVUE */
.uni-list--border:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: "";
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: #e5e5e5;
}
/* #endif */
.uni-list-item__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding-right: 8px;
flex: 1;
color: #3b4144;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.uni-list-item__content--center {
justify-content: center;
}
.uni-list-item__content-title {
font-size: 14px;
color: #3b4144;
overflow: hidden;
}
.uni-list-item__content-note {
margin-top: 6rpx;
color: #999;
font-size: 12px;
overflow: hidden;
}
.uni-list-item__extra {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.uni-list-item__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.uni-list-item__icon {
margin-right: 18rpx;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-list-item__icon-img {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
height: 26px;
width: 26px;
margin-right: 10px;
}
.uni-icon-wrapper {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
padding: 0 10px;
}
.flex--direction {
flex-direction: column;
/* #ifndef APP-NVUE */
align-items: initial;
/* #endif */
}
.flex--justify {
/* #ifndef APP-NVUE */
justify-content: initial;
/* #endif */
}
.uni-list--lg {
height: 40px;
width: 40px;
}
.uni-list--base {
height: 26px;
width: 26px;
}
.uni-list--sm {
height: 20px;
width: 20px;
}
.uni-list-item__extra-text {
color: #999;
font-size: 12px;
}
.uni-ellipsis-1 {
/* #ifndef APP-NVUE */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
}
.uni-ellipsis-2 {
/* #ifndef APP-NVUE */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
/* #endif */
/* #ifdef APP-NVUE */
lines: 2;
/* #endif */
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<!-- #ifndef APP-NVUE -->
<view class="uni-list uni-border-top-bottom">
<view v-if="border" class="uni-list--border-top"></view>
<slot />
<view v-if="border" class="uni-list--border-bottom"></view>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<list class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop" loadmoreoffset="15">
<slot />
</list>
<!-- #endif -->
</template>
<script>
/**
* List 列表
* @description 列表组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} border = [true|false] 标题
*/
export default {
name: 'uniList',
'mp-weixin': {
options: {
multipleSlots: false
}
},
props: {
enableBackToTop: {
type: [Boolean, String],
default: false
},
scrollY: {
type: [Boolean, String],
default: false
},
border: {
type: Boolean,
default: true
}
},
// provide() {
// return {
// list: this
// };
// },
created() {
this.firstChildAppend = false;
},
methods: {
loadMore(e) {
this.$emit('scrolltolower');
}
}
};
</script>
<style scoped>
.uni-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
background-color: #ffffff;
position: relative;
flex-direction: column;
}
.uni-list--border {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: #e5e5e5;
border-top-style: solid;
border-top-width: 0.5px;
border-bottom-color: #e5e5e5;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: -1;
}
/* #ifndef APP-NVUE */
.uni-list--border-top {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: #e5e5e5;
z-index: 1;
}
.uni-list--border-bottom {
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: #e5e5e5;
}
/* #endif */
</style>

View File

@ -0,0 +1,65 @@
<template>
<!-- #ifdef APP-NVUE -->
<refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown">
<slot />
</refresh>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view ref="uni-refresh" class="uni-refresh" v-show="isShow">
<slot />
</view>
<!-- #endif -->
</template>
<script>
export default {
name: 'UniRefresh',
props: {
display: {
type: [String],
default: "hide"
}
},
data() {
return {
pulling: false
}
},
computed: {
isShow() {
if (this.display === "show" || this.pulling === true) {
return true;
}
return false;
}
},
created() {},
methods: {
onchange(value) {
this.pulling = value;
},
onrefresh(e) {
this.$emit("refresh", e);
},
onpullingdown(e) {
// #ifdef APP-NVUE
this.$emit("pullingdown", e);
// #endif
// #ifndef APP-NVUE
var detail = {
viewHeight: 90,
pullingDistance: e.height
}
this.$emit("pullingdown", detail);
// #endif
}
}
}
</script>
<style scoped>
.uni-refresh {
height: 0;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,87 @@
var pullDown = {
threshold: 95,
maxHeight: 200,
callRefresh: 'onrefresh',
callPullingDown: 'onpullingdown',
refreshSelector: '.uni-refresh'
};
function ready(newValue, oldValue, ownerInstance, instance) {
var state = instance.getState()
state.canPullDown = newValue;
// console.log(newValue);
}
function touchStart(e, instance) {
var state = instance.getState();
state.refreshInstance = instance.selectComponent(pullDown.refreshSelector);
state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined);
if (!state.canPullDown) {
return
}
// console.log("touchStart");
state.height = 0;
state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY;
state.refreshInstance.setStyle({
'height': 0
});
state.refreshInstance.callMethod("onchange", true);
}
function touchMove(e, ownerInstance) {
var instance = e.instance;
var state = instance.getState();
if (!state.canPullDown) {
return
}
var oldHeight = state.height;
var endY = e.touches[0].pageY || e.changedTouches[0].pageY;
var height = endY - state.touchStartY;
if (height > pullDown.maxHeight) {
return;
}
var refreshInstance = state.refreshInstance;
refreshInstance.setStyle({
'height': height + 'px'
});
height = height < pullDown.maxHeight ? height : pullDown.maxHeight;
state.height = height;
refreshInstance.callMethod(pullDown.callPullingDown, {
height: height
});
}
function touchEnd(e, ownerInstance) {
var state = e.instance.getState();
if (!state.canPullDown) {
return
}
state.refreshInstance.callMethod("onchange", false);
var refreshInstance = state.refreshInstance;
if (state.height > pullDown.threshold) {
refreshInstance.callMethod(pullDown.callRefresh);
return;
}
refreshInstance.setStyle({
'height': 0
});
}
function propObserver(newValue, oldValue, instance) {
pullDown = newValue;
}
module.exports = {
touchmove: touchMove,
touchstart: touchStart,
touchend: touchEnd,
propObserver: propObserver
}

64
mobile/src/locale/en.json Normal file
View File

@ -0,0 +1,64 @@
{
"app.name": "DataEase",
"navigate.menuHome": "Home",
"navigate.menuDir": "Dir",
"navigate.menuMe": "Me",
"navigate.search": "Search",
"navigate.personInfo": "Person Info",
"navigate.language": "Language",
"navigate.about": "About",
"navigate.login": "Login",
"searchPlaceholder": "Please Code Panel Name",
"commons": {
"cancel": "Cancel",
"sure": "Sure",
"en": "English",
"tw": "繁體中文",
"zh": "简体中文",
"sysLanguage": "Follow System",
"tips": "Tips"
},
"login": {
"title": "User Login",
"account": "Account:",
"accountPlaceholder": "Please Code Account",
"password": "Password:",
"passwordPlaceholder": "Please Code Password:",
"loginbtn": "Login",
"pwdFmtError": "Password Must More Than 6 Character",
"uOrpwdError": "Invalid Account Or Password"
},
"home": {
"tab1": "My Favorites",
"tab2": "Recent",
"tab3": "Share With Me"
},
"dir": {
"searchHistory": "Search History",
"clearConfirm": "Sure Clean All History ?",
"noHistory": "There Are No Any History",
"contentPrefix": "The Content You Code Are ",
"contentSuffix": "Will Be Marked As History When You Confirm"
},
"me": {
"moreInfo": "More Info",
"logout": "Logout",
"systemInfo": "System Info",
"userManual": "User Manual",
"community": "Community",
"enterprise": "Enterprise",
"standard": "Standard",
"organization": "Organization",
"email": "Email",
"createTime": "CreateTime"
},
"detail": {
"starSuccess": "Star Success"
}
}

View File

@ -0,0 +1,64 @@
{
"app.name": "Hello uni-app",
"navigate.menuHome": "首页",
"navigate.menuDir": "目录",
"navigate.menuMe": "我的",
"navigate.search": "搜索",
"navigate.personInfo": "个人信息",
"navigate.language": "语言",
"navigate.about": "关于",
"navigate.login": "登录",
"searchPlaceholder": "请输入仪表板名称",
"commons": {
"cancel": "取消",
"sure": "确定",
"en": "English",
"tw": "繁體中文",
"zh": "简体中文",
"sysLanguage": "跟随系统",
"tips": "提示"
},
"login": {
"title": "用户登录",
"account": "账号:",
"accountPlaceholder": "请输入账号",
"password": "密码:",
"passwordPlaceholder": "请输入密码",
"loginbtn": "登录",
"pwdFmtError": "密码最短为6个字符",
"uOrpwdError": "无效账号或密码"
},
"home": {
"tab1": "我的收藏",
"tab2": "最近浏览",
"tab3": "分享给我"
},
"dir": {
"searchPlaceholder": "请输入仪表板名称",
"searchHistory": "搜索历史",
"clearConfirm": "确定清除全部历史记录?",
"noHistory": "您还没有历史记录",
"contentPrefix": "您输入的内容为 ",
"contentSuffix": " 如果点击确定,将记录到历史搜索,并返回.如果取消不做操作"
},
"me": {
"moreInfo": "更多信息",
"logout": "注销",
"systemInfo": "系统信息",
"userManual": "用户手册",
"community": "社区",
"enterprise": "企业版",
"standard": "标准版",
"organization": "组织",
"email": "邮箱",
"createTime": "创建时间"
},
"detail": {
"starSuccess": "收藏成功"
}
}

View File

@ -0,0 +1,64 @@
{
"app.name": "Hello uni-app",
"navigate.menuHome": "首頁",
"navigate.menuDir": "目錄",
"navigate.menuMe": "我的",
"navigate.search": "搜索",
"navigate.personInfo": "個人信息",
"navigate.language": "語言",
"navigate.about": "關於",
"navigate.login": "登錄",
"searchPlaceholder": "請輸入儀表板名稱",
"commons": {
"cancel": "取消",
"sure": "確定",
"en": "English",
"tw": "繁體中文",
"zh": "简体中文",
"sysLanguage": "跟隨系統",
"tips": "提示"
},
"login": {
"title": "用戶登錄",
"account": "帳號:",
"accountPlaceholder": "請輸入帳號",
"password": "密碼:",
"passwordPlaceholder": "請輸入密碼",
"loginbtn": "登錄",
"pwdFmtError": "密碼最短為6個字符",
"uOrpwdError": "無效賬號或密碼"
},
"home": {
"tab1": "我的收藏",
"tab2": "最近瀏覽",
"tab3": "分享給我"
},
"dir": {
"searchPlaceholder": "請輸入儀表板名稱",
"searchHistory": "搜索歷史",
"clearConfirm": "確定清除全部歷史記錄?",
"noHistory": "您還沒有歷史記錄",
"contentPrefix": "您輸入的內容為 ",
"contentSuffix": " 如果點擊確定,將紀錄到歷史紀錄"
},
"me": {
"moreInfo": "更多信息",
"logout": "註銷",
"systemInfo": "系統信息",
"userManual": "用戶手冊",
"community": "社區",
"enterprise": "企業版",
"standard": "標準版",
"organization": "組織",
"email": "郵箱",
"createTime": "創建時間"
},
"detail": {
"starSuccess": "收藏成功"
}
}

31
mobile/src/main.js Normal file
View File

@ -0,0 +1,31 @@
import Vue from 'vue'
import App from './App'
import './common/style/index.css'
import en from './locale/en.json'
import zh from './locale/zh-Hans.json'
import tw from './locale/zh-Hant.json'
import VueI18n from 'vue-i18n'
const messages = {
en,
'zh-Hans': zh,
'zh-Hant': tw
}
import {parseLanguage} from '@/common/utils'
let i18nConfig = {
locale: parseLanguage() || uni.getLocale(),// 获取已设置的语言
messages
}
Vue.use(VueI18n)
const i18n = new VueI18n(i18nConfig)
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
i18n,
...App
})
app.$mount()

88
mobile/src/manifest.json Normal file
View File

@ -0,0 +1,88 @@
{
"name": "",
"appid": "",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"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": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"mp-qq" : {
"usingComponents" : true
},
"h5": {
"router": {
"base": "/de-app/"
},
"devServer": {
"proxy": {
"^(?!/login)": {
"target": "http://localhost:8081/",
"ws": false
}
}
}
}
}

202
mobile/src/pages.json Normal file
View File

@ -0,0 +1,202 @@
{
"pages": [
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "%navigate.login%",
"app-plus": {
"titleNView": false
}
}
},
{
"path": "pages/tabBar/home/index",
"style": {
"navigationBarTitleText": "%navigate.menuHome%",
"app-plus": {
"titleNView": false
},
"enablePullDownRefresh": true
}
},
{
"path": "pages/tabBar/home/detail",
"style": {
"navigationBarTitleText": "",
"app-plus": {
"titleNView": {
"type": "transparent",
"buttons": [{
"type": "share"
}]
}
},
"h5": {
"titleNView": {
"type": "transparent",
"buttons": []
}
}
}
},
{
"path": "pages/tabBar/dir/index",
"style": {
"navigationBarTitleText": "%navigate.menuDir%",
"app-plus": {
"titleNView": {
"type": "transparent",
"titleColor": "#fff",
"backgroundColor": "#0faeff",
"buttons": [],
"searchInput": {
"backgroundColor": "#fff",
"borderRadius": "6px",
"placeholder": "%searchPlaceholder%",
"disabled": true
}
}
},
"enablePullDownRefresh": true
}
},
{
"path": "pages/tabBar/dir/search",
"style": {
"navigationBarTitleText": "%navigate.search%",
"app-plus": {
"titleNView": {
"titleColor": "#fff",
"backgroundColor": "#0faeff",
"searchInput": {
"backgroundColor": "#fff",
"borderRadius": "6px",
"placeholder": "%searchPlaceholder%",
"autoFocus": true
}
}
}
}
},
{
"path": "pages/tabBar/dir/folder",
"style": {
"navigationBarTitleText": "",
"app-plus": {
"titleNView": {
"type": "transparent"
}
},
"h5": {
"titleNView": {
"type": "transparent",
"buttons": []
}
}
}
},
{
"path": "pages/tabBar/me/index",
"style": {
"navigationBarTitleText": "%navigate.menuMe%",
"app-plus": {
"titleNView": false
}
}
},
{
"path": "pages/tabBar/me/person",
"style": {
"navigationBarTitleText": "%navigate.personInfo%",
"app-plus": {
"titleNView": {
"type": "transparent"
}
}
}
},
{
"path": "pages/tabBar/me/language",
"style": {
"navigationBarTitleText": "%navigate.language%",
"app-plus": {
"titleNView": {
"type": "transparent"
}
}
}
},
{
"path": "pages/tabBar/me/about",
"style": {
"navigationBarTitleText": "%navigate.about%",
"app-plus": {
"titleNView": {
"type": "transparent"
}
}
}
},
{
"path": "pages/tabBar/me/outlink",
"style": {
"navigationBarTitleText": "",
"app-plus": {
"titleNView": {
"type": "transparent"
}
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "%app.name%",
"h5": {
"maxWidth": 1190,
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#F1F1F1"
}
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "%app.name%",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#ffffff"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#007AFF",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/tabBar/home/index",
"iconPath": "static/home.png",
"selectedIconPath": "static/home.png",
"text": "%navigate.menuHome%"
},
{
"pagePath": "pages/tabBar/dir/index",
"iconPath": "static/dir.png",
"selectedIconPath": "static/dir.png",
"text": "%navigate.menuDir%"
}, {
"pagePath": "pages/tabBar/me/index",
"iconPath": "static/me.png",
"selectedIconPath": "static/me.png",
"text": "%navigate.menuMe%"
}
]
}
}

View File

@ -0,0 +1,49 @@
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin: 200rpx auto 50rpx auto;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>

View File

@ -0,0 +1,344 @@
<template>
<view class="content">
<view class="input-group" >
<view class="input-row">
<text class="welcome">{{$t('login.title')}}</text>
</view>
<view class="input-row border">
<text class="title">{{$t('login.account')}}</text>
<m-input class="m-input" type="text" clearable focus v-model="username" :placeholder="$t('login.accountPlaceholder')"></m-input>
</view>
<view class="input-row border">
<text class="title">{{$t('login.password')}}</text>
<m-input type="password" displayable v-model="password" :placeholder="$t('login.passwordPlaceholder')"></m-input>
</view>
</view>
<view class="btn-row">
<button type="primary" class="primary" :loading="loginBtnLoading" @tap="bindLogin">{{$t('login.loginbtn')}}</button>
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
import mInput from '../../components/m-input.vue'
import {login, getInfo, getPublicKey } from '@/api/auth'
import {encrypt, setLocalPK, getLocalPK, setToken, getToken, setUserInfo, getUserInfo } from '@/common/utils'
export default {
components: {
mInput
},
data() {
return {
username: '',
loginBtnLoading: false,
password: ''
}
},
computed: mapState(['forcedLogin', 'hasLogin', 'univerifyErrorMsg', 'hideUniverify']),
onLoad() {
this.loadPublicKey()
if(getToken() && getUserInfo()) {
this.toMain()
}
},
methods: {
...mapMutations(['login']),
async loginByPwd() {
if (this.username.length < 3) {
uni.showToast({
icon: 'none',
title: '账号最短为 3 个字符'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: this.$t('login.pwdFmtError')
});
return;
}
const data = {
username: encrypt(this.username),
password: encrypt(this.password)
};
this.loginBtnLoading = true
login(data).then(res => {
if(res.success) {
setToken(res.data.token)
this.toMain()
}
}).catch(error => {
this.loginBtnLoading = false
uni.showToast({
icon: 'error',
title: error.response.data.message,
});
})
},
bindLogin() {
this.loginByPwd()
},
toMain(userName) {
getInfo().then(res => {
setUserInfo(res.data)
uni.reLaunch({
url: '../tabBar/home/index',
});
})
},
loadPublicKey() {
if(!getLocalPK()) {
getPublicKey().then(res => {
setLocalPK(res.data)
})
}
},
},
onReady() {
}
}
</script>
<style>
@import "@/components/m-icon/m-icon.css";
/*每个页面公共css */
page {
min-height: 100%;
display: flex;
font-size: 14px;
}
input,
textarea,
button {
font-size: 14px;
}
/* #ifdef MP-BAIDU */
page {
width: 100%;
height: 100%;
display: block;
}
swan-template {
width: 100%;
min-height: 100%;
display: flex;
}
/* 原生组件模式下需要注意组件外部样式 */
custom-component {
width: 100%;
min-height: 100%;
display: flex;
}
/* #endif */
/* #ifdef MP-ALIPAY */
page {
min-height: 100vh;
}
/* #endif */
/* 原生组件模式下需要注意组件外部样式 */
m-input {
width: 100%;
/* min-height: 100%; */
display: flex;
flex: 1;
}
.content {
display: flex;
flex: 1;
flex-direction: column;
background-color: #000000;
background-image: url(../../static/logo-bg.jpg);
padding: 10px;
justify-content: center;
background-repeat: no-repeat;
background-size: 100% 100%;
opacity: 0.75;
}
.input-group {
background-color: #ffffff;
margin-top: 20px;
position: relative;
opacity: 0.95;
border-radius: 10px;
overflow: hidden;
}
.input-group::before {
position: absolute;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.input-group::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.input-row {
display: flex;
flex-direction: row;
position: relative;
/* font-size: 18px; */
height: 50px;
line-height: 50px;
}
.input-row .title {
width: 70px;
padding-left: 15px;
}
.input-row.border::after {
position: absolute;
right: 0;
bottom: 0;
left: 8px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.btn-row {
margin-top: 10px;
padding: 10px 0;
}
button.primary {
background-color: #0faeff;
line-height: 40px;
border-radius: 5px;
overflow: hidden;
}
.login-type {
display: flex;
justify-content: center;
}
.login-type-btn {
line-height: 30px;
margin: 0px 15px;
}
.login-type-btn.act {
color: #0FAEFF;
border-bottom: solid 1px #0FAEFF;
}
.send-code-btn {
width: 120px;
text-align: center;
background-color: #0FAEFF;
color: #FFFFFF;
}
.action-row {
display: flex;
flex-direction: row;
justify-content: center;
}
.action-row navigator {
color: #007aff;
padding: 0 10px;
}
.oauth-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.oauth-image {
position: relative;
width: 50px;
height: 50px;
border: 1px solid #dddddd;
border-radius: 50px;
background-color: #ffffff;
}
.oauth-image image {
width: 30px;
height: 30px;
margin: 10px;
}
.oauth-image button {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.captcha-view {
line-height: 0;
justify-content: center;
align-items: center;
display: flex;
position: relative;
background-color: #f3f3f3;
}
.welcome {
padding-left: 15px;
font-size: x-large;
font-weight: 500;
letter-spacing: 2px;
}
</style>

View File

@ -0,0 +1,142 @@
<template>
<view class="page dataease-main">
<view>
<uni-list-item class="person-title" :title="banner.title" />
</view>
<!-- <uni-list>
<uni-list-item class="person-title" :title="banner.title" />
</uni-list> -->
<swiper class="swiper-box" style="flex: 1;" :duration="300" >
<swiper-item class="swiper-item" >
<uni-list >
<uni-list-item v-for="(node, index) in nodes" :key="index"
:title="node.text"
:showArrow="node.type === 'folder'"
:thumb="node.type === 'folder' ? '../../../static/folder.png' : '../../../static/yibiaobans.png'"
thumb-size="base"
clickable
@click="clickHandler(node)"
rightText="" />
</uni-list>
</swiper-item>
</swiper>
</view>
</template>
<script>
import {requestDir} from '@/api/panel'
export default {
data() {
return {
showSwiper: false,
imgUrls: [
'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b4b60b10-5168-11eb-bd01-97bc1429a9ff.jpg',
'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b1dcfa70-5168-11eb-bd01-97bc1429a9ff.jpg'
],
nodes: [],
banner: {}
};
},
onLoad(event) {
const payload = event.detailDate || event.payload;
// decode
try {
this.banner = JSON.parse(decodeURIComponent(payload));
} catch (error) {
this.banner = JSON.parse(payload);
}
uni.setNavigationBarTitle({
title: this.banner.title
});
setTimeout(()=>{
this.loadData(this.banner.id);
},350)
},
methods: {
loadData(pid) {
pid = pid || 'panel_list'
const param = {pid: pid}
requestDir(param).then(res => {
this.nodes = res.data
}).catch(e => {
})
},
clickHandler(node) {
const param = {
id: node.id,
title: node.text,
index: 4
}
if(node.type === 'panel') {
uni.navigateTo({
url: '../home/detail?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
return
}
uni.navigateTo({
url: './folder?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
}
}
};
</script>
<style>
image,
swiper,
.img-view {
width: 750rpx;
width: 100%;
height: 500rpx;
}
.page-section-title {
margin-top: 50rpx;
}
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 10px);
}
.swiper-box {
flex: 1;
margin-top: 5px;
background-color: #ffffff;
height: calc(100vh - 60px);
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.person-title {
font-weight: 700;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.uni-list{
overflow-y: scroll;
height: 100%;
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<view class="page dataease-main">
<swiper class="swiper-box" style="flex: 1;" :duration="300" >
<swiper-item class="swiper-item" >
<uni-list >
<uni-list-item v-for="(node, index) in nodes" :key="index"
:title="node.text"
:showArrow="node.type === 'folder'"
:thumb="node.type === 'folder' ? '../../../static/folder.png' : '../../../static/yibiaobans.png'"
thumb-size="base"
clickable
@click="clickHandler(node)"
rightText="" />
</uni-list>
</swiper-item>
</swiper>
</view>
</template>
<script>
import {requestDir} from '@/api/panel'
export default {
data() {
return {
showSwiper: false,
imgUrls: [
'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b4b60b10-5168-11eb-bd01-97bc1429a9ff.jpg',
'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b1dcfa70-5168-11eb-bd01-97bc1429a9ff.jpg'
],
nodes: []
};
},
onLoad() {
setTimeout(()=>{
this.loadData('panel_list');
},350)
},
/**
* searchInput 配置 disabled true 时触发
*/
onNavigationBarSearchInputClicked(e) {
uni.navigateTo({
url: './search'
});
},
onPullDownRefresh() {
this.loadData('panel_list');
},
/**
* 点击导航栏 buttons 时触发
*/
/* onNavigationBarButtonTap() {
uni.showModal({
title: '提示',
content: '用户点击了功能按钮,这里仅做展示。',
success: res => {
if (res.confirm) {
console.log('用户点击了确定');
}
}
});
} */
methods: {
loadData(pid) {
pid = pid || 'panel_list'
const param = {pid: pid}
requestDir(param).then(res => {
this.nodes = res.data
uni.stopPullDownRefresh();
}).catch(e => {
uni.stopPullDownRefresh();
})
},
clickHandler(node) {
const param = {
id: node.id,
title: node.text,
index: 4
}
if(node.type === 'panel') {
uni.navigateTo({
url: '../home/detail?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
return
}
uni.navigateTo({
url: './folder?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
}
}
};
</script>
<style>
image,
swiper,
.img-view {
width: 750rpx;
width: 100%;
height: 500rpx;
}
.page-section-title {
margin-top: 50rpx;
}
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
top: 40px;
padding: 5px;
height: calc(100vh - 90px);
}
.swiper-box {
flex: 1;
background-color: #ffffff;
height: calc(100vh - 100px);
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.uni-list {
overflow-y: scroll;
height: calc(100vh - 100px);
}
</style>

View File

@ -0,0 +1,224 @@
<template>
<view class="wrapper">
<view v-if="isHistory" class="history-box">
<view v-if="historyList.length > 0">
<view class="history-title">
<text>{{$t('dir.searchHistory')}}</text>
<text class="uni-icon uni-icon-trash" @click="clearSearch"></text>
</view>
<view class="history-content">
<view class="history-item" v-for="(item, index) in historyList" clickable @click="clickHandler(item)" :key="index">
{{ item.name }}
</view>
</view>
</view>
<view v-else class="no-data">{{$t('dir.noHistory')}}</view>
</view>
<view v-else class="history-box">
<view v-if="historyList.length > 0" class="history-list-box">
<view
class="history-list-item"
v-for="(item, index) in historyList"
:key="index"
@click="listTap(item)"
>
<rich-text :nodes="item.nameNodes"></rich-text>
</view>
</view>
<view v-else class="no-data">没有搜索到相关内容</view>
</view>
</view>
</template>
<script>
import util from '@/components/amap-wx/js/util.js';
import {requestDir} from '@/api/panel'
export default {
data() {
return {
historyList: [],
isHistory: true,
list: [],
flng: true,
timer: null
};
},
onLoad() {
// sdk
this.amapPlugin = util.mapInit();
this.historyList = uni.getStorageSync('search:history');
},
methods: {
/**
* 列表点击
*/
listTap(item) {
item = JSON.parse(JSON.stringify(item));
// ,
if (this.history) {
return;
} else {
this.isHistory = true;
//
//
util.setHistory(item);
// uni.navigateBack();
this.clickHandler(item)
}
},
/**
* 清理历史搜索数据
*/
clearSearch() {
uni.showModal({
title: this.$t('commons.tips'),
content: this.$t('dir.clearConfirm'),
success: res => {
if (res.confirm) {
this.historyList = util.removeHistory();
}
}
});
},
/**
* 关键字搜索
* 调用高德地图关键字搜索api
*/
getInputtips(val) {
const param = {name: val}
requestDir(param).then(res => {
let dataObj = res.data
dataObj.map(item => {
item.name = item.text
return util.dataHandle(item, val);
});
this.historyList = dataObj;
})
},
clickHandler(node) {
const param = {
id: node.id,
title: node.text,
index: 4
}
if(node.type === 'panel') {
uni.navigateTo({
url: '../home/detail?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
return
}
uni.navigateTo({
url: './folder?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
}
},
/**
* searchInput 输入时触发
*/
onNavigationBarSearchInputChanged(e) {
let text = e.text;
if (!text) {
this.isHistory = true;
this.historyList = [];
this.historyList = uni.getStorageSync('search:history');
return;
} else {
this.isHistory = false;
this.getInputtips(text);
}
},
/**
* 点击软键盘搜索按键触发
*/
onNavigationBarSearchInputConfirmed(e) {
let text = e.text;
if (!text) {
this.isHistory = true;
this.historyList = [];
this.historyList = uni.getStorageSync('search:history');
uni.showModal({
title: this.$t('commons.tips'),
content: this.$t('searchPlaceholder'),
success: res => {
if (res.confirm) {
}
}
});
return;
} else {
uni.showModal({
title: this.$t('commons.tips'),
content: this.$t('dir.contentPrefix') + text + this.$t('dir.contentSuffix'),
success: res => {
if (res.confirm) {
util.setHistory(text);
uni.navigateBack();
}
}
});
}
},
/**
* 点击导航栏 buttons 时触发
*/
onNavigationBarButtonTap() {
uni.showModal({
title: this.$t('commons.tips'),
content: '点击确定修改输入框的内容为abc',
success: res => {
if (res.confirm) {
const currentWebview = this.$mp.page.$getAppWebview();
currentWebview.setTitleNViewSearchInputText("abc");
}
}
});
}
};
</script>
<style>
.history-title {
display: flex;
justify-content: space-between;
padding: 20rpx 30rpx;
padding-bottom: 0;
font-size: 34rpx;
color: #333;
}
.history-title .uni-icon {
font-size: 40rpx;
}
.history-content {
display: flex;
flex-wrap: wrap;
padding: 15rpx;
}
.history-item {
padding: 4rpx 35rpx;
border: 1px #f1f1f1 solid;
background: #fff;
border-radius: 50rpx;
margin: 12rpx 10rpx;
color: #999;
}
.history-list-box {
/* margin: 10rpx 0; */
}
.history-list-item {
padding: 30rpx 0;
margin-left: 30rpx;
border-bottom: 1px #EEEEEE solid;
font-size: 28rpx;
}
.no-data {
text-align: center;
color: #999;
margin: 100rpx;
}
</style>

View File

@ -0,0 +1,300 @@
<template>
<view class="page dataease-main">
<uni-list>
<uni-list-item class="person-title" :title="banner.title" />
</uni-list>
<view class="article-content">
<view v-if="url">
<web-view
:webview-styles="webViewStyles"
style="height: calc(100vh - 112px);"
>
</web-view>
</view>
</view>
<!-- #ifdef MP-WEIXIN || MP-QQ -->
<ad v-if="htmlNodes.length > 0" unit-id="adunit-01b7a010bf53d74e"></ad>
<!-- #endif -->
<view class="card-actions">
<view v-if="banner.index === 2" class="card-actions-item">
</view>
<view v-else class="card-actions-item" @click="enshrine">
<uni-icons v-if="hasStar" type="star-filled" size="18" color="#007AFF"></uni-icons>
<uni-icons v-else type="star" size="18" color="#999"></uni-icons>
</view>
<view class="card-actions-item" @click="refresh">
<uni-icons type="reload" size="18" color="#999"></uni-icons>
</view>
</view>
</view>
</template>
<script>
import {addRecent, getToken} from '@/common/utils'
import {linkInfo, switchLink, star, unstar, starStatus} from '@/api/panel'
const DETAIL_PAGE_PATH = '/pages/tabBar/home/detail'
// import htmlParser from '@/common/html-parser.js'
function _handleShareChannels(provider) {
let channels = [];
for (let i = 0, len = provider.length; i < len; i++) {
switch (provider[i]) {
case 'weixin':
channels.push({
text: '分享到微信好友',
id: 'weixin',
sort: 0
});
channels.push({
text: '分享到微信朋友圈',
id: 'weixin',
sort: 1
});
break;
default:
break;
}
}
channels.sort(function(x, y) {
return x.sort - y.sort;
});
return channels;
}
export default {
data() {
return {
title: '',
banner: {},
htmlNodes: [],
webViewStyles: {
progress: {
color: '#FF3333'
},
height: '700px'
},
url: '',
hasStar: false,
refreshCount: 0
}
},
onLoad(event) {
// TODO 后面把参数名替换成 payload
const payload = event.detailDate || event.payload;
// 目前在某些平台参数会被主动 decode暂时这样处理。
try {
this.banner = JSON.parse(decodeURIComponent(payload));
uni.showLoading({
title: 'loading'
});
this.loadLinkUrl()
} catch (error) {
this.banner = JSON.parse(payload);
}
uni.setNavigationBarTitle({
title: this.banner.title
});
// this.getDetail();
this.addRecent()
uni.$emit('loadHomeIndex', {
index: 1
})
this.loadStarStatus()
},
onBackPress(e) {
if (!(this.refreshCount > 0)) {
return false
}
this.refreshCount -= 1
uni.navigateBack()
},
onShareAppMessage() {
return {
title: this.banner.title,
path: DETAIL_PAGE_PATH + '?detailDate=' + JSON.stringify(this.banner)
}
},
onNavigationBarButtonTap(event) {
const buttonIndex = event.index;
if (buttonIndex === 0) {
// 分享 H5 的页面
const shareProviders = [];
uni.getProvider({
service: 'share',
success: (result) => {
// 目前仅考虑分享到微信
if (result.provider && result.provider.length && ~result.provider.indexOf('weixin')) {
const channels = _handleShareChannels(result.provider);
uni.showActionSheet({
itemList: channels.map(channel => {
return channel.text;
}),
success: (result) => {
const tapIndex = result.tapIndex;
uni.share({
provider: 'weixin',
type: 0,
title: this.banner.title,
scene: tapIndex === 0 ? 'WXSceneSession' : 'WXSenceTimeline',
href: 'https://uniapp.dcloud.io/h5' + DETAIL_PAGE_PATH + '?detailDate=' + JSON.stringify(this.banner),
imageUrl: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b6304f00-5168-11eb-bd01-97bc1429a9ff.png'
});
}
});
} else {
uni.showToast({
title: '未检测到可用的微信分享服务'
});
}
},
fail: (error) => {
uni.showToast({
title: '获取分享服务失败'
});
}
});
}
},
methods: {
getDetail() {
uni.request({
url: 'https://unidemo.dcloud.net.cn/api/news/36kr/' + this.banner.post_id,
success: (data) => {
if (data.statusCode == 200) {
var htmlString = data.data.content.replace(/\\/g, "").replace(/<img/g, "<img style=\"display:none;\"");
//this.htmlNodes = htmlParser(htmlString);
}
},
fail: () => {
console.log('fail');
}
});
},
addRecent() {
const item = {id: this.banner.id, title: this.banner.title, index: this.banner.index}
addRecent(item)
},
enshrine() {
const method = this.hasStar ? unstar: star
method(this.banner.id).then(res => {
if(!this.hasStar) {
uni.showToast({
icon: 'success',
title: '收藏成功'
})
}
this.loadStarStatus()
uni.$emit('loadHomeIndex', {
index: 0
})
})
},
refresh() {
uni.showLoading({
title: 'loading'
});
this.url = null
this.loadLinkUrl()
this.refreshCount += 1
},
loadStarStatus() {
starStatus(this.banner.id).then(res => {
this.hasStar = res.data
})
},
loadLinkUrl() {
this.url = process.env.VUE_APP_BASE_API + 'tempMobileLink/' + this.banner.id + "/" + getToken()
const url = this.url
setTimeout(() => {
const iframe = document.getElementsByTagName("iframe")[0]
iframe.src = url
iframe.onload = e => {
uni.hideLoading()
}
}, 1000);
},
back() {
// #ifdef H5
let canBack = true
const pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack(1)
return;
}
let a = this.$router.go(-1)
// router.go失败之后则重定向到首页
if (a == undefined) {
uni.reLaunch({
url: "/pages/index/index"
})
}
return
// #endif
uni.navigateBack(1)
}
}
}
</script>
<style>
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 10px);
}
.person-title {
font-weight: 700;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.article-content {
height: calc(100vh - 110px);
margin: 5px 0;
background: #ffffff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
background: #ffffff;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
</style>

View File

@ -0,0 +1,415 @@
<template>
<view class="tabs">
<scroll-view id="tab-bar" class="scroll-h" :scroll-x="true" :show-scrollbar="false" :scroll-into-view="scrollInto">
<view v-for="(tab,index) in tabBars" :key="tab.id" class="uni-tab-item" :id="tab.id" :data-current="index" @click="ontabtap">
<text class="uni-tab-item-title" :class="tabIndex==index ? 'uni-tab-item-title-active' : ''">{{tab.name}}</text>
</view>
</scroll-view>
<view class="line-h"></view>
<swiper :current="tabIndex" class="swiper-box" style="flex: 1;" :duration="300" @change="ontabchange">
<swiper-item class="swiper-item" v-for="(tab,index1) in newsList" :key="index1">
<!-- #ifndef APP-NVUE -->
<scroll-view class="scroll-v list" enableBackToTop="true" scroll-y @scrolltolower="loadMore(index1)">
<view v-for="(newsitem,index2) in tab.data" :key="newsitem.id">
<media-item :options="newsitem" @close="close(index1,index2)" @click="goDetail(newsitem)"></media-item>
</view>
<view class="loading-more" v-if="tab.isLoading || tab.data.length > 12">
<text class="loading-more-text">{{tab.loadingText}}</text>
</view>
</scroll-view>
<!-- #endif -->
</swiper-item>
</swiper>
</view>
</template>
<script>
import mediaItem from './news-item.nvue';
import {requestHome} from '@/api/panel'
import {getRecent, formatHistoryDate} from '@/common/utils'
// 缓存每页最多
const MAX_CACHE_DATA = 100;
// 缓存页签数量
const MAX_CACHE_PAGE = 3;
export default {
components: {
mediaItem
},
data() {
return {
newsList: [],
cacheTab: [],
tabIndex: 0,
scrollInto: "",
showTips: false,
navigateFlag: false,
pulling: false,
refreshIcon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAB5QTFRFcHBw3Nzct7e39vb2ycnJioqK7e3tpqam29vb////D8oK7wAAAAp0Uk5T////////////ALLMLM8AAABxSURBVHja7JVBDoAgDASrjqj//7CJBi90iyYeOHTPMwmFZrHjYyyFYYUy1bwUZqtJIYVxhf1a6u0R7iUvWsCcrEtwJHp8MwMdvh2amHduiZD3rpWId9+BgPd7Cc2LIkPyqvlQvKxKBJ//Qwq/CacAAwDUv0a0YuKhzgAAAABJRU5ErkJggg=="
}
},
computed: {
tabBars() {
return [
{name: this.$t('home.tab1'), id: 'guanzhu'},
{name: this.$t('home.tab2'), id: 'tuijian' },
{name: this.$t('home.tab3'), id: 'tiyu'}
]
}
},
created() {
uni.$on('loadHomeIndex', this.loadHomeIndex)
},
beforeDestroy() {
uni.$off('loadHomeIndex',this.loadHomeIndex)
},
onLoad() {
setTimeout(()=>{
this.tabBars.forEach((tabBar) => {
this.newsList.push({
data: [],
isLoading: false,
refreshText: "",
loadingText: '加载更多...'
});
});
this.getList(0);
},350)
},
onPullDownRefresh() {
this.clearTabData(this.tabIndex)
this.getList(this.tabIndex, true)
},
methods: {
getList(index, replace) {
let activeTab = this.newsList[index]
if(replace) {
activeTab.lastTime = null
}
if (index === 1) {
this.loadRecentDats()
return
}
requestHome({type: index, lastTime: activeTab.lastTime}).then(res => {
var datas = res.data.listObject
if(datas.length > 0) {
datas.forEach(item => {
item.article_type = 1
item.image_url = '../../../static/yibiaobans.png'
if(item.time)
item.rightText = formatHistoryDate(item.time)
})
activeTab.lastTime = datas[datas.length - 1].time
if(replace) {
activeTab.data = datas
}else {
activeTab.data = activeTab.data.concat(datas)
}
}
uni.stopPullDownRefresh()
})
},
loadRecentDats() {
let activeTab = this.newsList[1]
let list = getRecent()
list.map(node => {
node.article_type = 1
node.image_url = '../../../static/yibiaobans.png'
if(node.time)
node.rightText = formatHistoryDate(node.time)
return node
})
activeTab.data = activeTab.data.concat(list)
uni.stopPullDownRefresh()
},
goDetail(node) {
const param = {
id: node.id,
title: node.title,
index: this.tabIndex
}
if(this.tabIndex === 1) {
param.index = node.index
}
uni.navigateTo({
url: './detail?detailDate=' + encodeURIComponent(JSON.stringify(param))
})
},
loadHomeIndex(e) {
const index = e.index
this.clearTabData(index)
this.getList(index)
},
// goDetail(e) {
// if (this.navigateFlag) {
// return;
// }
// this.navigateFlag = true;
// uni.navigateTo({
// url: './detail/detail?title=' + e.title
// });
// setTimeout(() => {
// this.navigateFlag = false;
// }, 200)
// },
close(index1, index2) {
uni.showModal({
content: '是否删除本条信息?',
success: (res) => {
if (res.confirm) {
this.newsList[index1].data.splice(index2, 1);
}
}
})
},
loadMore(e) {
setTimeout(() => {
this.getList(this.tabIndex);
}, 500)
},
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.switchTab(index);
},
ontabchange(e) {
// let index = e.target.current || e.detail.current;
// this.switchTab(index);
},
switchTab(index) {
if (this.newsList[index].data.length === 0) {
this.getList(index);
}
if (this.tabIndex === index) {
return;
}
// 缓存 tabId
if (this.newsList[this.tabIndex].data.length > MAX_CACHE_DATA) {
let isExist = this.cacheTab.indexOf(this.tabIndex);
if (isExist < 0) {
this.cacheTab.push(this.tabIndex);
//console.log("cache index:: " + this.tabIndex);
}
}
this.tabIndex = index;
this.scrollInto = this.tabBars[index].id;
// 释放 tabId
if (this.cacheTab.length > MAX_CACHE_PAGE) {
let cacheIndex = this.cacheTab[0];
this.clearTabData(cacheIndex);
this.cacheTab.splice(0, 1);
//console.log("remove cache index:: " + cacheIndex);
}
},
clearTabData(e) {
this.newsList[e].data.length = 0;
this.newsList[e].loadingText = "加载更多...";
},
refreshData() {},
onrefresh(e) {
var tab = this.newsList[this.tabIndex];
if (!tab.refreshFlag) {
return;
}
tab.refreshing = true;
tab.refreshText = "正在刷新...";
setTimeout(() => {
this.refreshData();
this.pulling = true;
tab.refreshing = false;
tab.refreshFlag = false;
tab.refreshText = "已刷新";
setTimeout(() => { // TODO fix ios和Android 动画时间相反问题
this.pulling = false;
}, 500);
}, 2000);
},
onpullingdown(e) {
var tab = this.newsList[this.tabIndex];
if (tab.refreshing || this.pulling) {
return;
}
if (Math.abs(e.pullingDistance) > Math.abs(e.viewHeight)) {
tab.refreshFlag = true;
tab.refreshText = "释放立即刷新";
} else {
tab.refreshFlag = false;
tab.refreshText = "下拉可以刷新";
}
},
newGuid() {
let s4 = function() {
return (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
}
return (s4() + s4() + "-" + s4() + "-4" + s4().substr(0, 3) + "-" + s4() + "-" + s4() + s4() + s4()).toUpperCase();
}
}
}
</script>
<style>
/* #ifndef APP-PLUS */
page {
width: 100%;
min-height: 100%;
display: flex;
}
/* #endif */
.tabs {
flex: 1;
flex-direction: column;
overflow: hidden;
background-color: #ffffff;
/* #ifndef APP-PLUS */
height: 100vh;
/* #endif */
}
.scroll-h {
width: 750rpx;
/* #ifdef H5 */
width:100%;
/* #endif */
height: 80rpx;
flex-direction: row;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
/* flex-wrap: nowrap; */
/* border-color: #cccccc;
border-bottom-style: solid;
border-bottom-width: 1px; */
}
.line-h {
height: 1rpx;
background-color: #cccccc;
}
.uni-tab-item {
/* #ifndef APP-PLUS */
display: inline-block;
/* #endif */
flex-wrap: nowrap;
padding-left: 34rpx;
padding-right: 34rpx;
}
.uni-tab-item-title {
color: #555;
font-size: 30rpx;
height: 80rpx;
line-height: 80rpx;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
}
.uni-tab-item-title-active {
color: #007AFF;
}
.swiper-box {
flex: 1;
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.scroll-v {
flex: 1;
/* #ifndef MP-ALIPAY */
flex-direction: column;
/* #endif */
width: 750rpx;
width:100%;
}
.update-tips {
position: absolute;
left: 0;
top: 41px;
right: 0;
padding-top: 5px;
padding-bottom: 5px;
background-color: #FDDD9B;
align-items: center;
justify-content: center;
text-align: center;
}
.update-tips-text {
font-size: 14px;
color: #ffffff;
}
.refresh {
width: 750rpx;
width:100%;
height: 64px;
justify-content: center;
}
.refresh-view {
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
}
.refresh-icon {
width: 30px;
height: 30px;
transition-duration: .5s;
transition-property: transform;
transform: rotate(0deg);
transform-origin: 15px 15px;
}
.refresh-icon-active {
transform: rotate(180deg);
}
.loading-icon {
width: 20px;
height: 20px;
margin-right: 5px;
color: #999999;
}
.loading-text {
margin-left: 2px;
font-size: 16px;
color: #999999;
}
.loading-more {
align-items: center;
justify-content: center;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}
.loading-more-text {
font-size: 28rpx;
color: #999;
}
</style>

View File

@ -0,0 +1,246 @@
<template>
<de-container>
<template v-slot:header>
<view class="tabs">
<scroll-view id="tab-bar" class="scroll-h" :scroll-x="true" :show-scrollbar="false" :scroll-into-view="scrollInto">
<view v-for="(tab,index) in tabBars" :key="tab.id" class="uni-tab-item" :id="tab.id" :data-current="index" @click="ontabtap">
<text class="uni-tab-item-title" :class="tabIndex==index ? 'uni-tab-item-title-active' : ''">{{tab.name}}</text>
</view>
</scroll-view>
</view>
</template>
<swiper :current="tabIndex" class="swiper-box" style="flex: 1;" :duration="300" @change="ontabchange">
<swiper-item class="swiper-item" v-for="(tab,index1) in newsList" :key="index1">
<uni-list>
<uni-list-item
v-for="(node, i) in tab.data"
:key="i"
clickable
@click="goDetail(node)"
:title="node.title"
thumb="../../../static/yibiaobans.png"
thumb-size="base"
:rightText="node.rightText"
/>
</uni-list>
</swiper-item>
</swiper>
</de-container>
</template>
<script>
// 缓存每页最多
const MAX_CACHE_DATA = 100
// 缓存页签数量
const MAX_CACHE_PAGE = 3
import DeContainer from "../../../components/DeContainer"
import {requestHome} from '@/api/panel'
import {getRecent, formatHistoryDate} from '@/common/utils'
export default {
components: {DeContainer},
data() {
return {
scrollInto: "",
tabIndex: 0,
newsList: [],
cacheTab: [],
extraIcon: {
color: '#4cd964',
size: '22',
type: 'gear-filled'
}
}
},
computed: {
tabBars() {
return [
{name: this.$t('home.tab1'), id: 'guanzhu'},
{name: this.$t('home.tab2'), id: 'tuijian' },
{name: this.$t('home.tab3'), id: 'tiyu'}
]
}
},
created() {
uni.$on('loadHomeIndex', this.loadHomeIndex)
},
beforeDestroy() {
uni.$off('loadHomeIndex',this.loadHomeIndex)
},
onLoad() {
setTimeout(()=>{
this.tabBars.forEach((tabBar) => {
this.newsList.push({
data: [],
isLoading: false,
refreshText: "",
loadingText: '加载更多...'
})
})
this.getList(0)
},0)
},
onPullDownRefresh() {
this.clearTabData(this.tabIndex)
this.getList(this.tabIndex)
},
methods: {
getList(index) {
let activeTab = this.newsList[index]
if (index === 1) {
this.loadRecentDats()
return
}
requestHome(index).then(res => {
activeTab.data = activeTab.data.concat(res.data)
uni.stopPullDownRefresh()
})
},
loadRecentDats() {
let activeTab = this.newsList[1]
let list = getRecent()
list.map(node => {
if(node.time)
node.rightText = formatHistoryDate(node.time)
return node
})
activeTab.data = activeTab.data.concat(list)
uni.stopPullDownRefresh()
},
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current
this.switchTab(index)
},
ontabchange(e) {
/* let index = e.target.current || e.detail.current
this.switchTab(index) */
},
switchTab(index) {
if (this.newsList[index].data.length === 0) {
this.getList(index)
}
if (this.tabIndex === index) {
return
}
// 缓存 tabId
if (this.newsList[this.tabIndex].data.length > MAX_CACHE_DATA) {
let isExist = this.cacheTab.indexOf(this.tabIndex)
if (isExist < 0) {
this.cacheTab.push(this.tabIndex)
}
}
this.tabIndex = index
this.scrollInto = this.tabBars[index].id
// 释放 tabId
if (this.cacheTab.length > MAX_CACHE_PAGE) {
let cacheIndex = this.cacheTab[0]
this.clearTabData(cacheIndex)
this.cacheTab.splice(0, 1)
}
},
clearTabData(e) {
this.newsList[e].data.length = 0
this.newsList[e].loadingText = "加载更多..."
},
goDetail(node) {
const param = {
id: node.id,
title: node.title,
index: this.tabIndex
}
if(this.tabIndex === 1) {
param.index = node.index
}
uni.navigateTo({
url: './detail?detailDate=' + encodeURIComponent(JSON.stringify(param))
})
},
loadHomeIndex(e) {
const index = e.index
this.clearTabData(index)
this.getList(index)
}
}
}
</script>
<style>
.tabs {
flex: 1;
flex-direction: column;
overflow: hidden;
background-color: #ffffff;
/* #ifndef APP-PLUS */
height: 100vh;
/* #endif */
}
.scroll-h {
width: 750rpx;
/* #ifdef H5 */
width:100%;
/* #endif */
height: 40px;
flex-direction: row;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
/* flex-wrap: nowrap; */
/* border-color: #cccccc;
border-bottom-style: solid;
border-bottom-width: 1px; */
}
.uni-tab-item {
/* #ifndef APP-PLUS */
display: inline-block;
/* #endif */
flex-wrap: nowrap;
padding-left: 34rpx;
padding-right: 34rpx;
}
.uni-tab-item-title {
color: #555;
font-size: 35rpx;
height: 40px;
line-height: 40px;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
}
.uni-tab-item-title-active {
color: #007AFF;
}
.swiper-box {
flex: 1;
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.uni-list{
overflow-y: scroll;
}
</style>

View File

@ -0,0 +1,215 @@
<template>
<!-- remove list-cell layer fix android 4.x overflow limit error: 28 layers! -->
<!-- <view class="list-cell view" @click="click"></view> -->
<view class="media-item view" hover-class="media-item-hover" v-if="options.title" @click="click">
<!-- <view class="view" :style="options.article_type === 2 ? 'flex-direction: row';" :class="{'media-image-right': options.article_type === 2, 'media-image-left': options.article_type === 1}"> -->
<!-- TODO 在支付宝小程序下 需要用 style 覆盖标签的默认样式 -->
<view class="view" :style="{flexDirection: (options.article_type === 1 || options.article_type === 2)?(options.article_type === 2 ?'row':'row-reverse'):'column' }">
<text class="info-text">{{options.rightText}}</text>
<text class="media-title" :class="{'media-title2': options.article_type === 1 || options.article_type === 2}">{{options.title}}</text>
<view v-if="options.image_list || options.image_url" class="image-section flex-row" :class="{'image-section-right': options.article_type === 2, 'image-section-left': options.article_type === 1}"
:style="{flexDirection: 'row' }">
<image class="image-list1" :class="{'image-list2': options.article_type === 1 || options.article_type === 2}" v-if="options.image_url"
:src="options.image_url"></image>
<image class="image-list3" v-if="options.image_list" :src="source.url" v-for="(source, i) in options.image_list"
:key="i" />
</view>
</view>
<!-- <view class="media-foot flex-row" style="flex-direction: column;">
<view class="media-info flex-row" style="flex-direction: row;">
<text class="info-text"></text>
<text class="info-text"></text>
<text class="info-text">{{options.rightText}}</text>
</view>
<view class="max-close-view" @click.stop="close">
<view class="close-l close-h"></view>
<view class="close-l close-v"></view>
</view>
</view> -->
<view class="media-item-line" style="position: absolute;"></view>
</view>
</template>
<script>
export default {
props: {
options: {
type: Object,
default: function(e) {
return {}
}
}
},
methods: {
click() {
this.$emit('click');
},
close(e) {
this.$emit('close');
}
}
}
</script>
<style>
.view {
flex-direction: column;
}
.flex-row {
flex-direction: row;
}
.flex-col {
flex-direction: column;
}
.list-cell {
width: 750rpx;
padding: 0 30rpx;
}
.uni-list-cell-hover {
background-color: #eeeeee;
}
.media-item {
position: relative;
flex: 1;
flex-direction: column;
/* border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #ebebeb; */
padding: 20rpx 30rpx 21rpx 30rpx;
}
.media-item-hover{
background-color: #eee;
}
.media-item-line {
position: absolute;
left: 30rpx;
right: 30rpx;
bottom: 0;
height: 1rpx;
background-color: #ebebeb;
}
.media-image-right {
flex-direction: row;
}
.media-image-left {
flex-direction: row-reverse;
}
.media-title {
flex: 1;
display: flex;
align-items: center;
}
.media-title {
lines: 3;
text-overflow: ellipsis;
font-size: 30rpx;
color: #555555;
}
.media-title2 {
flex: 1;
margin-top: 6rpx;
line-height: 40rpx;
}
.image-section {
margin-top: 20rpx;
flex-direction: row;
justify-content: space-between;
}
.image-section-right {
margin-top: 0rpx;
margin-left: 10rpx;
width: 225rpx;
height: 146rpx;
}
.image-section-left {
margin-top: 0rpx;
margin-right: 10rpx;
width: 80rpx;
height: 80rpx;
}
.image-list1 {
width: 690rpx;
height: 481rpx;
}
.image-list2 {
width: 80rpx;
height: 80rpx;
}
.image-list3 {
width: 225rpx;
/* #ifdef H5 */
width: 30%;
/* #endif */
height: 146rpx;
/* #ifdef H5 */
height: 146px;
/* #endif */
}
.media-info {
flex-direction: row;
align-items: center;
}
.info-text {
margin-right: 20rpx;
color: #999999;
font-size: 24rpx;
}
.media-foot {
margin-top: 25rpx;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.max-close-view {
position: relative;
align-items: center;
flex-direction: row;
width: 40rpx;
height: 30rpx;
line-height: 30rpx;
border-width: 1rpx;
border-style: solid;
border-color: #aaaaaa;
border-radius: 4px;
justify-content: center;
text-align: center;
}
.close-l {
position: absolute;
width: 18rpx;
height: 1rpx;
background-color: #aaaaaa;
}
.close-h {
transform: rotate(45deg);
}
.close-v {
transform: rotate(-45deg);
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<view class="page dataease-main">
<uni-list>
<uni-list-item class="person-title" :title="$t('navigate.about')" />
</uni-list>
<swiper class="swiper-box" style="flex: 1;" :duration="300" >
<swiper-item class="swiper-item" >
<view class="uni-center" style=" font-size:0;padding: 40px 40px 20px;">
<image class="image" mode="widthFix" src="../../../static/DataEase-01.png" />
</view>
<view class="person-lic">
<span v-if="license.edition === 'Enterprise'">{{$t('me.enterprise')}}</span>
<span v-else>{{$t('me.standard')}}</span>
</view>
<view class="person-lic">
<span>{{build}}</span>
</view>
<uni-list>
<uni-list-item clickable showArrow thumb-size="base" :title="$t('me.userManual')" @click="toUserManual" />
<uni-list-item clickable showArrow thumb-size="base" :title="$t('me.community')" @click="toGithub"/>
</uni-list>
</swiper-item>
</swiper>
</view>
</template>
<script>
import{buildVersion, validate} from '@/api/auth'
export default {
data() {
return {
build: null,
license: {}
}
},
onLoad(event) {
this.initVersion()
},
methods: {
toGithub() {
window.location.href = 'https://github.com/dataease/dataease'
},
toUserManual() {
const param = {linkIndex: 1}
uni.navigateTo({
url: './outlink?detailDate=' + encodeURIComponent(JSON.stringify(param))
});
},
initVersion() {
buildVersion().then(res => {
this.build = res.data
})
},
getLicenseInfo() {
this.validateHandler({}, res => {
this.license = this.getLicense(res.data)
})
},
validateHandler(param, success) {
validate(param).then(success)
},
getLicense(result) {
return {
status: result.status,
corporation: result.license ? result.license.corporation : '',
expired: result.license ? result.license.expired : '',
count: result.license ? result.license.count : '',
version: result.license ? result.license.version : '',
edition: result.license ? result.license.edition : ''
}
}
}
}
</script>
<style scoped>
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 90px);
}
.swiper-box {
flex: 1;
margin-top: 5px;
background-color: #ffffff;
height: calc(100vh - 60px);
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.person-title {
font-weight: 700;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.person-lic {
font-weight: 500;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
height: 50px;
text-overflow: ellipsis;
display: flex;
align-items: center;
justify-content: center;
}
.image {
width: 185px;
}
</style>

View File

@ -0,0 +1,114 @@
<template>
<view class="page dataease-main">
<view>
<uni-card >
<view class="uni-flex uni-row">
<view class="text uni-flex" style="width: 200rpx;height: 220rpx;-webkit-justify-content: center;justify-content: center;-webkit-align-items: center;align-items: center;">
<image src="../../../static/user.png" style="width: 150rpx;height: 150rpx;"></image>
</view>
<view class="uni-flex uni-column" style="-webkit-flex: 1;flex: 1;">
<view class="text" style="height: 90rpx;text-align: left;padding-left: 20rpx;padding-top: 40rpx; front-size: 25rpx;">
{{user.nickName}}
</view>
<view class="uni-flex uni-row" style="padding-left: 20rpx;">
<view class="text" style="-webkit-flex: 1;flex: 1;">{{roleNames}}</view>
<view class="more-info" style="-webkit-flex: 1;flex: 1;color: #409eff;" @click="showMore">{{$t('me.moreInfo')}}</view>
</view>
</view>
</view>
</uni-card>
</view>
<view>
<uni-list>
<uni-list-item :title="$t('navigate.language')" clickable showArrow thumb="../../../static/language.png" thumb-size="base" @click="toLanguage" :rightText="languageName" />
<uni-list-item :title="$t('navigate.about')" clickable showArrow thumb="../../../static/about.png" thumb-size="base" @click="toAbout" :rightText="$t('me.systemInfo')" />
</uni-list>
</view>
<view class="uni-padding-wrap uni-common-mt">
<button type="warn" @click="logout">{{$t('me.logout')}}</button>
</view>
</view>
</template>
<script>
import { setToken, getLanguage } from '@/common/utils'
import {getUserInfo, setUserInfo} from '@/common/utils'
export default {
data() {
return {
user: null,
roleNames: ''
}
},
created() {
this.user = getUserInfo()
this.roleNames = this.user.roles.map(role => role.name).toString()
},
onLoad(event) {
},
computed: {
languageName() {
const key = getLanguage();
if(key === 'sys') {
return this.$t('commons.sysLanguage')
}
if(key === 'en') {
return this.$t('commons.en')
}
if(key === 'zh-Hans') {
return this.$t('commons.zh')
}
if(key === 'zh-Hant') {
return this.$t('commons.tw')
}
}
},
methods: {
showMore() {
uni.navigateTo({
url: './person'
});
},
toLanguage() {
uni.navigateTo({
url: './language'
});
},
toAbout() {
uni.navigateTo({
url: './about'
});
},
logout() {
setToken(null)
setUserInfo(null)
uni.reLaunch({
url: '/'
});
}
}
}
</script>
<style scoped>
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 90px);
}
.uni-card {
margin: 0px;
}
.uni-padding-wrap {
padding: 0px;
}
</style>

View File

@ -0,0 +1,97 @@
<template>
<view class="page dataease-main">
<uni-list>
<uni-list-item class="person-title" :title="$t('navigate.language')" />
</uni-list>
<swiper class="swiper-box" style="flex: 1;" :duration="300" >
<swiper-item class="swiper-item" >
<radio-group @change="radioChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item,index) in items" :key="index">
<view>{{item.text}}</view>
<view>
<radio :value="item.value" :checked="item.value === language" />
</view>
</label>
</radio-group>
</swiper-item>
</swiper>
</view>
</template>
<script>
import {setLanguage, getLanguage} from '@/common/utils'
export default {
data() {
return {
language: 'sys'
}
},
computed: {
items() {
return [
{value: 'sys', text: this.$t('commons.sysLanguage')},
{value: 'zh-Hans', text: this.$t('commons.zh')},
{value: 'zh-Hant', text: this.$t('commons.tw')},
{value: 'en', text: this.$t('commons.en')}
]
}
},
onLoad(e) {
this.language = getLanguage()
},
methods: {
radioChange(node) {
this.language = node.detail.value
if(node.detail.value === 'sys') {
var local = uni.getLocale()
uni.setLocale(local)
this.$i18n.locale = local
}else {
uni.setLocale(node.detail.value)
this.$i18n.locale = node.detail.value
}
setLanguage(node.detail.value)
}
}
}
</script>
<style scoped>
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 90px);
}
.swiper-box {
flex: 1;
margin-top: 5px;
background-color: #ffffff;
height: calc(100vh - 60px);
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.person-title {
font-weight: 700;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -0,0 +1,33 @@
<template>
<view>
<web-view
:src="urls[banner.linkIndex]" >
</web-view>
</view>
</template>
<script>
export default {
data() {
return {
urls: [
'https://github.com/dataease/dataease',
'https://dataease.io/docs/user_manual/general/'
],
banner: {}
}
},
onLoad(event) {
// TODO payload
const payload = event.detailDate || event.payload;
// decode
try {
this.banner = JSON.parse(decodeURIComponent(payload));
} catch (error) {
this.banner = JSON.parse(payload);
}
},
}
</script>

View File

@ -0,0 +1,80 @@
<template>
<view class="page dataease-main">
<uni-list>
<uni-list-item class="person-title" :title="$t('navigate.personInfo')" />
</uni-list>
<swiper class="swiper-box" style="flex: 1;" :duration="300" >
<swiper-item class="swiper-item" >
<uni-list>
<uni-list-item :title="$t('me.organization')" :rightText="me.deptName"/>
<uni-list-item :title="$t('me.email')" :rightText="user.email" />
<uni-list-item :title="$t('me.createTime')" :rightText="me.timeStr" />
</uni-list>
</swiper-item>
</swiper>
</view>
</template>
<script>
import {getUserInfo} from '@/common/utils'
import {requestMe} from '@/api/panel'
export default {
data() {
return {
user: null,
me: {}
}
},
created() {
this.user = getUserInfo()
this.load()
},
onLoad(event) {
},
methods: {
load() {
requestMe().then(res => {
if(res.success && res.data)
this.me = res.data
if(this.me.createTime) {
this.me.timeStr = new Date(this.me.createTime).format('yyyy-MM-dd')
}
})
}
}
}
</script>
<style scoped>
.dataease-main {
position: fixed;
left: var(--window-left);
right: var(--window-right);
padding: 5px;
height: calc(100vh - 90px);
}
.swiper-box {
flex: 1;
margin-top: 5px;
background-color: #ffffff;
height: calc(100vh - 60px);
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.person-title {
font-weight: 700;
font-size: 15px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

15
mobile/src/settings.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
PUBLICKEY: 'public_key',
TokenKey: 'Authorization',
RefreshTokenKey: 'refreshauthorization',
LinkTokenKey: 'LINK-PWD-TOKEN',
title: 'DataEase',
WHITE_LIST: [
'/api/auth/login',
'/api/auth/getPublicKey'
],
RECENT_KEY: 'recently',
USER_INFO_KEY: 'user-info'
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
mobile/src/static/about.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
mobile/src/static/dir.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
mobile/src/static/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Some files were not shown because too many files have changed in this diff Show More