update 模板
This commit is contained in:
parent
d481ab6057
commit
9d3a875182
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"presets": [["@babel/preset-env", { "modules": false }]],
|
||||
"plugins": []
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# 所有环境默认
|
||||
VUE_APP_VERSION=1.0.0
|
||||
|
||||
# 页面 title 前缀
|
||||
VUE_APP_TITLE=管理平台
|
||||
|
||||
# 部署路径
|
||||
VUE_APP_PUBLIC_PATH=/
|
||||
|
||||
# 缓存前缀
|
||||
VUE_APP_LOCAL_CODE=admin
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
"plugin:vue/essential",
|
||||
//关闭ESlint关键代码
|
||||
// '@vue/standard'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: "babel-eslint",
|
||||
},
|
||||
rules: {
|
||||
//严格的检查缩进问题,不是报错,我们可以关闭这个检查规则,然后在终端输入npm run dev
|
||||
indent: ["off", 2],
|
||||
"vue/no-parsing-error": [2, { "x-invalid-end-tag": false }],
|
||||
//使用eslint时,严格模式下,报错Missing space before function parentheses的问题,意思是在方法名和刮号之间需要有一格空格。
|
||||
"space-before-function-paren": 0,
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
//关闭prettier
|
||||
"prettier/prettier": "off",
|
||||
"vue/no-use-v-if-with-v-for": "off",
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
package-lock.json
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"name": "antifraud",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"report": "vue-cli-service build --report",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.12.1",
|
||||
"dayjs": "^1.10.4",
|
||||
"echarts": "^5.1.1",
|
||||
"element-ui": "^2.15.1",
|
||||
"lodash": "^4.17.21",
|
||||
"lowdb": "^1.0.0",
|
||||
"vant": "^2.12.18",
|
||||
"vue": "^2.6.12",
|
||||
"vue-json-excel": "^0.3.0",
|
||||
"vue-mini-player": "^0.2.1",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-persistedstate": "^4.0.0-beta.3",
|
||||
"weixin-js-sdk": "^1.6.0",
|
||||
"xlsx": "^0.16.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.5.13",
|
||||
"@vue/cli-plugin-eslint": "^4.5.13",
|
||||
"@vue/cli-plugin-router": "^4.5.13",
|
||||
"@vue/cli-plugin-vuex": "^4.5.13",
|
||||
"@vue/cli-service": "^4.5.13",
|
||||
"postcss-px2rem": "^0.3.0",
|
||||
"amfe-flexible": "^2.2.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"babel-plugin-import": "^1.13.3",
|
||||
"compression-webpack-plugin": "^5.0.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"image-webpack-loader": "^7.0.1",
|
||||
"node-sass": "^5.0.0",
|
||||
"px2rem-loader": "^0.1.9",
|
||||
"sass": "^1.32.12",
|
||||
"sass-loader": "^10.2.0",
|
||||
"vconsole": "^3.5.1",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"vue-wxlogin": "^1.0.4",
|
||||
"webpack-bundle-analyzer": "^4.4.2"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/strongly-recommended",
|
||||
"eslint:recommended",
|
||||
"@vue/prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
var config = {};
|
||||
|
||||
config.API = "";
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||
<!-- <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=BRPBZ-RLNLJ-XQEFU-FDWTN-VQKI6-M5FVL&libraries=geometry"></script> -->
|
||||
<script src="<%= VUE_APP_PUBLIC_PATH %>config/config.js"></script>
|
||||
<!-- <script charset="utf-8" src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script> -->
|
||||
<!-- <link rel="icon" href="<%= VUE_APP_PUBLIC_PATH %>/imgs/fanzhalogo.png"> -->
|
||||
<title>
|
||||
<%= VUE_APP_TITLE %>
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to
|
||||
continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<% if (process.env.NODE_ENV==='production' ) { %>
|
||||
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
|
||||
<link rel="stylesheet" href="<%=css%>" as="style">
|
||||
<% } %>
|
||||
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
|
||||
<script src="<%=js%>"></script>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// myrefresh: () => import("@components/common/refresh")
|
||||
},
|
||||
computed: {
|
||||
...mapState("plugin/loading", {
|
||||
globalLoading: state => state.globalLoading
|
||||
}),
|
||||
...mapState("plugin/page", { doRefresh: "doRefresh" })
|
||||
},
|
||||
methods: {
|
||||
...mapActions("plugin/wechat", ["userInfoFailMsg"])
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch("plugin/loading/open", "globalLoading");
|
||||
},
|
||||
mounted() {}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
#app {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #f5f5f4;
|
||||
resize: both;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { assign, map } from "lodash";
|
||||
import { service, request } from "./service";
|
||||
import * as tools from "./tools";
|
||||
|
||||
const files = require.context("./modules", true, /\.js$/);
|
||||
const generators = files.keys().map((key) => files(key).default);
|
||||
|
||||
export default assign(
|
||||
{},
|
||||
...map(generators, (generator) =>
|
||||
generator({
|
||||
service,
|
||||
request,
|
||||
tools,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
export default ({ request }) => ({
|
||||
/**
|
||||
* @params proj code appid
|
||||
* @return proj code appid
|
||||
*/
|
||||
authWx(data = {}) {
|
||||
return request({
|
||||
url: `/verification?proj=${data.proj}&code=${data.code}&appid=${data.appid}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
loadConfigInfo(data = {}) {
|
||||
return request({
|
||||
url: "/usr/jsconfig",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
export default ({ request }) => ({
|
||||
/**
|
||||
* @description 下载网格长
|
||||
*/
|
||||
loadAdminPerson(data) {
|
||||
return request({
|
||||
url: `/usr/manager?id=${data.id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 获取辖区
|
||||
*/
|
||||
loadAdminArea() {
|
||||
return request({
|
||||
url: `/org/jurisdiction`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @description 随机获取视频url
|
||||
*/
|
||||
loadVideoUrl() {
|
||||
return request({
|
||||
url: `/video/get`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 回答者注册
|
||||
*/
|
||||
answererRegister(data = {}) {
|
||||
return request({
|
||||
url: `/usr/register`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 下载全部题目列表 已打乱
|
||||
*/
|
||||
loadQuestionList() {
|
||||
return request({
|
||||
url: `/question/get`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 下载单题选项
|
||||
* @params id
|
||||
*/
|
||||
loadQuestionItem(data = {}) {
|
||||
return request({
|
||||
url: `/question/item/${data.id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 提交答案
|
||||
* @params duration location answer
|
||||
*/
|
||||
questionSubmit(data = {}) {
|
||||
return request({
|
||||
url: `/question/submit`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 计数
|
||||
* @params duration location answer
|
||||
*/
|
||||
videoPlayCount(data = {}) {
|
||||
// let param;
|
||||
// if (data.id !== "") {
|
||||
// param = "?id=" + data.id;
|
||||
// }
|
||||
return request({
|
||||
url: `/video/count`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 下载大奖信息
|
||||
* @params id
|
||||
*/
|
||||
loadNoticePrice(data = {}) {
|
||||
return request({
|
||||
url: `/project/notice`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
export default ({ request }) => ({
|
||||
/**
|
||||
* @description 概述信息
|
||||
*/
|
||||
loadSummary() {
|
||||
return request({
|
||||
url: `/admin/summary`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 考核信息
|
||||
*/
|
||||
loadAssessment() {
|
||||
return request({
|
||||
url: `/admin/assessment`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 概述信息
|
||||
辖区id 秒级时间戳
|
||||
*/
|
||||
loadAnalysis(data) {
|
||||
return request({
|
||||
url: `/admin/analysis?id=${data.id}&s=${data.start}&e=${data.end}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 奖励信息
|
||||
*/
|
||||
loadFee() {
|
||||
return request({
|
||||
url: `/admin/fee`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
import axios from "axios";
|
||||
import { get, set } from "lodash";
|
||||
import { dbGet } from "@/libs/util.db";
|
||||
import { removeToken } from "@/libs/util.token";
|
||||
|
||||
import { errorLog, errorCreate, errorMsgCreate, loadingMsgCreate } from "./tools";
|
||||
import router from "@/router/index";
|
||||
import msg from "@/libs/util.message";
|
||||
import { Toast } from "vant";
|
||||
import store from "../store";
|
||||
|
||||
const serviceConfigApi = config.API;
|
||||
let toast;
|
||||
|
||||
/**
|
||||
* @description 创建请求实例
|
||||
*/
|
||||
function createService() {
|
||||
// 创建一个 axios 实例
|
||||
const service = axios.create();
|
||||
// 请求拦截
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = dbGet({ path: "token.value" });
|
||||
set(config, "headers.access-token", token);
|
||||
set(config, "toast", msg.loading(""));
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
// 发送失败
|
||||
console.log(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
// dataAxios 是 axios 返回数据中的 data
|
||||
const dataAxios = response.data;
|
||||
// 这个状态码是和后端约定的
|
||||
const { code } = dataAxios;
|
||||
//去掉 loading
|
||||
response.config.toast.clear();
|
||||
// 根据 code 进行判断
|
||||
if (code === undefined) {
|
||||
// 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本
|
||||
return dataAxios;
|
||||
} else {
|
||||
// 有 code 代表这是一个后端接口 可以进行进一步的判断
|
||||
|
||||
switch (code) {
|
||||
case 0:
|
||||
return dataAxios.data;
|
||||
case 1:
|
||||
removeToken();
|
||||
errorMsgCreate(`${dataAxios.msg}`);
|
||||
location.reload();
|
||||
return false;
|
||||
case 2:
|
||||
errorMsgCreate(`${dataAxios.msg}`);
|
||||
return false;
|
||||
default:
|
||||
// 不是正确的 code
|
||||
errorCreate(`${dataAxios.msg}: ${response.config.url}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// console.log(error);
|
||||
const status = get(error, "response.status");
|
||||
let toash = get(error, "response.config.toast");
|
||||
toash.clear();
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
error.message = "请求错误";
|
||||
break;
|
||||
case 401:
|
||||
error.message = "未授权,请登录";
|
||||
break;
|
||||
case 403:
|
||||
error.message = "拒绝访问";
|
||||
break;
|
||||
case 404:
|
||||
error.message = `请求地址出错: ${error.response.config.url}`;
|
||||
break;
|
||||
case 408:
|
||||
error.message = "请求超时";
|
||||
break;
|
||||
case 500:
|
||||
error.message = "服务器内部错误";
|
||||
break;
|
||||
case 501:
|
||||
error.message = "服务未实现";
|
||||
break;
|
||||
case 502:
|
||||
error.message = "网关错误";
|
||||
break;
|
||||
case 503:
|
||||
error.message = "服务不可用";
|
||||
break;
|
||||
case 504:
|
||||
error.message = "网关超时";
|
||||
break;
|
||||
case 505:
|
||||
error.message = "HTTP版本不受支持";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
errorLog(error);
|
||||
Toast.clear();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建请求方法
|
||||
* @param {Object} service axios 实例
|
||||
*/
|
||||
function createRequestFunction(service) {
|
||||
return function(config) {
|
||||
const token = dbGet({ path: "token.value" });
|
||||
const configDefault = {
|
||||
headers: {
|
||||
"access-token": token,
|
||||
"Content-Type": get(config, "headers.Content-Type", "application/json"),
|
||||
},
|
||||
timeout: 5000,
|
||||
baseURL: process.env.NODE_ENV === "production" ? serviceConfigApi : "/apis",
|
||||
data: {},
|
||||
};
|
||||
return service(Object.assign(configDefault, config));
|
||||
};
|
||||
}
|
||||
//
|
||||
|
||||
// 用于真实网络请求的实例和请求方法
|
||||
export const service = createService();
|
||||
export const request = createRequestFunction(service);
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import { Toast } from "vant";
|
||||
/**
|
||||
* @description 安全地解析 json 字符串
|
||||
* @param {String} jsonString 需要解析的 json 字符串
|
||||
* @param {String} defaultValue 默认值
|
||||
*/
|
||||
export function parse(jsonString = "{}", defaultValue = {}) {
|
||||
let result = defaultValue;
|
||||
try {
|
||||
result = JSON.parse(jsonString);
|
||||
} catch (error) {
|
||||
//console.log(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 接口请求返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
* @param {Number} code 状态码
|
||||
*/
|
||||
export function response(data = {}, msg = "", code = 0) {
|
||||
return [200, { code, msg, data }];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 接口请求返回 正确返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
*/
|
||||
export function responseSuccess(data = {}, msg = "成功") {
|
||||
return response(data, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 接口请求返回 错误返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
* @param {Number} code 状态码
|
||||
*/
|
||||
export function responseError(data = {}, msg = "请求失败", code = 500) {
|
||||
return response(data, msg, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 记录和显示错误
|
||||
* @param {Error} error 错误对象
|
||||
*/
|
||||
let errorLogFlag = false;
|
||||
|
||||
export function errorLog(error) {
|
||||
// 打印到控制台
|
||||
// if (errorLogFlag) return;
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
//console.log(error);
|
||||
}
|
||||
// 显示提示
|
||||
// errorLogFlag = true;
|
||||
|
||||
// Message.error({
|
||||
// content: error.message,
|
||||
// duration: 5,
|
||||
// onClose: () => {
|
||||
// errorLogFlag = false;
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建一个错误
|
||||
* @param {String} msg 错误信息
|
||||
*/
|
||||
export function errorCreate(msg) {
|
||||
const error = new Error(msg);
|
||||
errorLog(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建一个错误弹窗
|
||||
* @param {String} msg
|
||||
*/
|
||||
let msgFlag = false;
|
||||
export function errorMsgCreate(msg) {
|
||||
// 显示提示
|
||||
if (msgFlag) return;
|
||||
msgFlag = true;
|
||||
Toast.fail({
|
||||
message: msg,
|
||||
duration: 5000,
|
||||
onClose: () => {
|
||||
msgFlag = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let loadingFlag = false;
|
||||
export function loadingMsgCreate(msg) {
|
||||
// 显示提示
|
||||
if (loadingFlag) return;
|
||||
loadingFlag = true;
|
||||
Toast.loading({
|
||||
message: msg,
|
||||
duration: 5000,
|
||||
forbidClick: true,
|
||||
onClose: () => {
|
||||
loadingFlag = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import low from "lowdb";
|
||||
import LocalStorage from "lowdb/adapters/LocalStorage";
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
//console.log(`${process.env.VUE_APP_LOCAL_CODE}-${process.env.VUE_APP_VERSION}`);
|
||||
const adapter = new LocalStorage(`${process.env.VUE_APP_LOCAL_CODE}-${process.env.VUE_APP_VERSION}`);
|
||||
const db = low(adapter);
|
||||
|
||||
db.defaults({
|
||||
sys: {},
|
||||
database: {},
|
||||
}).write();
|
||||
|
||||
export default db;
|
||||
|
||||
/**
|
||||
* @description 检查路径是否存在 不存在的话初始化
|
||||
* @param {Object} payload dbName {String} 数据库名称
|
||||
* @param {Object} payload path {String} 路径
|
||||
* @param {Object} payload user {Boolean} 区分用户
|
||||
* @param {Object} payload validator {Function} 数据校验钩子 返回 true 表示验证通过
|
||||
* @param {Object} payload defaultValue {*} 初始化默认值
|
||||
* @returns {String} 可以直接使用的路径
|
||||
*/
|
||||
export function pathInit({ dbName = "database", path = "", user = true, validator = () => true, defaultValue = "" }) {
|
||||
const uuid = db.get("database.public.uuid").value() ? db.get("database.public.uuid") : "ghost-uuid";
|
||||
const currentPath = `${dbName}.${user ? `user.${uuid}` : "public"}${path ? `.${path}` : ""}`;
|
||||
const value = db.get(currentPath).value();
|
||||
if (!(value !== undefined && validator(value))) {
|
||||
db.set(currentPath, defaultValue).write();
|
||||
}
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将数据存储到指定位置 | 路径不存在会自动初始化
|
||||
* @description 效果类似于取值 dbName.path = value
|
||||
* @param {Object} payload dbName {String} 数据库名称
|
||||
* @param {Object} payload path {String} 存储路径
|
||||
* @param {Object} payload value {*} 需要存储的值
|
||||
* @param {Object} payload user {Boolean} 是否区分用户
|
||||
*/
|
||||
export function dbSet({ dbName = "database", path = "", value = "", user = false }) {
|
||||
db.set(
|
||||
pathInit({
|
||||
dbName,
|
||||
path,
|
||||
user,
|
||||
}),
|
||||
value
|
||||
).write();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取数据
|
||||
* @description 效果类似于取值 dbName.path || defaultValue
|
||||
* @param {Object} payload dbName {String} 数据库名称
|
||||
* @param {Object} payload path {String} 存储路径
|
||||
* @param {Object} payload defaultValue {*} 取值失败的默认值
|
||||
* @param {Object} payload user {Boolean} 是否区分用户
|
||||
*/
|
||||
export function dbGet({ dbName = "database", path = "", defaultValue = "", user = false }) {
|
||||
return cloneDeep(
|
||||
db
|
||||
.get(
|
||||
pathInit({
|
||||
dbName,
|
||||
path,
|
||||
user,
|
||||
defaultValue,
|
||||
})
|
||||
)
|
||||
.value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取存储数据库对象
|
||||
* @param {Object} payload user {Boolean} 是否区分用户
|
||||
*/
|
||||
export function database({ dbName = "database", path = "", user = false, validator = () => true, defaultValue = "" } = {}) {
|
||||
return db.get(
|
||||
pathInit({
|
||||
dbName,
|
||||
path,
|
||||
user,
|
||||
validator,
|
||||
defaultValue,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
let dayjs = require("dayjs");
|
||||
import { round, split, join, size } from "lodash";
|
||||
import tools from "@/libs/util.tool.js";
|
||||
|
||||
const vFilter = {
|
||||
/**
|
||||
* @description 没有值返回 -
|
||||
*/
|
||||
filterDefaultVal(value) {
|
||||
if (!value && value !== 0) return "-";
|
||||
return value;
|
||||
},
|
||||
/**
|
||||
* @description 判断数字 且增加百分号 没有则返回-
|
||||
*/
|
||||
filterPercentage(value) {
|
||||
if (value === "-" || value === 0) return value;
|
||||
return round(value, 0) + "%";
|
||||
},
|
||||
/**
|
||||
* @description 格式化配速 或分秒结构
|
||||
*/
|
||||
filterTimeMS(value) {
|
||||
//console.log(value);
|
||||
if (value === "-") return value;
|
||||
if (value == 0) return "0秒";
|
||||
if (!value) return 0;
|
||||
let num = new Number(value);
|
||||
num = num.toFixed(0);
|
||||
let mm = parseInt(num / 60);
|
||||
let ss = num - mm * 60;
|
||||
|
||||
return mm + "分" + ss + "秒";
|
||||
},
|
||||
/**
|
||||
* @description 米=>公里
|
||||
*/
|
||||
filterDistanceSum(value) {
|
||||
if (value === "-" || value === 0) return value;
|
||||
if (!value) return "-";
|
||||
let num = new Number(value);
|
||||
|
||||
return num / 1000;
|
||||
},
|
||||
/**
|
||||
* @description 格式化时间
|
||||
* @parmas format => 标准时间格式
|
||||
|
||||
*/
|
||||
filterDayFormat4unix(value, format) {
|
||||
if (value === "-" || value === 0) return value;
|
||||
if (!value) return "-";
|
||||
return dayjs(value).format(format);
|
||||
},
|
||||
filterDayFormat(value, format) {
|
||||
if (value === "-" || value === 0) return value;
|
||||
if (!value) return "-";
|
||||
let _val = dayjs(value);
|
||||
|
||||
return dayjs(_val).format(format);
|
||||
},
|
||||
/**
|
||||
* @description 没有值返回 -
|
||||
*/
|
||||
filterDayErrorDuration(value) {
|
||||
if (dayjs(value).get("year") > 2010) {
|
||||
return value;
|
||||
} else {
|
||||
return "-";
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 格式化
|
||||
*/
|
||||
filterSexVal(value) {
|
||||
value = Number(value);
|
||||
switch (value) {
|
||||
case 1:
|
||||
return "男";
|
||||
break;
|
||||
case 0:
|
||||
return "女";
|
||||
break;
|
||||
default:
|
||||
return "-";
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 生日计算虚岁
|
||||
*/
|
||||
filterSexVal(date) {
|
||||
if (date === "-" || date === 0) return date;
|
||||
|
||||
let _dayjs = dayjs(date);
|
||||
return dayjs().year() - _dayjs.year();
|
||||
},
|
||||
/**
|
||||
* @description 计算显示最大字数
|
||||
*/
|
||||
filterStrSize(value, lens) {
|
||||
let _split, _res;
|
||||
let _lens = tools.getByteLen(value);
|
||||
|
||||
if (_lens > lens) {
|
||||
let _curlens = tools.getByteCurLen4Size(value, lens);
|
||||
//console.log(_curlens);
|
||||
|
||||
_split = split(value, "", _curlens);
|
||||
_split.push("...");
|
||||
_res = join(_split, "");
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
|
||||
return _res;
|
||||
},
|
||||
};
|
||||
|
||||
export default vFilter;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import db from "./util.db";
|
||||
import token from "./util.token";
|
||||
import url from "./util.url";
|
||||
|
||||
const util = {
|
||||
db,
|
||||
url,
|
||||
token,
|
||||
};
|
||||
|
||||
export default util;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import { Toast } from "vant";
|
||||
|
||||
const msg = {};
|
||||
|
||||
msg.success = function(msg) {
|
||||
Toast.success({
|
||||
message: msg,
|
||||
duration: 2000,
|
||||
showClose: true,
|
||||
});
|
||||
};
|
||||
|
||||
msg.error = function(msg) {
|
||||
Toast.fail({
|
||||
message: msg,
|
||||
duration: 2000,
|
||||
showClose: true,
|
||||
});
|
||||
};
|
||||
|
||||
msg.loading = function(msg) {
|
||||
let _toast = Toast.loading({
|
||||
message: msg,
|
||||
duration: 0,
|
||||
showClose: true,
|
||||
// className: "sys-my-toash",
|
||||
forbidClick: true,
|
||||
});
|
||||
return _toast;
|
||||
};
|
||||
|
||||
export default msg;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import { dbSet, dbGet } from "./util.db";
|
||||
import api from "@/api";
|
||||
import { now } from "lodash";
|
||||
|
||||
// 处理用户体系相关判断
|
||||
|
||||
const token = {};
|
||||
/**
|
||||
* @description 判断本地token是否有效
|
||||
* @return true => 有效
|
||||
*/
|
||||
export function isActiveToken() {
|
||||
const timeout = dbGet({ path: "token.expired" });
|
||||
const _token = dbGet({ path: "token.value" });
|
||||
let _access = true;
|
||||
if (_token) {
|
||||
// 注意 毫秒时间戳
|
||||
if (timeout < now()) {
|
||||
_access = false;
|
||||
removeToken();
|
||||
}
|
||||
} else {
|
||||
_access = false;
|
||||
}
|
||||
return _access;
|
||||
}
|
||||
|
||||
// 删除token
|
||||
export function removeToken() {
|
||||
dbSet({ path: "token", value: {} });
|
||||
}
|
||||
|
||||
export function setToken(token, time) {
|
||||
const tokenData = { value: token, expired: now() + time * 1000 };
|
||||
const data = { path: "token", value: tokenData };
|
||||
dbSet(data);
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
return dbGet({ path: "token.value" });
|
||||
}
|
||||
|
||||
export function BSkeySet(SecretKey, time) {
|
||||
const BSkeyData = { value: SecretKey, expired: time };
|
||||
const data = { path: "BSkey", value: BSkeyData };
|
||||
dbSet(data);
|
||||
}
|
||||
export function BSkeyGet() {
|
||||
// 返回 秘钥以及有效期
|
||||
return dbGet({ path: "BSkey" });
|
||||
}
|
||||
|
||||
export default token;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
const tools = {};
|
||||
export default tools;
|
||||
|
||||
export function getByteLen(val) {
|
||||
let len = 0;
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
let a = val.charAt(i);
|
||||
if (a.match(/[^\x00-\xff]/gi) != null) {
|
||||
len += 1;
|
||||
} else {
|
||||
len += 0.5;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
export function getByteCurLen4Size(val, size) {
|
||||
let len = 0;
|
||||
let curlen = 0;
|
||||
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
let a = val.charAt(i);
|
||||
if (a.match(/[^\x00-\xff]/gi) != null) {
|
||||
len += 1;
|
||||
} else {
|
||||
len += 0.5;
|
||||
}
|
||||
curlen += 1;
|
||||
|
||||
if (len >= size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return curlen;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
const url = {};
|
||||
export default url;
|
||||
|
||||
url.getQueryString = (name) => {
|
||||
const locString = window.location.href;
|
||||
let rs = new RegExp("(^|)" + name + "=([^&]*)(&|$)", "gi").exec(locString),
|
||||
tmp;
|
||||
if ((tmp = rs)) {
|
||||
return decodeURI(tmp[2]);
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import Vue from "vue";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "@/store/index";
|
||||
|
||||
// 自适配 rem
|
||||
import "amfe-flexible";
|
||||
import "amfe-flexible/index.js";
|
||||
|
||||
// 框架插件
|
||||
import plugin from "@/plugin/index";
|
||||
import vueFilter from "@/libs/util.filter.js";
|
||||
|
||||
Vue.use(plugin);
|
||||
|
||||
// add 全局过滤器
|
||||
for (let key in vueFilter) {
|
||||
Vue.filter(key, vueFilter[key]);
|
||||
}
|
||||
|
||||
import Vant from "vant";
|
||||
import "vant/lib/index.css";
|
||||
Vue.use(Vant);
|
||||
|
||||
import "element-ui/lib/theme-chalk/index.css";
|
||||
import ElementUI from "element-ui";
|
||||
Vue.use(ElementUI);
|
||||
|
||||
import * as echarts from "echarts";
|
||||
Vue.prototype.$echarts = echarts;
|
||||
import { Toast } from "vant";
|
||||
Vue.prototype.$toast = Toast;
|
||||
Toast.allowMultiple();
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
// 轻量级 播放器
|
||||
import vueMiniPlayer from "vue-mini-player";
|
||||
import "vue-mini-player/lib/vue-mini-player.css";
|
||||
Vue.use(vueMiniPlayer);
|
||||
|
||||
// 导出插件
|
||||
import JsonExcel from "vue-json-excel";
|
||||
Vue.component("DownloadExcel", JsonExcel);
|
||||
|
||||
// import Vconsole from "vconsole";
|
||||
// let vConsole = new Vconsole();
|
||||
// Vue.use(vConsole);
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: (h) => h(App),
|
||||
}).$mount("#app");
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import msg from "@/libs/util.message";
|
||||
import api from "@/api";
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.prototype.$msg = msg;
|
||||
Vue.prototype.$api = api;
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import { includes, concat, get, values } from "lodash";
|
||||
|
||||
import { isActiveToken } from "@/libs/util.token";
|
||||
import store from "../store";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
import mobile from "./modules/mobile";
|
||||
import pc from "./modules/pc";
|
||||
import system from "./modules/system";
|
||||
|
||||
const routes = concat(system.children, mobile.children, pc.children);
|
||||
|
||||
const router = new VueRouter({
|
||||
// mode: "history",
|
||||
base: process.env.VUE_APP_PUBLIC_PATH,
|
||||
routes,
|
||||
});
|
||||
|
||||
// 路由守卫 进入路由之前
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 完整cur域名 wxjdk调用
|
||||
let curHref = window.location.href.split("#")[0];
|
||||
store.commit("plugin/wechat/setState", { name: "curHref", value: curHref });
|
||||
store.commit("plugin/wechat/setRedirUrl", { url: to.path });
|
||||
store.commit("plugin/wechat/setState", { name: "type", value: to.meta.type });
|
||||
store.dispatch("plugin/loading/open", "globalLoading");
|
||||
|
||||
let login = get(to.meta, "login", false);
|
||||
if (login) {
|
||||
await store.dispatch("plugin/wechat/userLogin");
|
||||
next();
|
||||
}
|
||||
|
||||
if (to.meta.auth) {
|
||||
let _access = isActiveToken();
|
||||
if (_access) {
|
||||
next();
|
||||
} else {
|
||||
if (to.meta.type === "mobile") {
|
||||
await store.dispatch("plugin/wechat/callbackWechat");
|
||||
} else {
|
||||
store.dispatch("plugin/loading/close", "globalLoading");
|
||||
next({ path: "/pc/login" });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
router.beforeResolve(async (to, from, next) => {
|
||||
let usrRegister = get(store.getters, "manage/register/userRegister", "");
|
||||
|
||||
if (to.meta.type === "mobile" && to.path !== "/mobile/register" && usrRegister) {
|
||||
let doRegister = get(store.state, "manage.register.doRegister");
|
||||
if (doRegister === false) {
|
||||
next({ path: "/mobile/register" });
|
||||
}
|
||||
}
|
||||
|
||||
let title = get(store.state, "plugin.baseinfo.title");
|
||||
if (title) {
|
||||
document.title = title;
|
||||
} else {
|
||||
document.title = process.env.VUE_APP_TITLE;
|
||||
}
|
||||
// 下拉刷新开关
|
||||
if (to.meta.refresh) {
|
||||
store.dispatch("plugin/page/able", "doRefresh");
|
||||
} else {
|
||||
store.dispatch("plugin/page/disable", "doRefresh");
|
||||
}
|
||||
// 防止屏幕抖动
|
||||
setTimeout(() => {
|
||||
store.dispatch("plugin/loading/close", "globalLoading");
|
||||
}, 500);
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
let login = true;
|
||||
let auth = true;
|
||||
let refresh = true;
|
||||
|
||||
export default {
|
||||
children: ((pre) => [
|
||||
// {
|
||||
// meta: { auth, type: pre, login, refresh },
|
||||
// path: `/`,
|
||||
// name: `index`,
|
||||
// component: () => import("@views/manage/mobile/index"),
|
||||
// },
|
||||
// {
|
||||
// path: `/${pre}/register`,
|
||||
// name: `${pre}register`,
|
||||
// component: () => import("@views/manage/mobile/register"),
|
||||
// meta: { auth, type: pre },
|
||||
// },
|
||||
// {
|
||||
// path: `/${pre}/question`,
|
||||
// name: `${pre}question`,
|
||||
// component: () => import("@views/manage/mobile/question"),
|
||||
// meta: { auth, type: pre },
|
||||
// },
|
||||
// {
|
||||
// path: `/${pre}/result`,
|
||||
// name: `${pre}result`,
|
||||
// component: () => import("@views/manage/mobile/result"),
|
||||
// meta: { auth, type: pre },
|
||||
// },
|
||||
// {
|
||||
// path: `/${pre}/test`,
|
||||
// name: `${pre}test`,
|
||||
// component: () => import("@views/manage/indextest"),
|
||||
// meta: { auth, type: pre, login },
|
||||
// },
|
||||
])("mobile"),
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
let login = true;
|
||||
let auth = true;
|
||||
|
||||
export default {
|
||||
children: ((pre) => [
|
||||
// {
|
||||
// path: `/${pre}/login`,
|
||||
// name: `${pre}login`,
|
||||
// component: () => import("@views/manage/pc/login"),
|
||||
// },
|
||||
])("pc"),
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
const meta = { auth: true };
|
||||
|
||||
export default {
|
||||
children: [
|
||||
{
|
||||
// 刷新页面
|
||||
path: "/",
|
||||
component: () => import("@views/index"),
|
||||
},
|
||||
{
|
||||
// 刷新页面
|
||||
path: "/redirect/:path*",
|
||||
name: "redirect",
|
||||
component: () => import("@views/redirect"),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
import createPersistedState from "vuex-persistedstate";
|
||||
|
||||
import plugin from "./modules/plugin";
|
||||
import manage from "./modules/manage";
|
||||
|
||||
import { set } from "lodash";
|
||||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
plugin,
|
||||
manage,
|
||||
},
|
||||
plugins: [
|
||||
createPersistedState({
|
||||
key: `${process.env.VUE_APP_LOCAL_CODE}-${process.env.VUE_APP_VERSION}-persisted`,
|
||||
reducer(val) {
|
||||
let _res = {};
|
||||
set(_res, "manage", val.manage);
|
||||
set(_res, "plugin.wechat.appid", val.plugin.wechat.appid);
|
||||
set(_res, "plugin.baseinfo", val.plugin.baseinfo);
|
||||
|
||||
return _res;
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* The file enables `@/store/index.js` to import all vuex modules
|
||||
* in a one-shot manner. There should not be any reason to edit this file.
|
||||
*/
|
||||
|
||||
const files = require.context("./modules", true, /\.js$/);
|
||||
const modules = {};
|
||||
|
||||
files.keys().forEach((key) => {
|
||||
modules[key.replace(/(\.\/|\.js)/g, "")] = files(key).default;
|
||||
});
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
modules,
|
||||
};
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
import { set, get, map, isArray, isObject, size, isEmpty } from "lodash";
|
||||
import apis from "@/api";
|
||||
import { now } from "lodash";
|
||||
import router from "@/router/index";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
// bind开关
|
||||
nowQs: 1,
|
||||
nowOptions: [],
|
||||
nowQsList: {},
|
||||
nowAsw: "",
|
||||
allQsList: "",
|
||||
historyQsList: [],
|
||||
historyOtList: [],
|
||||
answerQsList: {},
|
||||
start: "",
|
||||
duration: "",
|
||||
submit: false,
|
||||
errorList: [],
|
||||
redpackMsg: "恭喜发财",
|
||||
},
|
||||
getters: {
|
||||
qsSize: (state) => {
|
||||
return size(state.allQsList);
|
||||
},
|
||||
errorSize: (state, getters) => {
|
||||
return size(getters.errorDetailList);
|
||||
},
|
||||
errorDetailList: (state) => {
|
||||
let qsList = state.allQsList;
|
||||
let opList = state.historyOtList;
|
||||
let myasw = state.historyQsList;
|
||||
let curasw = state.errorList;
|
||||
let _res = [];
|
||||
|
||||
for (let index = 0; index < qsList.length; index++) {
|
||||
const item = qsList[index];
|
||||
let _qsID = item.ID;
|
||||
let cur = get(curasw, _qsID, "");
|
||||
let err = get(myasw, index + 1, "");
|
||||
|
||||
// 获取正确答案 没有则回答正确
|
||||
if (cur !== "" && cur !== err) {
|
||||
let content = item.Content;
|
||||
let options = get(opList, index + 1, "");
|
||||
_res.push({ index: index + 1, cur, err, content, options });
|
||||
}
|
||||
}
|
||||
return _res;
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
set(state, payload.name, payload.value);
|
||||
},
|
||||
clearState(state, payload) {
|
||||
let _val = get(state, payload.name);
|
||||
if (isArray(_val)) {
|
||||
set(state, payload.name, []);
|
||||
} else if (isObject(_val)) {
|
||||
set(state, payload.name, {});
|
||||
} else {
|
||||
set(state, payload.name, "");
|
||||
}
|
||||
},
|
||||
next(state, payload) {
|
||||
if (payload.qsSize === state.nowQs) return;
|
||||
set(state, "nowQs", state.nowQs + 1);
|
||||
},
|
||||
last(state) {
|
||||
if (state.nowQs === 1) return;
|
||||
let lastQs = state.nowQs - 1;
|
||||
set(state, "nowQs", lastQs);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 保存当前题目答案
|
||||
*/
|
||||
save({ state, commit }, payload) {
|
||||
let qs = state.nowQs;
|
||||
commit("setState", { name: ["historyQsList", qs], value: state.nowAsw });
|
||||
commit("setState", { name: ["answerQsList", state.nowQsList.ID], value: state.nowAsw });
|
||||
|
||||
commit("next", payload);
|
||||
},
|
||||
|
||||
/**
|
||||
* @description 下载新题目
|
||||
*/
|
||||
async loadQuestion({ commit }, payload) {
|
||||
const _this = this;
|
||||
commit("clearState", { name: "allQsList" });
|
||||
|
||||
let res = await apis.loadQuestionList();
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "allQsList", value: res });
|
||||
},
|
||||
/**
|
||||
* @description 根据nowQs 下载选项
|
||||
*/
|
||||
async loadQuestionItem({ state, commit }, payload) {
|
||||
const _this = this;
|
||||
commit("clearState", { name: "nowOptions" });
|
||||
let id = state.nowQsList.ID;
|
||||
let data = { id };
|
||||
let res = await apis.loadQuestionItem(data);
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "nowOptions", value: res });
|
||||
commit("setState", { name: ["historyOtList", state.nowQs], value: res });
|
||||
},
|
||||
/**
|
||||
* @description 切换题目
|
||||
*/
|
||||
async switchQs({ state, commit, dispatch }, payload) {
|
||||
let nowQsObj = get(state.allQsList, state.nowQs - 1);
|
||||
commit("clearState", { name: "nowAsw" });
|
||||
commit("setState", { name: "nowQsList", value: nowQsObj });
|
||||
|
||||
// 判断是否上一题
|
||||
let nextQsAsw = get(state.historyQsList, state.nowQs, "");
|
||||
if (nextQsAsw !== "") {
|
||||
commit("setState", { name: "nowAsw", value: nextQsAsw });
|
||||
commit("setState", { name: "nowOptions", value: get(state.historyOtList, state.nowQs, "") });
|
||||
} else {
|
||||
await dispatch("loadQuestionItem");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 提交题目
|
||||
*/
|
||||
async questionSubmit({ state, commit, dispatch, rootState }, payload) {
|
||||
const _this = this;
|
||||
let id = state.nowQsList.ID;
|
||||
|
||||
let duration = parseInt((now() - state.start) / 1000);
|
||||
let location = rootState.plugin.wechat.location;
|
||||
let answer = state.answerQsList;
|
||||
let inarea = rootState.plugin.wechat.inArea === true ? "是" : "否";
|
||||
// console.log(location, inarea);
|
||||
|
||||
let res = await apis.questionSubmit({ duration, location, answer, inarea });
|
||||
|
||||
if (res === false) return false;
|
||||
commit("setState", { name: "errorList", value: res.Reply });
|
||||
commit("setState", { name: "duration", value: duration });
|
||||
commit("setState", { name: "redpackMsg", value: res.Message });
|
||||
|
||||
// commit("setState", { name: "submit", value: true });
|
||||
},
|
||||
/**
|
||||
* @description 首次进入
|
||||
*/
|
||||
async firstQs({ state, commit, dispatch }, payload) {
|
||||
commit("setState", { name: "nowQs", value: 1 });
|
||||
commit("setState", { name: "submit", value: false });
|
||||
commit("setState", { name: "start", value: now() });
|
||||
},
|
||||
/**
|
||||
* @description 首次进入清空保存项
|
||||
*/
|
||||
async clearQuestion({ commit }, payload) {
|
||||
commit("clearState", { name: "historyQsList" });
|
||||
commit("clearState", { name: "historyOtList" });
|
||||
commit("clearState", { name: "answerQsList" });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
import { set, get, map, isArray, isObject, size, isEmpty } from "lodash";
|
||||
import apis from "@/api";
|
||||
import router from "@/router/index";
|
||||
import { Toast } from "vant";
|
||||
import msg from "@/libs/util.message";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
user: {},
|
||||
doRegister: false,
|
||||
adminAreaList: "",
|
||||
adminList: "",
|
||||
},
|
||||
getters: {
|
||||
userRegister: (state) => {
|
||||
let Mobile = get(state.user, "Mobile", "");
|
||||
let IDCard = get(state.user, "IDCard", "");
|
||||
let AdminID = get(state.user, "AdminID", "");
|
||||
if (isEmpty(Mobile) || isEmpty(IDCard) || isEmpty(AdminID)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
set(state, payload.name, payload.value);
|
||||
},
|
||||
clearState(state, payload) {
|
||||
let _val = get(state, payload.name);
|
||||
if (isArray(_val)) {
|
||||
set(state, payload.name, []);
|
||||
} else if (isObject(_val)) {
|
||||
set(state, payload.name, {});
|
||||
} else {
|
||||
set(state, payload.name, "");
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 获取网格长数据
|
||||
*/
|
||||
async loadAdminPerson({ commit }, data) {
|
||||
commit("clearState", { name: "adminList" });
|
||||
if (isEmpty(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let res = await apis.loadAdminPerson(data);
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "adminList", value: res });
|
||||
},
|
||||
/**
|
||||
* 获取辖区数据
|
||||
*/
|
||||
async loadAdminArea({ commit, state }) {
|
||||
commit("clearState", { name: "adminAreaList" });
|
||||
let res = await apis.loadAdminArea();
|
||||
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "adminAreaList", value: res });
|
||||
},
|
||||
/**
|
||||
* 提交注册
|
||||
*/
|
||||
async answererRegister({ commit, state }, data) {
|
||||
let res = await apis.answererRegister(data);
|
||||
|
||||
if (res === false) return;
|
||||
commit("plugin/tools/setState", { name: "searchList", value: res }, { root: true });
|
||||
commit("setState", { name: "doRegister", value: true });
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
import { set, get, map, isArray, isObject, size, cloneDeep } from "lodash";
|
||||
import apis from "@/api";
|
||||
import router from "@/router/index";
|
||||
import { Toast } from "vant";
|
||||
import msg from "@/libs/util.message";
|
||||
let dayjs = require("dayjs");
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
baseinfo: [],
|
||||
adminInfo: [],
|
||||
answerInfo: [],
|
||||
feeInfo: [],
|
||||
start: "",
|
||||
end: "",
|
||||
id: 0,
|
||||
answerSearchNumber: "",
|
||||
},
|
||||
getters: {
|
||||
adminInfo: (state) => {
|
||||
let adminInfo = cloneDeep(state.adminInfo);
|
||||
return map(adminInfo, (item) => {
|
||||
item.rate = ((item.ParticipateCount / item.PeopleCount) * 100).toFixed(1) + "%";
|
||||
item.curRate = ((item.ParticipateCount / item.PeopleCount) * 100).toFixed(1);
|
||||
return item;
|
||||
});
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
let name = payload.name;
|
||||
let value = payload.value;
|
||||
|
||||
if (!isArray(name)) {
|
||||
set(state, name, value);
|
||||
} else {
|
||||
if (size(name) === size(value) && isArray(value)) {
|
||||
map(name, (item, index) => set(state, item, get(value, index)));
|
||||
} else {
|
||||
map(name, (item) => set(state, item, value));
|
||||
}
|
||||
}
|
||||
},
|
||||
clearState(state, payload) {
|
||||
let _val = get(state, payload.name);
|
||||
if (isArray(_val)) {
|
||||
set(state, payload.name, []);
|
||||
} else if (isObject(_val)) {
|
||||
set(state, payload.name, {});
|
||||
} else {
|
||||
set(state, payload.name, "");
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 获取 基础信息
|
||||
*/
|
||||
async loadSummary({ commit, state }) {
|
||||
const _this = this;
|
||||
commit("clearState", { name: "baseinfo" });
|
||||
let res = await apis.loadSummary();
|
||||
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "baseinfo", value: res });
|
||||
},
|
||||
/**
|
||||
* 获取 考核信息
|
||||
*/
|
||||
async loadAssessment({ commit, state }) {
|
||||
const _this = this;
|
||||
commit("clearState", { name: "adminInfo" });
|
||||
let res = await apis.loadAssessment();
|
||||
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "adminInfo", value: res });
|
||||
},
|
||||
/**
|
||||
* 获取 用户信息
|
||||
*/
|
||||
async loadAnalysis({ commit, state }) {
|
||||
const _this = this;
|
||||
commit("clearState", { name: "answerInfo" });
|
||||
let id = state.id;
|
||||
if (id === 0) id = "";
|
||||
|
||||
let data = { id, start: state.start, end: state.end };
|
||||
let res = await apis.loadAnalysis(data);
|
||||
|
||||
if (res === false) return;
|
||||
//console.log(res);
|
||||
commit("setState", { name: "answerInfo", value: res });
|
||||
},
|
||||
/**
|
||||
* 获取 奖励发放时间
|
||||
*/
|
||||
async loadFee({ commit, state }) {
|
||||
commit("clearState", { name: "feeInfo" });
|
||||
let res = await apis.loadFee();
|
||||
|
||||
if (res === false) return;
|
||||
//console.log(res);
|
||||
commit("setState", { name: "feeInfo", value: res });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* The file enables `@/store/index.js` to import all vuex modules
|
||||
* in a one-shot manner. There should not be any reason to edit this file.
|
||||
*/
|
||||
|
||||
const files = require.context("./modules", true, /\.js$/);
|
||||
const modules = {};
|
||||
|
||||
files.keys().forEach((key) => {
|
||||
modules[key.replace(/(\.\/|\.js)/g, "")] = files(key).default;
|
||||
});
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
modules,
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import { set, get, map, isArray, isObject, size, isEmpty } from "lodash";
|
||||
import apis from "@/api";
|
||||
import router from "@/router/index";
|
||||
import { Toast } from "vant";
|
||||
import msg from "@/libs/util.message";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
title: "",
|
||||
orgName: "",
|
||||
},
|
||||
getters: {},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
let name = payload.name;
|
||||
let value = payload.value;
|
||||
|
||||
if (!isArray(name)) {
|
||||
set(state, name, value);
|
||||
} else {
|
||||
if (size(name) === size(value) && isArray(value)) {
|
||||
map(name, (item, index) => set(state, item, get(value, index)));
|
||||
} else {
|
||||
map(name, (item) => set(state, item, value));
|
||||
}
|
||||
}
|
||||
},
|
||||
clearState(state, payload) {
|
||||
let _val = get(state, payload.name);
|
||||
if (isArray(_val)) {
|
||||
set(state, payload.name, []);
|
||||
} else if (isObject(_val)) {
|
||||
set(state, payload.name, {});
|
||||
} else {
|
||||
set(state, payload.name, "");
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 设置页面title
|
||||
*/
|
||||
setWebBaseInfo({ state, commit, rootState }) {
|
||||
let user = rootState.manage.register.user;
|
||||
let orgName = user.OrgName;
|
||||
let ProJName = user.ProjectName;
|
||||
commit("setState", { name: ["orgName", "title"], value: [orgName, ProJName] });
|
||||
},
|
||||
|
||||
/**
|
||||
* 是否首页
|
||||
*/
|
||||
async getTitleSet({ state, commit, rootState }) {
|
||||
let title = state.title;
|
||||
//console.log(title);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { set } from "lodash";
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
// bind开关
|
||||
addDeviceId: false,
|
||||
},
|
||||
mutations: {
|
||||
setVisible(state, payload) {
|
||||
set(state, payload.dialogName, payload.dialogVisible);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 开启弹窗
|
||||
*/
|
||||
open({ commit }, name) {
|
||||
commit("setVisible", { dialogName: name, dialogVisible: true });
|
||||
},
|
||||
/**
|
||||
* @description 关闭弹窗
|
||||
*/
|
||||
close({ commit }, name) {
|
||||
commit("setVisible", { dialogName: name, dialogVisible: false });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { set } from "lodash";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
// 全局开关
|
||||
globalLoading: true,
|
||||
refreshLoading: false,
|
||||
},
|
||||
mutations: {
|
||||
setVisible(state, payload) {
|
||||
set(state, payload.name, payload.visible);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 开启对应加载条
|
||||
*/
|
||||
open({ commit }, name) {
|
||||
commit("setVisible", { name: name, visible: true });
|
||||
},
|
||||
/**
|
||||
* @description 关闭对应加载条
|
||||
*/
|
||||
close({ commit }, name) {
|
||||
commit("setVisible", { name: name, visible: false });
|
||||
},
|
||||
/**
|
||||
* @description 页面刷新
|
||||
*/
|
||||
refresh({ commit, dispatch }) {
|
||||
// commit("setVisible", { name: "refreshLoading", visible: false });
|
||||
|
||||
setTimeout(() => {
|
||||
dispatch("close", "refreshLoading");
|
||||
}, 1000);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import { set } from "lodash";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
doRefresh: true,
|
||||
},
|
||||
|
||||
mutations: {
|
||||
setVisible(state, payload) {
|
||||
set(state, payload.name, payload.visible);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 展示
|
||||
*/
|
||||
able({ commit }, name) {
|
||||
commit("setVisible", { name: name, visible: true });
|
||||
},
|
||||
/**
|
||||
* @description 隐藏
|
||||
*/
|
||||
disable({ commit }, name) {
|
||||
commit("setVisible", { name: name, visible: false });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { set } from "lodash";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
showPos: false,
|
||||
showHls: false,
|
||||
},
|
||||
|
||||
mutations: {
|
||||
setVisible(state, payload) {
|
||||
set(state, payload.comName, payload.visible);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 展示
|
||||
*/
|
||||
display({ commit }, name) {
|
||||
commit("setVisible", { comName: name, visible: true });
|
||||
},
|
||||
/**
|
||||
* @description 隐藏
|
||||
*/
|
||||
hide({ commit }, name) {
|
||||
commit("setVisible", { comName: name, visible: false });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { set } from "lodash";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
duration: "", // 日,周,月,年的英文 与dayjs (add, subtract)方法强关联 如果参数值变更 请修改相关方法
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
set(state, payload.name, payload.value);
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
};
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { set, get, map, isArray, isObject, size, isEmpty } from "lodash";
|
||||
|
||||
import apis from "@/api";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
searchList: [],
|
||||
checkVal: "",
|
||||
videoUrl: "",
|
||||
noticeList: [],
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
set(state, payload.name, payload.value);
|
||||
},
|
||||
clearState(state, payload) {
|
||||
let _val = get(state, payload.name);
|
||||
if (isArray(_val)) {
|
||||
set(state, payload.name, []);
|
||||
} else if (isObject(_val)) {
|
||||
set(state, payload.name, {});
|
||||
} else {
|
||||
set(state, payload.name, "");
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 随机获取一个视频地址
|
||||
*/
|
||||
async loadVideoUrl({ commit, state, dispatch }) {
|
||||
const _this = this;
|
||||
let res = await apis.loadVideoUrl();
|
||||
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "videoUrl", value: res });
|
||||
},
|
||||
/**
|
||||
* 视频播放计数
|
||||
*/
|
||||
async videoPlayCount() {
|
||||
let res = await apis.videoPlayCount();
|
||||
if (res === false) return;
|
||||
},
|
||||
/**
|
||||
* 头部滚动条 数据
|
||||
*/
|
||||
async loadNoticePrice({ commit, state }) {
|
||||
const _this = this;
|
||||
let res = await apis.loadNoticePrice();
|
||||
commit("clearState", { name: "noticeList" });
|
||||
|
||||
if (res === false) return;
|
||||
commit("setState", { name: "noticeList", value: res });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
import util from "@/libs/util";
|
||||
import { isActiveToken, setToken, removeToken } from "@/libs/util.token";
|
||||
import { set, includes, isEmpty, split } from "lodash";
|
||||
import apis from "@/api";
|
||||
import router from "@/router/index";
|
||||
import { Toast } from "vant";
|
||||
import wx from "weixin-js-sdk";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
code: "",
|
||||
appid: "",
|
||||
token: "",
|
||||
loginCount: 0,
|
||||
wx: "",
|
||||
// firstIn: true,
|
||||
curHref: "",
|
||||
redirect_uri: "",
|
||||
orgin: "https://www.yyjishu.com/antifraud/#",
|
||||
location: "",
|
||||
inArea: false,
|
||||
proj: "",
|
||||
isPcLoginSuccess: false,
|
||||
type: "",
|
||||
},
|
||||
getters: {
|
||||
isSuperAdmin: (state, getters, rootState) => {
|
||||
let user = rootState.manage.register.user;
|
||||
if (!user) return false;
|
||||
|
||||
if (user.Role === "街道办") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setState(state, payload) {
|
||||
set(state, payload.name, payload.value);
|
||||
},
|
||||
countLogin(state) {
|
||||
set(state, "loginCount", state.loginCount + 1);
|
||||
},
|
||||
setRedirUrl(state, payload) {
|
||||
let host = location.origin + process.env.VUE_APP_PUBLIC_PATH + "#";
|
||||
set(state, "redirect_uri", host + payload.url);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 无token登录流程
|
||||
*/
|
||||
|
||||
async userLogin({ state, commit, dispatch }) {
|
||||
let _doAuth = await dispatch("getUrlCode");
|
||||
if (_doAuth) {
|
||||
let _authSuccess = await dispatch("authUser");
|
||||
if (!_authSuccess) {
|
||||
Toast("用户鉴权失败,建议重新打开页面!");
|
||||
}
|
||||
await dispatch("replaceUrl");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @description 替换当前页面
|
||||
*/
|
||||
async replaceUrl({ state, commit, dispatch }) {
|
||||
let redirUrl = state.redirect_uri;
|
||||
window.location.href = redirUrl;
|
||||
},
|
||||
/**
|
||||
* @description 回调无感登录
|
||||
*/
|
||||
async callbackWechat({ commit, dispatch }) {
|
||||
let url = "https://open.weixin.qq.com/connect/oauth2/authorize";
|
||||
let appid = "wxd69449ebd878fa6d";
|
||||
let redirect_uri = "https%3A%2F%2Fwww.yyjishu.com%2Fantifraud%2F%23%2F%3Fproj%3D1%26appid%3Dwxd69449ebd878fa6d";
|
||||
let response_type = "code";
|
||||
let scope = "snsapi_userinfo#wechat_redirect";
|
||||
location.href = `${url}?appid=${appid}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}`;
|
||||
},
|
||||
/**
|
||||
* @description 获取url里 code appid proj值 并储存
|
||||
*/
|
||||
async getUrlCode({ commit, dispatch }) {
|
||||
let code = util.url.getQueryString("code");
|
||||
let appid = util.url.getQueryString("appid");
|
||||
let proj = util.url.getQueryString("proj");
|
||||
|
||||
if (isEmpty(code) || isEmpty(appid) || isEmpty(proj)) {
|
||||
return false;
|
||||
}
|
||||
commit("setState", { name: "code", value: code });
|
||||
commit("setState", { name: "appid", value: appid });
|
||||
commit("setState", { name: "proj", value: proj });
|
||||
return true;
|
||||
// await dispatch("userLogin");
|
||||
},
|
||||
/**
|
||||
* @description 用户鉴权
|
||||
*/
|
||||
async authUser({ state, commit, dispatch }) {
|
||||
let res = await apis.authWx({ code: state.code, appid: state.appid, proj: state.proj });
|
||||
if (res === false) {
|
||||
return false;
|
||||
}
|
||||
let { token, expirein, user } = res;
|
||||
commit("setState", { name: "token", value: token });
|
||||
commit("manage/register/setState", { name: "user", value: user }, { root: true });
|
||||
setToken(token, expirein);
|
||||
// 设置页面基础信息
|
||||
await dispatch("plugin/baseinfo/setWebBaseInfo", {}, { root: true });
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* @description 用户token失效 提示信息
|
||||
*/
|
||||
userInfoFailMsg() {
|
||||
Toast.fail({
|
||||
message: "用户登录失败\n请关闭后重试",
|
||||
overlay: true,
|
||||
duration: 0,
|
||||
});
|
||||
},
|
||||
layout({ commit }) {
|
||||
removeToken();
|
||||
// commit("setState", { name: "firstIn", value: true });
|
||||
commit("setState", "token");
|
||||
},
|
||||
/**
|
||||
* @description 微信jdk 鉴权
|
||||
*/
|
||||
async wxConfig({ state, commit, dispatch }) {
|
||||
//通过config接口注入权限验证配置 只要调后端接口就可以了。后端会把那些信息处理好,然后通过一个接口返给你这些参数
|
||||
let appId = state.appid;
|
||||
let uri = state.curHref;
|
||||
//console.log(appId, uri);
|
||||
let res = await apis.loadConfigInfo({ appid: appId, uri });
|
||||
if (res === false) {
|
||||
//console.log("wxconfig 注入失败");
|
||||
return;
|
||||
}
|
||||
let timestamp = res.Timestamp;
|
||||
let signature = res.Signature;
|
||||
let nonceStr = res.NonceStr;
|
||||
|
||||
wx.config({
|
||||
debug: false,
|
||||
appId,
|
||||
timestamp,
|
||||
signature,
|
||||
nonceStr,
|
||||
jsApiList: [
|
||||
"checkJsApi",
|
||||
"onMenuShareTimeline",
|
||||
"onMenuShareAppMessage",
|
||||
"onMenuShareQQ",
|
||||
"onMenuShareWeibo",
|
||||
"onMenuShareQZone",
|
||||
"hideMenuItems",
|
||||
"showMenuItems",
|
||||
"hideAllNonBaseMenuItem",
|
||||
"showAllNonBaseMenuItem",
|
||||
"translateVoice",
|
||||
"startRecord",
|
||||
"stopRecord",
|
||||
"onVoiceRecordEnd",
|
||||
"playVoice",
|
||||
"onVoicePlayEnd",
|
||||
"pauseVoice",
|
||||
"stopVoice",
|
||||
"uploadVoice",
|
||||
"downloadVoice",
|
||||
"chooseImage",
|
||||
"previewImage",
|
||||
"uploadImage",
|
||||
"downloadImage",
|
||||
"getNetworkType",
|
||||
"openLocation",
|
||||
"getLocation",
|
||||
"hideOptionMenu",
|
||||
"showOptionMenu",
|
||||
"closeWindow",
|
||||
"scanQRCode",
|
||||
"chooseWXPay",
|
||||
"openProductSpecificView",
|
||||
"addCard",
|
||||
"chooseCard",
|
||||
"openCard",
|
||||
],
|
||||
});
|
||||
wx.error(function(res) {
|
||||
Toast(res);
|
||||
});
|
||||
|
||||
commit("setState", { name: "wx", value: wx });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取地理位置
|
||||
*/
|
||||
getLocation({ commit, state, dispatch }) {
|
||||
return new Promise((resolve) => {
|
||||
state.wx.ready(function() {
|
||||
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
|
||||
state.wx.getLocation({
|
||||
type: "gcj02",
|
||||
success: function(res) {
|
||||
resolve(res);
|
||||
},
|
||||
fail: function(res) {
|
||||
Toast(res);
|
||||
resolve(res);
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
async isInArea({ commit, state, dispatch }) {
|
||||
await dispatch("wxConfig");
|
||||
let _getSuceess = dispatch("getLocation");
|
||||
_getSuceess.then((res) => {
|
||||
let { latitude, longitude } = res;
|
||||
console.log(latitude, longitude);
|
||||
|
||||
if (!latitude || !longitude) return;
|
||||
commit("setState", { name: "location", value: latitude + "," + longitude });
|
||||
dispatch("isPointInPolygon");
|
||||
});
|
||||
},
|
||||
isPointInPolygon({ state, commit }) {
|
||||
let path = [
|
||||
new TMap.LatLng(29.943883, 121.602682),
|
||||
new TMap.LatLng(29.955313, 121.602796),
|
||||
new TMap.LatLng(29.957481, 121.606207),
|
||||
new TMap.LatLng(29.960929, 121.605297),
|
||||
new TMap.LatLng(29.961914, 121.602568),
|
||||
new TMap.LatLng(29.97876, 121.603023),
|
||||
new TMap.LatLng(29.978681, 121.6091),
|
||||
new TMap.LatLng(29.980653, 121.609911),
|
||||
new TMap.LatLng(29.980753, 121.60585),
|
||||
new TMap.LatLng(29.988618, 121.60577),
|
||||
new TMap.LatLng(29.988871, 121.606063),
|
||||
new TMap.LatLng(29.994632, 121.605825),
|
||||
new TMap.LatLng(29.994702, 121.606464),
|
||||
new TMap.LatLng(29.996293, 121.606357),
|
||||
new TMap.LatLng(29.996546, 121.607156),
|
||||
new TMap.LatLng(29.998391, 121.606758),
|
||||
new TMap.LatLng(29.998908, 121.605797),
|
||||
new TMap.LatLng(29.999143, 121.605863),
|
||||
new TMap.LatLng(30.001682, 121.608335),
|
||||
new TMap.LatLng(30.001682, 121.608335),
|
||||
new TMap.LatLng(30.008685, 121.615431),
|
||||
new TMap.LatLng(30.009024, 121.618805),
|
||||
new TMap.LatLng(30.003759, 121.620452),
|
||||
new TMap.LatLng(30.002604, 121.617118),
|
||||
new TMap.LatLng(29.993428, 121.620547),
|
||||
new TMap.LatLng(29.993025, 121.619473),
|
||||
new TMap.LatLng(29.992184, 121.619874),
|
||||
new TMap.LatLng(29.991971, 121.620004),
|
||||
new TMap.LatLng(29.992139, 121.620845),
|
||||
new TMap.LatLng(29.987921, 121.623377),
|
||||
new TMap.LatLng(29.989076, 121.625925),
|
||||
new TMap.LatLng(29.984816, 121.628779),
|
||||
new TMap.LatLng(29.984911, 121.632577),
|
||||
new TMap.LatLng(29.979536, 121.635368),
|
||||
new TMap.LatLng(29.980577, 121.637394),
|
||||
new TMap.LatLng(29.975834, 121.643542),
|
||||
new TMap.LatLng(29.97771, 121.641016),
|
||||
new TMap.LatLng(29.979254, 121.643073),
|
||||
new TMap.LatLng(29.97518, 121.647262),
|
||||
new TMap.LatLng(29.9688, 121.636516),
|
||||
new TMap.LatLng(29.965233, 121.642626),
|
||||
new TMap.LatLng(29.964734, 121.637667),
|
||||
new TMap.LatLng(29.961819, 121.640147),
|
||||
new TMap.LatLng(29.960027, 121.636711),
|
||||
new TMap.LatLng(29.963852, 121.632747),
|
||||
new TMap.LatLng(29.960842, 121.630316),
|
||||
new TMap.LatLng(29.958927, 121.631453),
|
||||
new TMap.LatLng(29.956739, 121.626875),
|
||||
new TMap.LatLng(29.956126, 121.627974),
|
||||
new TMap.LatLng(29.953059, 121.626664),
|
||||
new TMap.LatLng(29.950817, 121.624055),
|
||||
new TMap.LatLng(29.951889, 121.622536),
|
||||
new TMap.LatLng(29.951689, 121.614817),
|
||||
new TMap.LatLng(29.949841, 121.608112),
|
||||
new TMap.LatLng(29.948257, 121.605613),
|
||||
new TMap.LatLng(29.943133, 121.603358),
|
||||
];
|
||||
|
||||
let _resLos = split(state.location, ",");
|
||||
let [lat, lng] = _resLos;
|
||||
// console.log(lat, lng);
|
||||
let userPot = new TMap.LatLng(lat, lng);
|
||||
let res = TMap.geometry.isPointInPolygon(userPot, path);
|
||||
// console.log(res);
|
||||
|
||||
// if (res === false) {
|
||||
// let test = [
|
||||
// new TMap.LatLng(29.816871, 121.486682),
|
||||
// new TMap.LatLng(29.818024, 121.48849),
|
||||
// new TMap.LatLng(29.816262, 121.490207),
|
||||
// new TMap.LatLng(29.814805, 121.488564),
|
||||
// ];
|
||||
// res = TMap.geometry.isPointInPolygon(userPot, test);
|
||||
// }
|
||||
|
||||
commit("setState", { name: "inArea", value: res });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* 全局变量
|
||||
* 命名规范 —— 遵守语义化命名:lg-大号、md-中号、base-基本号、sm-小号、mini-超小号
|
||||
*/
|
||||
|
||||
$font-weight-base: bold;
|
||||
$font-weight-none: 200px;
|
||||
|
||||
$border-color-dark: #e6e6e6;
|
||||
$border-color-base: #dcdfe6;
|
||||
$border-color-light: #e4e7ed;
|
||||
$border-color-lighter: #ebeef5;
|
||||
$border-color-xlight: #f2f6fc;
|
||||
|
||||
$font-color-primary: #303133;
|
||||
$font-color-regular: #606266;
|
||||
$font-color-secondary: #909399;
|
||||
|
||||
$font-size-lg: xx-large;
|
||||
$font-size-md: large;
|
||||
$font-size-base: middle;
|
||||
$font-size-sm: small;
|
||||
$font-size-mini: x-small;
|
||||
|
||||
$color-backgroud-primay: white;
|
||||
|
||||
$color-primary: #409eff;
|
||||
$color-important: #222222;
|
||||
$color-common: #606060;
|
||||
$color-desc: #909090;
|
||||
$color-disabled: #bfbfbf;
|
||||
$color-success: #67c23a;
|
||||
$color-error: #f56c6c;
|
||||
$color-warn: #e6a23c;
|
||||
$color-info: #909399;
|
||||
$color-lighting: #9013fe;
|
||||
|
||||
$line-height-none: 1;
|
||||
$line-height-compact: 1.3;
|
||||
$line-height-base: 1.5;
|
||||
$line-height-loose: 1.7;
|
||||
|
||||
$line-pc-margin: 20px;
|
||||
|
|
@ -0,0 +1,490 @@
|
|||
|
||||
@import './settings.scss';
|
||||
|
||||
$mobile-color-main: #ee6a59;
|
||||
$mobile-color-font: #3e3c36;
|
||||
$mobile-color-font-secend: #878787;
|
||||
$mobile-color-font-contrast: white;
|
||||
|
||||
$mobile-color-title: grey;
|
||||
|
||||
$mobile-font-thin: 300px;
|
||||
$mobile-font-bold: bold;
|
||||
$mobile-font-bolder: bolder;
|
||||
|
||||
$mobile-padding-left: 1rem;
|
||||
.icon-large {
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
.icon-big {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
.icon-small {
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
width: 3rem;
|
||||
height: 2rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
.icon-button-middle {
|
||||
width: 4rem;
|
||||
height: 3rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
.icon-button-big {
|
||||
width: 5rem;
|
||||
height: 2rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mobile-box-index {
|
||||
@include wh(100%, auto);
|
||||
padding: 0.7rem $mobile-padding-left;
|
||||
background-color: white;
|
||||
|
||||
.box-title {
|
||||
@include sc($mobile-font-base, $mobile-color-font);
|
||||
text-align: start;
|
||||
line-height: 1.2rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
.box-secend-title {
|
||||
@include sc($mobile-font-sm, $mobile-color-font-secend);
|
||||
text-align: end;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
.box-map {
|
||||
@include border-radius;
|
||||
}
|
||||
|
||||
.content {
|
||||
@include sc($mobile-font-base, $mobile-color-font);
|
||||
}
|
||||
.content-sm {
|
||||
@include sc($mobile-font-sm, $mobile-color-font);
|
||||
}
|
||||
.grey-backgd {
|
||||
background-color: #f7f8f9;
|
||||
}
|
||||
.icon {
|
||||
width: $mobile-font-base;
|
||||
height: $mobile-font-base;
|
||||
}
|
||||
}
|
||||
|
||||
.health-box-index {
|
||||
@include border-radius;
|
||||
@include wh(100%, auto);
|
||||
|
||||
background-color: rgb(250, 130, 225, 0.15);
|
||||
margin-bottom: 1rem;
|
||||
padding: 0.5rem 0.2rem;
|
||||
.col-name {
|
||||
@include sc($mobile-font-base, #3e3c36);
|
||||
font-weight: bold;
|
||||
}
|
||||
.col-unit {
|
||||
@include sc($mobile-font-sm, #3e3c36);
|
||||
}
|
||||
.col-content {
|
||||
@include sc($mobile-font-bg, #3e3c36);
|
||||
font-weight: bold;
|
||||
line-height: 3.5rem;
|
||||
text-align: start;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
.col-icon {
|
||||
width: $mobile-font-bg;
|
||||
height: $mobile-font-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-box-user {
|
||||
padding-top: 0.5rem;
|
||||
|
||||
.user-name {
|
||||
@include sc($mobile-font-md, $mobile-color-font);
|
||||
font-weight: normal;
|
||||
line-height: 2.5rem;
|
||||
text-align: start;
|
||||
}
|
||||
.org-name {
|
||||
@include sc($mobile-font-xsm, $mobile-color-font);
|
||||
font-weight: bold;
|
||||
line-height: 2.5rem;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
.user-avatar {
|
||||
@extend .icon-big;
|
||||
vertical-align: -0.15rem;
|
||||
}
|
||||
|
||||
.user-avatar-switch {
|
||||
width: 2rem;
|
||||
height: 2.8rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 4.4rem;
|
||||
left: 4rem;
|
||||
}
|
||||
.user-small {
|
||||
@extend .icon-small;
|
||||
vertical-align: -0.24rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-device-button {
|
||||
background-color: rgb(55, 115, 180, 0.15);
|
||||
border-radius: 1.5rem;
|
||||
padding: 0.1rem 0.5rem;
|
||||
.col-content {
|
||||
@include sc($mobile-font-sm, #5d9eff);
|
||||
}
|
||||
.col-icon {
|
||||
@extend .icon-small;
|
||||
vertical-align: -0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-postion-box {
|
||||
padding: 0.5rem 0.2rem;
|
||||
background-color: rgb(0, 0, 0, 0);
|
||||
|
||||
.icon {
|
||||
@extend .icon-small;
|
||||
vertical-align: -0.2rem;
|
||||
}
|
||||
.position {
|
||||
@include sc($mobile-font-base, #5d9eff);
|
||||
}
|
||||
.time {
|
||||
@include sc($mobile-font-sm, #878787);
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-rank-box {
|
||||
padding: 1.2rem 1rem;
|
||||
@include sc($mobile-font-base, #3e3c36);
|
||||
.col-left {
|
||||
text-align: start;
|
||||
}
|
||||
.col-right {
|
||||
text-align: end;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-share-index {
|
||||
@include wh(auto, auto);
|
||||
min-height: 100vh;
|
||||
max-width: 100vw;
|
||||
background-color: #f6f7f8;
|
||||
padding: 3.5rem 1rem 2rem 1rem;
|
||||
|
||||
.mobile-share-box {
|
||||
@include border-radius;
|
||||
background-color: #ffffff;
|
||||
padding: 1.2rem 1.2rem 1.2rem 1.2rem;
|
||||
margin-bottom: 1rem;
|
||||
.code-msg {
|
||||
@include sc($mobile-font-sm, #303030);
|
||||
}
|
||||
.main-msg {
|
||||
@include sc($mobile-font-base, #303030);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-device-box {
|
||||
@include wh(auto, auto);
|
||||
@include border-radius;
|
||||
max-width: 100vw;
|
||||
padding: 0.5rem;
|
||||
// margin: 0 2rem;
|
||||
|
||||
.device-icon {
|
||||
margin-top: 0.5rem;
|
||||
// @extend .icon-button-middle;
|
||||
}
|
||||
|
||||
.main-info {
|
||||
@include sc($mobile-font-base, #000000);
|
||||
line-height: 2rem;
|
||||
}
|
||||
.secend-info {
|
||||
@include sc($mobile-font-sm, #3e3c36);
|
||||
text-align: start;
|
||||
}
|
||||
.unbind-icon {
|
||||
@extend .icon-button-middle;
|
||||
}
|
||||
}
|
||||
.mobile-dvtype-index {
|
||||
background-color: #f6f7f8;
|
||||
@include wh(auto, auto);
|
||||
min-height: 100vh;
|
||||
max-width: 100vw;
|
||||
padding: 1rem 1.5rem;
|
||||
|
||||
.mobile-dvtype-box {
|
||||
@extend .mobile-device-box;
|
||||
background-color: #ffffff;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.button-icon {
|
||||
@extend .icon-button-big;
|
||||
vertical-align: -1.5rem;
|
||||
}
|
||||
}
|
||||
.mobile-device-advice {
|
||||
@include wh(auto, auto);
|
||||
@include full-screen;
|
||||
background-color: #0b0e15;
|
||||
|
||||
.main-icon {
|
||||
width: auto;
|
||||
height: auto;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
vertical-align: -0.2rem;
|
||||
}
|
||||
.button-icon {
|
||||
width: 6rem;
|
||||
height: 3rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
vertical-align: -3rem;
|
||||
}
|
||||
.buy-icon {
|
||||
width: 10rem;
|
||||
height: 3rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
vertical-align: -3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-dvdetail-index {
|
||||
@include full-screen;
|
||||
@include wh(auto, auto);
|
||||
background-color: #f8f9fd;
|
||||
|
||||
.device-detail-info {
|
||||
background-color: #efeff7;
|
||||
padding: 3rem 1rem;
|
||||
padding-top: 3rem;
|
||||
.bracelet-icon {
|
||||
padding-top: 0.4rem;
|
||||
}
|
||||
.state-msg {
|
||||
@include sc($mobile-font-bg, #303030);
|
||||
// font-weight: bold;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
.secend-msg {
|
||||
@include sc($mobile-font-base, #303030);
|
||||
opacity: 0.8;
|
||||
line-height: 1.4rem;
|
||||
text-align: start;
|
||||
}
|
||||
}
|
||||
.mobile-detail-content {
|
||||
padding: 2rem;
|
||||
|
||||
.detail-box-index {
|
||||
@include border-radius;
|
||||
@include sc($mobile-font-base, #303030);
|
||||
// font-weight: bold;
|
||||
line-height: 2rem;
|
||||
|
||||
background-color: #ffffff;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-org-box {
|
||||
@include wh(auto, auto);
|
||||
@include border-radius;
|
||||
max-width: 100vw;
|
||||
padding: 0.5rem;
|
||||
// margin: 0 2rem;
|
||||
|
||||
.device-icon {
|
||||
margin-top: 0.5rem;
|
||||
@extend .icon-button-middle;
|
||||
}
|
||||
|
||||
.main-info {
|
||||
@include sc($mobile-font-base, #000000);
|
||||
line-height: 2rem;
|
||||
}
|
||||
.secend-info {
|
||||
@include sc($mobile-font-sm, #3e3c36);
|
||||
text-align: start;
|
||||
}
|
||||
.unbind-icon {
|
||||
@extend .icon-button-middle;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-identity-sign {
|
||||
@include sc($mobile-font-xsm, #d5b870);
|
||||
line-height: 1.5;
|
||||
padding: 0 0.3rem;
|
||||
font-weight: bold;
|
||||
margin-left: 1rem;
|
||||
background-color: black;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.mobile-position-mapinfo {
|
||||
@include sc($mobile-font-md, #303030);
|
||||
|
||||
background-color: white;
|
||||
text-align: start;
|
||||
.icon {
|
||||
@extend .icon-small;
|
||||
vertical-align: -0.2rem;
|
||||
}
|
||||
.content {
|
||||
@include sc($mobile-font-base, #5d9eff);
|
||||
}
|
||||
}
|
||||
.detail-weektime-btn {
|
||||
color: black;
|
||||
background: black;
|
||||
border-radius: 1rem;
|
||||
background-color: white;
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-detail-infobox {
|
||||
.title {
|
||||
@include sc($mobile-font-base, #303030);
|
||||
text-align: start;
|
||||
font-weight: bold;
|
||||
padding-left: 1rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.1rem;
|
||||
}
|
||||
.title-mark {
|
||||
@include sc($mobile-font-xsm, grey);
|
||||
padding-bottom: 0.1rem;
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
.reference {
|
||||
@include sc($mobile-font-xsm, grey);
|
||||
text-align: end;
|
||||
opacity: 0.5;
|
||||
padding-right: 1rem;
|
||||
padding-bottom: 0.1rem;
|
||||
}
|
||||
.eval {
|
||||
@include sc($mobile-font-sm, #777777);
|
||||
padding: 1rem;
|
||||
text-align: start;
|
||||
background-color: white;
|
||||
|
||||
.bigval {
|
||||
font-size: $mobile-font-bg;
|
||||
font-weight: bolder;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
}
|
||||
.progress-index {
|
||||
background-color: #f4f5f5;
|
||||
padding-top: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////布局 block////////////
|
||||
.sys-padding-block {
|
||||
@include wh(auto, 1rem);
|
||||
}
|
||||
.layout-title-content {
|
||||
@include wh(auto, 2rem);
|
||||
@include sc($mobile-font-sm, #666666);
|
||||
line-height: 2rem;
|
||||
padding: 0 $mobile-padding-left;
|
||||
background-color: #f8f9fd;
|
||||
text-align: start;
|
||||
}
|
||||
.sys-text-left {
|
||||
text-align: start;
|
||||
}
|
||||
.sys-text-right {
|
||||
text-align: end;
|
||||
}
|
||||
.sys-btn-radius {
|
||||
.van-button {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sys-btn-card-allscreen {
|
||||
background-color: #f6f6f6;
|
||||
min-height: 100vh;
|
||||
padding: 1rem;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sys-box-index {
|
||||
background-color: white;
|
||||
padding: 1rem;
|
||||
margin: 0.5rem 0;
|
||||
line-height: 1.2;
|
||||
border-radius: 0.2rem;
|
||||
box-shadow: 0 2px 4px 0 rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.sys-bottom-border {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
.sys-big-title {
|
||||
@include sc($mobile-font-bger, white);
|
||||
line-height: 2;
|
||||
font-weight: bold;
|
||||
}
|
||||
.sys-sm-title {
|
||||
@include sc($mobile-font-sm, white);
|
||||
line-height: 2;
|
||||
}
|
||||
.sys-pc-bgtitle {
|
||||
@include sc($pc-font-sm, white);
|
||||
height: $pc-font-md;
|
||||
line-height: 1.5;
|
||||
text-align: start;
|
||||
padding: 0.1rem 0rem 0.1rem 0.4rem;
|
||||
background-color: #aadcff;
|
||||
box-shadow: 0 2px 4px 0 rgb(0 0 0 / 10%);
|
||||
span {
|
||||
@include sc($pc-font-xsm, white);
|
||||
}
|
||||
}
|
||||
.sys-my-toash {
|
||||
background-color: #5d9eff;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
$progresspadding: 30px;
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.title-lg {
|
||||
@include ft($font-size-lg, $line-height-base);
|
||||
}
|
||||
.title-md {
|
||||
@include ft($font-size-md, $line-height-base);
|
||||
}
|
||||
.font-sm {
|
||||
@include ft($font-size-sm, $line-height-base);
|
||||
}
|
||||
.font-bold {
|
||||
@include wc($font-weight-base, $font-color-primary);
|
||||
}
|
||||
|
||||
.margin {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
|
||||
::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/*定义滚动条轨道 内阴影+圆角*/
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 1px rgba(0, 0, 0, 0);
|
||||
border-radius: 10px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/*定义滑块 内阴影+圆角*/
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
* {
|
||||
-webkit-touch-callout: none; /*系统默认菜单被禁用*/
|
||||
-webkit-user-select: none; /*webkit浏览器*/
|
||||
-khtml-user-select: none; /*早期浏览器*/
|
||||
-moz-user-select: none; /*火狐*/
|
||||
-ms-user-select: none; /*IE10*/
|
||||
user-select: none;
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
//定位全屏
|
||||
@mixin allcover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
}
|
||||
// 定位顶部栏
|
||||
@mixin topcover {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
/*
|
||||
子元素排列
|
||||
*/
|
||||
@mixin contentEnd {
|
||||
position: absolute;
|
||||
}
|
||||
/*
|
||||
划线专区
|
||||
*/
|
||||
// 设置下划线
|
||||
@mixin bottomBoder($width, $color) {
|
||||
border-bottom: $width $color solid;
|
||||
}
|
||||
/*
|
||||
默认margin
|
||||
*/
|
||||
@mixin lrmg {
|
||||
margin: 0 $line-pc-margin;
|
||||
}
|
||||
|
||||
@mixin margin($tb, $lr) {
|
||||
margin: $tb $lr;
|
||||
}
|
||||
@mixin padding($tb, $lr) {
|
||||
padding: $tb $lr;
|
||||
}
|
||||
// auto适应
|
||||
@mixin autowh {
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
//transform上下左右居中
|
||||
@mixin ct {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
//定位上下左右居中
|
||||
@mixin ctp($width, $height) {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -$height/2;
|
||||
margin-left: -$width/2;
|
||||
}
|
||||
|
||||
//flex上下左右剧中
|
||||
@mixin fct() {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
//定位上下居中
|
||||
@mixin tb {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
//flex上下剧中
|
||||
@mixin ftb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
//定位左右居中
|
||||
@mixin lr {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
//flex左右剧中
|
||||
@mixin flr() {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
//宽高
|
||||
@mixin wh($width, $height) {
|
||||
width: $width;
|
||||
height: $height;
|
||||
}
|
||||
|
||||
//字体大小、行高、字体
|
||||
@mixin ft($size, $line-height) {
|
||||
font-size: $size;
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
//字体大小,颜色
|
||||
@mixin sc($size, $color) {
|
||||
font-size: $size;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
//字体粗细,颜色
|
||||
@mixin wc($weight, $color) {
|
||||
font-weight: $weight;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
//flex 布局和 子元素 对其方式
|
||||
@mixin fj($type: space-between) {
|
||||
display: flex;
|
||||
justify-content: $type;
|
||||
}
|
||||
|
||||
//2倍图、3倍图,默认2倍图
|
||||
@mixin bg-image($url) {
|
||||
background-image: url("./images/"+$url+"@2x.png");
|
||||
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
|
||||
background-image: url("./images/"+$url+"@3x.png");
|
||||
}
|
||||
}
|
||||
|
||||
//多行超出省略号
|
||||
@mixin ellipsis($line: 2, $line-height: 1.2) {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: $line;
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
@mixin modalbg($color-bg: rgba(0, 0, 0, 0.2)) {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: $color-bg;
|
||||
}
|
||||
|
||||
@mixin flex($direction: column, $wrap: nowrap) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
flex-wrap: $wrap;
|
||||
}
|
||||
|
||||
@mixin clear() {
|
||||
&:after {
|
||||
content: ".";
|
||||
clear: both;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
// 宽高度计算
|
||||
@mixin m-x($width: 1) {
|
||||
@if unit($width) ==px {
|
||||
margin: {
|
||||
left: $width !important;
|
||||
right: $width !important;
|
||||
}
|
||||
} @else {
|
||||
margin: {
|
||||
left: $width * 10px !important;
|
||||
right: $width * 10px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 有色box 圆角
|
||||
|
||||
@mixin border-radius {
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
//铺满屏幕
|
||||
@mixin full-screen {
|
||||
min-height: 100vh;
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
$mobile-font-mbger: 2rem;
|
||||
$mobile-font-bger: 1.6rem;
|
||||
$mobile-font-bg: 1.3rem; //18px
|
||||
$mobile-font-md: 1.15rem; //16px
|
||||
|
||||
$mobile-font-base: 1rem; //14px
|
||||
$mobile-font-sm: 0.85rem; //12px
|
||||
$mobile-font-xsm: 0.625rem; //10px
|
||||
$mobile-font-xxsm: 0.4rem;
|
||||
|
||||
$pc-font-bg: 1.3rem;
|
||||
$pc-font-md: 1.15rem;
|
||||
|
||||
$pc-font-base: 1rem; //50px
|
||||
$pc-font-sm: 0.6rem;
|
||||
$pc-font-xsm: 0.48rem;
|
||||
$pc-font-xxsm: 0.32rem;
|
||||
$pc-font-mini: 0.2rem;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<div>
|
||||
hello!
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "RedirectPage",
|
||||
created() {
|
||||
const { params, query } = this.$route;
|
||||
const { path } = params;
|
||||
if (path) {
|
||||
this.$router.replace({ path: `/${path}`, query });
|
||||
} else {
|
||||
this.$router.replace({ path: `/`, query });
|
||||
}
|
||||
},
|
||||
render(h) {
|
||||
return h();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
const path = require("path");
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir);
|
||||
}
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
const EXTERNALS = {
|
||||
vue: "Vue",
|
||||
axios: "axios",
|
||||
"element-ui": "ELEMENT",
|
||||
"vue-router": "VueRouter",
|
||||
vuex: "Vuex",
|
||||
vant: "vant",
|
||||
// "vuex-persistedstate": "createPersistedState",
|
||||
lodash: "_",
|
||||
dayjs: "dayjs",
|
||||
echarts: "echarts",
|
||||
};
|
||||
const CDN_LIST = {
|
||||
css: ["https://cdn.staticfile.org/element-ui/2.15.1/theme-chalk/index.min.css", "https://cdn.staticfile.org/vant/2.12.13/index.min.css"],
|
||||
js: [
|
||||
"https://cdn.staticfile.org/vue/2.6.12/vue.min.js",
|
||||
"https://cdn.staticfile.org/vue-router/3.5.1/vue-router.min.js",
|
||||
"https://cdn.staticfile.org/vuex/3.6.2/vuex.min.js",
|
||||
"https://cdn.staticfile.org/axios/0.21.1/axios.min.js",
|
||||
"https://cdn.staticfile.org/element-ui/2.15.1/index.min.js",
|
||||
"https://cdn.staticfile.org/vant/2.12.13/vant.min.js",
|
||||
// "https://cdn.staticfile.org/vuex-persistedstate/4.0.0-beta.3/vuex-persistedstate.min.js",
|
||||
"https://cdn.staticfile.org/lodash.js/4.17.21/lodash.min.js",
|
||||
"https://cdn.staticfile.org/dayjs/1.10.4/dayjs.min.js",
|
||||
"https://cdn.staticfile.org/echarts/5.1.2/echarts.min.js",
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
publicPath: process.env.VUE_APP_PUBLIC_PATH || "/",
|
||||
devServer: {
|
||||
proxy: {
|
||||
"/apis": {
|
||||
target: "https://api.yyjishu.com/antifraud",
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
"^/apis": "",
|
||||
},
|
||||
},
|
||||
},
|
||||
publicPath: process.env.VUE_APP_PUBLIC_PATH || "/",
|
||||
disableHostCheck: !isProduction, // 关闭 host check,方便使用 ngrok 之类的内网转发工具
|
||||
},
|
||||
chainWebpack: (config) => {
|
||||
// 设置一些常用alias
|
||||
config.resolve.alias
|
||||
.set("@", resolve("src"))
|
||||
.set("@assets", resolve("./src/assets"))
|
||||
.set("@components", resolve("src/components"))
|
||||
.set("@styles", resolve("src/styles"))
|
||||
.set("@layout", resolve("src/components/common/layout"))
|
||||
.set("@views", resolve("src/views"));
|
||||
|
||||
config.plugins.delete("prefetch");
|
||||
|
||||
// 压缩图片
|
||||
config.module
|
||||
.rule("images")
|
||||
.use("image-webpack-loader")
|
||||
.loader("image-webpack-loader")
|
||||
.options({ bypassOnDebug: true })
|
||||
.end();
|
||||
|
||||
if (isProduction) {
|
||||
// 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
|
||||
config.externals(EXTERNALS);
|
||||
config.plugin("html").tap((args) => {
|
||||
args[0].cdn = CDN_LIST;
|
||||
return args;
|
||||
});
|
||||
}
|
||||
},
|
||||
configureWebpack: (config) => {
|
||||
if (isProduction) {
|
||||
// 公共代码抽离
|
||||
config.optimization = {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
chunks: "all",
|
||||
test: /node_modules/,
|
||||
name: "vendor",
|
||||
minChunks: 1,
|
||||
maxInitialRequests: 5,
|
||||
minSize: 0,
|
||||
priority: 100,
|
||||
},
|
||||
common: {
|
||||
chunks: "all",
|
||||
test: /[\\/]src[\\/]js[\\/]/,
|
||||
name: "common",
|
||||
minChunks: 2,
|
||||
maxInitialRequests: 5,
|
||||
minSize: 0,
|
||||
priority: 60,
|
||||
},
|
||||
styles: {
|
||||
name: "styles",
|
||||
test: /\.(sa|sc|c)ss$/,
|
||||
chunks: "all",
|
||||
enforce: true,
|
||||
},
|
||||
runtimeChunk: {
|
||||
name: "manifest",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
scss: {
|
||||
additionalData: `
|
||||
@import "./src/styles/mixin";
|
||||
@import "./src/styles/_var";
|
||||
@import "./src/styles/all.scss";`,
|
||||
},
|
||||
postcss: {
|
||||
plugins: [require("postcss-px2rem")({ remUnit: 32 })],
|
||||
},
|
||||
},
|
||||
},
|
||||
productionSourceMap: false,
|
||||
};
|
||||
Loading…
Reference in New Issue