Commit dec35184 authored by 刘松's avatar 刘松

modify

parent 65f2b519
### Health check 'curl /ping'
FROM reg.yunpro.cn/library/node:9.11.1
WORKDIR /app
ADD ./package.json /app/
#front end
ADD ./dist /app/dist
ADD ./public /app/public
#server
ADD ./app.js /app/
#api
ADD ./api /app/api
RUN \
rm /etc/localtime && \
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN npm i --only=production --registry https://registry.npm.taobao.org
ENV SERVICE_PORT=8081
ENV PROJECT_LEVEL=production
ENV MONGO='mongodb://wkf-mongo:8199/addwechat'
ENV DEVICE='http://wk-center-ctrller-go:9911'
ENV GO='http://wk_tag_to_wechat:9912'
ENV NODE_ENV='production'
ENV BUILD_ENV=''
EXPOSE 8081
CMD node app.js
...@@ -3,82 +3,531 @@ const mongodb = require("mongodb"); ...@@ -3,82 +3,531 @@ const mongodb = require("mongodb");
const MongoClient = mongodb.MongoClient; const MongoClient = mongodb.MongoClient;
const axios = require("axios"); const axios = require("axios");
const moment = require('moment'); const moment = require('moment');
const jwt = require('jsonwebtoken'); const crypto = require('crypto');
const _ = require('lodash');
const qs = require('qs');
let db = {}; let db = {};
const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/addwechat?poolSize=100000000"; const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/addwechat?poolSize=100000000";
const AuthName = 'l_q6KiRVG4200kwRXIwVfgY1yOIa'; const AuthName = 'l_q6KiRVG4200kwRXIwVfgY1yOIa';
const AuthPass = 'N11ztBU2lExdNOklH2AmX4JOzdIa'; const AuthPass = 'N11ztBU2lExdNOklH2AmX4JOzdIa';
const host = process.env.GO || 'http://192.168.1.131:9912';
const deviceHost = process.env.DEVICE || 'http://192.168.1.122:9911';
//const host = "http://192.168.1.122:9912";
let authorition = '';
let access_token = null;
let tokenEndTime = 0;
const salt = "BreakingBad"; const salt = "BreakingBad";
const ROLES = {
ADMIN: 1,
PUB: 2,
SALEMANAGER: 3
}
const SECRET = 'remarketing-token'; const SECRET = 'remarketing-token';
let myToken = ''; let myToken = '';
let wechatMap = {};
const map2Code = {
'age': 'K000002',
'sex': 'K000001',
'flow_3': 'K003727',
'flow_6': 'K003728',
'consume_3': 'K003611',
'consume_6': 'K003726',
'city': 'K003681'
}
const city2code = { '北京': 'V0110000','天津': 'V0120000','上海': 'V0310000','重庆': 'V0500000','海口': 'V0460100','三亚': 'V0460200','保亭': 'V04602003','澄迈': 'V04601006','文昌': 'V04601003','临高': 'V04600032','五指山': 'V04602004','琼山': 'V04601001','昌江': 'V04600033','儋州': 'V0460003','陵水': 'V04602002','琼中': 'V04601008','屯昌': 'V04601007','万宁': 'V04601004','定安': 'V04601005','乐东': 'V04602001','琼海': 'V04601002','东方': 'V04600031','白沙': 'V04600034','广州': 'V0440100','汕尾': 'V0441500','阳江': 'V0441700','揭阳': 'V0445201','茂名': 'V0440901','江门': 'V0440700','韶关': 'V0440201','惠州': 'V0441300','梅州': 'V0441401','汕头': 'V0440510','深圳': 'V0440300','珠海': 'V0440400','佛山': 'V0440600','肇庆': 'V0441201','湛江': 'V0440800','中山': 'V0442000','河源': 'V0441600','清远': 'V0441800','云浮': 'V0441281','潮州': 'V0445100','东莞': 'V0441900','武汉': 'V0420100','襄樊': 'V0420600','鄂州': 'V0420700','孝感': 'V0420900','黄冈': 'V0422100','黄石': 'V0420200','咸宁': 'V0422300','荆州': 'V0422400','宜昌': 'V0420500','恩施': 'V0422800','十堰': 'V0422600','随州': 'V0420681','荆门': 'V0420800','江汉': 'V0422401','沈阳': 'V0210100','大连': 'V0210200','鞍山': 'V0210300','抚顺': 'V0210400','本溪': 'V0210500','丹东': 'V0210600','锦州': 'V0210700','营口': 'V0210800','阜新': 'V0210900','辽阳': 'V0211000','铁岭': 'V0211200','朝阳': 'V0211300','盘锦': 'V0211100','葫芦岛': 'V0211400','德宏': 'V0533100','文山': 'V0532600','保山': 'V0533000','临沧': 'V0533500','怒江傈': 'V0533300','迪庆': 'V0533400','昭通': 'V0532100','昆明': 'V0530100','红河': 'V0532500','大理': 'V0532900','丽江': 'V0533200','楚雄': 'V0532300','玉溪': 'V0532400','曲靖': 'V0532200','西双版纳': 'V0532800','普洱': 'V0533600','定西': 'V0622400','平凉': 'V0622700','庆阳': 'V0622800','武威': 'V0622300','张掖': 'V0622201','嘉峪关': 'V0620200','天水': 'V0620500','临夏': 'V0622901','白银': 'V0620400','金昌': 'V0620300','酒泉': 'V0622100','陇南': 'V0622600','甘南': 'V0623000','兰州': 'V0620100','呼和浩特': 'V0150100','包头': 'V0150200','乌海': 'V0150300','赤峰': 'V0150400','兴安': 'V0152200','通辽': 'V0152301','锡林郭勒': 'V0152500','乌兰察布': 'V0152600','鄂尔多斯': 'V0152700','巴彦淖尔': 'V0152800','阿拉善': 'V0152900','呼伦贝尔': 'V0152302','海拉尔': 'V0152101','贵阳': 'V0520100','遵义': 'V0522100','安顺': 'V0522500','铜仁': 'V0522200','毕节': 'V0522400','六盘水': 'V0520200','黔西南': 'V0522900','黔东南': 'V0523100','黔南': 'V0523200','郑州': 'V0410100','开封': 'V0410200','洛阳': 'V0410300','平顶山': 'V0410400','安阳': 'V0410500','鹤壁': 'V0410600','新乡': 'V0410700','焦作': 'V0410800','濮阳': 'V0410900','许昌': 'V0411000','漯河': 'V0411100','三门峡': 'V0411200','商丘': 'V0412300','周口': 'V0412700','驻马店': 'V0412801','南阳': 'V0412901','信阳': 'V0413000','济源': 'V0412800','杭州': 'V0330100','宁波': 'V0330200','温州': 'V0330300','台州': 'V0332600','金华': 'V0330700','嘉兴': 'V0330400','绍兴': 'V0330600','湖州': 'V0330500','丽水': 'V0332500','衢州': 'V0330800','舟山': 'V0330900','南京': 'V0320100','苏州': 'V0320500','无锡': 'V0320200','常州': 'V0320400','扬州': 'V0321000','镇江': 'V0321100','南通': 'V0320600','徐州': 'V0320300','泰州': 'V0321082','盐城': 'V0320900','淮安': 'V0320800','连云港': 'V0320700','宿迁': 'V0320881','长春': 'V0220100','吉林': 'V0220200','延边': 'V0222400','四平': 'V0220300','通化': 'V0220500','白城': 'V0220800','辽源': 'V0220400','松原': 'V0220700','白山': 'V0220600','西宁': 'V0630100','海东': 'V0632100','格尔木': 'V0632801','海北': 'V0632200','海南': 'V0632500','海西': 'V0632800','果洛': 'V0632600','玉树': 'V0632700','黄南': 'V0632300','拉萨': 'V0540100','日喀则': 'V0542300','山南': 'V0542200','林芝': 'V0542600','昌都': 'V0542100','那曲': 'V0542400','阿里': 'V0542500','长沙': 'V0430100','株洲': 'V0430200','湘潭': 'V0430300','衡阳': 'V0430400','岳阳': 'V0430600','益阳': 'V0430900','郴州': 'V0431000','常德': 'V0430700','娄底': 'V0432500','邵阳': 'V0430500','湘西': 'V0433100','张家界': 'V0430800','怀化': 'V0431200','永州': 'V0431100','福州': 'V0350100','厦门': 'V0350200','泉州': 'V0350500','漳州': 'V0350600','宁德': 'V0352200','莆田': 'V0350300','南平': 'V0352100','三明': 'V0350400','龙岩': 'V0352600','成都': 'V0510100','自贡': 'V0510300','攀枝花': 'V0510400','泸州': 'V0510500','德阳': 'V0510600','绵阳': 'V0510700','广元': 'V0510800','遂宁': 'V0510900','内江': 'V0511000','乐山': 'V0511100','南充': 'V0511300','眉山': 'V0513800','宜宾': 'V0512500','广安': 'V0513600','达州': 'V0513000','雅安': 'V0513100','巴中': 'V0513700','资阳': 'V0513900','阿坝': 'V0513200','甘孜': 'V0513300','凉山': 'V0513400','东川': 'V0530200','乌鲁木齐': 'V0650100','克拉玛依': 'V0650200','吐鲁番': 'V0652101','哈密': 'V0652201','昌吉': 'V0652301','博尔塔拉': 'V0650300','巴音郭楞': 'V0650500','阿克苏': 'V0652901','克孜勒苏': 'V0650600','喀什': 'V0653101','和田': 'V0653201','奎屯': 'V0654001','伊犁': 'V0650400','塔城': 'V0654201','阿勒泰': 'V0654301','石河子': 'V0659001','南昌': 'V0360100','九江': 'V0360400','上饶': 'V0362233','抚州': 'V0362500','宜春': 'V0362200','吉安': 'V0362400','赣州': 'V0362100','景德镇': 'V0360200','萍乡': 'V0360300','新余': 'V0360500','鹰潭': 'V0360600','马鞍山': 'V0340500','蚌埠': 'V0340300','安庆': 'V0340800','芜湖': 'V0340200','六安': 'V0342400','合肥': 'V0340100','阜阳': 'V0342100','淮南': 'V0340400','铜陵': 'V0340700','宣城': 'V0342500','滁州': 'V0341100','宿州': 'V0342200','淮北': 'V0340600','黄山': 'V0341000','池州': 'V0342900','亳州': 'V0343000','巢湖': 'V0342600','朔州': 'V0140600','忻州': 'V0142200','太原': 'V0140100','大同': 'V0140200','阳泉': 'V0140300','晋中': 'V0142400','长治': 'V0140400','晋城': 'V0140500','临汾': 'V0142600','吕梁': 'V0142300','运城': 'V0142700','邯郸': 'V0130400','保定': 'V0130600','张家口': 'V0130700','唐山': 'V0130200','沧州': 'V0130900','邢台': 'V0130500','秦皇岛': 'V0130300','石家庄': 'V0130100','承德': 'V0130800','廊坊': 'V0131000','衡水': 'V0133000','银川': 'V0640100','吴忠': 'V0642100','石嘴山': 'V0640200','固原': 'V0642200','中卫': 'V0642300','宝鸡': 'V0610300','西安': 'V0610100','延安': 'V0612601','渭南': 'V0612101','咸阳': 'V0610400','榆林': 'V0612701','铜川': 'V0610200','商洛': 'V0612501','安康': 'V0612401','汉中': 'V0612301','南宁': 'V0450100','桂林': 'V0450300','柳州': 'V0450200','梧州': 'V0450400','玉林': 'V0452500','百色': 'V0452600','钦州': 'V0452800','河池': 'V0452700','北海': 'V0450500','崇左': 'V0453200','贺州': 'V0453000','贵港': 'V0452900','防城港': 'V0450600','来宾': 'V0453100','哈尔滨': 'V0230100','齐齐哈尔': 'V0230200','牡丹江': 'V0231000','佳木斯': 'V0230800','绥化': 'V0232300','大庆': 'V0230600','鸡西': 'V0230300','黑河': 'V0231100','伊春': 'V0230700','双鸭山': 'V0230500','鹤岗': 'V0230400','七台河': 'V0230900','大兴安岭': 'V0232700','济南': 'V0370100','青岛': 'V0370200','淄博': 'V0370300','枣庄': 'V0370400','东营': 'V0370500','烟台': 'V0370600','潍坊': 'V0370700','济宁': 'V0370800','泰安': 'V0370900','威海': 'V0371000','日照': 'V0371100','莱芜': 'V0371200','临沂': 'V0372801','德州': 'V0372401','聊城': 'V0372500','滨州': 'V0372300','菏泽': 'V0372900' }
//initAuthorization();
// TODO ! put into init // TODO ! put into init
MongoClient.connect(dbpath, (err, conn) => { MongoClient.connect(dbpath, (err, conn) => {
if (err) return console.log(err); if (err)
console.log("#### DB CONNECTED"); return console.log(err);console.log("#### DB CONNECTED");
db = conn.db(process.env.MONGO_DB || "remarketing"); db = conn.db(process.env.MONGO_DB || "addwechat");
initMongo();
db db
.collection("session") .collection("session")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 }); .createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
}); });
// router.get('/*',function (req, res) {
// res.send("das"); function initMongo() {
// }) db.collection('account').update({ username: 'admin'},{ $set: { password: md5password('123asd') } }, { upsert: 1},(err,rep) => {
router.get('/ping',function (req, res) { console.dir(err);
console.dir(rep.result);
})
}
function initAuthorization() {
let b = new Buffer(AuthName + ':' + AuthPass);
let s = b.toString('base64');
authorition = "Basic" + s;
console.dir(authorition);
}
setInterval(() => {
//console.dir(' in setInterval');
axios(deviceHost + '/get_device', {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
refreshOnlineMap(rep.data.msg.list)
})
.catch(err => {
devicelist = [];
wechatMap = {};
});
},1000 * 60 * 3 );
function refreshOnlineMap(devices) {
for(var k in devices) {
if(devices[k].weChatInfo && devices[k].weChatInfo.wechatId) {
wechatMap[devices[k].weChatInfo.wechatId] = devices[k].weChatInfo;
}
}
//console.dir(wechatMap);
}
router.get('/ping',async function (req, res) {
//let a = await generateToken();
res.send({ status: 'ok' }); res.send({ status: 'ok' });
}) })
router.get('/search',function (req, res) { router.get('/search',async (req, res) => {
res.send({ status: 'ok' }); let { page = 0, size = 0 } = req.query;
if(page > 0) page -= 1;
let options = { skip: parseInt(page * size), limit: parseInt(size) };
let count = await db.collection('filters').count({})
db.collection('filters').find({})
.sort({createdAt: -1})
.skip(parseInt(page * size))
.limit(parseInt(size))
.toArray(async (err,rep) => {
let arrs = await getCount(rep)
if(err) return res.status(500).json({ error: '数据获取错误' });
else return res.status(200).json({ count, list: arrs });
});
}) })
const created = ''; router.get('/qrcode',async (req, res) => {
function generateToken(token) { let { sn, type='get' } = req.query;
let timeNow = Math.floor(Date.now() / 1000); axios(deviceHost + (type='get' ? '/get_qr_code/' : 're_qr_code') + sn, {
if(token) method: "GET",
// let token = jwt.sign({ headers: { "Content-Type": "application/json" },
// data, timeout: 300000
// exp: created + 3600 * 24 })
// }, salt, {algorithm: 'RS256'}); .then(async rep => {
// console.log(token); console.dir(rep.data.msg)
return token; if(rep.data && rep.data.msg && rep.data.msg.qrcode) {
} //console.dir(rep.data.msg.qrcode);
res.status(200).json({ qrcode: 'data:image/png;base64,' + rep.data.msg.qrcode });
} else{
//res.status(200).json({ qrcode: 'data:image/png;base64,' + "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAHzklEQVR4Xu2bbYxUVxnH//87sy/CwrwEKKJS2Z27EDWaWOMHaWpSP6iJxqZpWhuV8iK77Axs0YCF3bVZuoTSaku7MLNs5EVt0rSoVbEx8qFoqzG20Rqrxbozs4tCGpQ6M8tLu7Bz72PustR5uTP33pk7w3zY/ch9nnP+/98995wz5zwQN+DPt//0CkW5+gDILxNogsgxePid1Cb1VL3lsJ4d+mJj7R5wQIA1BDy5fQsgAH4OTXkwvaXjr/XSVRcAxhv3KNMDQtxXaNzMqECeF/LBTI/651qDqCmAWeP9Qqy1Y9zE7AlNUQYmN3X8sVYgagLAf2D8ZlLrB7G+QuP5fkVeADmQCqt/cBuEqwBmjCvZPgDrCDa5LVaAF3Xyocme0Em32nYFQGA0uRxZre/aG3ffeKFZAX5P4VAqEvpVtSCqAhCMJj4gRB+gb6iH8WKz8ooQQ+mezucrBVERgOBw/P3iwU5Qvk6wudLO3coTwatCDmXCoZ85bdMRgPeM/ON9raLsBGRjIxgv/jTkNYK7Uz2hH4M09hWWf7YAzNv/r2UtyhXjjXc1onETl6dEZHf6vPosBqmXo1AWwIxxz9QOCLtItFjibLAAESRI9KXC6o9KSSsJwHcw+QmPrp0EuKDBfDmXI+xKRULfM0ssCSAQHXua5L3Oe2u8DBH8Oh1Rb3cIIP4wiR2NZ8e5IgFG0mE17AgAjr3eHDzfPCI0dnWwNVk6l1aPDPlJSvxrEVlyyRmA2WhfLHGLAnmSwOp6yHWrD4H8RcD7M2H1xYpXgdxEXzR+lwJ8l8TNbomsSTuCc7qC/sym0FE7ewFnQ3s43hLwSi+Bbzfc6iB4B5THUm0L92LN0st24RYBmB+dWNrC7PcB+ESU7elIx+8KG2sbji9u8mIXgC5Xfu7aVWsSN3OSJHiaGnaketWzhSGBaPJWQt8nlH9PZ7nuUq96PjemCEAgFv8NgU8bQUbjFBzRr3q3Zb6xIlPY+ILRiVVN2ekDID9ThYfKU0Ve1qhEJsOhPxU2svDQmaD3ytSjcu1M4rrPk6mwmqfVDECGgC+3QYG8JVC2ZcKhH5ipDUYTnwP0fSBXVe7GfqZATlPnA6nN6jGzLH8scR+hP04wmOdDkElH1IDVCCgCcD3B+B2ue7BmsltNFnV8TDyB/ya6IPIQwUX27TiIFFwQYk86iyfQq14pGpGx8ZVeaEcIfMqsVakWwLXPQq4SeDSV5W4zEYHRpA+a1g9gq1tnBAJoEDmU9crAxe6VbxWZOzrRGnxnul8EO0h6SyF1BcD/R4Oc1qlsKHU8NXMELnwExF0O3nFxqMgL096mzRe7V7xh1o5vJHG7Ivphgh+06sdVADkgnpnOsrdwdr3+PDCSWE2RJwHcYiUw77nI30U829KbO35plmesVs3MPkHgHrvt1gTA7GoxCUFfOhwaMd18iNAfS35Nob4X4HvLCTYmXICD6UWhg7ibWlHsoCiBJYkeiuwF2WbX/IxON+aAsuIFr4Kedelw+2umcaNvzgvql7dD8C0A8/JmaMhVEe7PtGq7sGHVRbP8QGz8oxDtKImPOzH+7mitNYDZ0aBRMJzyzh9A97K3zYQaBy2tnqk9AhpXZITIcxqxfTLcOW5q7PAbC4JT3iGBbCGhVGK+LiMg/xvGWV1hb6Yn9NNSgv0Hxz9GHQvT4fbfloyJJu9UoEdBLK3UeF1HgInIE1Nay/q3tyx/04kB48gdFOMU57NO8iw+0eo2QhULEbksxK70IvVx04ktt+FRaQpoiW8SGATQWnGfJok1nwRtiD2VVZQ7LmzqiJvFLjyYVL269guAK2205TikEQAYP7DOULg6FQmdyXVwbcjrL1stk45d5yQ0BABDjw4cyoTVjfkA4oeNu8VqDFrlNgwAEZlIRzrbcwUHYvF/ElhuZaKa5w0DACKXUpHOvPuGYHTsEsj51Ri0yp0DUI+doNVbmHk+NwLmPoG5OWBuEpxbBeaWwbl9QP5WeG4j1Bg7wWA0fg7ETbY2NJUG3aCNEATnUhE171C2+GosGj9O4ouVerOVd4MACHA8HVa/lKuxCEDwQPxuUfBMTatCbhAA6Lin8D7RtD4gMDL2Beh8ioTf1ht1GlR/AFMQrk1FQs8WSi1ZINE2kljSJPIYga869WcZX18AJyDcWHgCdV2jZYWI/8DYbVRo3Lh2WBqzG1APAIKzOpT7M5GO58rJsgQwkzwcbwl6sFMoO10pla0hAOMmmcD+lGd+f6mLmbKTYDlavtF4h5KVIyRvs/uyTeNqBMCoGi97NWcixt4IKEgMRONfAbCPxOKKQLgMQIBJAP3pnlDMTmVYxSMgN9G/b8LP5mnjhtYolHIG0kUAAil7PW/1gpwJN2lt4cj4J72iHQXwIavO3n3uAgCjTqhcgYZdLVUDmOloULzBxcmtoAzZus6qAoBViY5d47aXQScN2r7QrBCAiLyke7netEjLidCcWHdGQEHn/ljiDkWMK20uc2MVEMF5AbdlIqEfVuizZFpNAMz0Fv1Pm5+TuyjYWlTUYHMEGIWaAhzGFe92s0JNN2DUDsCsOrOyFhG8no6oH8k1EIjG/0biwzn/dipLz7oLPe2vuGG0VBs1BzA7SSqBmxLdEDxs/Hd5XZfPZzZ3vpQPIHkrqB+nSLMOPJJZrO6xrCVwgcz/AM6LC33oCUZ5AAAAAElFTkSuQmCC" });
res.status(500).json({ error: rep.data.errorCode === 1000 ? '设备离线,稍后重试' : '获取失败,稍后重试'});
}
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '获取失败'});
});
})
router.post('/login',function(req,res) {
const { username, password } = req.body; router.get('/tasks',async (req, res) => {
if(username === 'break' && password === '123456'){ let { page = 0, size = 10 } = req.query;
axios.post('http://10.1.0.216:9912/getAuth',{ if(page > 0) page -= 1;
AuthName, let options = { skip: parseInt(page * size), limit: parseInt(size) };
AuthPass let count = await db.collection('taskWrap').count({})
}) db.collection('taskWrap').find({})
.then(rep => { .sort({createdAt: -1})
if(rep && rep.status === 200) { .skip(parseInt(page * size))
res.send({result:rep.data}); .limit(parseInt(size))
} .toArray(async (err,rep) => {
if(err) return res.status(500).json({ error: '数据获取错误' });
else { else {
res.send({ msg: '服务器开小差了' }); let arrs = await getOkCount(rep);
arrs = arrs.map( x => {
x.weChatInfo = wechatMap[x.user_id]
return x;
});
console.dir(arrs);
return res.status(200).json({ count, list: arrs });
} }
}) });
.catch(err => { })
res.send({ msg: err });
router.get('/task/detail',async (req, res) => {
let { page = 0, size = 10 , taskWrapID = null} = req.query;
if(page > 0) page -= 1;
let options = { skip: parseInt(page * size), limit: parseInt(size) };
let count = await db.collection('tasks').count({ taskWrapID: OID(taskWrapID) })
db.collection('tasks').find({ taskWrapID: OID(taskWrapID) })
.sort({createdAt: -1})
.skip(parseInt(page * size))
.limit(parseInt(size))
.toArray(async (err,rep) => {
if(err) return res.status(500).json({ error: '数据获取错误' });
else return res.status(200).json({ count, list: rep });
});
})
function getNum(total,num) {
let s = ''
for (var i = 0; i < total - (num + '').length; i++) {
s += '0';
}
return s + num;
}
router.post("/task", async function(req, res) {
let { count, id, user_id, greet } = req.body;
if(!id) return res.status(500).json({ error: '参数错误'});
let { respData } = await db.collection('filters').findOne({ _id: OID(id) });
let task_count = await db.collection('tasks').count({ filterID: OID(id) });
let customers = [];
if( respData.customers && respData.customers.length ) {
customers = respData.customers.slice(task_count, parseInt(count) + task_count)
}
let data = customers.map( x => {
return {
user_id : user_id,
date : moment().format('YYYYMMDD'),
greet : greet,
phone : x,
wechat_id: x,
filterID: OID(id)
}
})
db.collection('tasks').insertMany(data, async (err,rep) => {
if (err) return res.status(500).json({ error: '服务器错误'});
else {
let ids = []
if(rep && rep.ops) {
ids = rep.ops.map( x => x._id);
let code = getNum(6, await db.collection('taskWrap').count());
db.collection('taskWrap').insert({
code,
createdAt: Date.now(),
user_id,
greet,
filterID: id,
ids
},async (err,rep) => {
if(rep.ops[0]._id) {
let _rep = await db.collection('tasks').update({ _id:{ $in: ids} },{ $set: { taskWrapID: rep.ops[0]._id }},{ multi: 1})
res.status(200).json(_rep);
}
else res.status(500).json({ error: '数据异常'});
});
}
}
})
});
async function getCount(arrays) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const count = (x._id) ? await db
.collection("tasks")
.count({ filterID: x._id }) : 0;
r(_.merge(x, { used: count } ));
}));
}); });
const arrs = await Promise.all(tasks);
return arrs;
}
async function getOkCount(arrays) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const count = (x._id) ? await db
.collection("tasks")
.count({ taskWrapID: x._id, status: { $exists: 1} }) : 0;
r(_.merge(x, { used: count } ));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
router.get('/is_login_wechat/',async (req, res) => {
let { sn } = req.query;
axios(deviceHost + '/is_login_wechat/' + sn, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.msg) {
res.status(200).json(rep.data.msg);
} else{
res.status(500).json({ error: rep.data.errorCode === 1000 ? '设备离线,稍后重试' : '获取失败,稍后重试'});
}
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '获取失败'});
});
})
router.get('/devices',async (req, res) => {
axios(deviceHost + '/get_device', {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.msg && rep.data.msg.list) {
res.status(200).json({ list: rep.data.msg.list });
} else{
res.status(500).json({ error: rep.data.errorCode === 1000 ? '设备离线,稍后重试' : '获取失败,稍后重试'});
}
})
.catch(err => {
if (err) return res.status(500).json({ error: '获取失败'});
});
})
// generateToken();
async function generateToken() {
let timeNow = Math.floor(Date.now() / 1000);
console.dir('begin token');
return new Promise((r,e) => {
axios(host + '/getAuth', {
method: "POST",
data: qs.stringify({
AuthName,
AuthPass
}),
headers: {
"Content-type": "application/x-www-form-urlencoded",
"Authorization": authorition
}
})
.then(rep => {
if( rep && rep.data && rep.data.access_token ) {
access_token = access_token;
tokenEndTime = Date.now() + parseInt(rep.data.expires_in) * 1000
r(rep.data);
} else {
e('not known error');
}
})
.catch(err => {
e(err);
});
});
}
function generateRequestID() {
let num = '';
for(let i=0; i<4; i++){
num += Math.floor(Math.random()*10);
} }
else{ return `U200000` + moment().format('YYYYMMDDHHmmss') + num;
res.send({ msg: '用户名密码错误' }); }
router.post("/login", function(req, res) {
// check sessionID
checkSession(req.body, (err, rep) => {
if (err) return res.sendStatus(500);
if (!rep) {
//没有符合的session
return authorize(req.body, (err, rep) => {
if (err) return res.status(500).json({ error: '账户或密码错误' });
if (!rep) return res.status(403).json({ error: '账户或密码错误' });
//验证通过
const account = _.merge(rep, { sessionID: genSessionID(rep._id) });
delete account.password;
res.send({ status: "ok", account });
});
} else {
db
.collection("account")
.findOne({ _id: OID(rep.accountID) }, (err, rep) => {
if (err || !rep) return res.status(500).json({ error: '账户或密码错误' });
const account = _.merge(rep, { sessionID: req.body.sessionID });
delete account.password;
res.send({ status: "ok", account });
});
}
});
});
function generateQueryModel (body) {
let attrs = [];
let age = [];
let consumption = [];
let flow = [];
let sex = [];
let areas = [];
let { ageEnd, ageStart, consumptionDuring, consumptionEnd, consumptionStart, districts, dsgroup, flowDuring, flowEnd, flowStart, sexlist } = body;
if(!isNaN(ageEnd) && !isNaN(ageStart)) {
age = [{ attrCode: map2Code['age'], relation: 5, attrValue: ageEnd, condition: 'or' },{ attrCode: map2Code['age'], relation: 3, attrValue: ageStart, condition: 'or' }];
attrs= attrs.concat(age);
} }
if(!isNaN(consumptionStart) && !isNaN(consumptionEnd)) {
if(consumptionDuring === '近三月平均') {
consumption = [{ attrCode: map2Code['consume_3'], relation: 5, attrValue: consumptionEnd, condition: 'or' },{ attrCode: map2Code['consume_3'], relation: 3, attrValue: consumptionStart, condition: 'or' }];
} else {
consumption = [{ attrCode: map2Code['consume_6'], relation: 5, attrValue: consumptionEnd, condition: 'or' },{ attrCode: map2Code['consume_3'], relation: 3, attrValue: consumptionStart, condition: 'or' }];
}
attrs= attrs.concat(consumption);
}
if(!isNaN(flowStart) && !isNaN(flowEnd)) {
if(flowDuring === '近三月平均') {
flow = [{ attrCode: map2Code['flow_3'], relation: 5, attrValue: flowEnd, condition: 'or' },{ attrCode: map2Code['flow_3'], relation: 3, attrValue: flowStart, condition: 'or' }];
} else {
flow = [{ attrCode: map2Code['flow_6'], relation: 5, attrValue: flowEnd, condition: 'or' },{ attrCode: map2Code['consume_3'], relation: 3, attrValue: flowStart, condition: 'or' }];
}
attrs= attrs.concat(flow);
}
if( sexlist && sexlist.indexOf('男') >= 0 ) {
sex.push({ attrCode: map2Code['sex'], relation: 1, attrValue: '01', condition: 'or' });
}
if( sexlist && sexlist.indexOf('女') >= 0 ) {
sex.push({ attrCode: map2Code['sex'], relation: 1, attrValue: '02', condition: 'or' });
}
if( sex.length ) attrs= attrs.concat(sex);
if(districts) {
districts.forEach( x => {
x.cities.forEach( y => {
areas.push({ attrCode: map2Code['city'], relation: 1, attrValue: city2code[y], condition: 'or' })
})
})
}
if( areas.length ) attrs= attrs.concat(areas);
return attrs;
}
router.post("/model/query", function(req,res) {
checkSession(req.body, async (err,result) => {
if(!err) {
let { access_token } = await generateToken();
console.dir(access_token);
let model = generateQueryModel(req.body);
console.dir(JSON.stringify({
requestId: generateRequestID(),
queryModel: [{ attrList: model }],
}));
axios(host + '/modelUserListQuery', {
method: "POST",
data: JSON.stringify({
requestId: generateRequestID(),
queryModel: [{ attrList: model }],
}),
timeout: 1000 * 60 * 10,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": access_token
}
})
.then(rep => {
console.dir(rep.data);
if(rep && rep.data && rep.data.respData) {
rep.data.createdAt = Date.now();
db.collection('filters').insert(_.merge(rep.data,req.body),(err,rep) => {
if(err) return res.status(500).json({ error: '数据存储错误' });
else return res.status(200).json(rep.data);
});
} else {
return res.status(500).json({ error: '请求数据错误' });
}
})
.catch(err => {
return res.status(500).json({ error: '请求错误' });
});
} else return res.status(500).json({ error: '请先登录再操作' });
})
}); });
router.post("/logout",function(req,res) {
let { sessionID } = req.body;
db
.collection('session')
.remove({ _id: OID(sessionID) }, (err, rep) => {
if (err || !rep) return res.sendStatus(500);
res.send({ status: "ok", rep });
});
});
function checkSession(data, callback) {
if (!data.sessionID) return callback(null);
db
.collection("session")
.findOne({ sessionID: OID(data.sessionID) }, (err, rep) => {
if (err || !rep) return callback(err, null);
callback(null, rep);
});
}
function authorize(data, callback) {
db.collection("account").findOne({ username: data.username }, (err, rep) => {
if (err || !rep) return callback(err, null);
if (md5password(data.password) !== rep.password)
return callback("password wrong", null);
callback(null, rep);
});
}
function genSessionID(accountID) {
const sessionID = mongodb.ObjectID();
db.collection("session").insert(
{
createdAt: new Date(),
sessionID,
accountID
},
(err, rep) => {
if (err) console.log(err);
}
);
return sessionID;
}
function md5password(str) {
const salt = ",tom";
const hash = crypto
.createHash("md5")
.update(str + salt)
.digest()
.toString("hex");
return hash;
}
function OID(str) {
return typeof str === 'string' ? mongodb.ObjectID(str) : str;
}
module.exports = { module.exports = {
router router
} }
\ No newline at end of file
...@@ -14,10 +14,14 @@ app.use(bodyParser.urlencoded({ ...@@ -14,10 +14,14 @@ app.use(bodyParser.urlencoded({
})); }));
app.use(cookieParser()); app.use(cookieParser());
app.use(express.static(__dirname + '/dist')); app.use(express.static(__dirname + '/dist'));
app.use('/api', api.router);
app.get('/*',function(req,res) { app.get('/*',function(req,res) {
res.sendFile(path.resolve(__dirname , 'dist/index.html')); res.sendFile(path.resolve(__dirname , 'dist/index.html'));
}) });
app.use('/api', api.router);
server.listen(process.env.PORT || 8081, function() { server.listen(process.env.PORT || 8081, function() {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -13,11 +13,12 @@ ...@@ -13,11 +13,12 @@
"axios": "^0.18.0", "axios": "^0.18.0",
"body-parser": "^1.18.3", "body-parser": "^1.18.3",
"cookie-parser": "^1.4.3", "cookie-parser": "^1.4.3",
"element-ui": "^2.4.5", "element-ui": "^2.4.7",
"express": "^4.16.3", "express": "^4.16.3",
"jsonwebtoken": "^8.3.0", "lodash": "^4.17.11",
"moment": "^2.22.2", "moment": "^2.22.2",
"mongodb": "^3.1.6", "mongodb": "^3.1.6",
"qs": "^6.5.2",
"vue": "^2.5.17", "vue": "^2.5.17",
"vue-class-component": "^6.0.0", "vue-class-component": "^6.0.0",
"vue-property-decorator": "^7.0.0", "vue-property-decorator": "^7.0.0",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>wk_add_wehcat</title> <title>联通微信加粉</title>
</head> </head>
<body> <body>
<noscript> <noscript>
......
import axios from 'axios';
axios.defaults.withCredentials = true;
const getTaskList = (size: number, page?: number) => {
return axios.get(`/api/tasks?page=${page}&size=${size}`);
};
const getDetailList = (size: number, page: number, taskWrapID: string) => {
return axios.get(`/api/task/detail?page=${page}&size=${size}&taskWrapID=${taskWrapID}`);
};
const createTask = (
form: {
count: number,
id: string,
user_id: string,
greet: string,
}) => {
return axios.post(`api/task`, form);
};
export {
getTaskList,
createTask,
getDetailList,
};
import axios from 'axios';
axios.defaults.withCredentials = true;
const getDeviceList = () => {
return axios.get(`/api/devices`);
};
const getQrcode = (sn: string, type: string) => {
return axios.get(`/api/qrcode?sn=${sn}&type=${type}`);
};
const getDeviceStatus = (sn: string) => {
return axios.get(`/api/is_login_wechat?sn=${sn}`);
};
export {
getDeviceList,
getQrcode,
getDeviceStatus,
};
...@@ -3,19 +3,38 @@ import axios from 'axios'; ...@@ -3,19 +3,38 @@ import axios from 'axios';
axios.defaults.withCredentials = true; axios.defaults.withCredentials = true;
const getFilterList = (size: number, page?: number) => { const getFilterList = (size: number, page?: number) => {
return axios.get(`/api/permission?page=${page}&size=${size}`); return axios.get(`/api/search?page=${page}&size=${size}`);
}; };
const createFilterList = ( const createFilterList = (
form: {
ageEnd: string,
ageStart: string,
consumptionDuring: string,
consumptionEnd: string,
consumptionStart: string,
districts: any,
dsgroup: string,
flow: string,
flowDuring: string,
flowEnd: string,
flowStart: string,
sexlist: string,
}) => {
return axios.post(`api/model/query`, form);
};
const filterCount = (
form: { form: {
name: string, name: string,
desc: string, desc: string,
code: string, code: string,
}) => { }) => {
return axios.post(`api/search`, form); return axios.post(`api/model/count`, form);
}; };
export { export {
getFilterList, getFilterList,
createFilterList, createFilterList,
filterCount,
}; };
...@@ -140,19 +140,19 @@ export default class CommonTable extends Vue { ...@@ -140,19 +140,19 @@ export default class CommonTable extends Vue {
let str = ''; let str = '';
switch (num) { switch (num) {
case 0: case 0:
str = '没有微信'; str = '添加成功';
break; break;
case 1: case 1:
str = '等待通过'; str = '已是好友';
break; break;
case 2: case 2:
str = '添加失败'; str = '没有该用户';
break; break;
case 3: case 3:
str = '已是好友'; str = '其他异常';
break; break;
case 4: case 100:
str = '添加成功'; str = '未执行';
break; break;
} }
return str; return str;
......
...@@ -6,8 +6,32 @@ import './plugins/element.js'; ...@@ -6,8 +6,32 @@ import './plugins/element.js';
Vue.config.productionTip = false; Vue.config.productionTip = false;
new Vue({ store.dispatch('LOGIN', {
router, sessionID: localStorage.getItem('__sessionID'),
store, callback(err: any) {
render: (h) => h(App), const State: any = store.state;
}).$mount('#app'); router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!State.login.isLogin) {
next({ path: '/login', query: { redirect: to.fullPath } });
} else {
next();
}
} else {
if (to.path === '/login' && State.login.isLogin) {
next({ path: '/' });
} else {
next(); // 确保一定要调用 next()
}
}
});
/* eslint-disable no-new */
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
},
});
...@@ -16,6 +16,7 @@ export default new Router({ ...@@ -16,6 +16,7 @@ export default new Router({
path: '/', path: '/',
name: 'home', name: 'home',
component: Home, component: Home,
meta: { requiresAuth: true },
children: [ children: [
{ {
path: '/filternumber', path: '/filternumber',
...@@ -31,6 +32,7 @@ export default new Router({ ...@@ -31,6 +32,7 @@ export default new Router({
}, },
{ {
path: '/login', path: '/login',
meta: { requiresAuth: false },
name: 'login', name: 'login',
component: Login, component: Login,
}, },
......
...@@ -4,7 +4,7 @@ import Vuex from 'vuex'; ...@@ -4,7 +4,7 @@ import Vuex from 'vuex';
import login from './modules/login'; import login from './modules/login';
import filterNumber from './modules/filterNumber'; import filterNumber from './modules/filterNumber';
import addTask from './modules/addTask'; import addTask from './modules/addTask';
import device from './modules/device';
Vue.use(Vuex); Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
...@@ -12,5 +12,6 @@ export default new Vuex.Store({ ...@@ -12,5 +12,6 @@ export default new Vuex.Store({
login, login,
filterNumber, filterNumber,
addTask, addTask,
device
}, },
}); });
import { Commit } from 'vuex'; import { Commit } from 'vuex';
import { Message } from 'element-ui'; import { Message } from 'element-ui';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '../types'; import { GET_TASKLIST, CREATE_TASK, GET_DETAILLIST } from '../types';
import { getFilterList, createFilterList } from '@/api/filterNumber'; import { getTaskList, createTask, getDetailList } from '@/api/addTask';
interface PermissionAttribute {
id?: string;
name: string;
code: string;
desc?: string;
status?: boolean;
createdAt?: number;
updatedAt?: number;
}
export interface State { export interface State {
dataList: any[]; dataList: any[];
count: number; count: number;
detailData: any;
page: number;
size: number;
} }
const filterNumberState: State = { const filterNumberState: State = {
dataList: [ 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, count: 0,
page: 1,
size: 10,
detailData: {
count: 0,
page: 1,
size: 10,
dataList: [],
},
}; };
const actions = { const actions = {
[GET_FILTERLIST]( [GET_TASKLIST](
context: { commit: Commit, state: State }, context: { commit: Commit, state: State },
payload: { size: number, page?: number }, payload: { size: number, page?: number },
) { ) {
// 获取角色列表 // 获取角色列表
getFilterList(payload.size, payload.page).then((data) => { getTaskList(payload.size, payload.page).then((data) => {
const result = data.data.result; const result = data.data;
if (result) { if (result.list) {
context.commit(GET_FILTERLIST, result); context.commit(GET_TASKLIST, result);
} else { } else {
Message.error(`获取数据失败错误原因是${data.data.msg}`); Message.error(`获取数据失败`);
} }
}).catch((err) => { }).catch((err: any) => {
throw(err); throw(err);
}); });
}, },
[CREATE_FILTERLIST]( [GET_DETAILLIST](
context: { commit: Commit, state: State },
payload: { size: number, taskWrapID: any, page: number },
) {
getDetailList(payload.size, payload.page, payload.taskWrapID).then((data: any) => {
const result = data.data;
if (result.list) {
context.commit(GET_DETAILLIST, result);
} else {
Message.error(`获取数据失败`);
}
}).catch((err: any) => {
throw(err);
});
},
[CREATE_TASK](
context: { commit: Commit, state: State }, context: { commit: Commit, state: State },
payload: { payload: {
name: string, count: number,
desc: string, id: string,
code: string, user_id: string,
greet: string,
}) { }) {
// 创建角色 // 创建角色
createFilterList(payload).then((data) => { createTask(payload).then((data) => {
const result = data.data.result; const result = data.data;
if (result) { if (result.list) {
context.commit(CREATE_FILTERLIST, result); context.commit(CREATE_TASK, result);
Message.success('角色创建成功'); Message.success('创建成功');
} else { } else {
Message.error(data.data.msg); Message.error(data.data.msg);
} }
...@@ -214,12 +84,37 @@ const actions = { ...@@ -214,12 +84,37 @@ const actions = {
}; };
const mutations = { const mutations = {
[GET_FILTERLIST](state: State, data: { rows: PermissionAttribute[], count: number }) { [GET_TASKLIST](state: State, data: { list: any[], count: number }) {
state.dataList = data.rows; state.dataList = data.list.map( (x: any) => {
return {
name: x.code,
wechatTotal: (x.weChatInfo && x.weChatInfo.nickname) ? x.weChatInfo.nickname : x.user_id,
total: x.ids.length,
online: x.weChatInfo,
used: x.used || 0,
createdAt: x.createdAt,
_id: x._id,
};
});
state.count = data.count; state.count = data.count;
state.page = parseInt(data.page);
state.size = parseInt(data.size || 10);
},
[GET_DETAILLIST](state: State, data: { list: any[], count: number }) {
state.detailData.dataList = data.list.map( (x: any) => {
return {
number: x.phone,
date: x.date || 0,
callbackcode: x.status || 100,
};
});
state.detailData.count = data.count;
state.detailData.page = parseInt(data.page);
state.detailData.size = parseInt(data.size || 10);
}, },
[CREATE_FILTERLIST](state: State, data: PermissionAttribute) { [CREATE_TASK](state: State, data: any) {
state.dataList.unshift(data); state.dataList.unshift(data);
state.count += 1; state.count += 1;
}, },
......
import { Commit } from 'vuex';
import { Message } from 'element-ui';
import { GET_DEVICELIST, GET_QRCODE, GET_WECHAT, RESET_QRCODE, RESET_WECHATINFO } from '../types';
import { getDeviceList, getQrcode, getDeviceStatus } from '@/api/device';
export interface State {
deviceList: any[];
qrcode: string;
weChatInfo: any;
taskID: any;
}
const deviceState: State = {
deviceList: [],
qrcode: '',
weChatInfo: {},
taskID: null,
};
const actions = {
[GET_DEVICELIST](
context: { commit: Commit, state: State },
payload: {},
) {
getDeviceList().then((data) => {
const result = data.data;
if (result) {
context.commit(GET_DEVICELIST, result);
} else {
Message.error(`获取设备失败`);
}
}).catch((err: any) => {
throw(err);
});
},
[GET_QRCODE](
context: { commit: Commit, state: State },
payload: { sn: string, type: string}) {
// 获取二维码
getQrcode(payload.sn, payload.type).then((_data) => {
const result = _data.data;
if (result) {
const taskID = setInterval(() => {
getDeviceStatus(payload.sn).then((data) => {
if( data.data && data.data.WeChat && data.data.status === '1' ) {
window.clearInterval(context.state.taskID);
context.commit(GET_WECHAT, data.data.WeChat);
}
});
}, 1000);
result.taskID = taskID;
context.commit(GET_QRCODE, result);
} else {
Message.error(`获取二维码失败`);
}
}).catch((err) => {
throw(err);
});
},
[RESET_QRCODE](
context: { commit: Commit, state: State }) {
// 获取二维码
context.commit(RESET_QRCODE, '');
},
[RESET_WECHATINFO](
context: { commit: Commit, state: State }, data: any) {
// 获取二维码
context.commit(RESET_WECHATINFO, data);
},
};
const mutations = {
[GET_DEVICELIST](state: State, data: { list: any[]}) {
state.deviceList = data.list.map( (x: any) => {
const wechat = x.weChatInfo && x.weChatInfo.nickname ? x.weChatInfo.nickname : '未登录';
return {
label: x.deviceSN + '[' + wechat + ']',
value: x.deviceSN + '[' + wechat + ']',
weChatInfo: x.weChatInfo,
};
});
},
[GET_QRCODE](state: State, data: { qrcode: string, taskID: any }) {
state.qrcode = data.qrcode;
state.taskID = data.taskID;
},
[GET_WECHAT](state: State, data: any) {
state.weChatInfo = data;
},
[RESET_QRCODE](state: State, data: any) {
state.qrcode = data;
},
[RESET_WECHATINFO](state: State, data: any) {
state.weChatInfo = data;
},
};
export default {
state: deviceState,
actions,
mutations,
};
import { Commit } from 'vuex'; import { Commit } from 'vuex';
import { Message } from 'element-ui'; import { Message } from 'element-ui';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '../types'; import { GET_FILTERLIST, CREATE_FILTERLIST, FILTERLIST_COUNT } from '../types';
import { getFilterList, createFilterList } from '@/api/filterNumber'; import { getFilterList, createFilterList, filterCount } from '@/api/filterNumber';
interface PermissionAttribute { interface PermissionAttribute {
id?: string; id?: string;
...@@ -17,84 +17,17 @@ interface PermissionAttribute { ...@@ -17,84 +17,17 @@ interface PermissionAttribute {
export interface State { export interface State {
dataList: any[]; dataList: any[];
count: number; count: number;
page: number;
size: number;
deviceList: any[];
} }
const filterNumberState: State = { const filterNumberState: State = {
dataList: [ dataList: [],
{ deviceList: [{ label: '1', value: '1'}],
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, count: 0,
page: 0,
size: 10,
}; };
const actions = { const actions = {
...@@ -102,13 +35,12 @@ const actions = { ...@@ -102,13 +35,12 @@ const actions = {
context: { commit: Commit, state: State }, context: { commit: Commit, state: State },
payload: { size: number, page?: number }, payload: { size: number, page?: number },
) { ) {
// 获取角色列表
getFilterList(payload.size, payload.page).then((data) => { getFilterList(payload.size, payload.page).then((data) => {
const result = data.data.result; const result = data.data;
if (result) { if (result) {
context.commit(GET_FILTERLIST, result); context.commit(GET_FILTERLIST, result);
} else { } else {
Message.error(`获取数据失败错误原因是${data.data.msg}`); Message.error(`获取数据失败`);
} }
}).catch((err) => { }).catch((err) => {
throw(err); throw(err);
...@@ -116,18 +48,46 @@ const actions = { ...@@ -116,18 +48,46 @@ const actions = {
}, },
[CREATE_FILTERLIST]( [CREATE_FILTERLIST](
context: { commit: Commit, state: State },
payload: {
ageEnd: string,
ageStart: string,
consumptionDuring: string,
consumptionEnd: string,
consumptionStart: string,
districts: any,
dsgroup: string,
flow: string,
flowDuring: string,
flowEnd: string,
flowStart: string,
sexlist: string,
callback: any,
}) {
// 筛选
createFilterList(payload).then((data: any) => {
Message.success('创建成功');
// payload.callback && payload.callback();
}).catch((err: any) => {
Message.success('创建失败');
// payload.callback && payload.callback();
throw(err);
});
},
[FILTERLIST_COUNT](
context: { commit: Commit, state: State }, context: { commit: Commit, state: State },
payload: { payload: {
name: string, name: string,
desc: string, desc: string,
code: string, code: string,
}) { }) {
// 创建角色 // 筛选
createFilterList(payload).then((data) => { filterCount(payload).then((data) => {
const result = data.data.result; const result = data.data;
if (result) { if (result) {
context.commit(CREATE_FILTERLIST, result); context.commit(FILTERLIST_COUNT, result);
Message.success('角色创建成功'); Message.success('筛选数量成功');
} else { } else {
Message.error(data.data.msg); Message.error(data.data.msg);
} }
...@@ -138,15 +98,54 @@ const actions = { ...@@ -138,15 +98,54 @@ const actions = {
}; };
const mutations = { const mutations = {
[GET_FILTERLIST](state: State, data: { rows: PermissionAttribute[], count: number }) { [GET_FILTERLIST](state: State, data: { list: any, count: number }) {
state.dataList = data.rows; state.dataList = data.list.map( (x: any) => {
let filter = '';
if( x.sexlist ) {
filter += (x.sexlist.join('、') + ',');
}
if( x.ageStart && x.ageEnd ) {
filter += ((x.ageStart + '-' + x.ageEnd) + ',');
}
if( x.districts ) {
let cities:any = [];
x.districts.forEach((x:any) => {
cities = cities.concat(x.cities)
})
filter += (cities.join('、') + ',')
}
if( x.flowStart && x.flowEnd ) {
filter += ((x.flowStart + '-' + x.flowEnd) + 'M,');
}
if( x.consumptionStart && x.consumptionEnd ) {
filter += ((x.consumptionStart + '-' + x.consumptionEnd) + '元');
}
let total = x.respData && x.respData.total ? x.respData.total : 0;
let count = x.respData && x.respData.customers ? x.respData.customers.length : 0;
return {
numberGroup: x.dsgroup,
total: total,
used: x.used || 0,
count: count,
_id: x._id,
createdAt: x.createdAt || Date.now(),
filterList: filter,
};
});
state.count = data.count; state.count = data.count;
state.page = parseInt(data.page);
state.size = parseInt(data.size || 10);
}, },
[CREATE_FILTERLIST](state: State, data: PermissionAttribute) { /*[CREATE_FILTERLIST](state: State, data: PermissionAttribute) {
state.dataList.unshift(data); state.dataList.unshift(data);
state.count += 1; state.count += 1;
}, },
[FILTERLIST_COUNT](state: State, data: PermissionAttribute) {
state.dataList.unshift(data);
state.count += 1;
},*/
}; };
export default { export default {
......
import { Commit } from 'vuex'; import { Commit } from 'vuex';
import { Message } from 'element-ui'; import { Message } from 'element-ui';
import { GET_TOKEN } from '../types'; import { LOGIN } from '../types';
import { getUser } from '@/api/login'; import { getUser } from '@/api/login';
export interface State { export interface State {
isLogin: boolean; isLogin: boolean;
account: { username: string };
} }
const loginState: State = { const loginState: State = {
isLogin: false, isLogin: false,
account: { username: '' }
}; };
const actions = { const actions = {
[GET_TOKEN]( [LOGIN](
context: { commit: Commit, state: State }, context: { commit: Commit, state: State },
payload: { username: string, password: string }, payload: { username: string, password: string, callback: any },
) { ) {
// 获取角色列表 // 获取角色列表
getUser(payload).then((data) => { getUser(payload).then((result) => {
const result = data.data.result; console.dir(result.data);
if (result) { if (result.data && result.data.account) {
context.commit(GET_TOKEN, result); context.commit(LOGIN, result.data.account);
if(payload.callback) payload.callback(null, result.data.account);
} else { } else {
Message.error(`获取数据失败错误原因是${data.data.msg}`); Message.error(`获取数据失败错误`);
} }
}).catch((err) => { }).catch((data) => {
throw(err); Message.error(data.error ? data.error : `账户或密码错误`)
if(payload.callback) payload.callback(data.error ? data.error : `账户或密码错误`);
}); });
}, },
...@@ -35,8 +39,10 @@ const actions = { ...@@ -35,8 +39,10 @@ const actions = {
}; };
const mutations = { const mutations = {
[GET_TOKEN](state: State, data: { username: string, password: string }) { [LOGIN](state: State, data: { username: string, sessionID: string }) {
state.isLogin = true; state.isLogin = true;
localStorage.setItem('__sessionID', data.sessionID);
state.account.username = data.username;
// state.dataList = data.rows; // state.dataList = data.rows;
// state.count = data.count; // state.count = data.count;
}, },
......
// 获取用户列表
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 GET_FILTERLIST = 'GET_FILTERLIST';
// 创建筛选条件 // 创建筛选条件
export const CREATE_FILTERLIST = 'CREATE_FILTERLIST'; export const CREATE_FILTERLIST = 'CREATE_FILTERLIST';
// 查询筛选条件用户
export const FILTERLIST_COUNT = 'FILTERLIST_COUNT';
// 登录 // 登录
export const GET_TOKEN = 'GET_TOKEN'; export const LOGIN = 'LOGIN';
export const CREATE_TASK = 'CREATE_TASK';
export const GET_TASKLIST = 'GET_TASKLIST';
export const GET_QRCODE = 'GET_QRCODE';
export const GET_DEVICELIST = 'GET_DEVICELIST';
export const GET_WECHAT = 'GET_WECHAT';
export const RESET_QRCODE = 'RESET_QRCODE';
export const RESET_WECHATINFO = 'RESET_WECHATINFO';
export const GET_DETAILLIST = 'GET_DETAILLIST';
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
/> />
<div class="pagination"> <div class="pagination">
<Pagination <Pagination
:page='page' :page='addTaskState.page'
:size='size' :size='addTaskState.size'
:total='addTaskState.count' :total='addTaskState.count'
:paginationSizeChange='paginationSizeChange' :paginationSizeChange='paginationSizeChange'
:paginationPageChange='paginationPageChange'/> :paginationPageChange='paginationPageChange'/>
...@@ -25,16 +25,16 @@ ...@@ -25,16 +25,16 @@
<div class="dialog-body"> <div class="dialog-body">
<!-- 此处借用了filterState的数据 --> <!-- 此处借用了filterState的数据 -->
<CommonTable <CommonTable
:dataList='addTaskState.dataList[dialog.index].taskList' :dataList='addTaskState.detailData.dataList'
:tHeadList='tHeadLists' :tHeadList='tHeadLists'
/> />
<div class="dialog-pagination"> <div class="dialog-pagination">
<Pagination <Pagination
:page='page' :page='addTaskState.detailData.page'
:size='size' :size='addTaskState.detailData.size'
:total='addTaskState.count' :total='addTaskState.detailData.count'
:paginationSizeChange='paginationSizeChange' :paginationSizeChange='detailSizeChange'
:paginationPageChange='paginationPageChange'/> :paginationPageChange='detailPageChange'/>
</div> </div>
</div> </div>
<div class="dialog-footer" slot='footer'> <div class="dialog-footer" slot='footer'>
...@@ -54,7 +54,7 @@ import { Component, Vue } from 'vue-property-decorator'; ...@@ -54,7 +54,7 @@ import { Component, Vue } from 'vue-property-decorator';
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { Action, State } from 'vuex-class'; import { Action, State } from 'vuex-class';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '@/store/types'; import { GET_TASKLIST, CREATE_TASK, GET_DETAILLIST } from '@/store/types';
import CommonTable from '@/components/CommonTable.vue'; import CommonTable from '@/components/CommonTable.vue';
import Pagination from '@/components/Pagination.vue'; import Pagination from '@/components/Pagination.vue';
...@@ -71,8 +71,10 @@ export default class AddTask extends Vue { ...@@ -71,8 +71,10 @@ export default class AddTask extends Vue {
}; };
@State('addTask') public addTaskState: any; @State('addTask') public addTaskState: any;
@Action(GET_FILTERLIST) public getFilterlist: any; @Action(GET_TASKLIST) public getTasklist: any;
@Action(CREATE_FILTERLIST) public createFilter: any; @Action(CREATE_TASK) public createTask: any;
@Action(GET_DETAILLIST) public getDetailList: any;
// 初始化数据 // 初始化数据
// 表格 // 表格
...@@ -103,7 +105,7 @@ export default class AddTask extends Vue { ...@@ -103,7 +105,7 @@ export default class AddTask extends Vue {
label: '目标号码', label: '目标号码',
width: '120', width: '120',
}, { }, {
prop: 'createdAt', prop: 'date',
label: '创建时间', label: '创建时间',
width: 'auto', width: 'auto',
}, { }, {
...@@ -131,7 +133,11 @@ export default class AddTask extends Vue { ...@@ -131,7 +133,11 @@ export default class AddTask extends Vue {
// 表格 // 表格
public detailRow(index: number) { public detailRow(index: number) {
// 点击表格进行编辑 // 点击表格进行编辑
this.setDialogData('taskDetail', index); this.dialog.name = 'taskDetail';
this.$data.isDialogShow = true;
this.getDetailList({ page:1, size:10 ,taskWrapID: this.addTaskState.dataList[index]._id });
//this.setDialogData('taskDetail', index);
} }
public setDialogData(name: string, index: number) { public setDialogData(name: string, index: number) {
...@@ -215,10 +221,10 @@ export default class AddTask extends Vue { ...@@ -215,10 +221,10 @@ export default class AddTask extends Vue {
} }
// // 生命周期 // 生命周期
// public mounted() { public mounted() {
// // this.getPermission({ size: this.size, page: this.page }); this.getTasklist({ size: this.size, page: this.page });
// } }
} }
</script> </script>
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
/> />
<div class="pagination"> <div class="pagination">
<Pagination <Pagination
:page='page' :page='numberFilterState.page'
:size='size' :size='numberFilterState.size'
:total='numberFilterState.count' :total='numberFilterState.count'
:paginationSizeChange='paginationSizeChange' :paginationSizeChange='paginationSizeChange'
:paginationPageChange='paginationPageChange'/> :paginationPageChange='paginationPageChange'/>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<div class="dialog"> <div class="dialog">
<!-- 筛选 --> <!-- 筛选 -->
<template v-if='dialog.name === "addFilter"'> <template v-if='dialog.name === "addFilter"'>
<el-dialog title="新建筛选" :visible.sync="isDialogShow" width="700px"> <el-dialog title="新建筛选" :visible.sync="isDialogShow" width="700px" :before-close="handleClose">
<div class="dialog-body"> <div class="dialog-body">
<el-form <el-form
style="margin: 0px 10px;min-height: 418px;" style="margin: 0px 10px;min-height: 418px;"
...@@ -210,10 +210,10 @@ ...@@ -210,10 +210,10 @@
<!-- 加粉 --> <!-- 加粉 -->
<template v-else-if="dialog.name === 'addWechat'"> <template v-else-if="dialog.name === 'addWechat'">
<el-dialog title="新建筛选" :visible.sync="isDialogShow" width="500px"> <el-dialog title="加粉任务" :visible.sync="isDialogShow" width="500px" :before-close="handleCloseWechat" >
<el-form :model="addForm" :rules="addWechatRules" ref='addForm'> <el-form :model="addForm" :rules="addWechatRules" ref='addForm'>
<el-form-item label="号码数量:" :label-width="formLabelWidth" prop='used'> <el-form-item label="号码数量:" :label-width="formLabelWidth" prop='used'>
<span name='number'><span class="data">{{dialog.data.used}}</span>/5000</span> <span name='number'><span class="data">{{ dialog.data.used || 0 }}</span> / {{ dialog.data.count }}</span>
</el-form-item> </el-form-item>
<div class="flex"> <div class="flex">
<el-form-item label="本次添加:" <el-form-item label="本次添加:"
...@@ -228,7 +228,7 @@ ...@@ -228,7 +228,7 @@
<el-form-item label="每日添加:" <el-form-item label="每日添加:"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="everydayAdd"> prop="everydayAdd">
<el-input v-model="addForm.everydayAdd" auto-complete="off" width='90%'> <el-input v-model="addForm.everydayAdd" auto-complete="off" width='90%' disabled>
<template slot='suffix'> <template slot='suffix'>
</template> </template>
...@@ -236,17 +236,31 @@ ...@@ -236,17 +236,31 @@
</el-form-item> </el-form-item>
</div> </div>
<el-form-item label="设备列表:"
:label-width="formLabelWidth"
prop="deviceSn">
<el-select v-model="addForm.deviceSn" placeholder="请选择" @change="changeDevice">
<el-option
v-for="item in deviceState.deviceList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="验证用语:" <el-form-item label="验证用语:"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="verificationLanguage"> 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-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>
<el-form-item label="目标微信:" <el-form-item label="目标微信:"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="verificationLanguage"> >
<div class="QRcode flex" v-loading='QRreload'> <div class="QRcode flex" v-loading='QRreload'>
<img src="../assets/qr.png" alt="二维码" width="150px" height="150px"> <img :src="(deviceState.weChatInfo && deviceState.weChatInfo.headImgUri) ? deviceState.weChatInfo.headImgUri : deviceState.qrcode" alt="二维码" width="150px" height="150px"/>
<p>请用目标微信扫码<span class="data" style="margin-left:8px;text-decoration:underline" @click="refreshQRCode">刷新</span></p> <p>请用目标微信扫码<span class="data" style="margin-left:8px;text-decoration:underline" @click="refreshQRCode" disabled>刷新</span></p>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -268,7 +282,7 @@ import { Component, Vue } from 'vue-property-decorator'; ...@@ -268,7 +282,7 @@ import { Component, Vue } from 'vue-property-decorator';
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { Action, State } from 'vuex-class'; import { Action, State } from 'vuex-class';
import { GET_FILTERLIST, CREATE_FILTERLIST } from '@/store/types'; import { GET_FILTERLIST, CREATE_FILTERLIST, GET_QRCODE, GET_DEVICELIST, RESET_QRCODE, CREATE_TASK, RESET_WECHATINFO } from '@/store/types';
import CommonTable from '@/components/CommonTable.vue'; import CommonTable from '@/components/CommonTable.vue';
import Pagination from '@/components/Pagination.vue'; import Pagination from '@/components/Pagination.vue';
...@@ -286,23 +300,36 @@ export default class FilterNumber extends Vue { ...@@ -286,23 +300,36 @@ export default class FilterNumber extends Vue {
}; };
@State('filterNumber') public numberFilterState: any; @State('filterNumber') public numberFilterState: any;
@State('device') public deviceState: any;
@Action(GET_FILTERLIST) public getFilterlist: any; @Action(GET_FILTERLIST) public getFilterlist: any;
@Action(GET_DEVICELIST) public getDevicelist: any;
@Action(GET_QRCODE) public getQrcode: any;
@Action(CREATE_FILTERLIST) public createFilter: any; @Action(CREATE_FILTERLIST) public createFilter: any;
@Action(RESET_QRCODE) public resetQrcode: any;
@Action(CREATE_TASK) public createTask: any;
@Action(RESET_WECHATINFO) public resetWechat: any;
// 初始化数据 // 初始化数据
// 表格 // 表格
public tHeadList = [{ public tHeadList = [{
prop: 'name', prop: 'numberGroup',
label: '编号', label: '号码组',
width: '150', width: '200',
}, { }, {
prop: 'createdAt', prop: 'createdAt',
label: '创建时间', label: '创建时间',
width: '150', width: '150',
}, { },
prop: 'numberGroup', {
label: '号码组', prop: 'total',
width: '200', label: '数据规模',
width: '100',
},
{
prop: 'count',
label: '本次获取数',
width: '100',
}, { }, {
prop: 'filterList', prop: 'filterList',
label: '筛选条件', label: '筛选条件',
...@@ -366,8 +393,7 @@ export default class FilterNumber extends Vue { ...@@ -366,8 +393,7 @@ export default class FilterNumber extends Vue {
{'p': '湖北', 'c': ['武汉', '黄石', '十堰', {'p': '湖北', 'c': ['武汉', '黄石', '十堰',
'宜昌', '襄樊', '鄂州', '荆门', '宜昌', '襄樊', '鄂州', '荆门',
'孝感', '荆州', '黄冈', '咸宁', '孝感', '荆州', '黄冈', '咸宁',
'随州', '恩施', '仙桃', '潜江', '随州', '恩施']},
'天门', '神农架']},
{'p': '湖南', 'c': ['长沙', '株洲', '湘潭', {'p': '湖南', 'c': ['长沙', '株洲', '湘潭',
'衡阳', '邵阳', '岳阳', '常德', '衡阳', '邵阳', '岳阳', '常德',
'张家界', '益阳', '郴州', '永州', '张家界', '益阳', '郴州', '永州',
...@@ -387,7 +413,7 @@ export default class FilterNumber extends Vue { ...@@ -387,7 +413,7 @@ export default class FilterNumber extends Vue {
{'p': '四川', 'c': ['成都', '自贡', '攀枝花', {'p': '四川', 'c': ['成都', '自贡', '攀枝花',
'泸州', '德阳', '绵阳', '广元', '泸州', '德阳', '绵阳', '广元',
'遂宁', '内江', '乐山', '南充', '遂宁', '内江', '乐山', '南充',
'眉山', '宜宾', '广安', '达', '眉山', '宜宾', '广安', '达',
'雅安', '巴中', '资阳', '阿坝', '雅安', '巴中', '资阳', '阿坝',
'甘孜', '凉山']}, '甘孜', '凉山']},
{'p': '贵州', 'c': ['贵阳', '六盘水', '遵义', '安顺', {'p': '贵州', 'c': ['贵阳', '六盘水', '遵义', '安顺',
...@@ -406,14 +432,12 @@ export default class FilterNumber extends Vue { ...@@ -406,14 +432,12 @@ export default class FilterNumber extends Vue {
'平凉', '酒泉', '庆阳', '定西', '平凉', '酒泉', '庆阳', '定西',
'陇南', '临夏', '甘南']}, '陇南', '临夏', '甘南']},
{'p': '青海', 'c': ['西宁', '海东', '海北', {'p': '青海', 'c': ['西宁', '海东', '海北',
'黄南', '海南', '果洛', '玉树', '梅西']}, '黄南', '海南', '果洛', '玉树']},
{'p': '宁夏', 'c': ['银川', '石嘴山', '吴忠', '固原', '中卫']}, {'p': '宁夏', 'c': ['银川', '石嘴山', '吴忠', '固原', '中卫']},
{'p': '新疆', 'c': ['乌鲁木齐', '克拉玛依', '吐鲁番', {'p': '新疆', 'c': ['乌鲁木齐', '克拉玛依', '吐鲁番',
'哈密', '昌吉', '博尔塔拉', '巴音郭楞', '哈密', '昌吉', '博尔塔拉', '巴音郭楞',
'阿克苏', '克孜勒苏', '喀什', '和田', '阿克苏', '克孜勒苏', '喀什', '和田',
'伊犁', '塔城', '阿勒泰', '石河子', '伊犁', '塔城', '阿勒泰', '石河子']}].map( (x) => {
'阿拉尔', '图木舒克', '五家渠']},
{'p': '地区', 'c': ['香港', '澳门', '台湾']}].map( (x) => {
const city = { const city = {
province: x.p, province: x.p,
checkAll: false, checkAll: false,
...@@ -442,8 +466,9 @@ export default class FilterNumber extends Vue { ...@@ -442,8 +466,9 @@ export default class FilterNumber extends Vue {
public addForm = { public addForm = {
thisTimeAdd: '', thisTimeAdd: '',
everydayAdd: '', everydayAdd: 20,
verificationLanguage: '', verificationLanguage: '',
deviceSn: ''
}; };
public filterForm = { public filterForm = {
...@@ -451,7 +476,6 @@ export default class FilterNumber extends Vue { ...@@ -451,7 +476,6 @@ export default class FilterNumber extends Vue {
ageStart: '', ageStart: '',
ageEnd: '', ageEnd: '',
sexlist: [], sexlist: [],
flow: [],
flowStart: '', flowStart: '',
flowEnd: '', flowEnd: '',
consumptionStart: '', consumptionStart: '',
...@@ -462,7 +486,7 @@ export default class FilterNumber extends Vue { ...@@ -462,7 +486,7 @@ export default class FilterNumber extends Vue {
public dialog = { public dialog = {
name: '', name: '',
data: {}, data: { _id: '' },
index: 0, index: 0,
}; };
...@@ -476,6 +500,9 @@ export default class FilterNumber extends Vue { ...@@ -476,6 +500,9 @@ export default class FilterNumber extends Vue {
everydayAdd: [ everydayAdd: [
{ validator: this.validateEverydayAdd, trigger: 'blur' }, { validator: this.validateEverydayAdd, trigger: 'blur' },
], ],
validateSn: [
{ validator: this.validateSn, trigger: 'change' },
],
verificationLanguage: [ verificationLanguage: [
{ validator: this.verificationLanguage, trigger: 'blur' }, { validator: this.verificationLanguage, trigger: 'blur' },
], ],
...@@ -533,6 +560,7 @@ export default class FilterNumber extends Vue { ...@@ -533,6 +560,7 @@ export default class FilterNumber extends Vue {
public setDialogData(name: string, index: number) { public setDialogData(name: string, index: number) {
// 设置弹框数据 // 设置弹框数据
this.dialog.name = name; this.dialog.name = name;
this.getDevicelist();
this.$data.isDialogShow = true; this.$data.isDialogShow = true;
this.dialog.data = this.numberFilterState.dataList[index]; this.dialog.data = this.numberFilterState.dataList[index];
this.dialog.index = index; this.dialog.index = index;
...@@ -566,20 +594,31 @@ export default class FilterNumber extends Vue { ...@@ -566,20 +594,31 @@ export default class FilterNumber extends Vue {
// 分页 // 分页
public paginationSizeChange(index: number) { public paginationSizeChange(index: number) {
this.size = index; this.size = index;
// this.getPermission({ size: this.size, page: this.page }); this.getFilterlist({ size: this.size, page: this.page });
} }
public paginationPageChange(index: number) { public paginationPageChange(index: number) {
this.page = index; this.page = index;
// this.getPermission({ size: this.size, page: this.page }); this.getFilterlist({ size: this.size, page: this.page });
} }
// 清除表单元素及弹框属性 // 清除表单元素及弹框属性
public cleanDialogForm(form: string) { public cleanDialogForm(form: string) {
const newform = this.$data[form]; //const newform = this.$data[form];
Object.keys(newform).forEach((val, ind) => { if(form === 'filterForm') this.$refs.filterForm.resetFields();
newform[val] = ''; else this.$refs.addForm.resetFields();
}); if(form === 'addForm') {
this.resetQrcode();
}
/* Object.keys(newform).forEach((val, ind) => {
let t = '';
if( val === 'flowDuring' || val === 'consumptionDuring') {
t = '近三月平均';
}
newform[val] = t;
});*/
//console.dir(this.$data[form]);
//console.dir('====> end');
} }
// 弹框 // 弹框
...@@ -616,15 +655,41 @@ export default class FilterNumber extends Vue { ...@@ -616,15 +655,41 @@ export default class FilterNumber extends Vue {
return true; return true;
} }
public handleClose(done: any) {
this.cleanDialogForm('filterForm');
done && done();
}
public handleCloseWechat(done: any) {
this.cleanDialogForm('addForm');
done && done();
}
public sumbitAddFilter() { public sumbitAddFilter() {
const form = this.$data.filterForm; const form = this.$data.filterForm;
const area = this.$data.area;
this.$refs.filterForm.validate((valid: any) => { this.$refs.filterForm.validate((valid: any) => {
if (valid) { if (valid) {
// 提交 let areas: any = [];
// this.createPermission(form).then((data: any) => { area.provinceOptions.forEach( (x:any) => {
// this.closeDialog(); let temp: any = { province: '', cities: [] };
// this.cleanDialogForm('addForm'); if( x.checkedCities && x.checkedCities.length ) {
// }); temp.cities = x.checkedCities;
temp.province = x.province;
}
if( temp && temp.province && temp.province.length) {
areas.push(temp);
}
});
form.districts = areas;
form.callback = () => {
this.cleanDialogForm('filterForm');
}
//console.dir(form);
this.createFilter(form).then((data: any) => {
this.closeDialog();
//this.cleanDialogForm('filterForm');
});
} }
}); });
} }
...@@ -633,6 +698,18 @@ export default class FilterNumber extends Vue { ...@@ -633,6 +698,18 @@ export default class FilterNumber extends Vue {
const form = this.$data.addForm; const form = this.$data.addForm;
this.$refs.addForm.validate((valid: any) => { this.$refs.addForm.validate((valid: any) => {
if (valid) { if (valid) {
if(this.deviceState.weChatInfo && this.deviceState.weChatInfo.wechatId) {
let data = {
count: form.thisTimeAdd,
id: this.dialog.data._id,
user_id:this.deviceState.weChatInfo.wechatId,
greet: form.verificationLanguage,
}
this.createTask(data).then((data: any) => {
this.closeDialog();
this.cleanDialogForm('addForm');
});
}
// 提交 // 提交
// this.createPermission(form).then((data: any) => { // this.createPermission(form).then((data: any) => {
// this.closeDialog(); // this.closeDialog();
...@@ -700,6 +777,14 @@ export default class FilterNumber extends Vue { ...@@ -700,6 +777,14 @@ export default class FilterNumber extends Vue {
callback(); callback();
} }
public validateSn(rule: any, value: any, callback: any) {
if (!value || !value.length) {
callback(new Error('名称不可为空'));
return false;
}
callback();
}
public validateSexList(rule: any, value: any, callback: any) { public validateSexList(rule: any, value: any, callback: any) {
if (value.length === 0) { if (value.length === 0) {
callback(new Error('至少选中一位')); callback(new Error('至少选中一位'));
...@@ -738,6 +823,20 @@ export default class FilterNumber extends Vue { ...@@ -738,6 +823,20 @@ export default class FilterNumber extends Vue {
callback(); callback();
} }
public changeDevice(value: any) {
let sn = value.split('[')[0];
if(value.indexOf('未登录') >= 0) {
this.resetWechat('')
this.getQrcode({sn: sn, type: 'get'});
} else {
this.deviceState.deviceList.forEach((x: any) => {
if(x.value == value) {
this.resetWechat(x.weChatInfo)
}
})
}
}
public validateProvince(rule: any, value: any, callback: any) { public validateProvince(rule: any, value: any, callback: any) {
const provincelist = this.area.checkedProvinces; const provincelist = this.area.checkedProvinces;
const provinceOptions = this.area.provinceOptions; const provinceOptions = this.area.provinceOptions;
...@@ -816,10 +915,10 @@ export default class FilterNumber extends Vue { ...@@ -816,10 +915,10 @@ export default class FilterNumber extends Vue {
callback(); callback();
} }
// // 生命周期 // 生命周期
// public mounted() { public mounted() {
// // this.getPermission({ size: this.size, page: this.page }); this.getFilterlist({ size: this.size, page: this.page });
// } }
} }
</script> </script>
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
import { getUser } from '../api/login'; import { getUser } from '../api/login';
import { Action, State } from 'vuex-class'; import { Action, State } from 'vuex-class';
import { GET_TOKEN } from '@/store/types'; import { LOGIN } from '@/store/types';
@Component({ @Component({
...@@ -30,7 +30,7 @@ import { GET_TOKEN } from '@/store/types'; ...@@ -30,7 +30,7 @@ import { GET_TOKEN } from '@/store/types';
export default class Overview extends Vue { export default class Overview extends Vue {
@State('login') public loginState: any; @State('login') public loginState: any;
@Action(GET_TOKEN) public getToken: any; @Action(LOGIN) public getToken: any;
public loginForm = { public loginForm = {
username: '', username: '',
password: '', password: '',
...@@ -46,11 +46,11 @@ export default class Overview extends Vue { ...@@ -46,11 +46,11 @@ export default class Overview extends Vue {
} }
const sumbitBtn = this.$refs.sumbitBtn; const sumbitBtn = this.$refs.sumbitBtn;
this.getToken(this.loginForm).then(() => { this.getToken(this.loginForm).then(() => {
const islogin = this.loginState.islogin; const isLogin = this.loginState.isLogin;
if (!islogin) { if (!isLogin) {
sumbitBtn.disabled = islogin; sumbitBtn.disabled = isLogin;
} else { } else {
sumbitBtn.disabled = islogin; sumbitBtn.disabled = isLogin;
this.$router.push('/filterNumber'); this.$router.push('/filterNumber');
} }
}); });
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
<!-- 头部 --> <!-- 头部 -->
<el-header class="app-header"> <el-header class="app-header">
<span style="font-weight: bold; font-size: 20px; margin-left: 70px;"> <span style="font-weight: bold; font-size: 20px; margin-left: 70px;">
<img src="../../assets/logo.png" alt="" width="201px" style="margin-top:8px"> <img src="../../assets/logo.png" alt="" width="201px" style="margin-top:8px"/>
</span> </span>
<el-dropdown style="line-height: 60px;float: right;margin: 0px 30px;"> <el-dropdown style="line-height: 60px;float: right;margin: 0px 30px;">
<span class="theme-text"> <span class="theme-text">
{{ currentUser.username }}<i class="el-icon-arrow-down el-icon--right"></i> {{ currentUser }}<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item> <el-dropdown-item>
...@@ -26,10 +26,11 @@ ...@@ -26,10 +26,11 @@
style="height: 100%;" style="height: 100%;"
text-color="#888888" text-color="#888888"
:router=true :router=true
default-active="/filternumber"
:unique-opened=true> :unique-opened=true>
<li class="welcome"> <li class="welcome">
<i class="el-icon-people"></i> <i class="el-icon-people"></i>
<span slot="title">Welcome Vincent</span> <span slot="title">Welcome {{ currentUser }}</span>
</li> </li>
<el-menu-item v-for="item in menuItems" :key=item.index @click=routeTo :route=item.index :index=item.index> <el-menu-item v-for="item in menuItems" :key=item.index @click=routeTo :route=item.index :index=item.index>
<i :class=item.icon></i> <i :class=item.icon></i>
...@@ -60,14 +61,17 @@ import { Component, Vue } from 'vue-property-decorator'; ...@@ -60,14 +61,17 @@ import { Component, Vue } from 'vue-property-decorator';
index: '/addtask', index: '/addtask',
icon: 'el-icon-tickets', icon: 'el-icon-tickets',
}], }],
currentUser: {
username: 'wangzezhi',
},
}; };
}, },
computed: {
currentUser() {
return 'username';
},
},
methods: { methods: {
routeTo() { routeTo() {
// TODO // TODO
console.dir('in routeto');
}, },
logout() { logout() {
// TODO // TODO
......
var t = ["V0110000|北京|011|V0110000|1|010|北京市",
"V0120000|天津|013|V0120000|2|022|天津市",
"V0310000|上海|031|V0310000|3|021|上海市",
"V0500000|重庆|083|V0500000|4|023|重庆市",
"V0460100|海口|050|V0460100|5|0898|海口市",
"V0460200|三亚|050|V0460200|6|0898|三亚市",
"V04602003|保亭|050|V04602003|7|0898|保亭黎族苗族自治县",
"V04601006|澄迈|050|V04601006|8|0898|澄迈县",
"V04601003|文昌|050|V04601003|9|0898|文昌市 ",
"V04600032|临高|050|V04600032|10|0898|临高县 ",
"V04602004|五指山|050|V04602004|11|0898|五指山市",
"V04601001|琼山|050|V04601001|12|0898|琼山",
"V04600033|昌江|050|V04600033|13|0898|昌江黎族自治县 ",
"V0460003|儋州|050|V0460003|14|0898|儋州市",
"V04602002|陵水|050|V04602002|15|0898|陵水黎族自治县",
"V04601008|琼中|050|V04601008|16|0898|琼中黎族苗族自治县 ",
"V04601007|屯昌|050|V04601007|17|0898|屯昌县",
"V04601004|万宁|050|V04601004|18|0898|万宁市",
"V04601005|定安|050|V04601005|19|0898|定安县",
"V04602001|乐东|050|V04602001|20|0898|乐东黎族自治县",
"V04601002|琼海|050|V04601002|21|0898|琼海市",
"V04600031|东方|050|V04600031|22|0898|东方市",
"V04600034|白沙|050|V04600034|23|0898|白沙黎族自治县 ",
"V0440100|广州|051|V0440100|24|020|广州市",
"V0441500|汕尾|051|V0441500|25|0660|汕尾市",
"V0441700|阳江|051|V0441700|26|0662|阳江市",
"V0445201|揭阳|051|V0445201|27|0663|揭阳市",
"V0440901|茂名|051|V0440901|28|0668|茂名市",
"V0440700|江门|051|V0440700|29|0750|江门市",
"V0440201|韶关|051|V0440201|30|0751|韶关市",
"V0441300|惠州|051|V0441300|31|0752|惠州市",
"V0441401|梅州|051|V0441401|32|0753|梅州市",
"V0440510|汕头|051|V0440510|33|0754|汕头市",
"V0440300|深圳|051|V0440300|34|0755|深圳市",
"V0440400|珠海|051|V0440400|35|0756|珠海市",
"V0440600|佛山|051|V0440600|36|0757|佛山市",
"V0441201|肇庆|051|V0441201|37|0758|肇庆市",
"V0440800|湛江|051|V0440800|38|0759|湛江市",
"V0442000|中山|051|V0442000|39|0760|中山市",
"V0441600|河源|051|V0441600|40|0762|河源市",
"V0441800|清远|051|V0441800|41|0763|清远市",
"V0441281|云浮|051|V0441281|42|0766|云浮市",
"V0445100|潮州|051|V0445100|43|0768|潮州市",
"V0441900|东莞|051|V0441900|44|0769|东莞市",
"V0420100|武汉|071|V0420100|45|027|武汉市",
"V0420600|襄樊|071|V0420600|46|0710|襄樊市",
"V0420700|鄂州|071|V0420700|47|0711|鄂州市",
"V0420900|孝感|071|V0420900|48|0712|孝感市",
"V0422100|黄冈|071|V0422100|49|0713|黄冈市",
"V0420200|黄石|071|V0420200|50|0714|黄石市",
"V0422300|咸宁|071|V0422300|51|0715|咸宁市",
"V0422400|荆州|071|V0422400|52|0716|荆州市",
"V0420500|宜昌|071|V0420500|53|0717|宜昌市",
"V0422800|恩施|071|V0422800|54|0718|恩施土家族苗族自治州",
"V0422600|十堰|071|V0422600|55|0719|十堰市",
"V0420681|随州|071|V0420681|56|0722|随州市",
"V0420800|荆门|071|V0420800|57|0724|荆门市",
"V0422401|江汉|071|V0422401|58|0728|江汉市",
"V0210100|沈阳|091|V0210100|59|024|沈阳市",
"V0210200|大连|091|V0210200|60|0411|大连市",
"V0210300|鞍山|091|V0210300|61|0412|鞍山市",
"V0210400|抚顺|091|V0210400|62|024|抚顺市",
"V0210500|本溪|091|V0210500|63|0414|本溪市",
"V0210600|丹东|091|V0210600|64|0415|丹东市",
"V0210700|锦州|091|V0210700|65|0416|锦州市",
"V0210800|营口|091|V0210800|66|0417|营口市",
"V0210900|阜新|091|V0210900|67|0418|阜新市",
"V0211000|辽阳|091|V0211000|68|0419|辽阳市",
"V0211200|铁岭|091|V0211200|69|024|铁岭市",
"V0211300|朝阳|091|V0211300|70|0421|朝阳市",
"V0211100|盘锦|091|V0211100|71|0427|盘锦市",
"V0211400|葫芦岛|091|V0211400|72|0429|葫芦岛市",
"V0533100|德宏|086|V0533100|73|0692|德宏傣族景颇族自治州",
"V0532600|文山|086|V0532600|74|0876|文山壮族苗族自治州",
"V0533000|保山|086|V0533000|75|0875|保山市",
"V0533500|临沧|086|V0533500|76|0883|临沧市",
"V0533300|怒江傈|086|V0533300|77|0886|怒江僳僳族自治州",
"V0533400|迪庆|086|V0533400|78|0887|迪庆藏族普米族自治县",
"V0532100|昭通|086|V0532100|79|0870|昭通市",
"V0530100|昆明|086|V0530100|80|0871|昆明市",
"V0532500|红河|086|V0532500|81|0873|红河哈尼族彝族自治州",
"V0532900|大理|086|V0532900|82|0872|大理白族自治州",
"V0533200|丽江|086|V0533200|83|0888|丽江市",
"V0532300|楚雄|086|V0532300|84|0878|楚雄彝族自治州",
"V0532400|玉溪|086|V0532400|85|0877|玉溪市",
"V0532200|曲靖|086|V0532200|86|0874|曲靖市",
"V0532800|西双版纳|086|V0532800|87|691|西双版纳傣族自治州",
"V0533600|普洱|086|V0533600|89|0879|普洱市",
"V0622400|定西|087|V0622400|90|0932|定西市",
"V0622700|平凉|087|V0622700|91|0933|平凉市",
"V0622800|庆阳|087|V0622800|92|0934|庆阳市",
"V0622300|武威|087|V0622300|93|0935|武威市",
"V0622201|张掖|087|V0622201|94|0936|张掖市",
"V0620200|嘉峪关|087|V0620200|95|0937|嘉峪关市",
"V0620500|天水|087|V0620500|96|0938|天水市",
"V0622901|临夏|087|V0622901|97|0930|临夏回族自治州",
"V0620400|白银|087|V0620400|98|0943|白银市",
"V0620300|金昌|087|V0620300|99|0935|金昌市",
"V0622100|酒泉|087|V0622100|100|0937|酒泉市",
"V0622600|陇南|087|V0622600|101|0939|陇南市",
"V0623000|甘南|087|V0623000|102|0941|甘南藏族自治州",
"V0620100|兰州|087|V0620100|103|0931|兰州市",
"V0150100|呼和浩特|010|V0150100|104|0471|呼和浩特市",
"V0150200|包头|010|V0150200|105|0472|包头市",
"V0150300|乌海|010|V0150300|106|0473|乌海市",
"V0150400|赤峰|010|V0150400|107|0476|赤峰市",
"V0152200|兴安|010|V0152200|108|0482|兴安盟",
"V0152301|通辽|010|V0152301|109|0475|通辽市",
"V0152500|锡林郭勒|010|V0152500|110|0479|锡林郭勒盟",
"V0152600|乌兰察布|010|V0152600|111|0474|乌兰察布市",
"V0152700|鄂尔多斯|010|V0152700|112|0477|鄂尔多斯市",
"V0152800|巴彦淖尔|010|V0152800|113|0478|巴彦淖尔市",
"V0152900|阿拉善|010|V0152900|114|0483|阿拉善盟",
"V0152302|呼伦贝尔|010|V0152302|115|0470|呼伦贝尔市",
"V0152101|海拉尔|010|V0152101|116|0470|海拉尔市",
"V0520100|贵阳|085|V0520100|117|0851|贵阳市",
"V0522100|遵义|085|V0522100|118|0852|遵义市",
"V0522500|安顺|085|V0522500|119|0853|安顺市",
"V0522200|铜仁|085|V0522200|122|0856|铜仁市",
"V0522400|毕节|085|V0522400|123|0857|毕节市",
"V0520200|六盘水|085|V0520200|124|0858|六盘水市",
"V0522900|黔西南|085|V0522900|126|0859|黔西南布依族苗族自治州",
"V0523100|黔东南|085|V0523100|127|0855|黔东南苗族侗族自治州",
"V0523200|黔南|085|V0523200|128|0854|黔南布依族苗族自治州",
"V0410100|郑州|076|V0410100|129|0371|郑州市",
"V0410200|开封|076|V0410200|130|0378|开封市",
"V0410300|洛阳|076|V0410300|131|0379|洛阳市",
"V0410400|平顶山|076|V0410400|132|0375|平顶山市",
"V0410500|安阳|076|V0410500|133|0372|安阳市",
"V0410600|鹤壁|076|V0410600|134|0392|鹤壁市",
"V0410700|新乡|076|V0410700|135|0373|新乡市",
"V0410800|焦作|076|V0410800|136|0391|焦作市",
"V0410900|濮阳|076|V0410900|137|0393|濮阳市",
"V0411000|许昌|076|V0411000|138|0374|许昌市",
"V0411100|漯河|076|V0411100|139|0395|漯河市",
"V0411200|三门峡|076|V0411200|140|0398|三门峡市",
"V0412300|商丘|076|V0412300|141|0370|商丘市",
"V0412700|周口|076|V0412700|142|0394|周口市",
"V0412801|驻马店|076|V0412801|143|0396|驻马店市",
"V0412901|南阳|076|V0412901|144|0377|南阳市",
"V0413000|信阳|076|V0413000|145|0376|信阳市",
"V0410880|济源|076|V0410880|146|0391|济源市",
"V0412880|济源|076|V0412880|146|0391|济源市",
"V0412800|济源|076|V0412800|147|0397|济源市",
"V0330100|杭州|036|V0330100|148|0571|杭州市",
"V0330200|宁波|036|V0330200|149|0574|宁波市",
"V0330300|温州|036|V0330300|150|0577|温州市",
"V0332600|台州|036|V0332600|151|0576|台州市",
"V0330700|金华|036|V0330700|152|0579|金华市",
"V0330400|嘉兴|036|V0330400|153|0573|嘉兴市",
"V0330600|绍兴|036|V0330600|154|0575|绍兴市",
"V0330500|湖州|036|V0330500|155|0572|湖州市",
"V0332500|丽水|036|V0332500|156|0578|丽水市",
"V0330800|衢州|036|V0330800|157|0570|衢州市",
"V0330900|舟山|036|V0330900|158|0580|舟山市",
"V0320100|南京|034|V0320100|159|025|南京市",
"V0320500|苏州|034|V0320500|160|0512|苏州市",
"V0320200|无锡|034|V0320200|161|0510|无锡市",
"V0320400|常州|034|V0320400|162|0519|常州市",
"V0321000|扬州|034|V0321000|163|0514|扬州市",
"V0321100|镇江|034|V0321100|164|0511|镇江市",
"V0320600|南通|034|V0320600|165|0513|南通市",
"V0320300|徐州|034|V0320300|166|0516|徐州市",
"V0321082|泰州|034|V0321082|167|0523|泰州市",
"V0320900|盐城|034|V0320900|168|0515|盐城市",
"V0320800|淮安|034|V0320800|169|0517|淮安市",
"V0320700|连云港|034|V0320700|170|0518|连云港市",
"V0320881|宿迁|034|V0320881|171|0527|宿迁市",
"V0220100|长春|090|V0220100|172|0431|长春市",
"V0220200|吉林|090|V0220200|173|0432|吉林市",
"V0222400|延边|090|V0222400|174|0433|延边朝鲜族自治州",
"V0220300|四平|090|V0220300|175|0434|四平市",
"V0220500|通化|090|V0220500|176|0435|通化市",
"V0220800|白城|090|V0220800|177|0436|白城市",
"V0220400|辽源|090|V0220400|178|0437|辽源市",
"V0220700|松原|090|V0220700|179|0438|松原市",
"V0220600|白山|090|V0220600|180|0439|白山市",
"V0630100|西宁|070|V0630100|181|0971|西宁市",
"V0632100|海东|070|V0632100|182|0972|海东地区",
"V0632801|格尔木|070|V0632801|183|0979|格尔木市",
"V0632200|海北|070|V0632200|184|0970|海北藏族",
"V0632500|海南|070|V0632500|185|0974|海南藏族",
"V0632800|海西|070|V0632800|186|0977|海西蒙古族藏族",
"V0632600|果洛|070|V0632600|187|0975|果洛藏族",
"V0632700|玉树|070|V0632700|188|0976|玉树藏族",
"V0632300|黄南|070|V0632300|189|0973|黄南藏族自治州",
"V0540100|拉萨|079|V0540100|190|0891|拉萨市",
"V0542300|日喀则|079|V0542300|191|0892|日喀则地区",
"V0542200|山南|079|V0542200|192|0893|山南地区",
"V0542600|林芝|079|V0542600|193|0894|林芝地区",
"V0542100|昌都|079|V0542100|194|0895|昌都地区",
"V0542400|那曲|079|V0542400|195|0896|那曲地区",
"V0542500|阿里|079|V0542500|196|0897|阿里地区",
"V0430100|长沙|074|V0430100|197|0731|长沙市",
"V0430200|株洲|074|V0430200|198|0733|株洲市",
"V0430300|湘潭|074|V0430300|199|0732|湘潭市",
"V0430400|衡阳|074|V0430400|200|0734|衡阳市",
"V0430600|岳阳|074|V0430600|201|0730|岳阳市",
"V0430900|益阳|074|V0430900|202|0737|益阳市",
"V0431000|郴州|074|V0431000|203|0735|郴州市",
"V0430700|常德|074|V0430700|204|0736|常德市",
"V0432500|娄底|074|V0432500|205|0738|娄底市",
"V0430500|邵阳|074|V0430500|206|0739|邵阳市",
"V0433100|湘西|074|V0433100|207|0743|湘西土家族苗族自治州",
"V0430800|张家界|074|V0430800|208|0744|张家界市",
"V0431200|怀化|074|V0431200|209|0745|怀化市",
"V0431100|永州|074|V0431100|210|0746|永州市",
"V0350100|福州|038|V0350100|211|0591|福州市",
"V0350200|厦门|038|V0350200|212|0592|厦门市",
"V0350500|泉州|038|V0350500|213|0595|泉州市",
"V0350600|漳州|038|V0350600|214|0596|漳州市",
"V0352200|宁德|038|V0352200|215|0593|宁德市",
"V0350300|莆田|038|V0350300|216|0594|莆田市",
"V0352100|南平|038|V0352100|217|0599|南平市",
"V0350400|三明|038|V0350400|218|0598|三明市",
"V0352600|龙岩|038|V0352600|219|0597|龙岩市",
"V0510100|成都|081|V0510100|220|028|成都市",
"V0510300|自贡|081|V0510300|221|0813|自贡市",
"V0510400|攀枝花|081|V0510400|222|0812|攀枝花市",
"V0510500|泸州|081|V0510500|223|0830|泸州市",
"V0510600|德阳|081|V0510600|224|0838|德阳市",
"V0510700|绵阳|081|V0510700|225|0816|绵阳市",
"V0510800|广元|081|V0510800|226|0839|广元市",
"V0510900|遂宁|081|V0510900|227|0825|遂宁市",
"V0511000|内江|081|V0511000|228|0832|内江市",
"V0511100|乐山|081|V0511100|229|0833|乐山市",
"V0511300|南充|081|V0511300|230|0817|南充市",
"V0513800|眉山|081|V0513800|231|028|眉山市",
"V0512500|宜宾|081|V0512500|232|0831|宜宾市",
"V0513600|广安|081|V0513600|233|0826|广安市",
"V0513000|达州|081|V0513000|234|0818|达州市",
"V0513100|雅安|081|V0513100|235|0835|雅安市",
"V0513700|巴中|081|V0513700|236|0827|巴中市",
"V0513900|资阳|081|V0513900|237|028|资阳市",
"V0513200|阿坝|081|V0513200|238|0837|阿坝藏族羌族",
"V0513300|甘孜|081|V0513300|239|0836|甘孜藏族",
"V0513400|凉山|081|V0513400|240|0834|凉山彝族自治州",
"V0530200|东川|086|V0530200|241|0871|东川市",
"V0650100|乌鲁木齐|089|V0650100|242|0991|乌鲁木齐市",
"V0650200|克拉玛依|089|V0650200|243|0990|克拉玛依市",
"V0652101|吐鲁番|089|V0652101|244|0995|吐鲁番地区",
"V0652201|哈密|089|V0652201|245|0902|哈密地区",
"V0652301|昌吉|089|V0652301|246|0994|昌吉回族自治州",
"V0650300|博尔塔拉|089|V0650300|247|0909|博尔塔拉蒙古自治州",
"V0650500|巴音郭楞|089|V0650500|248|0996|巴音郭楞蒙古自治州",
"V0652901|阿克苏|089|V0652901|249|0997|阿克苏地区",
"V0650600|克孜勒苏|089|V0650600|250|0908|克孜勒苏柯尔克孜自治州",
"V0653101|喀什|089|V0653101|251|0998|喀什地区",
"V0653201|和田|089|V0653201|252|0903|和田地区",
"V0654001|奎屯|089|V0654001|253|0992|奎屯市",
"V0650400|伊犁|089|V0650400|254|0999|伊犁哈萨克自治州",
"V0654201|塔城|089|V0654201|255|0901|塔城市",
"V0654301|阿勒泰|089|V0654301|256|0906|阿勒泰地区",
"V0659001|石河子|089|V0659001|257|0993|石河子市",
"V0360100|南昌|075|V0360100|258|0791|南昌市",
"V0360400|九江|075|V0360400|259|0792|九江市",
"V0362233|上饶|075|V0362233|260|0793|上饶市",
"V0362500|抚州|075|V0362500|261|0794|抚州市",
"V0362200|宜春|075|V0362200|262|0795|宜春市",
"V0362400|吉安|075|V0362400|263|0796|吉安市",
"V0362100|赣州|075|V0362100|264|0797|赣州市",
"V0360200|景德镇|075|V0360200|265|0798|景德镇市",
"V0360300|萍乡|075|V0360300|266|0799|萍乡市",
"V0360500|新余|075|V0360500|267|0790|新余市",
"V0360600|鹰潭|075|V0360600|268|0701|鹰潭市",
"V0340500|马鞍山|030|V0340500|269|0555|马鞍山市",
"V0340300|蚌埠|030|V0340300|270|0552|蚌埠市",
"V0340800|安庆|030|V0340800|271|0556|安庆市",
"V0340200|芜湖|030|V0340200|272|0553|芜湖市",
"V0342400|六安|030|V0342400|273|0564|六安市",
"V0340100|合肥|030|V0340100|274|0551|合肥市",
"V0342100|阜阳|030|V0342100|275|0558|阜阳市",
"V0340400|淮南|030|V0340400|276|0554|淮南市",
"V0340700|铜陵|030|V0340700|277|0562|铜陵市",
"V0342500|宣城|030|V0342500|278|0563|宣州市",
"V0341100|滁州|030|V0341100|279|0550|滁州市",
"V0342200|宿州|030|V0342200|280|0557|宿州市",
"V0340600|淮北|030|V0340600|281|0561|淮北市",
"V0341000|黄山|030|V0341000|282|0559|黄山市",
"V0342900|池州|030|V0342900|283|0566|池州市",
"V0343000|亳州|030|V0343000|284|0558|亳州市",
"V0342600|巢湖|030|V0342600|285|0551|巢湖市",
"V0140600|朔州|019|V0140600|286|0349|朔州市",
"V0142200|忻州|019|V0142200|287|0350|忻州市",
"V0140100|太原|019|V0140100|288|0351|太原市",
"V0140200|大同|019|V0140200|289|0352|大同市",
"V0140300|阳泉|019|V0140300|290|0353|阳泉市",
"V0142400|晋中|019|V0142400|291|0354|晋中市 ",
"V0140400|长治|019|V0140400|292|0355|长治市",
"V0140500|晋城|019|V0140500|293|0356|晋城市",
"V0142600|临汾|019|V0142600|294|0357|临汾市",
"V0142300|吕梁|019|V0142300|295|0358|吕梁市",
"V0142700|运城|019|V0142700|296|0359|运城市",
"V0130400|邯郸|018|V0130400|297|0310|邯郸市",
"V0130600|保定|018|V0130600|298|0312|保定市",
"V0130700|张家口|018|V0130700|299|0313|张家口市",
"V0130200|唐山|018|V0130200|300|0315|唐山市",
"V0130900|沧州|018|V0130900|301|0317|沧州市",
"V0130500|邢台|018|V0130500|302|0319|邢台市",
"V0130300|秦皇岛|018|V0130300|303|0335|秦皇岛市",
"V0130100|石家庄|018|V0130100|304|0311|石家庄市",
"V0130800|承德|018|V0130800|305|0314|承德市",
"V0131000|廊坊|018|V0131000|306|0316|廊坊市",
"V0133000|衡水|018|V0133000|307|0318|衡水市",
"V0640100|银川|088|V0640100|308|0951|银川市",
"V0642100|吴忠|088|V0642100|309|0953|吴忠市",
"V0640200|石嘴山|088|V0640200|310|0952|石嘴山市",
"V0642200|固原|088|V0642200|311|0954|固原市",
"V0642300|中卫|088|V0642300|312|0955|中卫市",
"V0610300|宝鸡|084|V0610300|313|0917|宝鸡市",
"V0610100|西安|084|V0610100|314|029|西安市",
"V0612601|延安|084|V0612601|315|0911|延安市",
"V0612101|渭南|084|V0612101|316|0913|渭南市",
"V0610400|咸阳|084|V0610400|317|0910|咸阳市",
"V0612701|榆林|084|V0612701|318|0912|榆林市",
"V0610200|铜川|084|V0610200|319|0919|铜川市",
"V0612501|商洛|084|V0612501|320|0914|商洛市",
"V0612401|安康|084|V0612401|321|0915|安康市",
"V0612301|汉中|084|V0612301|322|0916|汉中市",
"V0450100|南宁|059|V0450100|323|0771|南宁市",
"V0450300|桂林|059|V0450300|324|0773|桂林市",
"V0450200|柳州|059|V0450200|325|0772|柳州市",
"V0450400|梧州|059|V0450400|326|0774|梧州市",
"V0452500|玉林|059|V0452500|327|0775|玉林市",
"V0452600|百色|059|V0452600|328|0776|百色市",
"V0452800|钦州|059|V0452800|329|0777|钦州市",
"V0452700|河池|059|V0452700|330|0778|河池市",
"V0450500|北海|059|V0450500|331|0779|北海市",
"V0453200|崇左|059|V0453200|332|0771|崇左市",
"V0453000|贺州|059|V0453000|333|0774|贺州市",
"V0452900|贵港|059|V0452900|334|0775|贵港市",
"V0450600|防城港|059|V0450600|335|0770|防城港市",
"V0453100|来宾|059|V0453100|336|0772|来宾市",
"V0230100|哈尔滨|097|V0230100|337|0451|哈尔滨市",
"V0230200|齐齐哈尔|097|V0230200|338|0452|齐齐哈尔市",
"V0231000|牡丹江|097|V0231000|339|0453|牡丹江市",
"V0230800|佳木斯|097|V0230800|340|0454|佳木斯市",
"V0232300|绥化|097|V0232300|341|0455|绥化市",
"V0230600|大庆|097|V0230600|342|0459|大庆市",
"V0230300|鸡西|097|V0230300|343|0467|鸡西市",
"V0231100|黑河|097|V0231100|344|0456|黑河市",
"V0230700|伊春|097|V0230700|345|0458|伊春市",
"V0230500|双鸭山|097|V0230500|346|0469|双鸭山市",
"V0230400|鹤岗|097|V0230400|347|0468|鹤岗市",
"V0230900|七台河|097|V0230900|348|0464|七台河市",
"V0232700|大兴安岭|097|V0232700|349|0457|大兴安岭地区",
"V0370100|济南|017|V0370100|350|0531|济南市",
"V0370200|青岛|017|V0370200|351|0532|青岛市",
"V0370300|淄博|017|V0370300|352|0533|淄博市",
"V0370400|枣庄|017|V0370400|353|0632|枣庄市",
"V0370500|东营|017|V0370500|354|0546|东营市",
"V0370600|烟台|017|V0370600|355|0535|烟台市",
"V0370700|潍坊|017|V0370700|356|0536|潍坊市",
"V0370800|济宁|017|V0370800|357|0537|济宁市",
"V0370900|泰安|017|V0370900|358|0538|泰安市",
"V0371000|威海|017|V0371000|359|0631|威海市",
"V0371100|日照|017|V0371100|360|0633|日照市",
"V0371200|莱芜|017|V0371200|361|0634|莱芜市",
"V0372801|临沂|017|V0372801|362|0539|临沂市",
"V0372401|德州|017|V0372401|363|0534|德州市",
"V0372500|聊城|017|V0372500|364|0635|聊城市",
"V0372300|滨州|017|V0372300|365|0543|滨州市",
"V0372900|菏泽|017|V0372900|366|0530|菏泽市"]
var e = [
{'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': ['乌鲁木齐', '克拉玛依', '吐鲁番',
'哈密', '昌吉', '博尔塔拉', '巴音郭楞',
'阿克苏', '克孜勒苏', '喀什', '和田',
'伊犁', '塔城', '阿勒泰', '石河子']}]
let arrs = {};
t.forEach( x => {
let key = x.split('|')[0];
let short = x.split('|')[1];
arrs[short] = key;
});
console.dir(arrs);
e.forEach( x => {
x.c.forEach( y => {
console.dir(arrs[y])
})
})
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