Commit 9439301b authored by caobo's avatar caobo

Initial commit

parents
> 1%
last 2 versions
not ie <= 8
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
module.exports = {
plugins: {
autoprefixer: {}
}
}
# wk_add_wehcat
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Run your unit tests
```
npm run test:unit
```
module.exports = {
presets: [
'@vue/app'
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "wk_add_wehcat",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"axios": "^0.18.0",
"element-ui": "^2.4.5",
"vue": "^2.5.17",
"vue-class-component": "^6.0.0",
"vue-property-decorator": "^7.0.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"vuex-class": "^0.3.1"
},
"devDependencies": {
"@types/chai": "^4.1.0",
"@types/mocha": "^5.2.4",
"@vue/cli-plugin-babel": "^3.0.0",
"@vue/cli-plugin-typescript": "^3.0.0",
"@vue/cli-plugin-unit-mocha": "^3.0.0",
"@vue/cli-service": "^3.0.0",
"@vue/test-utils": "^1.0.0-beta.20",
"chai": "^4.1.2",
"node-sass": "^4.9.2",
"sass-loader": "^7.0.3",
"typescript": "^3.0.0",
"vue-cli-plugin-element": "^1.0.0",
"vue-template-compiler": "^2.5.17"
}
}
<!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.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>wk_add_wehcat</title>
</head>
<body>
<noscript>
<strong>We're sorry but wk_add_wehcat doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view/>
</div>
</template>
<style lang="scss">
html,body,#app {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
import axios from 'axios';
axios.defaults.withCredentials = true;
const getFilterList = (size: number, page?: number) => {
return axios.get(`/api/permission?page=${page}&size=${size}`);
};
const createFilterList = (
form: {
name: string,
desc: string,
code: string,
}) => {
return axios.post(`api/permission`, form);
};
export {
getFilterList,
createFilterList,
};
import axios from 'axios';
axios.defaults.withCredentials = true;
const getPermissions = (size: number, page?: number) => {
return axios.get(`/api/permission?page=${page}&size=${size}`);
};
const createPermission = (
form: {
name: string,
desc: string,
code: string,
}) => {
return axios.post(`api/permission`, form);
};
const updatePermission = (
form: {
id: string,
name?: string,
desc?: string,
status?: boolean,
}) => {
return axios.put(`api/permission`, form);
};
const deletePermission = (form: { permissionId: string }) => {
return axios.delete(`/api/permission`, { data: { permissionId: form.permissionId } });
};
export {
getPermissions,
createPermission,
updatePermission,
deletePermission,
};
import axios from 'axios';
axios.defaults.withCredentials = true;
const getRoles = (size: number, page?: number) => {
return axios.get(`/api/rolePermission?page=${page}&size=${size}`);
};
const createRole = (
form: {
name: string,
status?: boolean,
isUsed?: boolean,
parent?: string,
children?: string,
}) => {
return axios.post(`api/role`, form);
};
const updateRole = (
form: {
id: string,
status?: boolean,
isUsed?: boolean,
parent?: string,
children?: string,
}) => {
return axios.put(`api/role`, form);
};
const deleteRole = (form: { roleId: string }) => {
return axios.delete(`/api/role`, { data: { roleId: form.roleId } });
};
const setPermission = (form: { permissionId: string, roleId: string }) => {
return axios.post(`/api/setPermission`, form);
};
export {
getRoles,
createRole,
updateRole,
deleteRole,
setPermission,
};
import axios from 'axios';
axios.defaults.withCredentials = true;
const getPassports = (size: number, page?: number) => {
return axios.get(`/api/passport?page=${page}&size=${size}`);
};
const createPassport = (
form: {
password: string,
username: string,
email: string,
}) => {
return axios.post(`/api/passport`, form);
};
const updatePassport = (
form: {
id: string,
password?: string,
IsDelete?: boolean,
}) => {
return axios.put(`/api/passport`, form);
};
const deletePassport = (form: {id: string}) => {
return axios.delete(`/api/passport`, {data: {id: form.id}});
};
const setRole = (form: { passportId: string, roleId: string }) => {
return axios.post(`/api/setRole`, form);
};
export {
getPassports,
createPassport,
updatePassport,
deletePassport,
setRole,
};
<template>
<el-table
border
:data="dataList"
style="width: 100%"
>
<el-table-column
v-for='(value, index) in tHeadList'
:key='index'
:prop='value.prop'
:width="value.width"
:show-overflow-tooltip='true'
align="center"
:label="value.label">
<template slot-scope="scope">
<template v-if="value.prop === 'createdAt' || value.prop === 'updatedAt'">
{{ stringToTime(scope.row[value.prop]) }}
</template>
<template v-else-if="value.prop === 'online'">
{{ isOnline(scope.row[value.prop]) }}
</template>
<template v-else-if="value.prop === 'status'">
{{ scope.row.used }} / {{ scope.row.total }}
</template>
<template v-else-if="value.prop === 'callbackcode'">
{{ isCallbackCode(scope.row[value.prop]) }}
</template>
<template v-else>
{{ scope.row[value.prop] }}
</template>
</template>
</el-table-column>
<template v-if='addable || detailable'>
<el-table-column
fixed="right"
label="操作"
align="center"
width="100">
<template slot-scope="scope">
<template v-if='addable'>
<el-button
@click.native.prevent="addRow(scope.$index)"
type="text"
size="small">
加粉
</el-button>
</template>
<template v-if='detailable'>
<el-button
@click.native.prevent="detailRow(scope.$index)"
type="text"
size="small">
详情
</el-button>
</template>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import { Action, State } from 'vuex-class';
@Component({
props: {
tHeadList: {
type: Array,
default: () => {
return [];
},
},
dataList: {
type: Array,
default: () => {
return [];
},
},
addable: {
type: Boolean,
default: false,
},
detailable: {
type: Boolean,
default: false,
},
addRow: {
type: Function,
default: () => {
// 这里传入要添加的函数
},
},
detailRow: {
type: Function,
default: () => {
// 这里传入要编辑的函数
},
},
setRow: {
type: Function,
default: () => {
// 这里传入要设置的函数
},
},
},
})
export default class CommonTable extends Vue {
@State('role') public RoleState: any;
public isFirstZero(num: number) {
let str = '';
if (num < 10) {
str = '0' + num;
} else {
str = String(num);
}
return str;
}
public stringToTime(str: string) {
const date = new Date(Number(str));
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const newstr = `${this.isFirstZero(year)}-${this.isFirstZero(month)}-${this.isFirstZero(day)}`;
return newstr;
}
public isOnline(bool: boolean) {
if (bool) {
return '在线';
}
return '离线';
}
public isCallbackCode(num: number) {
let str = '';
switch (num) {
case 0:
str = '没有微信';
break;
case 1:
str = '等待通过';
break;
case 2:
str = '添加失败';
break;
case 3:
str = '已是好友';
break;
case 4:
str = '添加成功';
break;
}
return str;
}
public searchRoleById(id: string) {
const roles = this.RoleState.roles;
let str = '';
roles.map((val: any, ind: any) => {
if (val.id === id) {
str = val.name;
}
});
return str;
}
public mapRoles(data: any[]) {
if (data) {
let str = '';
data.map((val: any, ind: number) => {
str = str + val.name + ' 、';
});
return str;
}
return '';
}
public mapPermissions(data: any[]) {
if (data) {
let str = '';
data.map((val: any, ind: number) => {
str = str + val.desc + ' 、';
});
return str;
}
return '';
}
}
</script>
<template>
<el-pagination
@size-change="paginationSizeChange"
@current-change="paginationPageChange"
:current-page="page"
:page-sizes="[10, 20, 50, 100]"
:page-size="size"
layout="total, sizes, prev, pager, next"
:total="total">
</el-pagination>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({
props: {
total: {
type: Number,
default: 0,
},
page: {
type: Number,
default: 0,
},
size: {
type: Number,
default: 10,
},
paginationSizeChange: {
type: Function,
default: () => {
// 条数的修改
},
},
paginationPageChange: {
type: Function,
default: () => {
// 页数的修改
},
},
},
})
export default class Pagination extends Vue {
}
</script>
<style lang="scss" scoped>
</style>
/*
Write your variables here. All available variables can be
found in element-ui/packages/theme-chalk/src/common/var.scss.
For example, to overwrite the theme color:
*/
$--color-primary: teal;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './plugins/element.js';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
import Vue from 'vue'
import ElementUI, { Message } from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI, {
size: 'medium'
});
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/layout/Layout.vue';
const Login = () => import('./views/Login.vue');
const FilterNumber = () => import('./views/FilterNumber.vue');
const AddTask = () => import('./views/AddTask.vue');
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home,
children: [
{
path: '/filternumber',
name: 'filternumber',
component: FilterNumber,
},
{
path: '/addtask',
name: 'addtask',
component: AddTask,
},
],
},
{
path: '/login',
name: 'login',
component: Login,
},
],
});
import Vue, { VNode } from 'vue';
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any;
}
}
}
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
import Vue from 'vue';
import Vuex from 'vuex';
import filterNumber from './modules/filterNumber';
import addTask from './modules/addTask';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
filterNumber,
addTask,
},
});
import { Commit } from 'vuex';
import { Message } from 'element-ui';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '../types';
import { getFilterList, createFilterList } from '@/api/filterNumber';
interface PermissionAttribute {
id?: string;
name: string;
code: string;
desc?: string;
status?: boolean;
createdAt?: number;
updatedAt?: number;
}
export interface State {
dataList: any[];
count: number;
}
const filterNumberState: State = {
dataList: [
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 4},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 1},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 2},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 3},
{number: '18612341234', createdAt: '1536549523672', callbackcode: 0},
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{ number: '18612341234', createdAt: '1536549523672', callbackcode: 1 },
],
},
{
name: '0001',
wechatTotal: '王二狗(123)',
status: false,
total: 5000,
used: 3000,
createdAt: '1536549529672',
taskList: [
{ number: '18612341234', createdAt: '1536549523672', callbackcode: 0 },
],
},
],
count: 0,
};
const actions = {
[GET_FILTERLIST](
context: { commit: Commit, state: State },
payload: { size: number, page?: number },
) {
// 获取角色列表
getFilterList(payload.size, payload.page).then((data) => {
const result = data.data.result;
if (result) {
context.commit(GET_FILTERLIST, result);
} else {
Message.error(`获取数据失败错误原因是${data.data.msg}`);
}
}).catch((err) => {
throw(err);
});
},
[CREATE_FILTERLIST](
context: { commit: Commit, state: State },
payload: {
name: string,
desc: string,
code: string,
}) {
// 创建角色
createFilterList(payload).then((data) => {
const result = data.data.result;
if (result) {
context.commit(CREATE_FILTERLIST, result);
Message.success('角色创建成功');
} else {
Message.error(data.data.msg);
}
}).catch((err) => {
throw(err);
});
},
};
const mutations = {
[GET_FILTERLIST](state: State, data: { rows: PermissionAttribute[], count: number }) {
state.dataList = data.rows;
state.count = data.count;
},
[CREATE_FILTERLIST](state: State, data: PermissionAttribute) {
state.dataList.unshift(data);
state.count += 1;
},
};
export default {
state: filterNumberState,
actions,
mutations,
};
import { Commit } from 'vuex';
import { Message } from 'element-ui';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '../types';
import { getFilterList, createFilterList } from '@/api/filterNumber';
interface PermissionAttribute {
id?: string;
name: string;
code: string;
desc?: string;
status?: boolean;
createdAt?: number;
updatedAt?: number;
}
export interface State {
dataList: any[];
count: number;
}
const filterNumberState: State = {
dataList: [
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
{
name: '0001',
total: 5000,
used: 3000,
createdAt: '1536549529672',
numberGroup: '某某号码组',
filterList: '男, 女, 12-16; 北京,天津,山东,河北,张家口,石家庄,太原,深圳,广州,吉林,桂林,张家口,石家庄,太原,深圳,广州,吉林,桂林',
},
],
count: 0,
};
const actions = {
[GET_FILTERLIST](
context: { commit: Commit, state: State },
payload: { size: number, page?: number },
) {
// 获取角色列表
getFilterList(payload.size, payload.page).then((data) => {
const result = data.data.result;
if (result) {
context.commit(GET_FILTERLIST, result);
} else {
Message.error(`获取数据失败错误原因是${data.data.msg}`);
}
}).catch((err) => {
throw(err);
});
},
[CREATE_FILTERLIST](
context: { commit: Commit, state: State },
payload: {
name: string,
desc: string,
code: string,
}) {
// 创建角色
createFilterList(payload).then((data) => {
const result = data.data.result;
if (result) {
context.commit(CREATE_FILTERLIST, result);
Message.success('角色创建成功');
} else {
Message.error(data.data.msg);
}
}).catch((err) => {
throw(err);
});
},
};
const mutations = {
[GET_FILTERLIST](state: State, data: { rows: PermissionAttribute[], count: number }) {
state.dataList = data.rows;
state.count = data.count;
},
[CREATE_FILTERLIST](state: State, data: PermissionAttribute) {
state.dataList.unshift(data);
state.count += 1;
},
};
export default {
state: filterNumberState,
actions,
mutations,
};
// 获取用户列表
export const GET_PASSPORTS = 'GET_PASSPORTS';
// 添加用户
export const CREATE_PASSPORT = 'CREATE_PASSPORT';
// 编辑用户
export const UPDATE_PASSPORT = 'UPDATE_PASSPORT';
// 删除用户
export const DELETE_PASSPORT = 'DELETE_PASSPORT';
// 获取角色权限
export const GET_ROLES = 'GET_ROLES';
// 设置用户角色
export const SET_ROLE = 'SET_ROLE';
// 添加角色
export const CREATE_ROLE = 'CREATE_ROLE';
// 更新角色
export const UPDATE_ROLE = 'UPDATE_ROLE';
// 删除角色
export const DELETE_ROLE = 'DELETE_ROLE';
// 获取权限列表
export const GET_PERMISSIONS = 'GET_PERMISSIONS';
// 设置角色权限
export const SET_PERMISSION = 'SET_PERMISSION';
// 添加权限
export const CREATE_PERMISSION = 'CREATE_PERMISSION';
// 更新权限
export const UPDATE_PERMISSION = 'UPDATE_PERMISSION';
// 删除权限
export const DELETE_PERMISSION = 'DELETE_PERMISSION';
// 获取筛选列表
export const GET_FILTERLIST = 'GET_FILTERLIST';
// 创建筛选条件
export const CREATE_FILTERLIST = 'CREATE_FILTERLIST';
// export const GET_FILTERLIST = 'GET_FILTERLIST';
// export const GET_FILTERLIST = 'GET_FILTERLIST';
<template>
<div class="add-task">
<header>
<h2>加粉任务</h2>
</header>
<section>
<div class="section-body">
<CommonTable
:dataList='addTaskState.dataList'
:tHeadList='tHeadList'
:detailable='detailable'
:detailRow='detailRow'
/>
<div class="pagination">
<Pagination
:page='page'
:size='size'
:total='addTaskState.count'
:paginationSizeChange='paginationSizeChange'
:paginationPageChange='paginationPageChange'/>
</div>
<div class="dialog">
<template v-if="dialog.name === 'taskDetail'">
<el-dialog title="任务详情" :visible.sync="isDialogShow" width="500px">
<div class="dialog-body">
<!-- 此处借用了filterState的数据 -->
<CommonTable
:dataList='addTaskState.dataList[dialog.index].taskList'
:tHeadList='tHeadLists'
/>
<div class="dialog-pagination">
<Pagination
:page='page'
:size='size'
:total='addTaskState.count'
:paginationSizeChange='paginationSizeChange'
:paginationPageChange='paginationPageChange'/>
</div>
</div>
<div class="dialog-footer" slot='footer'>
<el-button type="primary" @click="sumbitAddWechat" >确 定</el-button>
<el-button @click="closeDialog" >取 消</el-button>
</div>
</el-dialog>
</template>
</div>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { mapActions, mapState } from 'vuex';
import { Action, State } from 'vuex-class';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '@/store/types';
import CommonTable from '@/components/CommonTable.vue';
import Pagination from '@/components/Pagination.vue';
@Component({
components: {
CommonTable,
Pagination,
},
})
export default class AddTask extends Vue {
public $refs!: {
ruleForm: HTMLFormElement,
};
@State('addTask') public addTaskState: any;
@Action(GET_FILTERLIST) public getFilterlist: any;
@Action(CREATE_FILTERLIST) public createFilter: any;
// 初始化数据
// 表格
public tHeadList = [{
prop: 'name',
label: '任务编号',
width: '120',
}, {
prop: 'createdAt',
label: '创建时间',
width: 'auto',
}, {
prop: 'wechatTotal',
label: '目标微信',
width: 'auto',
}, {
prop: 'online',
label: '在线状态',
width: 'auto',
}, {
prop: 'status',
label: '任务状态',
width: 'auto',
}];
public tHeadLists = [{
prop: 'number',
label: '目标号码',
width: '120',
}, {
prop: 'createdAt',
label: '创建时间',
width: 'auto',
}, {
prop: 'callbackcode',
label: '添加结果',
width: 'auto',
}];
public detailable = true;
// 分页
public page = 1;
public size = 10;
// 弹框
public isDialogShow = false;
public formLabelWidth = '100px';
public dialog = {
name: '',
data: {},
index: 0,
};
// 方法封装
// 表格
public detailRow(index: number) {
// 点击表格进行编辑
this.setDialogData('taskDetail', index);
}
public setDialogData(name: string, index: number) {
// 设置弹框数据
this.dialog.name = name;
this.$data.isDialogShow = true;
this.dialog.data = this.addTaskState.dataList[index];
this.dialog.index = index;
}
// 分页
public paginationSizeChange(index: number) {
this.size = index;
// this.getPermission({ size: this.size, page: this.page });
}
public paginationPageChange(index: number) {
this.page = index;
// this.getPermission({ size: this.size, page: this.page });
}
// 清除表单元素及弹框属性
public cleanDialogForm(form: string) {
const newform = this.$data[form];
Object.keys(newform).forEach((val, ind) => {
newform[val] = '';
});
}
// 弹框
public closeDialog() {
this.$data.isDialogShow = false;
this.dialog.name = '';
}
// 去除表格无用数据
public deleteInvalidData(data: any) {
const obj: any = {};
Object.keys(data).forEach((value) => {
if (data[value] !== '' && data[value] !== undefined) {
obj[value] = data[value];
}
});
return obj;
}
public sumbitAddFilter() {
// console.log(this.filterForm);
}
public sumbitAddWechat() {
const form = this.$data.addForm;
this.$refs.ruleForm.validate((valid: any) => {
if (valid) {
// console.log('验证通过了');
// 提交
// this.createPermission(form).then((data: any) => {
// this.closeDialog();
// this.cleanDialogForm('addForm');
// });
}
});
}
public ageFormat(val: string) {
return val + '岁';
}
// 验证方式
public validateThisTimeAdd(rule: any, value: any, callback: any) {
const reg = new RegExp('^[0-9]*$', 'i');
if (value === '') {
callback(new Error('请输入添加总条数'));
return false;
}
if (!reg.test(value)) {
callback(new Error('仅能输入数字'));
return false;
}
callback();
}
// // 生命周期
// public mounted() {
// // this.getPermission({ size: this.size, page: this.page });
// }
}
</script>
<style lang="scss" scoped>
.add-task{
text-align: left;
section{
padding: 30px 20px;
background-color: #fff;
.data{
color:#3396FC!important;
}
.section-title{
i{
margin-right: 8px;
}
}
.section-body{
margin-top: 20px;
position: relative;
padding-bottom: 30px;
.pagination{
position: absolute;
right: 5px;
bottom: -20px;
}
.dialog{
position: relative;
.flex{
display: flex;
}
.dialog-body{
padding: 10px;
position: relative;
}
.dialog-pagination{
position: absolute;
right: 5px;
bottom: -30px;
}
.dialog-footer{
text-align: right;
button{
margin-right: 10px;
}
}
}
}
}
}
</style>
<template>
<div class="filter-number">
<header>
<h2>号码筛选</h2>
</header>
<section>
<div class="section-title">
<el-button type="primary" @click='addFilter'>
<i class="el-icon-plus"></i>创建筛选
</el-button>
</div>
<div class="section-body">
<CommonTable
:dataList='numberFilterState.dataList'
:tHeadList='tHeadList'
:addable='addable'
:addRow='addRow'
/>
<div class="pagination">
<Pagination
:page='page'
:size='size'
:total='numberFilterState.count'
:paginationSizeChange='paginationSizeChange'
:paginationPageChange='paginationPageChange'/>
</div>
<div class="dialog">
<!-- 筛选 -->
<template v-if='dialog.name === "addFilter"'>
<el-dialog title="新建筛选" :visible.sync="isDialogShow" width="700px">
<div class="dialog-body">
<el-form
style="margin: 0px 10px;min-height: 418px;"
:model="filterForm"
status-icon
:rules="addFilterFormRules"
ref="filterForm"
class="demo-ruleForm"
>
<el-form-item label="用户组名称:" name="dsgroup" :label-width="formLabelWidth" prop='dsgroup'>
<el-input v-model="filterForm.dspgroup"
style='width:80%; margin-left:10px'
placeholder="请输入用户组名称(限20字)"
name='dspgroup'
clearable />
</el-form-item>
<!-- 基础特征 -->
<div class="basic-feature">
<div class="title">基础特征</div>
<div class="flex">
<el-form-item label="性别" prop="sexlist" style="width:30%" name='sexlist'>
<el-checkbox-group v-model="filterForm.sexlist">
<el-checkbox v-for="sex in sexes" :label="sex" :key="sex">{{ sex }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="年龄" prop="agelist" style="width:50%" :label-width="formLabelWidth">
<div class="flex">
<div class="flex-item" >
<el-input v-model="addForm.everydayAdd" auto-complete="off" width='30%'>
<template slot='suffix'>
</template>
</el-input>
</div>
<span style="width:20%;text-align:center"> —— </span>
<div class="flex-item" >
<el-input v-model="addForm.everydayAdd" auto-complete="off" width='30%'>
<template slot='suffix'>
</template>
</el-input>
</div>
</div>
</el-form-item>
</div>
<div class="flex">
<el-form-item label="省市">
<div class="flex">
<ul class="provincelist">
<li v-for='(province, ind) in area.provinceOptions' :key="ind" @click='getProvince(ind)'>
<el-checkbox
style="margin:0px 10px;"
:indeterminate="province.isIndeterminate"
v-model="province.checkAll"
@change="handleProvienceCheckAllChange(ind,$event)" ></el-checkbox>
<span style="display:inline-block;text-align:left;" >{{ province.province }}</span>
</li>
</ul>
<ul class="cityarea">
<template v-if='cityShow'>
<li v-for='(province, index) in area.provinceOptions' :key="index">
<template v-if='index === checkedIndex'>
<ul class="citylist">
<!-- {{province}} -->
<el-checkbox-group
v-model="province.checkedCities"
@change="handleCheckedCitiesChange">
<el-checkbox
v-for='(city, ind) in province.cityOptions'
style="margin:0px 10px;"
:key='ind'
:label='city'>
<span style="display:inline-block;text-align:left;">{{ city }}</span>
</el-checkbox>
</el-checkbox-group>
</ul>
</template>
</li>
</template>
</ul>
</div>
</el-form-item>
</div>
</div>
<!-- 业务特征 -->
<div class="business-feature">
<div class="title">业务特征</div>
<div class="flex">
<div class="flex">
<el-form-item label="流量" prop="flowDuring" label-width="60px">
<el-select v-model="filterForm.flowDuring">
<el-option
v-for="date in duringList"
:key="date"
:label="date"
:value="date">
</el-option>
</el-select>
</el-form-item>
<div class="flex" style='width:40%;margin-left:40px'>
<el-form-item prop="flowStart" >
<el-input v-model='filterForm.flowStart'>
<template slot='suffix'>
M
</template>
</el-input>
</el-form-item>
<span style="width:35%;text-align:center;line-height:30px"> —— </span>
<el-form-item prop='flowEnd'>
<el-input v-model='filterForm.flowEnd'>
<template slot='suffix'>
M
</template>
</el-input>
</el-form-item>
</div>
</div>
</div>
</div>
<!-- 消费特征 -->
<div class="consumption-feature">
<div class="title">消费特征</div>
<div class="flex">
<div class="flex">
<el-form-item label="话费" prop="consumptionDuring" label-width="60px">
<el-select v-model="filterForm.consumptionDuring">
<el-option
v-for="date in duringList"
:key="date"
:label="date"
:value="date">
</el-option>
</el-select>
</el-form-item>
<div class="flex" style='width:40%;margin-left:40px;line-height:30px'>
<el-form-item prop="flowStart" >
<el-input v-model='filterForm.flowStart'>
<template slot='suffix'>
</template>
</el-input>
</el-form-item>
<span style="width:35%;text-align:center"> —— </span>
<el-form-item prop='flowEnd'>
<el-input v-model='filterForm.flowEnd'>
<template slot='suffix'>
</template>
</el-input>
</el-form-item>
</div>
</div>
</div>
</div>
</el-form>
</div>
<div class="dialog-footer" slot='footer'>
<el-button type="primary" @click="sumbitAddFilter" >确 定</el-button>
<el-button @click="closeDialog" >取 消</el-button>
</div>
</el-dialog>
</template>
<!-- 加粉 -->
<template v-else-if="dialog.name === 'addWechat'">
<el-dialog title="新建筛选" :visible.sync="isDialogShow" width="500px">
<el-form :model="addForm" :rules="addWechatRules" ref='addForm'>
<el-form-item label="号码数量:" :label-width="formLabelWidth" prop='used'>
<span name='number'><span class="data">{{dialog.data.used}}</span>/5000</span>
</el-form-item>
<div class="flex">
<el-form-item label="本次添加:"
:label-width="formLabelWidth"
prop="thisTimeAdd">
<el-input v-model="addForm.thisTimeAdd" auto-complete="off" width='90%'>
<template slot='suffix'>
</template>
</el-input>
</el-form-item>
<el-form-item label="每日添加:"
:label-width="formLabelWidth"
prop="everydayAdd">
<el-input v-model="addForm.everydayAdd" auto-complete="off" width='90%'>
<template slot='suffix'>
</template>
</el-input>
</el-form-item>
</div>
<el-form-item label="验证用语:"
:label-width="formLabelWidth"
prop="verificationLanguage">
<el-input v-model="addForm.verificationLanguage" type='textarea' auto-complete="off" placeholder="限40字" resize='none' :autosize="{ minRows: 4, maxRows: 4}"></el-input>
</el-form-item>
<el-form-item label="目标微信:"
:label-width="formLabelWidth"
prop="verificationLanguage">
<div class="QRcode flex" v-loading='QRreload'>
<img src="../assets/qr.png" alt="二维码" width="150px" height="150px">
<p>请用目标微信扫码<span class="data" style="margin-left:8px;text-decoration:underline" @click="refreshQRCode">刷新</span></p>
</div>
</el-form-item>
</el-form>
<div class="dialog-footer" slot='footer'>
<el-button type="primary" @click="sumbitAddWechat" >确 定</el-button>
<el-button @click="closeDialog" >取 消</el-button>
</div>
</el-dialog>
</template>
</div>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { mapActions, mapState } from 'vuex';
import { Action, State } from 'vuex-class';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '@/store/types';
import CommonTable from '@/components/CommonTable.vue';
import Pagination from '@/components/Pagination.vue';
@Component({
components: {
CommonTable,
Pagination,
},
})
export default class FilterNumber extends Vue {
public $refs!: {
addForm: HTMLFormElement,
filterForm: HTMLFormElement,
};
@State('filterNumber') public numberFilterState: any;
@Action(GET_FILTERLIST) public getFilterlist: any;
@Action(CREATE_FILTERLIST) public createFilter: any;
// @Action(UPDATE_PERMISSION) public updatePermission: any;
// @Action(DELETE_PERMISSION) public deletePermission: any;
// 初始化数据
// 表格
public tHeadList = [{
prop: 'name',
label: '编号',
width: '150',
}, {
prop: 'createdAt',
label: '创建时间',
width: '150',
}, {
prop: 'numberGroup',
label: '号码组',
width: '200',
}, {
prop: 'filterList',
label: '筛选条件',
width: 'auto',
}];
public addable = true;
public deleteable = true;
public area = {
nation: '全国',
checkAll: false,
checkedProvinces: [] as any,
provinceOptions: [
{'p': '直辖市', 'c': ['北京', '天津', '上海', '重庆']},
{'p': '河北', 'c': ['石家庄', '唐山', '秦皇岛',
'邯郸', '邢台', '保定', '张家口',
'承德', '沧州', '廊坊', '衡水']},
{'p': '山西', 'c': ['太原', '大同', '阳泉',
'长治', '晋城', '朔州', '晋中',
'运城', '忻州', '临汾', '吕梁']},
{'p': '内蒙古', 'c': ['呼和浩特', '包头', '乌海',
'赤峰', '通辽', '鄂尔多斯', '呼伦贝尔',
'巴彦淖尔', '乌兰察布', '兴安', '锡林郭勒', '阿拉善']},
{'p': '辽宁', 'c': ['沈阳', '大连', '鞍山',
'抚顺', '本溪', '丹东', '锦州',
'营口', '阜新', '辽阳', '盘锦',
'铁岭', '朝阳', '葫芦岛']},
{'p': '吉林', 'c': ['长春', '吉林', '四平',
'辽源', '通化', '白山', '松原',
'白城', '延边']},
{'p': '黑龙江', 'c': ['哈尔滨', '齐齐哈尔', '鸡西',
'鹤岗', '双鸭山', '大庆', '伊春',
'佳木斯', '七台河', '牡丹江', '黑河',
'绥化', '大兴安岭']},
{'p': '江苏', 'c': ['南京', '无锡', '徐州',
'常州', '苏州', '南通', '连云港',
'淮安', '盐城', '扬州', '镇江', '泰州', '宿迁']},
{'p': '浙江', 'c': ['杭州', '宁波', '温州',
'嘉兴', '湖州', '绍兴', '金华',
'衢州', '舟山', '台州', '丽水']},
{'p': '安徽', 'c': ['合肥', '芜湖', '蚌埠',
'淮南', '马鞍山', '淮北', '铜陵',
'安庆', '黄山', '滁州', '阜阳',
'宿州', '巢湖', '六安', '亳州',
'池州', '宣城']},
{'p': '福建', 'c': ['福州', '厦门', '莆田',
'三明', '泉州', '漳州', '南平',
'龙岩', '宁德']},
{'p': '江西', 'c': ['南昌', '景德镇', '萍乡',
'九江', '新余', '鹰潭', '赣州',
'吉安', '宜春', '抚州', '上饶']},
{'p': '山东', 'c': ['济南', '青岛', '淄博',
'枣庄', '东营', '烟台', '潍坊',
'济宁', '泰安', '威海', '日照',
'莱芜', '临沂', '德州', '聊城',
'滨州', '菏泽']},
{'p': '河南', 'c': ['郑州', '开封', '洛阳',
'平顶山', '安阳', '鹤壁', '新乡',
'焦作', '濮阳', '许昌', '漯河',
'三门峡', '南阳', '商丘', '信阳',
'周口', '驻马店', '济源']},
{'p': '湖北', 'c': ['武汉', '黄石', '十堰',
'宜昌', '襄樊', '鄂州', '荆门',
'孝感', '荆州', '黄冈', '咸宁',
'随州', '恩施', '仙桃', '潜江',
'天门', '神农架']},
{'p': '湖南', 'c': ['长沙', '株洲', '湘潭',
'衡阳', '邵阳', '岳阳', '常德',
'张家界', '益阳', '郴州', '永州',
'怀化', '娄底', '湘西']},
{'p': '广东', 'c': ['广州', '韶关', '深圳',
'珠海', '汕头', '佛山', '江门',
'湛江', '茂名', '肇庆', '惠州',
'梅州', '汕尾', '河源', '阳江',
'清远', '东莞', '中山', '潮州',
'揭阳', '云浮']},
{'p': '广西', 'c': ['南宁', '柳州', '桂林',
'梧州', '北海', '防城港', '钦州',
'贵港', '玉林', '百色', '贺州',
'河池', '来宾', '崇左']},
{'p': '海南', 'c': ['海口', '三亚', '五指山',
'琼海', '儋州', '文昌', '万宁', '东方']},
{'p': '四川', 'c': ['成都', '自贡', '攀枝花',
'泸州', '德阳', '绵阳', '广元',
'遂宁', '内江', '乐山', '南充',
'眉山', '宜宾', '广安', '达川',
'雅安', '巴中', '资阳', '阿坝',
'甘孜', '凉山']},
{'p': '贵州', 'c': ['贵阳', '六盘水', '遵义', '安顺',
'铜仁', '黔西南', '毕节', '黔东南', '黔南']},
{'p': '云南', 'c': ['昆明', '曲靖', '玉溪', '保山',
'昭通', '丽江', '普洱', '临沧',
'楚雄', '红河', '文山', '西双版纳',
'大理', '德宏', '怒江傈', '迪庆']},
{'p': '西藏', 'c': ['拉萨', '昌都', '山南',
'日喀则', '那曲', '阿里', '林芝']},
{'p': '陕西', 'c': ['西安', '铜川', '宝鸡',
'咸阳', '渭南', '延安', '汉中',
'榆林', '安康', '商洛']},
{'p': '甘肃', 'c': ['兰州', '嘉峪关', '金昌',
'白银', '天水', '武威', '张掖',
'平凉', '酒泉', '庆阳', '定西',
'陇南', '临夏', '甘南']},
{'p': '青海', 'c': ['西宁', '海东', '海北',
'黄南', '海南', '果洛', '玉树', '梅西']},
{'p': '宁夏', 'c': ['银川', '石嘴山', '吴忠', '固原', '中卫']},
{'p': '新疆', 'c': ['乌鲁木齐', '克拉玛依', '吐鲁番',
'哈密', '昌吉', '博尔塔拉', '巴音郭楞',
'阿克苏', '克孜勒苏', '喀什', '和田',
'伊犁', '塔城', '阿勒泰', '石河子',
'阿拉尔', '图木舒克', '五家渠']},
{'p': '地区', 'c': ['香港', '澳门', '台湾']}].map( (x) => {
const city = {
province: x.p,
checkAll: false,
checkedCities: [] as any,
cityOptions: x.c,
isIndeterminate: false,
};
return city;
}),
isIndeterminate: false,
};
// 分页
public page = 1;
public size = 10;
// 弹框
public isDialogShow = false;
public formLabelWidth = '100px';
public QRreload = false;
public checkedIndex = 0;
public cityShow = false;
public sexes = ['男', '女'];
public duringList = ['近三月平均', '近六月平均'];
public addForm = {
thisTimeAdd: '',
everydayAdd: '',
verificationLanguage: '',
};
public filterForm = {
dsgroup: '',
agerange: [10, 80],
sexlist: [],
flow: [],
flowStart: '',
flowEnd: '',
consumptionStart: '',
consumptionEnd: '',
flowDuring: '近三月平均',
consumptionDuring: '近三月平均',
};
public dialog = {
name: '',
data: {},
index: 0,
};
// 规则匹配(加粉筛选)
public addWechatRules = {
thisTimeAdd: [
{ validator: this.validateThisTimeAdd, trigger: 'blur' },
],
everydayAdd: [
{ validator: this.validateEverydayAdd, trigger: 'blur' },
],
verificationLanguage: [
{ validator: this.verificationLanguage, trigger: 'blur' },
],
};
public addFilterFormRules = {
dsgroup: [
{ validator: this.validateDsgroup, trigger: 'blur' },
],
sexlist: [
{ validator: this.validateSexList, trigger: 'change' },
],
verificationLanguage: [
{ validator: this.verificationLanguage, trigger: 'blur' },
],
};
// // 方法封装
// 添加用户
public addFilter() {
// 添加用户按钮
this.dialog.name = 'addFilter';
this.$data.isDialogShow = true;
}
public getProvince(index: number) {
this.checkedIndex = index;
this.cityShow = true;
}
// 表格
public addRow(index: number) {
// 点击表格进行编辑
this.setDialogData('addWechat', index);
}
public setDialogData(name: string, index: number) {
// 设置弹框数据
this.dialog.name = name;
this.$data.isDialogShow = true;
this.dialog.data = this.numberFilterState.dataList[index];
this.dialog.index = index;
}
public handleProvienceCheckAllChange(index: number, val: boolean) {
const area = this.area;
const province = area.provinceOptions[index];
const provinceOptionsLenth = area.provinceOptions.length;
province.checkedCities = val ? province.cityOptions : [];
province.isIndeterminate = false;
area.checkedProvinces =
area.provinceOptions.filter((x) => {
return x.checkAll;
}).map((x) => {
return x.province;
});
area.isIndeterminate =
area.checkedProvinces.length > 0 &&
area.checkedProvinces.length < provinceOptionsLenth;
}
public handleCheckedCitiesChange(value: any) {
const checkedCount = value.length;
const city = this.area.provinceOptions[this.checkedIndex];
city.checkAll = city.cityOptions.length === checkedCount;
city.isIndeterminate = checkedCount > 0 && checkedCount < city.cityOptions.length;
}
// 分页
public paginationSizeChange(index: number) {
this.size = index;
// this.getPermission({ size: this.size, page: this.page });
}
public paginationPageChange(index: number) {
this.page = index;
// this.getPermission({ size: this.size, page: this.page });
}
// 清除表单元素及弹框属性
public cleanDialogForm(form: string) {
const newform = this.$data[form];
Object.keys(newform).forEach((val, ind) => {
newform[val] = '';
});
}
// 弹框
public closeDialog() {
this.$data.isDialogShow = false;
this.dialog.name = '';
}
// 去除表格无用数据
public deleteInvalidData(data: any) {
const obj: any = {};
Object.keys(data).forEach((value) => {
if (data[value] !== '' && data[value] !== undefined) {
obj[value] = data[value];
}
});
return obj;
}
public refreshQRCode(data: any) {
// 请求二维码
this.QRreload = true;
setTimeout(() => {
this.QRreload = false;
}, 3000);
}
public sumbitAddFilter() {
const form = this.$data.filterForm;
this.$refs.filterForm.validate((valid: any) => {
if (valid) {
// console.log('验证通过了');
// 提交
// this.createPermission(form).then((data: any) => {
// this.closeDialog();
// this.cleanDialogForm('addForm');
// });
}
});
}
public sumbitAddWechat() {
const form = this.$data.addForm;
this.$refs.addForm.validate((valid: any) => {
if (valid) {
// console.log('验证通过了');
// 提交
// this.createPermission(form).then((data: any) => {
// this.closeDialog();
// this.cleanDialogForm('addForm');
// });
}
});
}
public ageFormat(val: string) {
return val + '岁';
}
// 验证方式
// 加粉验证
public validateThisTimeAdd(rule: any, value: any, callback: any) {
const reg = new RegExp('^[0-9]*$', 'i');
if (value === '') {
callback(new Error('请输入添加总条数'));
return false;
}
if (!reg.test(value)) {
callback(new Error('仅能输入数字'));
return false;
}
callback();
}
public validateEverydayAdd(rule: any, value: any, callback: any) {
const reg = new RegExp('^[0-9]*$', 'i');
if (value === '') {
callback(new Error('请输入每日添加数'));
return false;
}
if (!reg.test(value)) {
callback(new Error('仅能输入数字'));
return false;
}
callback();
}
public verificationLanguage(rule: any, value: any, callback: any) {
// console.log(value.length);
if (value && value.length >= 40) {
callback(new Error('字符长度不可超过40字'));
return false;
}
callback();
}
// 筛选部分验证
public validateDsgroup(rule: any, value: any, callback: any) {
if(!value) {
callback(new Error('名称不可为空'));
return false;
}
if(value.length >=20) {
callback(new Error('字符长度不可超过20字'));
return false;
}
callback();
}
public validateSexList(rule: any, value: any, callback: any) {
if(value.length === 0) {
callback(new Error('至少选中一位'));
return false;
}
callback();
}
public validateAgeList(rule: any, value: any, callback: any) {
if(value.length === 0) {
callback(new Error('至少选中一位'));
return false;
}
callback();
}
// // 生命周期
// public mounted() {
// // this.getPermission({ size: this.size, page: this.page });
// }
}
</script>
<style lang="scss" scoped>
.filter-number{
text-align: left;
section{
padding: 30px 20px;
background-color: #fff;
.data{
color:#3396FC!important;
}
.section-title{
i{
margin-right: 8px;
}
}
.section-body{
margin-top: 20px;
position: relative;
padding-bottom: 30px;
.pagination{
position: absolute;
right: 5px;
bottom: -20px;
}
.dialog{
position: relative;
.flex{
display: flex;
}
.provincelist{
display: flex;
width: 50%;
border-right: 1px solid #ccc;
flex-wrap: wrap;
padding-left: 0;
margin: 0;
height: 140px;
overflow-y: scroll;
li{
text-align: center;
text-align: left;
padding: 0px;
margin-left: 5px;
list-style: none;
}
}
.cityarea{
width: 50%;
padding-left: 0;
margin-top: 0;
li {
list-style: none;
}
.citylist{
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin: 0;
height: 140px;
overflow-y: scroll;
>div{
display: flex;
flex-wrap: wrap;
height: 140px;
overflow-y: scroll;
width: 100%;
}
li{
text-align: center;
padding: 0px;
margin-left: 5px;
list-style: none;
}
}
}
.dialog-body{
padding: 10px;
.title{
color: #3396FC;
font-size: 18px;
line-height: 30px;
margin-bottom: 15px;
}
.basic-feature{
.flex-item{
flex-basis: 40%;
}
}
}
.QRcode{
justify-content: center;
align-items: center;
flex-direction: column;
p{
margin: 5px ;
}
}
.dialog-footer{
text-align: right;
button{
margin-right: 10px;
}
}
}
}
}
}
</style>
<template>
<div class="bg">
<div class="login">
<el-form>
<el-form-item label="用户名" label-width="80px"
prop="username">
<el-input v-model="loginForm.username" auto-complete="off" placeholder="请输入您的用户名"></el-input>
</el-form-item>
<el-form-item label="密码" label-width="80px"
prop="password">
<el-input v-model="loginForm.password" auto-complete="off" placeholder="请输入您的密码" type="password"></el-input>
</el-form-item>
</el-form>
<el-button @click='loginSumbit()'>
登录
</el-button>
</div>
</div>
</template>
<script lang='ts'>
import { Component, Vue } from 'vue-property-decorator';
@Component({
})
export default class Overview extends Vue {
public loginForm = {
username: '',
password: '',
};
public loginSumbit() {
if (this.loginForm.username === 'zhangsan' && this.loginForm.password === '123456') {
// 发送请求,接受到token。
this.$router.push('/filternumber');
} else {
this.$message.error('您所输入的用户名或密码不正确');
}
}
}
</script>
<style scoped lang='scss'>
.bg{
width: 100%;
height: 100%;
background: rgba($color: #000000, $alpha: 0.4);
}
.login{
// width: 500px;
padding: 50px 50px 50px 20px;
position: absolute;
left: 50%;
top:50%;
background-color: #fff;
// height: 300px;
border: 1px solid #ccc;
transform: translate(-50%, -50%);
}
</style>
\ No newline at end of file
<template>
<el-container class="app-wraper">
<!-- 头部 -->
<el-header class="app-header">
<span style="font-weight: bold; font-size: 20px; margin-left: 70px;">
<img src="../../assets/logo.png" alt="" width="201px" style="margin-top:8px">
</span>
<el-dropdown style="line-height: 60px;float: right;margin: 0px 30px;">
<span class="theme-text">
{{ currentUser.username }}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<span @click="routeTo({ index:'/profile' })" >个人中心</span>
</el-dropdown-item>
<el-dropdown-item>
<span @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-container>
<el-aside width="210px" class="app-aside">
<!-- 左侧导航 -->
<el-menu
style="height: 100%;"
text-color="#888888"
:router=true
:unique-opened=true>
<li class="welcome">
<i class="el-icon-people"></i>
<span slot="title">Welcome Vincent</span>
</li>
<el-menu-item v-for="item in menuItems" :key=item.index @click=routeTo :route=item.index :index=item.index>
<i :class=item.icon></i>
<span slot="title">{{ item.title }}</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main class="app-main">
<!-- 右侧主题内容 -->
<router-view/>
</el-main>
</el-container>
</el-container>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({
data() {
return {
menuItems: [{
title: '号码筛选',
index: '/filternumber',
icon: 'el-icon-menu',
}, {
title: '加粉任务',
index: '/addtask',
icon: 'el-icon-tickets',
}],
currentUser: {
username: 'wangzezhi',
},
};
},
methods: {
routeTo() {
// TODO
},
logout() {
// TODO
},
},
})
export default class Layout extends Vue {}
</script>
<style lang="scss" scoped>
.app-wraper {
&:after {
content: "";
display: table;
clear: both;
}
background-color: #f7f7f7;
height: 100%;
width: 100%;
position: relative;
.app-header {
background: #fff;
box-shadow: 0 2px 3px 0 rgba(100,100,100,0.15);
text-align: left;
line-height: 60px;
}
.app-aside {
width: 210px;
margin: 30px 30px 0 30px;
border-radius: 4px;
box-shadow: 0 2px 3px 0 rgba(100,100,100,0.15);
.welcome {
height: 60px;
line-height: 60px;
font-size: 14px;
}
.el-menu-item {
height: 46px;
padding: 0 80px 0 20px;
line-height: 46px;
span {
margin-left: 10px;
}
}
.el-menu-item.is-active {
border-left: 2px solid #409EFF;
}
}
.app-main {
overflow-y: scroll;
}
}
</style>
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
propsData: { msg },
});
expect(wrapper.text()).to.include(msg);
});
});
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"node",
"mocha",
"chai"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
{
"defaultSeverity": "warning",
"extends": [
"tslint:recommended"
],
"linterOptions": {
"exclude": [
"node_modules/**"
]
},
"rules": {
"quotemark": [true, "single"],
"indent": [true, "spaces", 2],
"interface-name": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-consecutive-blank-lines": false,
"object-literal-key-quotes": [true, "consistent"]
}
}
module.exports = {
baseUrl: process.env.NODE_ENV === 'production' ?
'/production-sub-path/' :
'/',
devServer: {
// proxy: 'http://localhost:8999',
proxy: 'http://10.1.0.99:8999',
},
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment