diff --git a/config/env/torrents.js b/config/env/torrents.js index e7f397be..ef1863a6 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -808,7 +808,8 @@ module.exports = { backupFilesListPerPage: 15, torrentPeersListPerPage: 15, homeOrderTorrentListPerType: 9, - homeNewestTorrentListPerType: 14 + homeNewestTorrentListPerType: 14, + uploaderUserListPerPage: 15 }, /** diff --git a/modules/about/server/controllers/makers.server.controller.js b/modules/about/server/controllers/makers.server.controller.js index 5016f170..c47744d3 100644 --- a/modules/about/server/controllers/makers.server.controller.js +++ b/modules/about/server/controllers/makers.server.controller.js @@ -79,6 +79,7 @@ exports.update = function (req, res) { maker.name = req.body.name; maker.desc = req.body.desc; + maker.upload_access = req.body.upload_access; maker.save(function (err) { if (err) { diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index 7e4819cf..195ec59e 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -21,6 +21,7 @@ MENU_CHAT: 'Chat', MENU_TORRENTS: 'Torrents', MENU_TORRENTS_ADMIN: 'Manage Torrents', + MENU_UPLOADER_ADMIN: 'Manage Uploader', MENU_TORRENTS_ADMIN_EDAU: 'Announce Editor', MENU_ADMIN_OFFICIAL_INVITATION: 'Send official invitation', MENU_ADMIN_BACKUP: 'System Backup Files Database', @@ -183,6 +184,7 @@ ADMIN_USER_UPLIST: 'User uploaded list', USER_INFO: 'User Info', ADMIN_TORRENTS_LIST: 'Torrents List', + ADMIN_UPLOADER_LIST: 'Uploader List', ADMIN_ANNOUNCE_EDIT: 'Announce Editor', ADMIN_MESSAGES: 'System Messages', ADMIN_TRACES_LIST: 'Traces List', @@ -506,6 +508,24 @@ ANNOUNCE_EDIT_TIP: 'Upload a torrent file,
automatic replacement Announce URL & Comment', ANNOUNCE_COMMENT: 'Announce Comment', + //uploader admin + UPLOADER: { + CAPTION_MAKER: 'Uploader - Maker Group', + CAPTION_USER: 'Uploader - User', + FIELDS_NAME: 'Name', + FIELDS_DISPLAY_NAME: 'DisplayName', + FIELDS_MAKER: 'Maker', + FIELDS_LEVEL: 'Level', + FIELDS_FOUNDER: 'Founder', + FIELDS_USER_COUNT: 'Users', + FIELDS_TORRENT_COUNT: 'Torrents', + FIELDS_VOTE: 'Votes', + FIELDS_UPLOAD_ACCESS: 'Upload Access', + FIELDS_REVIEW: 'review', + FIELDS_PASS: 'pass', + ACCESS_CHANGED_SUCCESSFULLY: 'Upload access changed successfully' + }, + //vip views VIP: { VIP_TITLE: 'VIP Club', diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index 8b191f5f..b9b589ef 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -21,6 +21,7 @@ MENU_CHAT: '聊天室', MENU_TORRENTS: '种子', MENU_TORRENTS_ADMIN: '种子管理', + MENU_UPLOADER_ADMIN: '上传权限管理', MENU_TORRENTS_ADMIN_EDAU: '种子修改器', MENU_ADMIN_OFFICIAL_INVITATION: '发送官方邀请', MENU_ADMIN_BACKUP: '系统备份文件管理', @@ -182,8 +183,9 @@ ADMIN_USER_WARNING: '用户正被警告', ADMIN_USER_UPLIST: '用户上传的种子', USER_INFO: '用户信息', - ADMIN_ANNOUNCE_EDIT: '种子修改器', ADMIN_TORRENTS_LIST: '种子管理', + ADMIN_UPLOADER_LIST: '上传权限列表', + ADMIN_ANNOUNCE_EDIT: '种子修改器', ADMIN_MESSAGES: '系统消息', ADMIN_TRACES_LIST: '系统日志', ADMIN_FORUMS_CONFIGURE: '论坛配置', @@ -506,6 +508,23 @@ ANNOUNCE_EDIT_TIP: '上传一个种子文件,
自动替换 Announce URLComment', ANNOUNCE_COMMENT: 'Announce Comment', + //uploader admin + UPLOADER: { + CAPTION_MAKER: '资源制作小组上传', + CAPTION_USER: '用户上传', + FIELDS_NAME: '名称', + FIELDS_DISPLAY_NAME: '用户昵称', + FIELDS_MAKER: '资源组', + FIELDS_LEVEL: '用户等级', + FIELDS_FOUNDER: '创建者', + FIELDS_USER_COUNT: '成员数', + FIELDS_TORRENT_COUNT: '种子数', + FIELDS_VOTE: '评分', + FIELDS_UPLOAD_ACCESS: '上传权限', + FIELDS_REVIEW: '需要审核', + FIELDS_PASS: '直接通过' + }, + //vip views VIP: { VIP_TITLE: 'VIP 会员', diff --git a/modules/core/client/less/mt.less b/modules/core/client/less/mt.less index b9ddfff6..0d5cf955 100644 --- a/modules/core/client/less/mt.less +++ b/modules/core/client/less/mt.less @@ -713,6 +713,10 @@ body { } } +.control-small-height { + height: 24px !important; +} + .panel-body { dl { margin-bottom: 0; @@ -744,6 +748,24 @@ body { } .tb-v-middle { + &.top-border { + > thead { + > tr { + > th { + border-top: 2px solid #ddd !important; + } + } + } + } + &.bottom-border { + > tbody { + > tr:last-child { + > td { + border-bottom: 2px solid #ddd !important; + } + } + } + } > thead, > tbody { > tr { diff --git a/modules/torrents/client/config/admin/torrents-admin.client.menu.js b/modules/torrents/client/config/admin/torrents-admin.client.menu.js index 78af27c7..ff0d1566 100644 --- a/modules/torrents/client/config/admin/torrents-admin.client.menu.js +++ b/modules/torrents/client/config/admin/torrents-admin.client.menu.js @@ -14,6 +14,12 @@ state: 'admin.torrents', position: 1 }); + menuService.addSubMenuItem('topbar', 'admin', { + title: 'MENU_UPLOADER_ADMIN', + state: 'admin.uploader', + roles: ['admin'], + position: 2 + }); menuService.addSubMenuItem('topbar', 'admin', { title: 'MENU_TORRENTS_ADMIN_EDAU', diff --git a/modules/torrents/client/config/admin/torrents-admin.client.routes.js b/modules/torrents/client/config/admin/torrents-admin.client.routes.js index bcd68d51..6fb12659 100644 --- a/modules/torrents/client/config/admin/torrents-admin.client.routes.js +++ b/modules/torrents/client/config/admin/torrents-admin.client.routes.js @@ -17,6 +17,13 @@ pageTitle: 'PAGETITLE.ADMIN_TORRENTS_LIST' } }) + .state('admin.uploader', { + url: '/uploader', + templateUrl: '/modules/torrents/client/views/admin/uploader-list.client.view.html', + data: { + pageTitle: 'PAGETITLE.ADMIN_UPLOADER_LIST' + } + }) .state('admin.announce', { url: '/announce', templateUrl: '/modules/torrents/client/views/admin/announce-edit.client.view.html', diff --git a/modules/torrents/client/controllers/admin/uploader-list.client.controller.js b/modules/torrents/client/controllers/admin/uploader-list.client.controller.js new file mode 100644 index 00000000..08bd829f --- /dev/null +++ b/modules/torrents/client/controllers/admin/uploader-list.client.controller.js @@ -0,0 +1,115 @@ +(function () { + 'use strict'; + + angular + .module('torrents') + .controller('UploaderAdminController', UploaderAdminController); + + UploaderAdminController.$inject = ['$scope', '$state', '$translate', '$timeout', 'Authentication', 'Notification', 'MakerGroupService', + 'MeanTorrentConfig', 'AdminService', '$window', 'ModalConfirmService', 'NotifycationService', 'DebugConsoleService', 'TorrentGetInfoServices', + 'ResourcesTagsServices', 'localStorageService' + ]; + + function UploaderAdminController($scope, $state, $translate, $timeout, Authentication, Notification, MakerGroupService, MeanTorrentConfig, + AdminService, $window, ModalConfirmService, NotifycationService, mtDebug, TorrentGetInfoServices, + ResourcesTagsServices, localStorageService) { + var vm = this; + vm.user = Authentication.user; + vm.TGI = TorrentGetInfoServices; + vm.itemsPerPageConfig = MeanTorrentConfig.meanTorrentConfig.itemsPerPage; + + /** + * init + */ + vm.init = function () { + vm.getUploadByMaker(); + vm.buildUploadUserPager(); + }; + + /** + * getUploadByMaker + */ + vm.getUploadByMaker = function () { + MakerGroupService.query(function (data) { + vm.uploadMakerList = data; + mtDebug.info(data); + }); + }; + + /** + * buildPager + */ + vm.buildUploadUserPager = function () { + vm.pagedItems = []; + vm.itemsPerPage = vm.itemsPerPageConfig.uploaderUserListPerPage; + vm.currentPage = 1; + vm.figureOutItemsToDisplay(); + }; + + /** + * figureOutItemsToDisplay + * @param callback + */ + vm.figureOutItemsToDisplay = function (callback) { + vm.getUploadByUser(vm.currentPage, function (items) { + vm.filterLength = items.total; + vm.pagedItems = items.rows; + + if (callback) callback(); + }); + }; + + /** + * getUploadByUser + */ + vm.getUploadByUser = function (p, callback) { + AdminService.getUploaderList({ + skip: (p - 1) * vm.itemsPerPage, + limit: vm.itemsPerPage + }) + .then(onSuccess); + + function onSuccess(data) { + mtDebug.info(data); + callback(data); + } + }; + + /** + * pageChanged + */ + vm.pageChanged = function () { + var element = angular.element('#top_of_user_list'); + + vm.figureOutItemsToDisplay(function () { + $timeout(function () { + $('html,body').animate({scrollTop: element[0].offsetTop - 60}, 200); + }, 10); + }); + }; + + /** + * onUploaderMakerAccessChanged + * @param m + */ + vm.onUploaderMakerAccessChanged = function (m) { + m.$update(function (res) { + vm.uploadMakerList[vm.uploadMakerList.indexOf(m)] = res; + NotifycationService.showSuccessNotify('UPLOADER.ACCESS_CHANGED_SUCCESSFULLY'); + }); + }; + + /** + * onUploaderUserAccessChanged + * @param u + */ + vm.onUploaderUserAccessChanged = function (u) { + var user = new AdminService(u); + user.$update(function (res) { + console.log(res); + vm.pagedItems[vm.pagedItems.indexOf(u)] = res; + NotifycationService.showSuccessNotify('UPLOADER.ACCESS_CHANGED_SUCCESSFULLY'); + }); + }; + } +}()); diff --git a/modules/torrents/client/views/admin/uploader-list.client.view.html b/modules/torrents/client/views/admin/uploader-list.client.view.html new file mode 100644 index 00000000..ae8359ed --- /dev/null +++ b/modules/torrents/client/views/admin/uploader-list.client.view.html @@ -0,0 +1,116 @@ +
+
+
+

