v0.1.1
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,6 @@
|
||||
from datetime import datetime
|
||||
from ninja.errors import HttpError
|
||||
from ninja_extra import ControllerBase, api_controller, route
|
||||
from ninja_extra.permissions import IsAuthenticated
|
||||
from ninja_jwt.authentication import JWTAuth
|
||||
from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from docxtpl import DocxTemplate
|
||||
@@ -14,7 +12,6 @@ from apps.dict.models import Dict
|
||||
# 导入工具函数
|
||||
from utils.util import get_str_dict, get_list_dict, get_testType, get_ident, get_str_abbr
|
||||
from utils.chapter_tools.csx_chapter import create_csx_chapter_dict
|
||||
from utils.util import MyHTMLParser_p
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.forms.models import model_to_dict
|
||||
from apps.createDocument.extensions.util import create_dg_docx
|
||||
@@ -25,6 +22,8 @@ from utils.path_utils import project_path
|
||||
from apps.createSeiTaiDocument.extensions.logger import GenerateLogger
|
||||
# 导入mixins-处理文档片段
|
||||
from apps.createDocument.extensions.mixins import FragementToolsMixin
|
||||
# 导入工具
|
||||
from apps.createDocument.extensions.tools import demand_sort_by_designKey
|
||||
|
||||
# @api_controller("/generate", tags=['生成大纲文档'], auth=JWTAuth(), permissions=[IsAuthenticated])
|
||||
@api_controller("/generate", tags=['生成大纲文档'])
|
||||
@@ -47,10 +46,12 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin):
|
||||
|
||||
# 查出第一轮所有testdemand
|
||||
project_round_one = project_qs.pField.filter(key=0).first()
|
||||
testDemand_qs = project_round_one.rtField.all()
|
||||
testDemand_qs = project_round_one.rtField.all().select_related('design')
|
||||
# 按照自己key排序,这样可以按照design的key排序
|
||||
sorted_demand_qs = sorted(testDemand_qs, key=demand_sort_by_designKey)
|
||||
|
||||
# 遍历第一轮测试项:默认是ID排序
|
||||
for single_qs in testDemand_qs:
|
||||
for single_qs in sorted_demand_qs:
|
||||
type_index = type_number_list.index(int(single_qs.testType))
|
||||
# 先查询其testDemandContent信息
|
||||
content_list = []
|
||||
@@ -665,7 +666,6 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin):
|
||||
test_items = design.dtField.all()
|
||||
# 连接两个QuerySet,默认去重
|
||||
test_items = test_items.union(design.odField.all())
|
||||
print('ok:', test_items)
|
||||
for test_item in test_items:
|
||||
reveal_ident = "_".join(
|
||||
["XQ", get_testType(test_item.testType, "testType"), test_item.ident])
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
import base64
|
||||
import io
|
||||
from pathlib import Path
|
||||
from copy import deepcopy
|
||||
from typing import Union
|
||||
from ninja_extra import api_controller, ControllerBase, route
|
||||
from ninja_extra.permissions import IsAuthenticated
|
||||
from ninja_jwt.authentication import JWTAuth
|
||||
from ninja.errors import HttpError
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.db.models import QuerySet, Q
|
||||
from docxtpl import DocxTemplate, RichText, InlineImage
|
||||
from docx.shared import Mm
|
||||
from docxtpl import DocxTemplate
|
||||
from docx import Document
|
||||
# 导入模型
|
||||
from apps.project.models import Project, Round, Dut
|
||||
from apps.dict.models import Dict, DictItem
|
||||
from apps.dict.models import Dict
|
||||
# 导入项目工具
|
||||
from utils.util import get_list_dict, get_str_dict, MyHTMLParser, get_ident, get_case_ident, get_testType
|
||||
from utils.util import get_list_dict, get_str_dict, get_ident, get_case_ident, get_testType
|
||||
from utils.chapter_tools.csx_chapter import create_csx_chapter_dict
|
||||
from utils.chen_response import ChenResponse
|
||||
from apps.createDocument.extensions import util
|
||||
@@ -27,6 +21,8 @@ from apps.createDocument.extensions.parse_rich_text import RichParser
|
||||
from apps.createDocument.extensions.documentTime import DocTime
|
||||
# 导入生成日志记录模块
|
||||
from apps.createSeiTaiDocument.extensions.logger import GenerateLogger
|
||||
# 导入排序
|
||||
from apps.createDocument.extensions.tools import demand_sort_by_designKey
|
||||
|
||||
chinese_round_name: list = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
|
||||
|
||||
@@ -266,9 +262,7 @@ class GenerateControllerHSM(ControllerBase):
|
||||
@route.get("/create/hdemand", url_name="create-hdemand")
|
||||
@transaction.atomic
|
||||
def create_hdemand(self, id: int):
|
||||
"""
|
||||
生成非第一轮的多个测试需求
|
||||
"""
|
||||
"""生成非第一轮的多个测试需求"""
|
||||
project_path_str = project_path(id)
|
||||
tpl_path = Path.cwd() / 'media' / project_path_str / 'form_template/hsm' / '回归测试需求.docx'
|
||||
doc = DocxTemplate(tpl_path)
|
||||
@@ -284,9 +278,13 @@ class GenerateControllerHSM(ControllerBase):
|
||||
test_type_len = Dict.objects.get(code='testType').dictItem.count()
|
||||
type_number_list = [i for i in range(1, test_type_len + 1)]
|
||||
list_list = [[] for j in range(1, test_type_len + 1)]
|
||||
|
||||
# 获得本轮次所有testDemand
|
||||
testDemand_qs = hround.rtField.all()
|
||||
for demand in testDemand_qs:
|
||||
testDemand_qs = hround.rtField.all().select_related('design')
|
||||
# 根据自己key排序
|
||||
sorted_demand_qs = sorted(testDemand_qs, key=demand_sort_by_designKey)
|
||||
|
||||
for demand in sorted_demand_qs:
|
||||
type_index = type_number_list.index(int(demand.testType))
|
||||
content_list = []
|
||||
for (index, content) in enumerate(demand.testQField.all()):
|
||||
@@ -324,7 +322,7 @@ class GenerateControllerHSM(ControllerBase):
|
||||
"doc_list": doc_list,
|
||||
"design_description": parser.get_final_list(doc),
|
||||
"test_demand_content": content_list,
|
||||
"testMethod": testmethod_str,
|
||||
"testMethod": testmethod_str.strip(),
|
||||
"adequacy": demand.adequacy.replace("\n", "\a"),
|
||||
"testDesciption": demand.testDesciption.replace("\n", "\a") # 测试项描述
|
||||
}
|
||||
|
||||
BIN
apps/createDocument/extensions/__pycache__/tools.cpython-313.pyc
Normal file
BIN
apps/createDocument/extensions/__pycache__/tools.cpython-313.pyc
Normal file
Binary file not shown.
9
apps/createDocument/extensions/tools.py
Normal file
9
apps/createDocument/extensions/tools.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from apps.project.models import TestDemand
|
||||
|
||||
def demand_sort_by_designKey(demand_obj: TestDemand) -> tuple[int, ...]:
|
||||
"""仅限于测试项排序函数,传入sorted函数的key里面"""
|
||||
parts = demand_obj.key.split('-')
|
||||
sort_tuple = tuple(int(part) for part in parts)
|
||||
return sort_tuple
|
||||
|
||||
__all__ = ['demand_sort_by_designKey']
|
||||
Binary file not shown.
@@ -23,6 +23,7 @@ from apps.project.schemas.design import DeleteSchema, DesignFilterSchema, Design
|
||||
from apps.project.tools.delete_change_key import design_delete_sub_node_key
|
||||
from utils.smallTools.interfaceTools import conditionNoneToBlank
|
||||
from apps.project.tools.auto_create_data import auto_create_renji
|
||||
from apps.project.tool.dragAndDrop import DesignDrapAtoB
|
||||
|
||||
@api_controller("/project", auth=JWTAuth(), permissions=[IsAuthenticated], tags=['设计需求数据'])
|
||||
class DesignController(ControllerBase):
|
||||
@@ -66,7 +67,10 @@ class DesignController(ControllerBase):
|
||||
# 处理树状数据
|
||||
@route.get("/getDesignDemandInfo", response=List[DesignTreeReturnSchema], url_name="design-info")
|
||||
def get_design_tree(self, payload: DesignTreeInputSchema = Query(...)):
|
||||
qs = Design.objects.filter(project__id=payload.project_id, dut__key=payload.key).order_by('id')
|
||||
qs = Design.objects.filter(
|
||||
project__id=payload.project_id,
|
||||
dut__key=payload.key
|
||||
).select_related('project', 'dut')
|
||||
return qs
|
||||
|
||||
# 添加设计需求
|
||||
@@ -241,3 +245,24 @@ class DesignController(ControllerBase):
|
||||
# 最后记得save
|
||||
new_design_obj.save()
|
||||
return ChenResponse(status=200, code=200, message='复制当前设计需求成功', data="")
|
||||
|
||||
# 拖拽更变desing的key,同dut下其他design也变动
|
||||
@route.get("/switch_position", url_name='design-switch-position')
|
||||
@transaction.atomic
|
||||
def switch_position(self, from_key: str, to_key: str, pos: int, project_id: int):
|
||||
from_key_list = from_key.split("-")
|
||||
to_key_list = to_key.split("-")
|
||||
# 如果两个设计需求被测件或轮次不一样则报错
|
||||
if from_key_list[:-1] != to_key_list[:-1]:
|
||||
return ChenResponse(status=422, code=40022, message="无法交换不同父节点的设计需求")
|
||||
# 先查询两个design
|
||||
from_design_obj: Design = Design.objects.filter(key=from_key, project_id=project_id).first()
|
||||
to_design_obj: Design = Design.objects.filter(key=to_key, project_id=project_id).first()
|
||||
if not from_design_obj or not to_design_obj:
|
||||
return ChenResponse(status=404, code=40004, message="设计需求不存在")
|
||||
# 获取父节点下所有design
|
||||
parant_dut = from_design_obj.dut
|
||||
design_qs = parant_dut.rsField.all()
|
||||
# 根据pos将from排到后面
|
||||
return_key = DesignDrapAtoB(from_design_obj, to_design_obj, design_qs, pos)
|
||||
return ChenResponse(status=200, data=return_key)
|
||||
|
||||
BIN
apps/project/tool/__pycache__/dragAndDrop.cpython-313.pyc
Normal file
BIN
apps/project/tool/__pycache__/dragAndDrop.cpython-313.pyc
Normal file
Binary file not shown.
43
apps/project/tool/dragAndDrop.py
Normal file
43
apps/project/tool/dragAndDrop.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from django.db.models import QuerySet
|
||||
|
||||
from apps.project.models import Design, TestDemand
|
||||
from typing import Union
|
||||
|
||||
def DesignDrapAtoB(a: Design,
|
||||
b: Design,
|
||||
origin_qs: QuerySet[Design, Design],
|
||||
pos: Union[-1 | 1]) -> str:
|
||||
"""该函数传入拖拽design和释放到的design,然后更改排序,完成key的重新设置"""
|
||||
# 判断是移动到b前面还是后面
|
||||
list_qs = list(origin_qs)
|
||||
list_qs.remove(a)
|
||||
b_index = list_qs.index(b)
|
||||
if pos == -1:
|
||||
list_qs.insert(b_index, a)
|
||||
elif pos == 1:
|
||||
list_qs.insert(b_index + 1, a)
|
||||
# 重新完成排序后调整key
|
||||
prefix = "".join([a.dut.key, "-"])
|
||||
for index, obj in enumerate(list_qs):
|
||||
obj.key = "".join([prefix, str(index)])
|
||||
# 需要测试项调整key
|
||||
designConvertDemadnKey(obj)
|
||||
obj.save()
|
||||
return a.key
|
||||
|
||||
def designConvertDemadnKey(desgin_obj: Design):
|
||||
"""传入Design对象,集体修改demand和case的key"""
|
||||
for demand in desgin_obj.dtField.all():
|
||||
design_key = desgin_obj.key
|
||||
demand_last_key = demand.key.split("-")[-1]
|
||||
demand.key = "-".join([design_key, demand_last_key])
|
||||
demandConvertCaseKey(demand)
|
||||
demand.save()
|
||||
|
||||
def demandConvertCaseKey(demand_obj:TestDemand):
|
||||
"""传入Demand对象集体修改case的key"""
|
||||
for case in demand_obj.tcField.all():
|
||||
demand_key = demand_obj.key
|
||||
case_last_key = case.key.split("-")[-1]
|
||||
case.key = "-".join([demand_key, case_last_key])
|
||||
case.save()
|
||||
Binary file not shown.
Binary file not shown.
@@ -8,7 +8,6 @@ from ninja import Query
|
||||
from django.db import transaction
|
||||
from django.contrib.auth import authenticate
|
||||
from django.shortcuts import get_object_or_404
|
||||
from ninja_jwt.tokens import RefreshToken
|
||||
from ninja_jwt.authentication import JWTAuth
|
||||
from ninja_jwt.controller import TokenObtainPairController
|
||||
from ninja_jwt import schema
|
||||
@@ -17,37 +16,25 @@ from utils.chen_response import ChenResponse
|
||||
from apps.user.schema import UserInfoOutSchema, CreateUserSchema, CreateUserOutSchema, \
|
||||
UserRetrieveInputSchema, \
|
||||
UserRetrieveOutSchema, UpdateDeleteUserSchema, UpdateDeleteUserOutSchema, DeleteUserSchema, LogOutSchema, \
|
||||
LogInputSchema, LogDeleteInSchema, AdminModifyPasswordSchema
|
||||
LogInputSchema, LogDeleteInSchema, AdminModifyPasswordSchema, MyTokenObtainPairOutSchema, \
|
||||
MyTokenObtainPairInputSchema
|
||||
from apps.user.models import TableOperationLog, Users as UserClass
|
||||
from apps.project.models import Project
|
||||
# 工具函数
|
||||
from utils.chen_crud import update, multi_delete
|
||||
from apps.user.tools.ldap_tools import load_ldap_users
|
||||
# 导入登录日志函数
|
||||
from utils.log_util.request_util import save_login_log
|
||||
|
||||
Users: UserClass = get_user_model() # type:ignore
|
||||
Users = get_user_model()
|
||||
|
||||
# 定义用户登录接口,包含token刷新和生成
|
||||
@api_controller("/system", tags=['用户token控制和登录接口'])
|
||||
class UserTokenController(TokenObtainPairController):
|
||||
auto_import = True
|
||||
|
||||
@route.post("/login", url_name='login')
|
||||
def obtain_token(self, user_token: schema.TokenObtainPairSerializer):
|
||||
"""新版本有特性,后期修改"""
|
||||
# 注意TokenObtainPairSerializer是老版本,所以兼容,本质是TokenObtainPairInputSchema
|
||||
user: UserClass = user_token._user
|
||||
if user:
|
||||
# 判断是否为启用状态
|
||||
if user.status == '2':
|
||||
return ChenResponse(status=500, code=500, message='账号已被禁用,请联系管理员...')
|
||||
save_login_log(request=self.context.request, user=user) # 保存登录日志
|
||||
refresh = RefreshToken.for_user(user)
|
||||
token = refresh.access_token # type:ignore
|
||||
return ChenResponse(code=200,
|
||||
data={'token': str(token), 'refresh': str(refresh),
|
||||
'token_exp_data': datetime.fromtimestamp(token["exp"], tz=timezone.utc)})
|
||||
@route.post("/login", response=MyTokenObtainPairOutSchema, url_name='login')
|
||||
def obtain_token(self, user_token: MyTokenObtainPairInputSchema):
|
||||
user_token.check_user_authentication_rule()
|
||||
return user_token.to_response_schema()
|
||||
|
||||
@route.get("/getInfo", response=UserInfoOutSchema, url_name="get_info", auth=JWTAuth())
|
||||
def get_user_info(self):
|
||||
|
||||
@@ -3,9 +3,13 @@ from django.contrib.auth.models import Group
|
||||
from ninja_schema import ModelSchema, model_validator, Schema
|
||||
from ninja_extra.exceptions import APIException
|
||||
from ninja_extra import status
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Type, Dict
|
||||
from ninja import Field
|
||||
from ninja.errors import HttpError
|
||||
from ninja_jwt.schema import TokenObtainInputSchemaBase
|
||||
from ninja_jwt.tokens import RefreshToken
|
||||
from utils.log_util.request_util import save_login_log
|
||||
|
||||
UserModel = Users
|
||||
|
||||
@@ -113,3 +117,34 @@ class AdminModifyPasswordSchema(Schema):
|
||||
newPassword: str
|
||||
newPassword_confirmation: str
|
||||
oldPassword: str
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~JWT~~~~~~~~~~~~~~~~~~~~
|
||||
# 定义输出的内容,修改了输出access变为token,新增token_exp_data字段
|
||||
class MyTokenObtainPairOutSchema(Schema):
|
||||
token: str
|
||||
refresh: str
|
||||
token_exp_data: datetime
|
||||
|
||||
class MyTokenObtainPairInputSchema(TokenObtainInputSchemaBase):
|
||||
@classmethod
|
||||
def get_response_schema(cls) -> Type[Schema]:
|
||||
"""修改默认的返回Schema"""
|
||||
return MyTokenObtainPairOutSchema
|
||||
|
||||
@classmethod
|
||||
def get_token(cls, user) -> Dict:
|
||||
"""因为输出Schema修改,这里修改输出的token字典字段"""
|
||||
values = {}
|
||||
refresh = RefreshToken.for_user(user)
|
||||
token = refresh.access_token
|
||||
values["token"] = str(token) # 修改在这里 # type:ignore
|
||||
values['refresh'] = str(refresh)
|
||||
values["token_exp_data"] = datetime.fromtimestamp(token["exp"], tz=timezone.utc)
|
||||
return values
|
||||
|
||||
def authenticate(self, request, credentials: Dict):
|
||||
super().authenticate(request, credentials)
|
||||
if self._user:
|
||||
save_login_log(request, self._user)
|
||||
if self._user.status == '2': # type:ignore
|
||||
raise HttpError(401, "账号已被禁用,请联系管理员...")
|
||||
|
||||
Binary file not shown.
@@ -7,12 +7,16 @@ env = environ.Env()
|
||||
|
||||
# 2. LDAP服务器host和port
|
||||
server_uri = env('AUTH_LDAP_SERVER_URI', default='ldap://dns.paisat.cn:389')
|
||||
dn = env('AUTH_LDAP_BIND_DN',default='CN=Administrator,CN=Users,DC=sstc,DC=ctu')
|
||||
password = env('AUTH_LDAP_BIND_PASSWORD',default='WXWX2019!!!!!!')
|
||||
base_dn = env('BASE_DN',default='OU=all,DC=sstc,DC=ctu')
|
||||
filter_str = env('FILTER_STR',default='(sAMAccountName=%(user)s)')
|
||||
|
||||
# 3. 连接LDAP服务器进行操作
|
||||
def load_ldap_users(url=server_uri,
|
||||
dn="CN=Administrator,CN=Users,DC=sstc,DC=ctu",
|
||||
pwd="WXWX2019!!!!!!",
|
||||
search_dn="OU=ALL,DC=sstc,DC=ctu",
|
||||
dn=dn,
|
||||
pwd=password,
|
||||
search_dn=base_dn,
|
||||
search_filter='(&(sAMAccountName=*))'):
|
||||
Users = get_user_model()
|
||||
|
||||
@@ -50,6 +54,7 @@ def load_ldap_users(url=server_uri,
|
||||
c_user.email = user_dict['email']
|
||||
update_flag = True
|
||||
if update_flag:
|
||||
c_user.set_password('wxwx2018!!!')
|
||||
c_user.save()
|
||||
else:
|
||||
user_dict['remark'] = '自动同步LDAP数据用户'
|
||||
|
||||
Reference in New Issue
Block a user