From 6d1bb9039da8ea7a4762afd31345538804471156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A2=E4=B9=90=E9=A9=AC?= <38058090+SkywalkerSpace@users.noreply.github.com> Date: Fri, 17 May 2024 11:14:55 +0800 Subject: [PATCH] Subscription (#6069) * subscription api * subscription page * subscriptionAPI.js * buy quota * add currency icons --------- Co-authored-by: Michael An <2331806369@qq.com> --- frontend/config/webpack.entry.js | 1 + frontend/src/assets/icons/currency.svg | 1 + frontend/src/components/common/account.js | 7 + frontend/src/components/subscription.js | 523 ++++++++++++++++++ frontend/src/css/subscription.css | 230 ++++++++ frontend/src/pages/org-admin/index.js | 2 + .../src/pages/org-admin/org-subscription.js | 32 ++ frontend/src/pages/org-admin/side-panel.js | 11 +- frontend/src/subscription.js | 72 +++ frontend/src/utils/constants.js | 1 + frontend/src/utils/subscription-api.js | 61 ++ media/css/seahub_react.css | 1 + media/img/qr-sale.png | Bin 0 -> 97467 bytes seahub/api2/endpoints/admin/organizations.py | 30 + seahub/api2/endpoints/admin/users.py | 27 +- seahub/api2/endpoints/subscription.py | 132 +++++ seahub/api2/views.py | 3 +- .../organizations/org_admin_react.html | 2 + seahub/organizations/urls.py | 2 + seahub/organizations/views.py | 2 + seahub/settings.py | 1 + seahub/subscription/__init__.py | 0 seahub/subscription/settings.py | 10 + seahub/subscription/urls.py | 7 + seahub/subscription/utils.py | 90 +++ seahub/subscription/views.py | 91 +++ seahub/templates/base_for_react.html | 1 + seahub/templates/subscription/pay_result.html | 8 + .../subscription/subscription_react.html | 19 + seahub/urls.py | 15 +- 30 files changed, 1377 insertions(+), 5 deletions(-) create mode 100644 frontend/src/assets/icons/currency.svg create mode 100644 frontend/src/components/subscription.js create mode 100644 frontend/src/css/subscription.css create mode 100644 frontend/src/pages/org-admin/org-subscription.js create mode 100644 frontend/src/subscription.js create mode 100644 frontend/src/utils/subscription-api.js create mode 100644 media/img/qr-sale.png create mode 100644 seahub/api2/endpoints/subscription.py create mode 100644 seahub/subscription/__init__.py create mode 100644 seahub/subscription/settings.py create mode 100644 seahub/subscription/urls.py create mode 100644 seahub/subscription/utils.py create mode 100644 seahub/subscription/views.py create mode 100644 seahub/templates/subscription/pay_result.html create mode 100644 seahub/templates/subscription/subscription_react.html diff --git a/frontend/config/webpack.entry.js b/frontend/config/webpack.entry.js index 4f4b1eb78a6..9b88e763b90 100644 --- a/frontend/config/webpack.entry.js +++ b/frontend/config/webpack.entry.js @@ -38,6 +38,7 @@ const entryFiles = { sysAdmin: '/pages/sys-admin', search: '/pages/search', uploadLink: '/pages/upload-link', + subscription: '/subscription.js', }; const getEntries = (isEnvDevelopment) => { diff --git a/frontend/src/assets/icons/currency.svg b/frontend/src/assets/icons/currency.svg new file mode 100644 index 00000000000..23bc368565e --- /dev/null +++ b/frontend/src/assets/icons/currency.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/common/account.js b/frontend/src/components/common/account.js index 1f991c1b567..379e3d52250 100644 --- a/frontend/src/components/common/account.js +++ b/frontend/src/components/common/account.js @@ -6,6 +6,10 @@ import { seafileAPI } from '../../utils/seafile-api'; import { siteRoot, gettext, appAvatarURL, enableSSOToThirdpartWebsite } from '../../utils/constants'; import toaster from '../toast'; +const { + isOrgContext, +} = window.app.pageOptions; + const propTypes = { isAdminPanel: PropTypes.bool, }; @@ -22,6 +26,7 @@ class Account extends Component { isStaff: false, isOrgStaff: false, usageRate: '', + enableSubscription: false, }; this.isFirstMounted = true; } @@ -81,6 +86,7 @@ class Account extends Component { isInstAdmin: resp.data.is_inst_admin, isOrgStaff: resp.data.is_org_staff === 1 ? true : false, showInfo: !this.state.showInfo, + enableSubscription: resp.data.enable_subscription, }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); @@ -163,6 +169,7 @@ class Account extends Component { {gettext('Settings')} + {(this.state.enableSubscription && !isOrgContext) && {'付费管理'}} {this.renderMenu()} {enableSSOToThirdpartWebsite && {gettext('Customer Portal')}} {gettext('Log out')} diff --git a/frontend/src/components/subscription.js b/frontend/src/components/subscription.js new file mode 100644 index 00000000000..e1c00945bb0 --- /dev/null +++ b/frontend/src/components/subscription.js @@ -0,0 +1,523 @@ +import React, { Component, Fragment } from 'react'; +import PropTypes from 'prop-types'; +import toaster from './toast'; +import { Modal, ModalHeader, ModalBody, ModalFooter, InputGroup, InputGroupAddon, InputGroupText, Input, Button } from 'reactstrap'; +import { gettext, serviceURL } from '../utils/constants'; +import { Utils } from '../utils/utils'; +import { subscriptionAPI } from '../utils/subscription-api'; +import Loading from './loading'; + +import '../css/layout.css'; +import '../css/subscription.css'; + +const { + isOrgContext, +} = window.app.pageOptions; + + +const PlansPropTypes = { + plans: PropTypes.array.isRequired, + onPay: PropTypes.func.isRequired, + paymentType: PropTypes.string.isRequired, + handleContentScroll: PropTypes.func.isRequired, +}; + +class Plans extends Component { + constructor(props) { + super(props); + this.state = { + currentPlan: props.plans[0], + assetQuotaUnitCount: 1, + count: 1, + }; + } + + togglePlan = (plan) => { + this.setState({currentPlan: plan}, () => { + }); + }; + + onPay = () => { + let { paymentType } = this.props; + let { currentPlan, assetQuotaUnitCount, count } = this.state; + let totalAmount, assetQuota, newUserCount; + + // parse + if (paymentType === 'paid') { + newUserCount = currentPlan.count; + totalAmount = currentPlan.total_amount; + } else if (paymentType === 'extend_time') { + newUserCount = currentPlan.count; + assetQuota = currentPlan.asset_quota; + totalAmount = currentPlan.total_amount; + } else if (paymentType === 'add_user') { + newUserCount = count; + totalAmount = count * currentPlan.price_per_user; + } else if (paymentType === 'buy_quota') { + assetQuota = (assetQuotaUnitCount) * currentPlan.asset_quota_unit; + totalAmount = assetQuotaUnitCount * currentPlan.price_per_asset_quota_unit; + } else { + toaster.danger(gettext('Internal Server Error.')); + return; + } + + this.props.onPay(currentPlan.plan_id, newUserCount, assetQuota, totalAmount); + }; + + onCountInputChange = (e) => { + let { currentPlan } = this.state; + if (!currentPlan.can_custom_count) { + return; + } + let count = e.target.value.replace(/^(0+)|[^\d]+/g, ''); + if (count < 1) { + count = 1; + } else if (count > 9999) { + count = 9999; + } + this.setState({count: count}); + }; + + onAssetQuotaUnitCountInputChange = (e) => { + let { currentPlan } = this.state; + if (!currentPlan.can_custom_asset_quota) { + return; + } + let count = e.target.value.replace(/^(0+)|[^\d]+/g, ''); + if (count < 1) { + count = 1; + } else if (count > 9999) { + count = 9999; + } + this.setState({assetQuotaUnitCount: count}); + }; + + renderPaidOrExtendTime = () => { + let { plans, paymentType } = this.props; + let { currentPlan } = this.state; + let boughtQuota = 0; + if (paymentType === 'extend_time') { + boughtQuota = currentPlan.asset_quota - 100; + } + let totalAmount = currentPlan.total_amount; + let originalTotalAmount = totalAmount; + return ( +
+ {'选择方案'} +
+ {plans.map((item, index) => { + let selectedCss = item.plan_id === currentPlan.plan_id ? 'plan-selected' : ''; + let countDescription = '¥' + item.price_per_user; + if (isOrgContext) { + countDescription += '/每用户'; + } + return ( +
+ {item.name} + {countDescription} +
+ ); + })} +
+ + {paymentType === 'extend_time' && boughtQuota > 0 && + + {'增加空间'} +
+
+ {currentPlan.asset_quota_unit + 'GB x ' + (boughtQuota / currentPlan.asset_quota_unit)} + {/* 续费时候需要减去附赠的100GB */} + {'¥' + (boughtQuota / currentPlan.asset_quota_unit) * currentPlan.price_per_asset_quota_unit} +
+
+
+ } + + {'方案汇总'} +
+
+
+ {'所选方案'} + {currentPlan.name} +
+ {isOrgContext && +
+ {'成员人数'} + {currentPlan.count + '人'} +
+ } +
+ {'可用空间'} + {'100GB(附赠)' + (boughtQuota > 0 ? '+' + boughtQuota + 'GB(扩充)' : '')} +
+
+ {'到期时间'} + {currentPlan.new_term_end} +
+
+ {'实际支付金额'} + + {originalTotalAmount !== totalAmount && + {'¥' + originalTotalAmount} + } + {'¥' + totalAmount + ' '} + +
+
+
+ +
+ ); + }; + + renderAddUser = () => { + let { currentPlan, count } = this.state; + let operationIntro = '新增用户'; + let originalTotalAmount = count * currentPlan.price_per_user; + let totalAmount = originalTotalAmount; + return ( +
+
+

{currentPlan.name}

+ + {'¥ '}{currentPlan.price}{' ' + currentPlan.description} + + + + {operationIntro} + + + + + {'总价 ¥ ' + totalAmount} + {originalTotalAmount !== totalAmount && + {' ¥' + originalTotalAmount} + } + + {'有效期至 ' + currentPlan.new_term_end} + {'注:当有效期剩余天数少于计划中的时候,增加用户的价格按天来计算'} + +
+ ); + }; + + renderBuyQuota = () => { + let { currentPlan, assetQuotaUnitCount } = this.state; + let operationIntro = '新增空间'; + let originalTotalAmount = assetQuotaUnitCount * currentPlan.price_per_asset_quota_unit; + let totalAmount = originalTotalAmount; + return ( +
+
+

{currentPlan.name}

+ + {'¥ '}{currentPlan.asset_quota_price}{' ' + currentPlan.asset_quota_description} + + + + {operationIntro} + + + + {' x ' + currentPlan.asset_quota_unit + 'GB'} + + + + {'总价 ¥ ' + totalAmount} + {originalTotalAmount !== totalAmount && + {' ¥' + originalTotalAmount} + } + + {'有效期至 ' + currentPlan.new_term_end} + {'注:当有效期剩余天数少于计划中的时候,增加空间的价格按天来计算'} + +
+ ); + }; + + render() { + let { paymentType } = this.props; + if (paymentType === 'paid' || paymentType === 'extend_time') { + return this.renderPaidOrExtendTime(); + } else if (paymentType === 'add_user') { + return this.renderAddUser(); + } else if (paymentType === 'buy_quota') { + return this.renderBuyQuota(); + } else { + toaster.danger(gettext('Internal Server Error.')); + return; + } + } +} + +Plans.propTypes = PlansPropTypes; + +const PlansDialogPropTypes = { + isOrgContext: PropTypes.bool.isRequired, + paymentType: PropTypes.string.isRequired, + paymentTypeTrans: PropTypes.string.isRequired, + toggleDialog: PropTypes.func.isRequired, +}; + +class PlansDialog extends Component { + + constructor(props) { + super(props); + this.state = { + isLoading: true, + isWaiting: false, + planList: [], + paymentSourceList: [], + }; + } + + getPlans = () => { + subscriptionAPI.getSubscriptionPlans(this.props.paymentType).then((res) => { + this.setState({ + planList: res.data.plan_list, + paymentSourceList: res.data.payment_source_list, + isLoading: false, + }); + }).catch(error => { + let errorMsg = Utils.getErrorMsg(error); + this.setState({ + isLoading: false, + errorMsg: errorMsg, + }); + }); + }; + + onPay = (planID, count, asset_quota, totalAmount) => { + this.setState({ isWaiting: true }); + let payUrl = serviceURL + '/subscription/pay/?payment_source=' + this.state.paymentSourceList[0] + + '&payment_type=' + this.props.paymentType + '&plan_id=' + planID + + '&total_amount=' + totalAmount; + if (count) { + payUrl += '&count=' + count; + } + if (asset_quota) { + payUrl += '&asset_quota=' + asset_quota; + } + window.open(payUrl); + }; + + onReload = () => { + window.location.reload(); + }; + + componentDidMount() { + this.getPlans(); + } + + render() { + const { isLoading, isWaiting, planList } = this.state; + const { toggleDialog, paymentTypeTrans, paymentType } = this.props; + const modalStyle = (paymentType === 'paid' || paymentType === 'extend_time') ? + {width: '560px', maxWidth: '560px'} : {width: '560px'}; + + if (isLoading) { + return ( + + {paymentTypeTrans} + + + + + ); + } + if (isWaiting) { + return ( + + {paymentTypeTrans} + +
{'是否完成付款?'}
+
+ + + +
+ ); + } + return ( + + {paymentTypeTrans} + +
+ +
+
+
+ ); + } +} + +PlansDialog.propTypes = PlansDialogPropTypes; + +const propTypes = { + isOrgContext: PropTypes.bool.isRequired, + handleContentScroll: PropTypes.func, +}; + +class Subscription extends Component { + + constructor(props) { + super(props); + this.paymentTypeTransMap = { + paid: '立即购买', + extend_time: '立即续费', + add_user: '增加用户', + buy_quota: '增加空间', + }; + this.state = { + isLoading: true, + errorMsg: '', + isDialogOpen: false, + planName: this.props.isOrgContext ? '团队版' : '个人版', + userLimit: 20, + assetQuota: 1, + termEnd: '长期', + subscription: null, + paymentTypeList: [], + currentPaymentType: '', + errorMsgCode: '' + }; + } + + getSubscription = () => { + subscriptionAPI.getSubscription().then((res) => { + const subscription = res.data.subscription; + const paymentTypeList = res.data.payment_type_list; + if (!subscription) { + this.setState({ + isLoading: false, + paymentTypeList: paymentTypeList, + }); + } else { + let isActive = subscription.is_active; + let plan = subscription.plan; + this.setState({ + isLoading: false, + subscription, + planName: plan.name, + userLimit: subscription.user_limit, + assetQuota: isActive ? subscription.asset_quota : plan.asset_quota, + termEnd: isActive ? subscription.term_end : '已过期', + paymentTypeList: paymentTypeList, + }); + } + }).catch(error => { + let errorMsg = Utils.getErrorMsg(error); + this.setState({ + isLoading: false, + errorMsg: errorMsg, + }); + }); + }; + + toggleDialog = () => { + this.setState({ isDialogOpen: !this.state.isDialogOpen }); + }; + + togglePaymentType = (paymentType) => { + this.setState({ currentPaymentType: paymentType }); + this.toggleDialog(); + }; + + componentDidMount() { + this.getSubscription(); + } + + render() { + const { isLoading, errorMsg, planName, userLimit, assetQuota, termEnd, + isDialogOpen, paymentTypeList, currentPaymentType } = this.state; + if (isLoading) { + return ; + } + if (errorMsg) { + return

{errorMsg}

; + } + return ( + +
+
+

{'当前版本'}

+

{planName}

+
+ {this.props.isOrgContext && +
+

{'用户数限制'}

+

{userLimit}

+
+ } +
+

{'空间'}

+

{assetQuota ? assetQuota + 'GB' : '1GB'}

+
+
+

{'订阅有效期'}

+

{termEnd}

+
+
+

{'云服务付费方案'}

+

+ {'查看详情'} +

+
+ {paymentTypeList.map((item, index) => { + let name = this.paymentTypeTransMap[item]; + return ( + + ); + })} + {!this.state.subscription && +
+

{'销售咨询'}

+ +

{'微信扫码联系销售'}

+
+ } +
+ {isDialogOpen && + + } +
+ ); + } +} + +Subscription.propTypes = propTypes; + +export default Subscription; diff --git a/frontend/src/css/subscription.css b/frontend/src/css/subscription.css new file mode 100644 index 00000000000..7b02a0d57a2 --- /dev/null +++ b/frontend/src/css/subscription.css @@ -0,0 +1,230 @@ +.content { + padding: 0rem 1rem 8rem; + overflow: auto; + } + + .content .dropdown .btn-outline-primary { + color: #f19645; + background-color: transparent; + background-image: none; + border-color: #f19645; + } + + .content .dropdown .btn-outline-primary:hover { + color: #fff; + background-color: #f19645; + border-color: #f19645; + } + + .content .dropdown .btn-outline-primary:focus { + box-shadow: 0 0 0 2px rgba(241, 150, 69, 0.5); + } + + .content .dropdown .btn-outline-primary:active { + color: #fff; + background-color: #f19645; + border-color: #f19645; + } + + .content .dropdown .btn-outline-primary:not(:disabled):not(.disabled):active:focus, + .content .dropdown .btn-outline-primary:not(:disabled):not(.disabled).active:focus, + .content .dropdown .show > .btn-outline-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 2px rgba(241, 150, 69, 0.5); + } + + .subscription-info { + margin: 1em 0 3em; + } + + .subscription-info-heading { + font-size: 1rem; + font-weight: normal; + padding-bottom: 0.2em; + border-bottom: 1px solid #ddd; + margin-bottom: 0.7em; + } + + .price-version-container-header { + max-width: 90%; + border-radius: 10px; + padding: 0 1rem 2rem; + box-shadow: 0 3px 8px 3px rgba(116, 129, 141, 0.15); + overflow: hidden; + margin: 0.5rem 1rem; + } + + .price-version-container-header .price-version-container-top { + height: 10px; + margin: 0 -1rem; + } + + .price-version-container-header .price-version-plan-name { + font-size: 1.5rem; + padding: 1rem 0; + border-bottom: 1px solid #ED7109; + } + + .price-version-container-header .price-table-btn-details { + color: #fff; + font-size: 1rem; + } + + .price-version-container-header .font-500 { + font-weight: 500; + } + + .price-version-container-header .price-version-plan-price { + font-size: 2rem; + } + + .price-version-container-header .price-version-plan-whole-price { + font-size: 24px; + } + + .price-version-container-header .price-version-plan-valid-day, + .price-version-container-header .price-version-plan-user-number { + font-size: 18px; + } + + .subscription-container { + width: 480px; + margin: 0.5rem auto; + } + + .price-version-container-header .user-quota-plan-name { + margin-bottom: 24px; + text-align: center; + border-bottom: 1px solid rgba(253, 150, 68, 0.4); + } + + .subscription-container .items-dl { + margin-top: 10px; + } + + .plan-description-item { + border: 1px solid #bdbdbd; + border-radius: 5px; + margin: 0 0 10px; + display: flex; + justify-content: space-between; + background-color: #f9f9f9; + line-height: 3; + padding: 0 20px; + cursor: pointer; + } + + .plan-description-item.plan-selected { + background-color: #fff5eb; + border-color: #ED7109; + border-width: 2px; + } + + .plan-description-item .plan-name { + font-size: 20px; + font-weight: 500; + } + + .plan-description-item .plan-description { + font-size: 20px; + font-weight: 500; + color: #ED7109; + } + + .order-item { + margin: 0px; + display: flex; + justify-content: space-between; + border-left: 1px solid #bdbdbd; + border-right: 1px solid #bdbdbd; + background-color: #f9f9f9; + padding: 5px 20px; + line-height: 2; + } + + .order-item.order-item-top { + border-top: 1px solid #bdbdbd; + border-radius: 5px 5px 0 0; + } + + .order-item.order-item-middle { + border-bottom: 1px solid #bdbdbd; + } + + .order-item.order-item-bottom { + border-bottom: 1px solid #bdbdbd; + border-radius: 0 0 5px 5px; + } + + .order-item .order-into { + color: #666666; + } + + .order-item .order-value { + font-weight: 500; + color: #000; + } + + .order-item .order-value .input-group-append, + .order-item .order-value .input-group-prepend { + height: 38px; + } + + .order-item .order-price { + font-size: 26px; + font-weight: 500; + color: #ED7109; + } + + .order-item .order-price span:first-child { + font-size: 16px; + } + + .subscription-submit { + background-color: #ED7109; + border-radius: 5px; + width: 100%; + margin-bottom: 10px; + color: white; + height: 44px; + font-size: 16px; + } + + .subscription-notice { + font-size: 14px; + color: #9a9a9a; + } + + .subscription-container .subscription-subtitle { + font-size: 18px; + font-weight: 500; + } + + .subscription-container .subscription-list.order-item-top.order-item-bottom { + border-radius: 5px; + } + + .subscription-container .subscription-list span { + height: 36px; + line-height: 36px; + } + + .subscription-container .text-orange { + color: #ED7109 !important; + } + + .user-numbers.input-group .input-group-prepend { + width: 50%; + } + + .space-quota .input-group .input-group-append, + .space-quota .input-group .input-group-prepend { + width: 33.33%; + } + + .subscription-add-space .input-group .input-group-append .input-group-text, + .price-version-container-header .input-group .input-group-prepend .input-group-text { + width: 100%; + text-align: center; + font-weight: 500; + display: block; + } diff --git a/frontend/src/pages/org-admin/index.js b/frontend/src/pages/org-admin/index.js index 7ac17290e7d..e38f133fe31 100644 --- a/frontend/src/pages/org-admin/index.js +++ b/frontend/src/pages/org-admin/index.js @@ -36,6 +36,7 @@ import OrgLogsFileAudit from './org-logs-file-audit'; import OrgLogsFileUpdate from './org-logs-file-update'; import OrgLogsPermAudit from './org-logs-perm-audit'; import OrgSAMLConfig from './org-saml-config'; +import OrgSubscription from './org-subscription'; import '../../css/layout.css'; import '../../css/toolbar.css'; @@ -96,6 +97,7 @@ class Org extends React.Component { + diff --git a/frontend/src/pages/org-admin/org-subscription.js b/frontend/src/pages/org-admin/org-subscription.js new file mode 100644 index 00000000000..6006f585520 --- /dev/null +++ b/frontend/src/pages/org-admin/org-subscription.js @@ -0,0 +1,32 @@ +import React, { Component, Fragment } from 'react'; +import PropTypes from 'prop-types'; +import MainPanelTopbar from './main-panel-topbar'; +import Subscription from '../../components/subscription'; + +const propTypes = { + onCloseSidePanel: PropTypes.func, +}; + +class OrgSubscription extends Component { + render() { + return ( + + +
+
+
+

{'付费管理'}

+
+
+ +
+
+
+
+ ); + } +} + +OrgSubscription.propTypes = propTypes; + +export default OrgSubscription; diff --git a/frontend/src/pages/org-admin/side-panel.js b/frontend/src/pages/org-admin/side-panel.js index 0946548e6b5..b19273caffe 100644 --- a/frontend/src/pages/org-admin/side-panel.js +++ b/frontend/src/pages/org-admin/side-panel.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Link } from '@gatsbyjs/reach-router'; import Logo from '../../components/logo'; -import { gettext, siteRoot, enableMultiADFS } from '../../utils/constants'; +import Icon from '../../components/icon'; +import { gettext, siteRoot, enableSubscription, enableMultiADFS } from '../../utils/constants'; const propTypes = { isSidePanelClosed: PropTypes.bool.isRequired, @@ -80,6 +81,14 @@ class SidePanel extends React.Component { {gettext('Departments')} + {enableSubscription && +
  • + this.tabItemClick('subscription')} > + + {'付费管理'} + +
  • + }
  • this.tabItemClick('publinkadmin')} > diff --git a/frontend/src/subscription.js b/frontend/src/subscription.js new file mode 100644 index 00000000000..8c5177163d9 --- /dev/null +++ b/frontend/src/subscription.js @@ -0,0 +1,72 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; +import SideNav from './components/user-settings/side-nav'; +import Account from './components/common/account'; +import Notification from './components/common/notification'; +import Subscription from './components/subscription'; + +import './css/toolbar.css'; +import './css/search.css'; +import './css/user-settings.css'; + + +class UserSubscription extends React.Component { + + constructor(props) { + super(props); + this.sideNavItems = [ + { show: true, href: '#current-plan', text: '当前版本' }, + { show: true, href: '#asset-quota', text: '空间' }, + { show: true, href: '#current-subscription-period', text: '订阅有效期' }, + { show: true, href: '#product-price', text: '云服务付费方案' }, + ]; + this.state = { + curItemID: this.sideNavItems[0].href.substr(1), + }; + } + + handleContentScroll = (e) => { + // Mobile does not display the sideNav, so when scrolling don't update curItemID + const scrollTop = e.target.scrollTop; + const scrolled = this.sideNavItems.filter((item, index) => { + return item.show && document.getElementById(item.href.substr(1)).offsetTop - 45 < scrollTop; + }); + if (scrolled.length) { + this.setState({ + curItemID: scrolled[scrolled.length - 1].href.substr(1) + }); + } + }; + + render() { + let logoUrl = logoPath.startsWith('http') ? logoPath : mediaUrl + logoPath; + return ( +
    +
    + + logo + +
    + + +
    +
    +
    +
    + +
    +
    +

    {'付费管理'}

    + +
    +
    +
    + ); + } +} + +ReactDOM.render( + , + document.getElementById('wrapper') +); diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 3a461c64fa9..0bb26943f1f 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -140,6 +140,7 @@ export const orgEnableAdminCustomLogo = window.org ? window.org.pageOptions.orgE export const orgEnableAdminCustomName = window.org ? window.org.pageOptions.orgEnableAdminCustomName === 'True' : false; export const orgEnableAdminInviteUser = window.org ? window.org.pageOptions.orgEnableAdminInviteUser === 'True' : false; export const enableMultiADFS = window.org ? window.org.pageOptions.enableMultiADFS === 'True' : false; +export const enableSubscription = window.org ? window.org.pageOptions.enableSubscription : false; // sys admin export const constanceEnabled = window.sysadmin ? window.sysadmin.pageOptions.constance_enabled : ''; diff --git a/frontend/src/utils/subscription-api.js b/frontend/src/utils/subscription-api.js new file mode 100644 index 00000000000..9a45cd7a651 --- /dev/null +++ b/frontend/src/utils/subscription-api.js @@ -0,0 +1,61 @@ +import axios from 'axios'; +import cookie from 'react-cookies'; +import { siteRoot } from './constants'; + +class SubscriptionAPI { + + init({ server, username, password, token }) { + this.server = server; + this.username = username; + this.password = password; + this.token = token; //none + if (this.token && this.server) { + this.req = axios.create({ + baseURL: this.server, + headers: { 'Authorization': 'Token ' + this.token }, + }); + } + return this; + } + + initForSeahubUsage({ siteRoot, xcsrfHeaders }) { + if (siteRoot && siteRoot.charAt(siteRoot.length - 1) === '/') { + var server = siteRoot.substring(0, siteRoot.length - 1); + this.server = server; + } else { + this.server = siteRoot; + } + + this.req = axios.create({ + headers: { + 'X-CSRFToken': xcsrfHeaders, + } + }); + return this; + } + + getSubscription() { + const url = this.server + '/api/v2.1/subscription/'; + return this.req.get(url); + } + + getSubscriptionPlans(paymentType) { + const url = this.server + '/api/v2.1/subscription/plans/'; + let params = { + payment_type: paymentType, + }; + return this.req.get(url, { params: params }); + } + + getSubscriptionLogs() { + const url = this.server + '/api/v2.1/subscription/logs/'; + return this.req.get(url); + } + +} + +let subscriptionAPI = new SubscriptionAPI(); +let xcsrfHeaders = cookie.load('sfcsrftoken'); +subscriptionAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders }); + +export { subscriptionAPI }; diff --git a/media/css/seahub_react.css b/media/css/seahub_react.css index 648d24e7d48..cc819859d4d 100644 --- a/media/css/seahub_react.css +++ b/media/css/seahub_react.css @@ -668,6 +668,7 @@ a, a:hover { color: #ec8000; } color: #fff; } +.side-nav-con .seafile-multicolor-icon, .side-nav-con [class^="sf2-icon-"], .side-nav-con [class^="sf3-font-"], .side-nav-con [class^="fas"] { diff --git a/media/img/qr-sale.png b/media/img/qr-sale.png new file mode 100644 index 0000000000000000000000000000000000000000..e986c08b1c6c64f91a7f72bf157ff01ef2d9099f GIT binary patch literal 97467 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 n`~)jZN&R2wKT~l2zfbZ0b=zf$T-Jdh diff --git a/seahub/organizations/urls.py b/seahub/organizations/urls.py index 88b1ff52917..7cd2096eaf0 100644 --- a/seahub/organizations/urls.py +++ b/seahub/organizations/urls.py @@ -43,4 +43,6 @@ path('associate//', org_associate, name='org_associate'), path('samlconfig/', react_fake_view, name='saml_config'), + + re_path(r'^subscription/$', react_fake_view, name='org_subscription'), ] diff --git a/seahub/organizations/views.py b/seahub/organizations/views.py index d7dccc96724..a2fb49d4ed2 100644 --- a/seahub/organizations/views.py +++ b/seahub/organizations/views.py @@ -35,6 +35,7 @@ ORG_ENABLE_ADMIN_CUSTOM_LOGO, ORG_ENABLE_ADMIN_CUSTOM_NAME, \ ORG_ENABLE_ADMIN_INVITE_USER from seahub.organizations.utils import get_or_create_invitation_link +from seahub.subscription.utils import subscription_check # Get an instance of a logger logger = logging.getLogger(__name__) @@ -260,6 +261,7 @@ def react_fake_view(request, **kwargs): 'group_id': group_id, 'invitation_link': invitation_link, 'enable_multi_adfs': ENABLE_MULTI_ADFS, + 'enable_subscription': subscription_check(), }) @login_required diff --git a/seahub/settings.py b/seahub/settings.py index a42118e845d..815d4a568d2 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -277,6 +277,7 @@ 'seahub.krb5_auth', 'seahub.django_cas_ng', 'seahub.seadoc', + 'seahub.subscription', ] diff --git a/seahub/subscription/__init__.py b/seahub/subscription/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/seahub/subscription/settings.py b/seahub/subscription/settings.py new file mode 100644 index 00000000000..eacc941975f --- /dev/null +++ b/seahub/subscription/settings.py @@ -0,0 +1,10 @@ +from django.conf import settings + + +ENABLE_SUBSCRIPTION = getattr(settings, 'ENABLE_SUBSCRIPTION', False) +SUBSCRIPTION_SERVER_AUTH_KEY = getattr( + settings, 'SUBSCRIPTION_SERVER_AUTH_KEY', '') +SUBSCRIPTION_SERVER_URL = getattr( + settings, 'SUBSCRIPTION_SERVER_URL', '') + +SUBSCRIPTION_ORG_PREFIX = getattr(settings, 'SUBSCRIPTION_ORG_PREFIX', 'org_') diff --git a/seahub/subscription/urls.py b/seahub/subscription/urls.py new file mode 100644 index 00000000000..e6bf185ecd7 --- /dev/null +++ b/seahub/subscription/urls.py @@ -0,0 +1,7 @@ +from django.urls import re_path +from .views import subscription_view, subscription_pay_view + +urlpatterns = [ + re_path(r'^$', subscription_view, name="subscription"), + re_path(r'pay/$', subscription_pay_view, name="subscription-pay"), +] diff --git a/seahub/subscription/utils.py b/seahub/subscription/utils.py new file mode 100644 index 00000000000..f0aa0ecdc6d --- /dev/null +++ b/seahub/subscription/utils.py @@ -0,0 +1,90 @@ +import logging +import requests +from django.core.cache import cache + +from seahub.utils import normalize_cache_key +from seahub.utils import is_pro_version, is_org_context +from .settings import ENABLE_SUBSCRIPTION, SUBSCRIPTION_SERVER_AUTH_KEY, \ + SUBSCRIPTION_SERVER_URL, SUBSCRIPTION_ORG_PREFIX + +logger = logging.getLogger(__name__) + +SUBSCRIPTION_TOKEN_CACHE_KEY = 'SUBSCRIPTION_TOKEN' + + +def subscription_check(): + + if not is_pro_version() or not ENABLE_SUBSCRIPTION: + return False + + if not SUBSCRIPTION_SERVER_AUTH_KEY \ + or not SUBSCRIPTION_SERVER_URL: + logger.error('subscription relevant settings invalid.') + logger.error( + 'please check SUBSCRIPTION_SERVER_AUTH_KEY') + logger.error('SUBSCRIPTION_SERVER_URL: %s' % SUBSCRIPTION_SERVER_URL) + return False + + return True + + +def get_subscription_jwt_token(): + cache_key = normalize_cache_key(SUBSCRIPTION_TOKEN_CACHE_KEY) + jwt_token = cache.get(cache_key, None) + + if not jwt_token: + data = { + 'auth_key': SUBSCRIPTION_SERVER_AUTH_KEY, + } + url = SUBSCRIPTION_SERVER_URL.rstrip('/') + '/api/jwt-auth/' + response = requests.post(url, json=data) + if response.status_code >= 400: + raise ConnectionError(response.status_code, response.text) + + response_dic = response.json() + jwt_token = response_dic.get('token') + cache.set(cache_key, jwt_token, 3000) + + return jwt_token + + +def clear_subscription_jwt_token(): + cache_key = normalize_cache_key(SUBSCRIPTION_TOKEN_CACHE_KEY) + cache.set(cache_key, None) + + +def get_subscription_api_headers(): + jwt_token = get_subscription_jwt_token() + headers = { + 'Authorization': 'JWT ' + jwt_token, + 'Content-Type': 'application/json', + } + + return headers + + +def handler_subscription_api_response(response): + if response.status_code == 403: + clear_subscription_jwt_token() + response.status_code = 500 + + return response + + +def subscription_permission_check(request): + if is_org_context(request): + is_org_staff = request.user.org.is_staff + if not is_org_staff: + return False + + return True + + +def get_customer_id(request): + if is_org_context(request): + org_id = request.user.org.org_id + customer_id = SUBSCRIPTION_ORG_PREFIX + str(org_id) + else: + customer_id = request.user.username + + return customer_id diff --git a/seahub/subscription/views.py b/seahub/subscription/views.py new file mode 100644 index 00000000000..08b6bb8763c --- /dev/null +++ b/seahub/subscription/views.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012-2020 Seafile Ltd. +# encoding: utf-8 +import requests +import logging +from django.shortcuts import render +from django.utils.translation import gettext as _ +from django.http import HttpResponseRedirect + +from seahub.utils import render_error, is_org_context +from seahub.auth.decorators import login_required +from .utils import subscription_check, subscription_permission_check, \ + get_subscription_api_headers, get_customer_id, handler_subscription_api_response +from .settings import SUBSCRIPTION_SERVER_URL + +logger = logging.getLogger(__name__) + + +@login_required +def subscription_view(request): + """ + subscription + """ + if not subscription_check(): + return render_error(request, _('Feature is not enabled.')) + + if is_org_context(request): + return render_error(request, _('Permission denied.')) + + return_dict = {} + template = 'subscription/subscription_react.html' + return render(request, template, return_dict) + + +@login_required +def subscription_pay_view(request): + """ + subscription + """ + if not subscription_check(): + return render_error(request, _('Feature is not enabled.')) + + if not subscription_permission_check(request): + error_msg = _('Permission denied.') + return render_error(request, error_msg) + + plan_id = request.GET.get('plan_id') + payment_source = request.GET.get('payment_source') + payment_type = request.GET.get('payment_type') + count = request.GET.get('count') + asset_quota = request.GET.get('asset_quota') + total_amount = request.GET.get('total_amount') + + # main + try: + customer_id = get_customer_id(request) + headers = get_subscription_api_headers() + + data = { + 'customer_id': customer_id, + 'plan_id': plan_id, + 'payment_source': payment_source, + 'payment_type': payment_type, + 'total_amount': total_amount, + } + if count: + data['count'] = count + if asset_quota: + data['asset_quota'] = asset_quota + + url = SUBSCRIPTION_SERVER_URL.rstrip('/') + '/api/seafile/subscription/pay/' + response = requests.post(url, json=data, headers=headers) + response = handler_subscription_api_response(response) + response_dic = response.json() + if response.status_code >= 400: + error_msg = response_dic.get('error_msg') + if 'non_field_errors' in response_dic and response_dic['non_field_errors']: + error_msg = response_dic['non_field_errors'][0] + return render_error(request, error_msg) + + use_redirect_url = response_dic.get('use_redirect_url') + redirect_url = response_dic.get('redirect_url') + + if use_redirect_url and redirect_url: + return HttpResponseRedirect(redirect_url) + + if not use_redirect_url: + return render(request, 'subscription/pay_result.html', {'info': '支付成功'}) + except Exception as e: + logger.error(e) + error_msg = _('Internal Server Error') + return render_error(request, error_msg) diff --git a/seahub/templates/base_for_react.html b/seahub/templates/base_for_react.html index c79d6b088da..952c0fc9065 100644 --- a/seahub/templates/base_for_react.html +++ b/seahub/templates/base_for_react.html @@ -147,6 +147,7 @@ enableSeafileAI: {% if enable_seafile_ai %} true {% else %} false {% endif %}, canSetExProps: {% if can_set_ex_props %} true {% else %} false {% endif %}, enableSeaTableIntegration: {% if enable_seatable_integration %} true {% else %} false {% endif %}, + isOrgContext: {% if org is not None %} true {% else %} false {% endif %}, } }; diff --git a/seahub/templates/subscription/pay_result.html b/seahub/templates/subscription/pay_result.html new file mode 100644 index 00000000000..6a6a725035e --- /dev/null +++ b/seahub/templates/subscription/pay_result.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block main_panel %} +
    +

    {{ info }}

    +
    +{% endblock %} + diff --git a/seahub/templates/subscription/subscription_react.html b/seahub/templates/subscription/subscription_react.html new file mode 100644 index 00000000000..4be94901c56 --- /dev/null +++ b/seahub/templates/subscription/subscription_react.html @@ -0,0 +1,19 @@ +{% extends 'base_for_react.html' %} +{% load seahub_tags avatar_tags i18n %} +{% load render_bundle from webpack_loader %} + +{% block sub_title %}付费管理 - {% endblock %} + +{% block extra_style %} +{% render_bundle 'subscription' 'css' %} +{% endblock %} + +{% block extra_script %} + +{% render_bundle 'subscription' 'js' %} +{% endblock %} diff --git a/seahub/urls.py b/seahub/urls.py index 3d5bf276ecf..2e46b98b26d 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -141,7 +141,7 @@ from seahub.api2.endpoints.admin.device_errors import AdminDeviceErrors from seahub.api2.endpoints.admin.users import AdminUsers, AdminUser, AdminUserResetPassword, AdminAdminUsers, \ AdminUserGroups, AdminUserShareLinks, AdminUserUploadLinks, AdminUserBeSharedRepos, \ - AdminLDAPUsers, AdminSearchUser, AdminUpdateUserCcnetEmail + AdminLDAPUsers, AdminSearchUser, AdminUpdateUserCcnetEmail, AdminUserList from seahub.api2.endpoints.admin.device_trusted_ip import AdminDeviceTrustedIP from seahub.api2.endpoints.admin.libraries import AdminLibraries, AdminLibrary, \ AdminSearchLibrary @@ -163,7 +163,7 @@ AdminImportUsers from seahub.api2.endpoints.admin.operation_logs import AdminOperationLogs from seahub.api2.endpoints.admin.organizations import AdminOrganizations, \ - AdminOrganization, AdminSearchOrganization + AdminOrganization, AdminSearchOrganization, AdminOrganizationsBaseInfo from seahub.api2.endpoints.admin.institutions import AdminInstitutions, AdminInstitution from seahub.api2.endpoints.admin.institution_users import AdminInstitutionUsers, AdminInstitutionUser from seahub.api2.endpoints.admin.org_users import AdminOrgUsers, AdminOrgUser @@ -203,6 +203,7 @@ from seahub.ai.apis import LibrarySdocIndexes, Search, LibrarySdocIndex, TaskStatus, \ LibraryIndexState, QuestionAnsweringSearchInLibrary, FileDownloadToken +from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPlansView, SubscriptionLogsView urlpatterns = [ path('accounts/', include('seahub.base.registration_urls')), @@ -581,6 +582,7 @@ re_path(r'^api/v2.1/admin/ldap-users/$', AdminLDAPUsers.as_view(), name='api-v2.1-admin-ldap-users'), re_path(r'^api/v2.1/admin/search-user/$', AdminSearchUser.as_view(), name='api-v2.1-admin-search-user'), re_path(r'^api/v2.1/admin/update-user-ccnet-email/$', AdminUpdateUserCcnetEmail.as_view(), name='api-v2.1-admin-update-user-ccnet-email'), + re_path(r'^api/v2.1/admin/user-list/$', AdminUserList.as_view(), name='api-v2.1-admin-user-list'), # [^...] Matches any single character not in brackets # + Matches between one and unlimited times, as many times as possible @@ -672,6 +674,7 @@ ## admin::organizations re_path(r'^api/v2.1/admin/organizations/$', AdminOrganizations.as_view(), name='api-v2.1-admin-organizations'), + re_path(r'^api/v2.1/admin/organizations-basic-info/$', AdminOrganizationsBaseInfo.as_view(), name='api-v2.1-admin-organizations-basic-info'), re_path(r'^api/v2.1/admin/search-organization/$', AdminSearchOrganization.as_view(), name='api-v2.1-admin-Search-organization'), re_path(r'^api/v2.1/admin/organizations/(?P\d+)/$', AdminOrganization.as_view(), name='api-v2.1-admin-organization'), re_path(r'^api/v2.1/admin/organizations/(?P\d+)/users/$', AdminOrgUsers.as_view(), name='api-v2.1-admin-org-users'), @@ -990,3 +993,11 @@ re_path(r'^client-sso/(?P[^/]+)/$', client_sso, name="client_sso"), re_path(r'^client-sso/(?P[^/]+)/complete/$', client_sso_complete, name="client_sso_complete"), ] + +if getattr(settings, 'ENABLE_SUBSCRIPTION', False): + urlpatterns += [ + re_path(r'^subscription/', include('seahub.subscription.urls')), + re_path(r'^api/v2.1/subscription/$', SubscriptionView.as_view(), name='api-v2.1-subscription'), + re_path(r'^api/v2.1/subscription/plans/$', SubscriptionPlansView.as_view(), name='api-v2.1-subscription-plans'), + re_path(r'^api/v2.1/subscription/logs/$', SubscriptionLogsView.as_view(), name='api-v2.1-subscription-logs'), + ]