+ {{'UPLOADER.CAPTION_MAKER' | translate}} +

+ +
+ + + + + + + + + + + + + + + + + + + + + +
{{ 'UPLOADER.FIELDS_NAME' | translate}}{{ 'UPLOADER.FIELDS_FOUNDER' | translate}}{{ 'UPLOADER.FIELDS_USER_COUNT' | translate}}{{ 'UPLOADER.FIELDS_TORRENT_COUNT' | translate}}{{ 'UPLOADER.FIELDS_VOTE' | translate}}{{ 'UPLOADER.FIELDS_UPLOAD_ACCESS' | translate}}
+ + + + + {{m.members.length}} + + {{m.torrent_count}} + + {{vm.TGI.getVoteTitle()}} {{m.vote_average | number : 1}} / {{m.vote_count}} {{ 'TMDB_FIELDS.VOTE_UNIT' | translate}} + + +
+
+
+ +
+

+ {{'UPLOADER.CAPTION_USER' | translate}} +

+ +
    +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
{{ 'UPLOADER.FIELDS_DISPLAY_NAME' | translate}}{{ 'UPLOADER.FIELDS_LEVEL' | translate}}{{ 'UPLOADER.FIELDS_MAKER' | translate}}{{ 'UPLOADER.FIELDS_TORRENT_COUNT' | translate}}{{ 'UPLOADER.FIELDS_UPLOAD_ACCESS' | translate}}
+ + + + + + + + + + + + {{u.uptotal}} + + +
+
+ +
    +
