Commit 79ec63e3 authored by lvweichao's avatar lvweichao

feat: user

parent b25faadd
const Koa = require('koa'); const Koa = require('koa');
const views = require('koa-views'); const views = require('koa-views');
const serve = require('koa-static'); const serve = require('koa-static');
const koaBody = require('koa-body');
const bodyParser = require('koa-bodyparser'); const bodyParser = require('koa-bodyparser');
const path = require('path'); const path = require('path');
const router = require('./server/router'); const router = require('./server/router');
...@@ -12,6 +13,7 @@ const app = new Koa(); ...@@ -12,6 +13,7 @@ const app = new Koa();
app.use(serve(path.join(__dirname, './public'))); app.use(serve(path.join(__dirname, './public')));
app.use(bodyParser()); app.use(bodyParser());
app.use(koaBody({multipart: true}));
app.use(router.routes(), router.allowedMethods()); app.use(router.routes(), router.allowedMethods());
app.listen(config.port, () => { app.listen(config.port, () => {
......
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -19,10 +19,17 @@ const API_INTERNAL_URI = { ...@@ -19,10 +19,17 @@ const API_INTERNAL_URI = {
'production': "http://bp-test.go2yd.com" 'production': "http://bp-test.go2yd.com"
} }
const IDGEN_URI = {
'development': "https://bp-test.go2yd.com",
'test': "http://idgen-test.ini.yidian-inc.com",
'production': "http://idgen-test.ini.yidian-inc.com"
}
module.exports = { module.exports = {
env: env, env: env,
port: port, port: port,
LOGIN_URI: LOGIN_URI[env], LOGIN_URI: LOGIN_URI[env],
API_INTERNAL_URI: API_INTERNAL_URI[env], API_INTERNAL_URI: API_INTERNAL_URI[env],
PANDORA_URI: PANDORA_URI[env] PANDORA_URI: PANDORA_URI[env],
IDGEN_URI: IDGEN_URI[env]
}; };
exports.KS3_CONST = {
AccessKeyID: 'AKLTTpZx6fNBQsGSKe5chqHdXA',
AccessKeySecret: 'OG9Bk93RUHwaH71U9K+OtWkvx44AdMheywjFlifILikvh96jNGgznJm+AyR5l4wPhw==',
DOMAIN: 'ks3-cn-beijing.ksyun.com'
}
\ No newline at end of file
const fsPromise = require("fs/promises");
const IDGEN_URI = require('../config.js').IDGEN_URI
const Ks3Util = require('../utils/ksUtil').Ks3Util
const KS3_CONST = require('../constant').KS3_CONST
const req = require("../utils/request").httpReq;
const FormData = require('form-data');
const _get_obj_id = async (ctx, next) => {
var url = `${IDGEN_URI}/Ksy/ksyun/buildObectid`;
var opts = {
url: url,
qs: {
appid: 'merchant-b',
},
method: 'GET',
}
return await req(ctx, opts);
}
const _get_bucket = async (ctx, next) => {
var url = `${IDGEN_URI}/Ksy/ksyun/getBucket`;
var opts = {
url: url,
qs: {
appid: 'merchant-b',
},
method: 'GET',
}
// console.log(await req(ctx, opts))
return await req(ctx, opts)
}
const _get_token = async (ctx, next) => {
var url = `${IDGEN_URI}/Ksy/ksyun/getToken`;
var opts = {
url: url,
data: {
appid: 'merchant-b',
},
method: 'POST',
}
return await req(ctx, opts)
}
exports.get_obj_id = async (ctx, next) => {
ctx.body = _get_obj_id(ctx, next)
}
exports.get_bucket = async (ctx, next) => {
ctx.body = await _get_bucket(ctx, next)
}
exports.get_token = async (ctx, next) => {
ctx.body = await _get_token(ctx, next)
}
exports.get_ks3_config = async (ctx, next) => {
const { result: { bucket }} = await _get_bucket(ctx, next)
const { result: { objectId }} = await _get_obj_id(ctx, next)
const getExpires = (seconds) => {
return Math.round(new Date().getTime()/1000) + seconds;
};
const policy = {
"expiration": new Date(getExpires(3600)*1000).toISOString(), //一小时后
"conditions": [
["eq","$bucket", bucket],
["starts-with","$acl", "public-read"],
// ["starts-with", "$key", ""],
// ["starts-with", "$name", ""], //表单中传了name字段,也需要加到policy中
// ["starts-with", "$x-kss-meta-custom-param1",""],
// ["starts-with", "$x-kss-newfilename-in-body",""],//必须只包含小写字符
// ["starts-with", "$Cache-Control",""],
// ["starts-with", "$Expires", ""],
// ["starts-with", "$Content-Disposition", ""],
// ["starts-with", "$Content-Type",""],
// ["starts-with", "$Content-Encoding",""]
]
}
const stringToSign = Ks3Util.Base64.encode(JSON.stringify(policy))
console.log('stringToSign:::', stringToSign)
const signature = Ks3Util.b64_hmac_sha1(KS3_CONST.AccessKeySecret, stringToSign)
ctx.body = {
bucket,
objectId,
policy: stringToSign,
signature,
}
}
exports.upload_ks3_image = async (ctx, next) => {
// console.log('upload_ks3_image::::::', ctx.request.files)
const file = ctx.request.files && ctx.request.files.file;
// console.log(34444, file)
// const bucketOpt = {
// url: `${IDGEN_URI}/Ksy/ksyun/getBucket`,
// params: {
// appid: 'merchant-b',
// },
// method: 'GET',
// timeout: 8000,
// }
// const objIdOpt = {
// url: `${IDGEN_URI}/Ksy/ksyun/buildObectid`,
// params: {
// appid: 'merchant-b',
// },
// method: 'GET',
// timeout: 8000,
// }
// const { result: { bucket }} = await _get_bucket(ctx, next)
// const { result: { objectId }} = await _get_obj_id(ctx, next)
const { result: { bucket }} = await _get_bucket(ctx, next)
const { result: { objectId }} = await _get_obj_id(ctx, next)
console.log(3334444, bucket, objectId, file,)
const getExpires = (seconds) => {
return Math.round(new Date().getTime()/1000) + seconds;
};
const policy = {
"expiration": new Date(getExpires(3600)*1000).toISOString(), //一小时后
"conditions": [
["eq","$bucket", bucket],
["starts-with","$acl", "public-read"],
]
}
const stringToSign = Ks3Util.Base64.encode(JSON.stringify(policy))
console.log('stringToSign:::', stringToSign)
const signature = Ks3Util.b64_hmac_sha1(KS3_CONST.AccessKeySecret, stringToSign)
// const reader = fs.createReadStream(file.path);
const reader = await fsPromise.readFile(file.path);
const formData = new FormData()
formData.append('acl', 'public-read')
formData.append('key', objectId)
formData.append('signature', signature)
formData.append('KSSAccessKeyId', KS3_CONST.AccessKeyID)
formData.append('policy', stringToSign)
formData.append('bucket_name', stringToSign)
formData.append('file', reader)
// axios.post(OSS_URL, formData).then(res => {
// const { status } = res
// if (status === 200) {
// const data = {
// url: `${OSS_URL}/${key}`,
// type: fileType(file.name)
// }
// resolve(data)
// } else {
// reject(res)
// })
var opts = {
url: `http://${KS3_CONST.DOMAIN}/${bucket}`,
method: 'POST',
headers: {
// 'content-type': 'multipart/form-data'
...formData.getHeaders(),
'content-length': formData.getLengthSync(),
},
data: formData
}
console.log(3333333333, formData.getLengthSync());
const res = await req(ctx, opts);
console.log('sever ks3 image::::::', res)
ctx.body = res;
}
\ No newline at end of file
...@@ -17,6 +17,8 @@ var query = { ...@@ -17,6 +17,8 @@ var query = {
ctx.body = await req(ctx, opts); ctx.body = await req(ctx, opts);
} }
}; };
exports.query = async (ctx, next) => { exports.query = async (ctx, next) => {
var type = ctx.params.type; var type = ctx.params.type;
console.log("koa user::::::", type); console.log("koa user::::::", type);
...@@ -35,3 +37,47 @@ exports.query = async (ctx, next) => { ...@@ -35,3 +37,47 @@ exports.query = async (ctx, next) => {
}; };
} }
}; };
exports.user_list = async (ctx, next) => {
const url = `${API_INTERNAL_URI}/merchant/authority/get_user_list`;
const opts = {
url: url,
method: "GET",
qs: ctx.request.query,
};
ctx.body = await req(ctx, opts);
};
exports.user_detail = async (ctx, next) => {
const url = `${API_INTERNAL_URI}/merchant/authority/get_user_info`;
const opts = {
url: url,
method: "GET",
qs: ctx.request.query,
};
ctx.body = await req(ctx, opts);
};
exports.user_edit = async (ctx, next) => {
const url = `${API_INTERNAL_URI}/merchant/authority/update_user`;
const opts = {
url: url,
method: "POST",
json: true,
body: ctx.request.body,
};
ctx.body = await req(ctx, opts);
};
exports.user_new = async (ctx, next) => {
const url = `${API_INTERNAL_URI}/merchant/authority/add_user_role`;
const opts = {
url: url,
method: "POST",
json: true,
body: ctx.request.body,
};
ctx.body = await req(ctx, opts);
};
...@@ -4,6 +4,7 @@ const user = require("./controllers/user"); ...@@ -4,6 +4,7 @@ const user = require("./controllers/user");
const enterprise = require("./controllers/enterprise"); const enterprise = require("./controllers/enterprise");
const role = require('./controllers/role') const role = require('./controllers/role')
const life = require('./controllers/life-no') const life = require('./controllers/life-no')
const image = require('./controllers/image')
const router = Router(); const router = Router();
const API_VERSION = "/api/v1"; const API_VERSION = "/api/v1";
...@@ -16,6 +17,11 @@ router.post(`${API_VERSION}/emterprise_commit`, enterprise.entCommit); ...@@ -16,6 +17,11 @@ router.post(`${API_VERSION}/emterprise_commit`, enterprise.entCommit);
router.post(`${API_VERSION}/check_life`, enterprise.checkLife); router.post(`${API_VERSION}/check_life`, enterprise.checkLife);
router.post(`${API_VERSION}/create_life`, enterprise.createLife); router.post(`${API_VERSION}/create_life`, enterprise.createLife);
router.get(`${API_VERSION}/users`, user.user_list);
router.get(`${API_VERSION}/users/detail`, user.user_detail);
router.post(`${API_VERSION}/users/edit`, user.user_edit);
router.post(`${API_VERSION}/users/new`, user.user_new);
router.post(`${API_VERSION}/merchant/authority/role_list`, role.getRole_list) router.post(`${API_VERSION}/merchant/authority/role_list`, role.getRole_list)
router.post(`${API_VERSION}/merchant/authority/add_role`, role.getAdd_role) router.post(`${API_VERSION}/merchant/authority/add_role`, role.getAdd_role)
router.post(`${API_VERSION}/merchant/authority/update_role`, role.getUpdate_role) router.post(`${API_VERSION}/merchant/authority/update_role`, role.getUpdate_role)
...@@ -24,5 +30,10 @@ router.post(`${API_VERSION}/merchant/authority/get_role_info`, role.get_role_inf ...@@ -24,5 +30,10 @@ router.post(`${API_VERSION}/merchant/authority/get_role_info`, role.get_role_inf
router.post(`${API_VERSION}/merchant/lifeinner/life_info`, role.getUser_detail) router.post(`${API_VERSION}/merchant/lifeinner/life_info`, role.getUser_detail)
router.get(`${API_VERSION}/merchant/lifeinner/life_list`, life.get_life_list) router.get(`${API_VERSION}/merchant/lifeinner/life_list`, life.get_life_list)
router.get(`${API_VERSION}/image/get_image_id`, image.get_obj_id)
router.get(`${API_VERSION}/image/get_bucket`, image.get_bucket)
router.get(`${API_VERSION}/image/get_token`, image.get_token)
router.post(`${API_VERSION}/image/upload_ks3_image`, image.upload_ks3_image)
router.get(`${API_VERSION}/image/get_ks3_config`, image.get_ks3_config)
module.exports = router; module.exports = router;
Ks3 = {}
/*
* //使用hmac_sha1算法计算字符串的签名
* return base-64 encoded strings
*/
Ks3.b64_hmac_sha1 = function (key, data) {
return Ks3.binb2b64(Ks3.core_hmac_sha1(key, data));
}
/*
* Convert an array of big-endian words to a base-64 string
*/
Ks3.binb2b64 = function (binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16)
| (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8)
| ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) str += Ks3.b64pad;
else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
}
}
return str;
}
/*
* Calculate the HMAC-SHA1 of a key and some data
*/
Ks3.core_hmac_sha1 = function (key, data) {
var bkey = Ks3.str2binb(key);
if (bkey.length > 16) bkey = Ks3.core_sha1(bkey, key.length * Ks3.chrsz);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = Ks3.core_sha1(ipad.concat(Ks3.str2binb(data)), 512 + data.length * Ks3.chrsz);
return Ks3.core_sha1(opad.concat(hash), 512 + 160);
}
/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
Ks3.str2binb = function (str) {
var bin = Array();
var mask = (1 << Ks3.chrsz) - 1;
console.log('str2binb::::', str)
for (var i = 0; i < str.length * Ks3.chrsz; i += Ks3.chrsz)
bin[i >> 5] |= (str.charCodeAt(i / Ks3.chrsz) & mask) << (32 - Ks3.chrsz - i % 32);
return bin;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
Ks3.core_sha1 = function (x, len) {
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = x[i + j];
else w[j] = Ks3.rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
var t = Ks3.safe_add(Ks3.safe_add(Ks3.rol(a, 5), Ks3.sha1_ft(j, b, c, d)),
Ks3.safe_add(Ks3.safe_add(e, w[j]), Ks3.sha1_kt(j)));
e = d;
d = c;
c = Ks3.rol(b, 30);
b = a;
a = t;
}
a = Ks3.safe_add(a, olda);
b = Ks3.safe_add(b, oldb);
c = Ks3.safe_add(c, oldc);
d = Ks3.safe_add(d, oldd);
e = Ks3.safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
Ks3.rol = function(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
Ks3.sha1_ft = function(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
Ks3.sha1_kt = function(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
Ks3.safe_add = function (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*基于Javascript的Base64加解密算法*/
Ks3.Base64 = {
encTable :[ /*Base64编码表*/
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O' ,'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
],
decTable:[ /*Base64解码表*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
05, 06, 07, 08, 09, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, -1, -1, -1, -1, -1
],
encUTF8: function(str) { /*将任意字符串按UTF8编码*/
var code, res =[], len =str.length;
var byte1, byte2, byte3, byte4, byte5, byte6;
for (var i = 0; i < len; i++) {
//Unicode码:按范围确定字节数
code = str.charCodeAt(i);
//单字节ascii字符:U+00000000 – U+0000007F 0xxxxxxx
if (code > 0x0000 && code <= 0x007F) res.push(code);
//双字节字符:U+00000080 – U+000007FF 110xxxxx 10xxxxxx
else if (code >= 0x0080 && code <= 0x07FF) {
byte1 = 0xC0 | ((code >> 6) & 0x1F);
byte2 = 0x80 | (code & 0x3F);
res.push(byte1, byte2);
}
//三字节字符:U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
else if (code >= 0x0800 && code <= 0xFFFF) {
byte1 = 0xE0 | ((code >> 12) & 0x0F);
byte2 = 0x80 | ((code >> 6) & 0x3F);
byte3 = 0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3);
}
//四字节字符:U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x00010000 && code <= 0x001FFFFF) {
byte1 =0xF0 | ((code>>18) & 0x07);
byte2 =0x80 | ((code>>12) & 0x3F);
byte3 =0x80 | ((code>>6) & 0x3F);
byte4 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4);
}
//五字节字符:U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x00200000 && code <= 0x03FFFFFF) {
byte1 =0xF0 | ((code>>24) & 0x03);
byte2 =0xF0 | ((code>>18) & 0x3F);
byte3 =0x80 | ((code>>12) & 0x3F);
byte4 =0x80 | ((code>>6) & 0x3F);
byte5 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4, byte5);
}
//六字节字符:U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if (code >= 0x04000000 && code <= 0x7FFFFFFF) {
byte1 =0xF0 | ((code>>30) & 0x01);
byte2 =0xF0 | ((code>>24) & 0x3F);
byte3 =0xF0 | ((code>>18) & 0x3F);
byte4 =0x80 | ((code>>12) & 0x3F);
byte5 =0x80 | ((code>>6) & 0x3F);
byte6 =0x80 | (code & 0x3F);
res.push(byte1, byte2, byte3, byte4, byte5, byte6);
}
}
return res;
},
encode: function(str) {
/**
* 将任意字符串用Base64加密
* str:要加密的字符串
* utf8编码格式
*/
if (!str) return '';
var bytes = this.encUTF8(str);
var i = 0, len = bytes.length, res = [];
var c1, c2, c3;
while (i < len) {
c1 = bytes[i++] & 0xFF;
res.push(this.encTable[c1 >> 2]);
//结尾剩一个字节补2个=
if (i == len) {
res.push(this.encTable[(c1 & 0x03) << 4], '==');
break;
}
c2 = bytes[i++];
//结尾剩两个字节补1个=
if (i == len) {
res.push(this.encTable[((c1 & 0x03) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(this.encTable[(c2 & 0x0F) << 2], '=');
break;
}
c3 = bytes[i++];
res.push(this.encTable[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(this.encTable[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]);
res.push(this.encTable[c3 & 0x3F]);
}
return res.join('');
}
};
module.exports.Ks3Util = Ks3;
\ No newline at end of file
const { options } = require('less');
const request = require('request') const request = require('request')
exports.httpReq = (ctx, opts) => { exports.httpReq = (ctx, opts) => {
opts.timeout = opts.timeout || 1000 opts.timeout = opts.timeout || 1000
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// var time_start = +new Date() // var time_start = +new Date()
opts.qs = {...ctx.request.query, ...opts.qs};
request(opts, (err, res, body) => { request(opts, (err, res, body) => {
//console.info(`[Api] httpReq (${opts.url},${opts.headers && opts.headers.cookie}) spent: ${+new Date() - time_start}ms`) //console.info(`[Api] httpReq (${opts.url},${opts.headers && opts.headers.cookie}) spent: ${+new Date() - time_start}ms`)
if (!err) { if (!err) {
...@@ -14,4 +17,25 @@ exports.httpReq = (ctx, opts) => { ...@@ -14,4 +17,25 @@ exports.httpReq = (ctx, opts) => {
} }
}) })
}) })
} }
\ No newline at end of file
// const axios = require('axios')
// const instance = axios.create({})
// exports.httpReq = (ctx, opts) => {
// opts.timeout = opts.timeout || 1000
// return new Promise((resolve, reject) => {
// instance(opts).then((res) => {
// console.log(res);
// resolve(res.data);
// }).catch(({response}) => {
// // console.log(88888, response)
// reject(response.data.message)
// })
// })
// }
\ No newline at end of file
...@@ -13,17 +13,24 @@ ...@@ -13,17 +13,24 @@
</template> </template>
<script> <script>
export default { export default {
props: ['data', 'totalNum'], props: {
data: Object,
totalNum: Number,
pageSize: {
type: Number,
default: 20,
}
},
data () { data () {
return { return {
currentPage: 5, currentPage: 5
pageSize: 20
} }
}, },
methods: { methods: {
handleSizeChange (size) { handleSizeChange (size) {
console.log(`每页 ${size} 条`); console.log(`每页 ${size} 条`);
this.$emit('update', { pageSize: size }) this.$emit('update', { pageSize: size, })
}, },
handleCurrentChange (pageIndex) { handleCurrentChange (pageIndex) {
console.log(`当前页: ${pageIndex}`); console.log(`当前页: ${pageIndex}`);
......
exports.KS3_CONST = {
AccessKeyID: 'AKLTTpZx6fNBQsGSKe5chqHdXA',
AccessKeySecret: 'OG9Bk93RUHwaH71U9K+OtWkvx44AdMheywjFlifILikvh96jNGgznJm+AyR5l4wPhw==',
DOMAIN: 'ks3-cn-beijing.ksyun.com'
}
\ No newline at end of file
<template>
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList"
>
<el-button size="small" type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">只能上传 jpg/png 文件,且不超过 500kb</div>
</template>
</el-upload>
<input type="file" id="imgFile2">
<button @click="handleclick">Put上传</button>
</template>
<script>
import { ksOssUpload } from '@/service/ks3Image'
// import { uploadImageToKs3 } from '@/service/image'
export default {
data () {
return {
fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
}
},
beforeMount() {
},
methods: {
handleclick() {
var file = document.getElementById('imgFile2').files[0];
debugger;
console.log(33334444, file);
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
const { raw } = file;
console.log('handlePreview:::', file, typeof File);
console.log(222, raw)
ksOssUpload(raw)
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
// beforeRemove(file, fileList) {
// return this.$confirm(`确定移除 ${ file.name }?`);
// },
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="user-container">
<el-dialog :title="mode==='edit' ? '编辑用户':'创建用户'" v-model="modalVisable">
<el-form :model="userInfo">
<el-form-item label="用户ID" :label-width="formLabelWidth">
<el-input class="form-val" v-model="userInfo.user_id" size="medium" disabled></el-input>
</el-form-item>
<el-form-item label="状态" :label-width="formLabelWidth">
<!-- <el-input class="form-val">{{data.user_status===1?'启用':'禁用'}}</el-input> -->
<el-switch
class="form-val"
v-model="userInfo.user_status"
active-value=1
inactive-value=0
active-text="启用"
inactive-text="禁用"
>
</el-switch>
</el-form-item>
<el-form-item label="姓名" :label-width="formLabelWidth">
<el-input class="form-val" v-model="userInfo.user_name" disabled></el-input>
</el-form-item>
<el-form-item label="账号" :label-width="formLabelWidth">
<el-input class="form-val" v-model="userInfo.user_email" disabled></el-input>
</el-form-item>
<el-form-item label="手机号" :label-width="formLabelWidth">
<el-input class="form-val" v-model="userInfo.user_mobile"></el-input>
</el-form-item>
<el-form-item label="所属组织" :label-width="formLabelWidth">
<el-input class="form-val" v-model="userInfo.organization" disabled></el-input>
</el-form-item>
<el-form-item label="授权角色信息" :label-width="formLabelWidth">
<!-- <el-input class="form-val" v-model="userInfo.roles"></el-input> -->
<el-select v-model="userInfo.roles" multiple placeholder="请选择">
<el-option
v-for="item in roles"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="敏感词权限" :label-width="formLabelWidth">
<!-- <el-input class="form-val">{{userInfo.is_sensitive_authority === 1 ? '是' : '否'}}</el-input> -->
<el-switch
v-model="userInfo.is_sensitive_authority"
class="form-val"
active-value=1
inactive-value=0
active-text="开启"
inactive-text="关闭"
>
</el-switch>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button>取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { getRole_list as reqGetRoles } from '@/service/role';
export default {
name: 'UserInfoEditModal',
props: {
mode: {
type: String,
default: 'edit',
},
data: Object,
// title: {
// type: String,
// default: "用户信息",
// },
visable: {
type: Boolean,
default: false
}
},
data () {
return {
formLabelWidth: '120px',
userInfo: {},
roles: null,
modalVisable: false
}
},
watch: {
data(val) {
this.userInfo = val;
},
visable(val) {
this.modalVisable = val;
}
},
beforeMount(){
this.getRoles();
},
methods: {
async getRoles() {
const roles = await reqGetRoles();
console.log(67777, roles)
},
confirm() {
this.$emit('confirm', this.userInfo);
},
cancel() {
this.$emit('cancel');
}
},
}
</script>
<style lang="less">
.form-val {
margin-left: 20px;
width: 300px;
}
.form-val.el-input {
width: 80%;
}
</style>
\ No newline at end of file
<template>
<div class="user-container">
<el-dialog :title="title" v-model="modalVisable">
<el-form :model="data">
<el-form-item label="用户ID" :label-width="formLabelWidth">
<text class="form-val">{{data.user_id}}</text>
</el-form-item>
<el-form-item label="状态" :label-width="formLabelWidth">
<text class="form-val">{{data.user_status===1?'启用':'禁用'}}</text>
</el-form-item>
<el-form-item label="姓名" :label-width="formLabelWidth">
<text class="form-val">{{data.user_name}}</text>
</el-form-item>
<el-form-item label="账号" :label-width="formLabelWidth">
<text class="form-val">{{data.user_email}}</text>
</el-form-item>
<el-form-item label="手机号" :label-width="formLabelWidth">
<text class="form-val">{{data.user_mobile}}</text>
</el-form-item>
<el-form-item label="所属组织" :label-width="formLabelWidth">
<text class="form-val">{{data.organization}}</text>
</el-form-item>
<el-form-item label="添加账号人" :label-width="formLabelWidth">
<text class="form-val">{{data.create_user_name}}</text>
</el-form-item>
<el-form-item label="添加时间" :label-width="formLabelWidth">
<text class="form-val">{{data.create_time}}</text>
</el-form-item>
<el-form-item label="最后修改人账号" :label-width="formLabelWidth">
<text class="form-val">{{data.update_user_name}}</text>
</el-form-item>
<el-form-item label="最后修改时间" :label-width="formLabelWidth">
<text class="form-val">{{data.update_time}}</text>
</el-form-item>
<el-form-item label="授权角色信息" :label-width="formLabelWidth">
<text class="form-val">{{data.roles.map(ele => ele.name).join(',')}}</text>
</el-form-item>
<el-form-item label="敏感词权限" :label-width="formLabelWidth">
<text class="form-val">{{data.is_sensitive_authority === 1 ? '是' : '否'}}</text>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'UserInfoModal',
props: {
mode: {
type: String,
default: 'check',
},
data: Object,
title: {
type: String,
default: "用户信息",
},
visable: {
type: Boolean,
default: false
}
},
data () {
return {
formLabelWidth: '180px',
modalVisable: false,
}
},
watch: {
visable(val) {
this.modalVisable = val;
}
},
methods: {
},
}
</script>
<style lang="less">
.form-val {
margin-left: 20px;
}
</style>
\ No newline at end of file
...@@ -2,118 +2,241 @@ ...@@ -2,118 +2,241 @@
<template> <template>
<layout> <layout>
<div class="user"> <div class="user">
<el-form :inline="true" :model="formInline" class="demo-form-inline"> <el-form :inline="true" :model="pageParams" class="demo-form-inline">
<el-form-item label="生活号名称/企业名称"> <el-form-item label="用户姓名">
<el-input <el-input
class="search_life"
maxlength="15" maxlength="15"
v-model="formInline.user" v-model="pageParams.user_name"
placeholder="生活号名称/企业名称" placeholder="用户姓名"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="类型"> <el-form-item label="用户账号">
<el-select v-model="formInline.region" placeholder="类型"> <el-input
<el-option value="shanghai"></el-option> v-model="pageParams.user_email"
<el-option value="beijing"></el-option> placeholder="用户账号"
></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input
v-model="pageParams.user_mobile"
placeholder="手机号"
></el-input>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="pageParams.user_status" placeholder="状态">
<el-option value="1" label="启用"></el-option>
<el-option value="2" label="禁用"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item class="func-btn">
<el-button type="primary" @click="onSearchSubmit">查询</el-button> <el-button type="primary" @click="getUserList">查询</el-button>
<el-button @click="onReset">重置</el-button> <el-button @click="onReset">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table <el-table
:data="tableData" :data="renderUserList"
border border
style="width: 100%" style="width: 100%"
@row-click="toLifeDetail"
> >
<el-table-column prop="id" label="ID"> </el-table-column> <el-table-column prop="user_id" label="ID" width=70> </el-table-column>
<el-table-column prop="name" label="用户姓名"> </el-table-column> <el-table-column prop="user_name" label="用户姓名"> </el-table-column>
<el-table-column prop="address" label="用户账号"> </el-table-column> <el-table-column prop="user_email" label="用户账号"> </el-table-column>
<el-table-column prop="name" label="状态"> </el-table-column> <el-table-column prop="user_status" label="状态"> </el-table-column>
<el-table-column prop="date" label="手机号"> </el-table-column> <el-table-column prop="user_mobile" label="手机号"> </el-table-column>
<el-table-column prop="date" label="最后修改日期"> </el-table-column> <el-table-column prop="update_time" label="最后修改日期">
<el-table-column prop="date" label="最后修改人账号"> </el-table-column> </el-table-column>
<el-table-column prop="update_user_name" label="最后修改人账号">
</el-table-column>
<el-table-column fixed="right" label="操作" width="140">
<template #default="scope">
<el-button
type="text"
size="small"
@click="checkUser(scope.row)"
>查看</el-button
>
<el-button @click="editUser(scope.row)" type="text" size="small"
>修改</el-button
>
<el-button
v-if="scope.row.user_status === '启用'"
type="text"
size="small"
@click="enableUser"
>禁用</el-button
>
<el-button
v-if="scope.row.user_status === '禁用'"
type="text"
size="small"
@click="disableUser"
>启用</el-button
>
</template>
</el-table-column>
</el-table> </el-table>
<page :totalNum="totalNum" @update="update" /> <page
:totalNum="totalNum"
:pageSize="pageParams.size"
@update="updatePage"
/>
</div> </div>
<user-info-modal :data="curUserInfo" :visable="modalVisable.info"></user-info-modal>
<user-info-edit-modal :data="curUserInfo" :visable="modalVisable.edit" :mode="curOperateMode" @confirm="confirmEditModal" @cancel="cancelEditModal"></user-info-edit-modal>
</layout> </layout>
</template> </template>
<script> <script>
import Layout from '@/layouts' import Layout from "@/layouts";
import page from "@/components/Pagination" import page from "@/components/Pagination";
import UserInfoModal from './components/UserInfoModal';
import UserInfoEditModal from './components/UserInfoEditModal';
import { ElMessage } from "element-plus";
import {
getUserList as reqGetUserList,
getUserDetail as reqGetUserDetail,
editUser as reqEditUser,
createUser as reqCreateUser
} from "@/service/user";
export default { export default {
components: { components: {
Layout, Layout,
page page,
UserInfoModal,
UserInfoEditModal
}, },
data () { data() {
return { return {
params: { pageParams: {
page: 1, page: 1,
pageSize: 10 size: 20,
user_name: "",
user_email: "",
user_mobile: "",
user_status: "",
}, },
totalNum: 1000, totalNum: 0,
lifeList: [], userList: [],
tableData: [{ curUserInfo: {},
id: '001', modalVisable: {
date: '2016-05-02', info: false,
name: '王小虎', edit: false,
address: '上海市普陀区金沙江路 1518 弄' },
}, { curOperateMode: 'new'
id: '002', };
date: '2016-05-04', },
name: '王小虎', computed: {
address: '上海市普陀区金沙江路 1517 弄' renderUserList() {
}, { const statusMap = new Map([
id: '003', [1, "启用"],
date: '2016-05-01', [2, "禁用"],
name: '王小虎', [3, "删除"],
address: '上海市普陀区金沙江路 1519 弄' ]);
}, { return this.userList.map((ele) => {
id: '004', ele.user_status = statusMap.get(ele.user_status);
date: '2016-05-03', return ele;
name: '王小虎', });
address: '上海市普陀区金沙江路 1516 弄' },
}], },
formInline: { beforeMount() {
user: '', this.getUserList();
region: ''
}
}
}, },
methods: { methods: {
//查询 async getUserList() {
onSearchSubmit () { const { code, result } = await reqGetUserList(this.pageParams);
console.log(this.formInline.user, this.formInline.region, 'submit!');
if (code !== 0) {
ElMessage.error("获取用户列表出错!");
return;
}
const { data, count } = result;
this.totalNum = count;
this.userList = data;
}, },
//重置
onReset () { async setCurUserInfo(user_id) {
this.formInline.user = "", const { code, result } = await reqGetUserDetail({ user_id });
this.formInline.region = "" if (code === 0) {
this.curUserInfo = {
...result.user_info,
roles: result.role_list
}
} else {
ElMessage.error("获取用户信息出错!");
}
}, },
update (obj) {
Object.assign(this.params, obj) async checkUser(row) {
this.getlifeNoList(this.params) const { user_id } = row;
await this.setCurUserInfo(user_id);
this.openModal('info')
}, },
toLifeDetail (row) {
// this.$router.push({ path: lifeNoDetail }) async editUser(row) {
console.log(row.id, 'eee去详情') const { user_id } = row;
await this.setCurUserInfo(user_id);
console.log(988888, this.curUserInfo)
// this.openModal('edit');
this.modalVisable.edit = true;
this.curOperateMode = 'edit';
}, },
//获取列表数据
getlifeNoList () { openModal(key) {
Object.keys(this.modalVisable).forEach(ele => {
this.modalVisable[ele] = (key === ele);
});
console.log(3456675767, this.modalVisable);
},
confirmEditModal(userInfo) {
// this.curOperateMode
console.log('confirmEditModal:::::', userInfo);
if (this.curOperateMode === 'edit') {
reqEditUser()
} else if (this.curOperateMode === 'new') {
reqCreateUser()
}
},
cancelEditModal() {
},
//重置
onReset() {
this.pageParams = {
page: 1,
pageSize: 20,
user_name: "",
user_email: "",
user_mobile: "",
user_status: "",
};
},
updatePage({ page, pageSize }) {
page && (this.pageParams.page = page);
pageSize && (this.pageParams.pageSize = pageSize);
this.getUserList();
},
enableUser() {
} }
} },
} };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.life-no { .user {
margin: 30px; padding: 50px;
.search_life { .search_life {
width: 280px; width: 280px;
} }
.func-btn {
float: right;
}
} }
</style> </style>
...@@ -7,8 +7,9 @@ import Establish from '@/pages/Enterprise/Establish' ...@@ -7,8 +7,9 @@ import Establish from '@/pages/Enterprise/Establish'
import LifeNo from '../pages/Life-no/index.vue' import LifeNo from '../pages/Life-no/index.vue'
import LifeNoDetail from '../pages/Life-no/life-no-detail.vue' import LifeNoDetail from '../pages/Life-no/life-no-detail.vue'
// import User from '../pages/User/userList' import User from '../pages/User/userList'
import UserDetail from '../pages/User/user-detail.vue' import UserDetail from '../pages/User/user-detail.vue'
import AddRole from '../pages/Role/add-role.vue' import AddRole from '../pages/Role/add-role.vue'
import ManageRole from '../pages/Role/manage-role.vue' import ManageRole from '../pages/Role/manage-role.vue'
...@@ -27,6 +28,11 @@ const routes = [ ...@@ -27,6 +28,11 @@ const routes = [
name: 'Forbidden', name: 'Forbidden',
component: () => import(/* webpackChunkName: "enterprise" */ '@/pages/Catch/forbidden'), component: () => import(/* webpackChunkName: "enterprise" */ '@/pages/Catch/forbidden'),
}, },
{
path: '/demoImgUploader',
name: 'demoImgUploader',
component: () => import(/* webpackChunkName: "enterprise" */ '@/pages/DemoImageUpload'),
},
{ {
path: '/enterprise/certification', path: '/enterprise/certification',
name: 'Certification', name: 'Certification',
...@@ -63,6 +69,11 @@ const routes = [ ...@@ -63,6 +69,11 @@ const routes = [
component: LifeNoDetail, component: LifeNoDetail,
}, },
//用户管理 //用户管理
{
path: '/user',
name: 'User',
component: User,
},
{ {
path: '/userDetail', path: '/userDetail',
name: 'UserDetail', name: 'UserDetail',
......
import axios from '../utils/request';
export async function getImgId() {
const res = await axios.get("/api/v1/image/get_image_id")
return res;
}
export async function getImgBucket() {
const res = await axios.get("/api/v1/image/get_bucket")
return res;
}
export async function getImgToken() {
const res = await axios.get("/api/v1/image/get_token")
return res;
}
export async function uploadImageToKs3(file) {
const formData = new FormData();
formData.append("file", file);
const res = await axios.post("/api/v1/image/upload_ks3_image", formData)
return res;
}
export async function getKs3Config() {
const res = await axios.get("/api/v1/image/get_ks3_config")
return res;
}
\ No newline at end of file
import { getKs3Config } from "@/service/image";
import { KS3_CONST } from "@/config/constant";
import axios from '../utils/request';
// async function getRemoteConfig() {
// const imgId = await getImgId();
// const bucket = await getImgBucket();
// return {imgId, bucket}
// }
// const protocal = window.location.protocol === 'https:' ? 'https' : 'http';
// const { imgId, bucket } = await getRemoteConfig();
export async function ksOssUpload(file) {
const {bucket, objectId, policy, signature} = await getKs3Config();
const protocal = window.location.protocol === 'https:' ? 'https' : 'http';
const uploadURL = `${protocal}://${KS3_CONST.DOMAIN}/${bucket}`;
// return new Promise((resolve, reject) => {
// CommonServer.getKsOssSign().then(res => {
// const { accessid, policy, signature } = res
const formData = new FormData()
formData.append('acl', 'public-read')
formData.append('key', objectId)
formData.append('signature', signature)
formData.append('KSSAccessKeyId', KS3_CONST.AccessKeyID)
formData.append('policy', policy)
formData.append('file', file)
const res = await axios.post(uploadURL, formData).then(res => {
console.log(66666 ,res)
// const { status } = res
// if (status === 200) {
// const data = {
// url: `${OSS_URL}/${key}`,
// type: fileType(file.name)
// }
// resolve(data)
// } else {
// reject(res)
// }
})
// .catch(err => {
// reject(err)
// })
return res;
// }).catch(err => {})
// })
}
\ No newline at end of file
...@@ -15,3 +15,19 @@ export async function getPermissions (email) { ...@@ -15,3 +15,19 @@ export async function getPermissions (email) {
console.log("fe service, getPermissions:::", email) console.log("fe service, getPermissions:::", email)
return await axios.get("/api/v1/user/get_permissions", { params: { email } }); return await axios.get("/api/v1/user/get_permissions", { params: { email } });
} }
export async function getUserList (params) {
return await axios.get("/api/v1/users", { params });
}
export async function getUserDetail (params) {
return await axios.get("/api/v1/users/detail", { params });
}
export async function editUser (data) {
return await axios.post("/api/v1/users/edit", { data });
}
export async function createUser (data) {
return await axios.post("/api/v1/users/new", { data });
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* axios封装 * axios封装
*/ */
import axios from "axios"; import axios from "axios";
import store from "@/store"
// import { ElMessage } from "element-plus"; // import { ElMessage } from "element-plus";
// import { APP_URI } from "../config/app.config"; // import { APP_URI } from "../config/app.config";
/** /**
...@@ -29,8 +30,12 @@ export const defaultConfig = { ...@@ -29,8 +30,12 @@ export const defaultConfig = {
* default params * default params
* @returns {} * @returns {}
*/ */
const getDefaultParams = () => { }; const getDefaultParams = () => {
const getDefaultHeaders = () => { }; return {
'op_cur_user': store.state.userInfo && store.state.userInfo.email
}
};
const getDefaultHeaders = () => {};
/** /**
* axios instance * axios instance
......
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