diff --git a/fir_client/src/components/FirHeader.vue b/fir_client/src/components/FirHeader.vue index e70074d..8b909b8 100644 --- a/fir_client/src/components/FirHeader.vue +++ b/fir_client/src/components/FirHeader.vue @@ -50,9 +50,6 @@ 个人资料 API token 设置域名 - 下载码域名 - 存储管理 超级签名 @@ -132,9 +129,7 @@ }, {methods: 'GET', token: this.token}); } else if (command === 'setdomian') { - this.$store.dispatch("dodomainaction", 1); - } else if (command === 'setqrdomian') { - this.$store.dispatch("dodomainaction", 2); + this.$router.push({"name": 'FirUserDomain'}) } else if (command === 'myorder') { this.$router.push({"name": 'FirUserOrders'}) } else if (command === 'contact') { diff --git a/fir_client/src/components/apps/FirAppInfossecurity.vue b/fir_client/src/components/apps/FirAppInfossecurity.vue index a847f34..3441526 100644 --- a/fir_client/src/components/apps/FirAppInfossecurity.vue +++ b/fir_client/src/components/apps/FirAppInfossecurity.vue @@ -6,7 +6,8 @@ :close-on-press-escape="false" :visible.sync="bind_domain_sure" width="666px"> - + diff --git a/fir_client/src/components/base/BindDomain.vue b/fir_client/src/components/base/BindDomain.vue index 48e7dd1..5c36c1e 100644 --- a/fir_client/src/components/base/BindDomain.vue +++ b/fir_client/src/components/base/BindDomain.vue @@ -37,11 +37,12 @@ label="主机记录" > @@ -72,7 +74,7 @@ -

您的账户正在绑定域名:{{ domain_name }}

+

{{b_t_msg}}正在绑定域名:{{ domain_name }}

系统未检出到您的CNAME记录,请检查您的配置。

@@ -92,7 +94,7 @@ -

您的账户已绑定域名:{{ domain_name }}

+

{{b_t_msg}}已绑定域名:{{ domain_name }}

@@ -137,7 +139,7 @@ 上一步 - 强制绑定 + 强制绑定 下一步 @@ -164,6 +166,10 @@ type: Number, default: 1 }, + domain_state: { + type: Boolean, + default: false + }, }, data() { return { @@ -172,10 +178,14 @@ bind_domain_sure: true, domain_name: '', domain_tData: [{'type': 'CNAME', 'host': 'xxx', 'dns': 'demo.xxx.cn'}], - force_bind:false, + force_bind: false, + b_t_msg: '您的账户', } }, mounted() { + if (this.domain_type === 2) { + this.b_t_msg = '您的应用' + } this.bind_click(); }, beforeDestroy() { @@ -195,6 +205,9 @@ this.$store.dispatch("dodomainshow", false); } } + if (this.domain_state) { + this.$store.dispatch("dosetdomainstate", true); + } } else { if (data.code === 1004) { this.active = 1; @@ -218,12 +231,16 @@ this.$store.dispatch("dodomainshow", true); } } + if (this.domain_state) { + this.$store.dispatch("dosetdomainstate", true); + } } else { this.$message.error("解除绑定失败 " + data.msg) } }, {methods: 'DELETE', data: {app_id: this.app_id, domain_type: this.domain_type}}); }, bind_click() { + this.$store.dispatch("dosetdomainstate", false); domainFun(data => { if (data.code === 1000) { if (data.data) { @@ -266,13 +283,18 @@ } } else { this.$message.error("绑定失败 " + data.msg); - if(data.code === 1011){ - this.force_bind=true + if (data.code === 1011) { + this.force_bind = true } } }, { methods: 'POST', - data: {domain_name: this.domain_name, app_id: this.app_id, domain_type: this.domain_type,force_bind:force_bind} + data: { + domain_name: this.domain_name, + app_id: this.app_id, + domain_type: this.domain_type, + force_bind: force_bind + } }) } else if (this.active === 2) { this.check_cname() diff --git a/fir_client/src/components/user/FirUserDomain.vue b/fir_client/src/components/user/FirUserDomain.vue new file mode 100644 index 0000000..631629f --- /dev/null +++ b/fir_client/src/components/user/FirUserDomain.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/fir_client/src/components/user/FirUserOrders.vue b/fir_client/src/components/user/FirUserOrders.vue index c9a9cd1..4f17753 100644 --- a/fir_client/src/components/user/FirUserOrders.vue +++ b/fir_client/src/components/user/FirUserOrders.vue @@ -115,7 +115,7 @@
diff --git a/fir_client/src/restful/index.js b/fir_client/src/restful/index.js index 80222d9..948d3cd 100644 --- a/fir_client/src/restful/index.js +++ b/fir_client/src/restful/index.js @@ -662,3 +662,18 @@ export function wxutils(callBack, params, load = true) { true ); } + +/**访问域名绑定 */ +export function domaininfo(callBack, params, load = true) { + getData( + params.methods, + USERSEVER + '/domain_info', + params.data, + data => { + callBack(data); + }, + load, + true, + true + ); +} diff --git a/fir_client/src/router/index.js b/fir_client/src/router/index.js index 84afe79..b4fbbd5 100644 --- a/fir_client/src/router/index.js +++ b/fir_client/src/router/index.js @@ -152,6 +152,12 @@ const router = new VueRouter({ meta: {label: '订单详情'}, component: () => import("@/components/user/FirUserOrders"), }, + { + path: 'domain', + name: 'FirUserDomain', + meta: {label: '绑定域名详情'}, + component: () => import("@/components/user/FirUserDomain"), + }, { path: 'supersign-help', name: 'FirSuperSignHelp', diff --git a/fir_client/src/store/index.js b/fir_client/src/store/index.js index 05a8664..53bb3b0 100644 --- a/fir_client/src/store/index.js +++ b/fir_client/src/store/index.js @@ -17,6 +17,7 @@ const store = new Vuex.Store({ userInfoIndex: 0, show_domain_msg: false, domain_action: false, + domian_show_state: false, }, mutations: { setuserinfo(state, data) { @@ -36,9 +37,15 @@ const store = new Vuex.Store({ }, setdomainaction(state, val) { state.domain_action = val + }, + setdomainstate(state, val) { + state.domian_show_state = val } }, actions: { + dosetdomainstate(context, data) { + context.commit('setdomainstate', data); + }, dodomainaction(context, data) { context.commit('setdomainaction', data); }, @@ -56,7 +63,7 @@ const store = new Vuex.Store({ }, doucurrentapp(context, val) { context.commit('setcurrentapp', val) - } + }, } }); diff --git a/fir_client/vue.config.js b/fir_client/vue.config.js index 8dcaf5a..8b4fae0 100644 --- a/fir_client/vue.config.js +++ b/fir_client/vue.config.js @@ -82,7 +82,7 @@ if (page) { } } -const version='1.2.7'; +const version='1.2.8'; const pro_base_env = { baseUrl: 'https://flyapps.cn', diff --git a/fir_ser/api/migrations/0010_alter_userdomaininfo_domain_type.py b/fir_ser/api/migrations/0010_alter_userdomaininfo_domain_type.py new file mode 100644 index 0000000..b9adfb9 --- /dev/null +++ b/fir_ser/api/migrations/0010_alter_userdomaininfo_domain_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.3 on 2021-09-23 12:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0009_userdomaininfo_domain_type'), + ] + + operations = [ + migrations.AlterField( + model_name='userdomaininfo', + name='domain_type', + field=models.SmallIntegerField(choices=[(0, '下载码域名'), (1, '下载页域名'), (2, '应用专用域名')], default=1, + help_text='0 表示下载码域名,扫描下载码域名,会自动跳转到预览域名', verbose_name='域名类型'), + ), + ] diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index b49aa32..da7a850 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -482,7 +482,7 @@ class UserDomainInfo(models.Model): domain_name = models.CharField(verbose_name="下载页面域名", db_index=True, max_length=64, null=False, blank=False) is_enable = models.BooleanField(default=False, verbose_name="绑定成功") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") - domain_type_choices = ((0, '下载码域名'), (1, '预览下载域名'),) + domain_type_choices = ((0, '下载码域名'), (1, '下载页域名'), (2, '应用专用域名')) domain_type = models.SmallIntegerField(choices=domain_type_choices, default=1, verbose_name="域名类型", help_text="0 表示下载码域名,扫描下载码域名,会自动跳转到预览域名") @@ -490,5 +490,11 @@ class UserDomainInfo(models.Model): verbose_name = '用户分发域名绑定' verbose_name_plural = "用户分发域名绑定" + def save(self, *args, **kwargs): + if self.domain_type == 2: + if not self.app_id: + raise KeyError('app_id must exists when domain_type is 2') + super(UserDomainInfo, self).save(*args, **kwargs) + def __str__(self): return "%s-%s-%s" % (self.user_id, self.cname_id, self.domain_name) diff --git a/fir_ser/api/urls.py b/fir_ser/api/urls.py index d26cea0..76040a9 100644 --- a/fir_ser/api/urls.py +++ b/fir_ser/api/urls.py @@ -25,7 +25,7 @@ from api.views.storage import StorageView from api.views.receiveudids import IosUDIDView, TaskView from api.views.order import PriceView, OrderView, PaySuccess from api.views.supersign import DeveloperView, SuperSignUsedView, AppUDIDUsedView, SuperSignCertView -from api.views.domain import DomainCnameView +from api.views.domain import DomainCnameView, DomainInfoView from api.views.thirdlogin import ValidWxChatToken, ThirdWxAccount # router=DefaultRouter() @@ -59,6 +59,7 @@ urlpatterns = [ re_path("^certification$", CertificationView.as_view()), re_path(r"^pay_success/(?P\w+)$", PaySuccess.as_view()), re_path("^cname_domain$", DomainCnameView.as_view()), + re_path("^domain_info$", DomainInfoView.as_view()), re_path("^mp.weixin$", ValidWxChatToken.as_view()), re_path("^third.wx.login$", WeChatLoginView.as_view()), re_path("^third.wx.sync$", WeChatLoginCheckView.as_view()), diff --git a/fir_ser/api/utils/baseutils.py b/fir_ser/api/utils/baseutils.py index 3d931fd..6f2ac20 100644 --- a/fir_ser/api/utils/baseutils.py +++ b/fir_ser/api/utils/baseutils.py @@ -177,7 +177,7 @@ def get_user_domain_name(obj, domain_type=1): def get_app_domain_name(obj): - domain_obj = UserDomainInfo.objects.filter(app_id=obj, is_enable=True, domain_type=1).first() + domain_obj = UserDomainInfo.objects.filter(app_id=obj, is_enable=True, domain_type=2).first() if domain_obj: return domain_obj.domain_name return '' diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index b628485..3eb817d 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -586,3 +586,21 @@ class ThirdWxSerializer(serializers.ModelSerializer): class Meta: model = models.ThirdWeChatUserInfo exclude = ["id"] + + +class DomainNameSerializer(serializers.ModelSerializer): + class Meta: + model = models.UserDomainInfo + exclude = ["id", "user_id"] + + app_info = serializers.SerializerMethodField() + + def get_app_info(self, obj): + app_obj = obj.app_id + if app_obj: + app_info = { + 'app_id': app_obj.app_id, + 'name': app_obj.name, + } + return app_info + return {} diff --git a/fir_ser/api/views/domain.py b/fir_ser/api/views/domain.py index fc875bb..32eeb8c 100644 --- a/fir_ser/api/views/domain.py +++ b/fir_ser/api/views/domain.py @@ -3,7 +3,7 @@ # project: 3月 # author: NinEveN # date: 2021/3/29 - +from rest_framework.pagination import PageNumberPagination from rest_framework.views import APIView from api.utils.baseutils import is_valid_domain, get_cname_from_domain, get_user_domain_name, \ @@ -14,7 +14,9 @@ from rest_framework.response import Response from api.models import UserDomainInfo, Apps import logging +from api.utils.serializer import DomainNameSerializer from api.utils.storage.caches import del_cache_response_by_short, reset_app_wx_easy_type, reset_short_response_cache +from api.utils.utils import get_choices_dict logger = logging.getLogger(__name__) @@ -54,6 +56,7 @@ def add_new_domain_info(res, request, domain_name, domain_type): app_obj = Apps.objects.filter(app_id=app_id).first() if app_obj: data_dict['app_id'] = app_obj + data_dict['domain_type'] = 2 UserDomainInfo.objects.create(**data_dict) @@ -164,3 +167,38 @@ class DomainCnameView(APIView): reset_app_wx_easy_type(request.user, app_obj) user_domain_obj.delete() return Response(res.dict) + + +class PageNumber(PageNumberPagination): + page_size = 10 # 每页显示多少条 + page_size_query_param = 'size' # URL中每页显示条数的参数 + page_query_param = 'page' # URL中页码的参数 + max_page_size = None # 最大页码数限制 + + +class DomainInfoView(APIView): + authentication_classes = [ExpiringTokenAuthentication, ] + + def get(self, request): + res = BaseResponse() + search_key = request.query_params.get("search_key", None) + obj_lists = UserDomainInfo.objects.filter(user_id=request.user) + if search_key: + obj_lists1 = obj_lists.filter(domain_name=search_key) + if not obj_lists1: + obj_lists = obj_lists.filter(app_id__name__contains=search_key) + else: + obj_lists = obj_lists1 + + page_obj = PageNumber() + domain_info_serializer = page_obj.paginate_queryset( + queryset=obj_lists.order_by("-created_time").order_by('domain_type'), + request=request, + view=self) + domain_info = DomainNameSerializer(domain_info_serializer, many=True, ) + res.data = domain_info.data + res.count = obj_lists.count() + + res.domain_type_choices = get_choices_dict(UserDomainInfo.domain_type_choices) + + return Response(res.dict)