+
+
+
diff --git a/modules/users/client/controllers/admin/list-users.client.controller.js b/modules/users/client/controllers/admin/list-users.client.controller.js index 923ca765..04c1b237 100644 --- a/modules/users/client/controllers/admin/list-users.client.controller.js +++ b/modules/users/client/controllers/admin/list-users.client.controller.js @@ -18,6 +18,7 @@ vm.searchAdmin = false; vm.searchOper = false; vm.userStatus = 'all'; + /** * buildPager */ @@ -61,7 +62,6 @@ }); }; - /** * pageChanged */ diff --git a/modules/users/client/services/users.client.service.js b/modules/users/client/services/users.client.service.js index fa7243bb..a49a5b47 100644 --- a/modules/users/client/services/users.client.service.js +++ b/modules/users/client/services/users.client.service.js @@ -180,6 +180,10 @@ params: { userId: '@userId' } + }, + uploaderList: { + method: 'GET', + url: '/api/users/uploaderList' } }); @@ -210,6 +214,9 @@ }, resetVIPData: function (params) { return this.resetUserVIPData(params).$promise; + }, + getUploaderList: function (params) { + return this.uploaderList(params).$promise; } }); diff --git a/modules/users/client/views/admin/view-user.client.view.html b/modules/users/client/views/admin/view-user.client.view.html index a4419336..8f912fef 100644 --- a/modules/users/client/views/admin/view-user.client.view.html +++ b/modules/users/client/views/admin/view-user.client.view.html @@ -80,8 +80,8 @@
{{ 'STATUS_FIELD.MAKER' | translate}}:
- - {{m.name}} + + - diff --git a/modules/users/client/views/status/account.client.view.html b/modules/users/client/views/status/account.client.view.html index 3ed0cb8c..36901762 100644 --- a/modules/users/client/views/status/account.client.view.html +++ b/modules/users/client/views/status/account.client.view.html @@ -52,8 +52,8 @@
{{ 'STATUS_FIELD.MAKER' | translate}}:
- - {{m.name}} + + -
diff --git a/modules/users/client/views/userinfo/userinfo.client.view.html b/modules/users/client/views/userinfo/userinfo.client.view.html index b44962a6..ca8ce5f0 100644 --- a/modules/users/client/views/userinfo/userinfo.client.view.html +++ b/modules/users/client/views/userinfo/userinfo.client.view.html @@ -51,9 +51,9 @@
{{ 'STATUS_FIELD.MAKER' | translate}}:
- - {{m.name}} - + + + -
diff --git a/modules/users/server/controllers/admin.server.controller.js b/modules/users/server/controllers/admin.server.controller.js index 836b069d..9367e2e3 100644 --- a/modules/users/server/controllers/admin.server.controller.js +++ b/modules/users/server/controllers/admin.server.controller.js @@ -39,6 +39,7 @@ exports.update = function (req, res) { user.lastName = req.body.lastName; user.displayName = user.firstName + ' ' + user.lastName; user.roles = req.body.roles; + user.upload_access = req.body.upload_access; user.save(function (err) { if (err) { @@ -384,6 +385,61 @@ exports.addVIPMonths = function (req, res) { } }; +/** + * uploaderList + * @param req + * @param res + */ +exports.uploaderList = function (req, res) { + var skip = 0; + var limit = 0; + + if (req.query.skip !== undefined) { + skip = parseInt(req.query.skip, 10); + } + if (req.query.limit !== undefined) { + limit = parseInt(req.query.limit, 10); + } + + var countQuery = function (callback) { + User.count({ + uptotal: {$gt: 0} + }, function (err, count) { + if (err) { + callback(err, null); + } else { + callback(null, count); + } + }); + }; + + var findQuery = function (callback) { + User.find({ + uptotal: {$gt: 0} + }, '-salt -password -providerData') + .sort('-uptotal') + .populate('makers', 'name') + .skip(skip) + .limit(limit) + .exec(function (err, users) { + if (err) { + callback(err, null); + } else { + callback(null, users); + } + }); + }; + + async.parallel([countQuery, findQuery], function (err, results) { + if (err) { + mtDebug.debugRed(err); + return res.status(422).send(err); + } else { + res.json({rows: results[1], total: results[0]}); + } + }); +}; + /** * resetVIPData * @param req diff --git a/modules/users/server/policies/admin.server.policy.js b/modules/users/server/policies/admin.server.policy.js index b5859830..cd234221 100644 --- a/modules/users/server/policies/admin.server.policy.js +++ b/modules/users/server/policies/admin.server.policy.js @@ -17,6 +17,7 @@ exports.invokeRolesPolicies = function () { { roles: ['admin'], allows: [ + {resources: '/api/users/uploaderList', permissions: '*'}, {resources: '/api/users/:userId/role', permissions: '*'}, {resources: '/api/users/:userId/VIPMonths/:months', permissions: '*'}, {resources: '/api/users/:userId/VIPMonths/reset', permissions: '*'} diff --git a/modules/users/server/routes/admin.server.routes.js b/modules/users/server/routes/admin.server.routes.js index 12c7cb49..2bc61b72 100644 --- a/modules/users/server/routes/admin.server.routes.js +++ b/modules/users/server/routes/admin.server.routes.js @@ -10,6 +10,9 @@ module.exports = function (app) { // User route registration first. Ref: #713 require('./users.server.routes.js')(app); + app.route('/api/users/uploaderList') + .get(adminPolicy.isAllowed, admin.uploaderList); + // Users collection routes app.route('/api/users') .get(adminPolicy.isAllowed, admin.list);