You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
560 lines
26 KiB
560 lines
26 KiB
|
10 months ago
|
import copy
|
||
|
|
import logging
|
||
|
|
import time
|
||
|
|
import traceback
|
||
|
|
import uuid
|
||
|
|
from itertools import islice
|
||
|
|
|
||
|
|
import openpyxl
|
||
|
|
from django.core.exceptions import ObjectDoesNotExist
|
||
|
|
from django.db import transaction
|
||
|
|
from django.db.models import Q
|
||
|
|
from django.http import FileResponse
|
||
|
|
from django_filters.rest_framework import DjangoFilterBackend
|
||
|
|
from openpyxl.comments import Comment
|
||
|
|
from openpyxl.worksheet.cell_range import CellRange
|
||
|
|
from openpyxl.worksheet.datavalidation import DataValidation
|
||
|
|
from rest_framework.decorators import action
|
||
|
|
from rest_framework.filters import SearchFilter, OrderingFilter
|
||
|
|
from rest_framework.permissions import IsAuthenticated
|
||
|
|
from rest_framework.views import APIView
|
||
|
|
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
|
||
|
|
|
||
|
|
from ChaCeRndTrans import settings
|
||
|
|
from ChaCeRndTrans.basic import CCAIResponse
|
||
|
|
from ChaCeRndTrans.code import *
|
||
|
|
from common.models import DataDictionaryDetail, DataDictionary
|
||
|
|
from common.serializers.dict_serializer import DictDetailSerializer
|
||
|
|
from rbac.models import Company, UserProfile
|
||
|
|
from rbac.serializers.user_serializer import CompanySerializer
|
||
|
|
from utils.custom import CustomViewBase, CommonPagination, RbacPermission, req_operate_by_user, asyncDeleteFile, \
|
||
|
|
ErrorTable, MyCustomError, time_int_to_str, time_str_to_int
|
||
|
|
|
||
|
|
err_logger = logging.getLogger('error')
|
||
|
|
|
||
|
|
|
||
|
|
class CompanyCustomViewSet(CustomViewBase):
|
||
|
|
'''
|
||
|
|
公司管理
|
||
|
|
'''
|
||
|
|
perms_map = (
|
||
|
|
{"*": "admin"}, {"*": "company_all"}, {"get": "company_list"},
|
||
|
|
{"post": "company_create"},
|
||
|
|
{"put": "company_edit"}, {"delete": "company_delete"}
|
||
|
|
)
|
||
|
|
queryset = Company.objects.all()
|
||
|
|
serializer_class = CompanySerializer
|
||
|
|
pagination_class = CommonPagination
|
||
|
|
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||
|
|
# filter_fields = ("",)
|
||
|
|
search_fields = ("name", "EUCC")
|
||
|
|
ordering_fields = ("id",)
|
||
|
|
authentication_classes = (JSONWebTokenAuthentication,)
|
||
|
|
permission_classes = (RbacPermission,)
|
||
|
|
|
||
|
|
def list(self, request, format=None):
|
||
|
|
pagination = {}
|
||
|
|
try:
|
||
|
|
params = request.GET
|
||
|
|
keyword = params.get('keyword')
|
||
|
|
page_size = params.get('size')
|
||
|
|
page = params.get('page')
|
||
|
|
sort = params.get('sort')
|
||
|
|
|
||
|
|
order_by = 'N.id desc'
|
||
|
|
if sort:
|
||
|
|
order_by = sort
|
||
|
|
|
||
|
|
if page is None:
|
||
|
|
page = 1
|
||
|
|
if page_size is None:
|
||
|
|
page_size = 10
|
||
|
|
start_index = (int(page) - 1) * int(page_size)
|
||
|
|
where = 'WHERE 1=1 '
|
||
|
|
param = []
|
||
|
|
if keyword:
|
||
|
|
where += 'AND (N.name LIKE %s OR N.EUCC LIKE %s ) '
|
||
|
|
param.append('%' + keyword + '%')
|
||
|
|
param.append('%' + keyword + '%')
|
||
|
|
|
||
|
|
sql = 'SELECT N.id, N.name, N.MainId, userMid, U.name as user, U.username,' \
|
||
|
|
'EUCC, employeesCount, hightechCode, hightechDate, AmStart, AmEnd, PmStart, PmEnd, tech, tolerance, checkIn ' \
|
||
|
|
'FROM chace_rnd.rbac_company AS N ' \
|
||
|
|
'LEFT JOIN chace_rnd.rbac_userprofile as U ON U.MainId = N.userMid ' \
|
||
|
|
'%s ORDER BY %s LIMIT %s,%s ' % (where, order_by, start_index, page_size)
|
||
|
|
query_rows = Company.objects.raw(sql, param)
|
||
|
|
|
||
|
|
count_sql = """ select N.id, count(N.id) as count
|
||
|
|
from chace_rnd.rbac_company AS N %s """ % where
|
||
|
|
count_result = Company.objects.raw(count_sql, param)
|
||
|
|
|
||
|
|
count = 0
|
||
|
|
if len(count_result) > 0:
|
||
|
|
count = count_result[0].count
|
||
|
|
rows = []
|
||
|
|
for item in query_rows:
|
||
|
|
item.__dict__.pop('_state')
|
||
|
|
if item.__dict__['tech'] and item.__dict__['tech'] != '':
|
||
|
|
item.__dict__['tech'] = item.__dict__['tech'].split(',')
|
||
|
|
if not item.__dict__['user'] or item.__dict__['user'] == '':
|
||
|
|
item.__dict__['user'] = item.__dict__['username']
|
||
|
|
item.__dict__['tolerance'] = time_int_to_str(item.__dict__['tolerance'])
|
||
|
|
rows.append(item.__dict__)
|
||
|
|
|
||
|
|
pagination = {
|
||
|
|
"page": page,
|
||
|
|
"page_size": page_size
|
||
|
|
}
|
||
|
|
|
||
|
|
return CCAIResponse(rows, count=count, pagination=pagination)
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, get company list failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取公司列表失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=True, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getAssociationUser", url_name="getAssociationUser")
|
||
|
|
def getAssociationUser(self, request, pk=None):
|
||
|
|
"""
|
||
|
|
获取该公司关联的用户列表
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
if not pk:
|
||
|
|
return CCAIResponse("请选择对应公司", BAD)
|
||
|
|
instance = Company.objects.get(id=int(pk))
|
||
|
|
user_list = UserProfile.objects.filter(company=instance).values()
|
||
|
|
return CCAIResponse(user_list)
|
||
|
|
except Company.DoesNotExist:
|
||
|
|
return CCAIResponse("该公司已被删除!", BAD)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, get getAssociationUser list failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取该公司关联的用户列表失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
def create(self, request, *args, **kwargs):
|
||
|
|
"""
|
||
|
|
直接新增公司
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
data = req_operate_by_user(request)
|
||
|
|
# 用户选择为其添加公司的用户
|
||
|
|
userMid = data.get('userMid')
|
||
|
|
if not userMid:
|
||
|
|
return CCAIResponse("Missing User Information", BAD)
|
||
|
|
user = UserProfile.objects.filter(MainId=userMid).first()
|
||
|
|
if not user:
|
||
|
|
return CCAIResponse("User Information Error", BAD)
|
||
|
|
companyMid = uuid.uuid4().__str__()
|
||
|
|
data['MainId'] = companyMid
|
||
|
|
tech = data.get('tech') # 技术领域
|
||
|
|
if tech:
|
||
|
|
data['tech'] = ','.join(tech)
|
||
|
|
tolerance = data.get('tolerance') # 容错时间
|
||
|
|
if tolerance:
|
||
|
|
data['tolerance'] = time_str_to_int(tolerance)
|
||
|
|
serializer = self.get_serializer(data=data)
|
||
|
|
serializer.is_valid(raise_exception=True)
|
||
|
|
with transaction.atomic():
|
||
|
|
company = self.perform_create(serializer)
|
||
|
|
user.company.add(company)
|
||
|
|
# headers = self.get_success_headers(serializer.data)
|
||
|
|
return CCAIResponse(data="success")
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, create company failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("直接新增公司失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
def perform_create(self, serializer):
|
||
|
|
# 重写序列化创建,返回创建的公司对象
|
||
|
|
return serializer.save()
|
||
|
|
|
||
|
|
def update(self, request, *args, **kwargs):
|
||
|
|
"""
|
||
|
|
如果用户修改拥有者
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
data = req_operate_by_user(request)
|
||
|
|
tech = data.get('tech')
|
||
|
|
tolerance = data.get('tolerance') # 容错时间
|
||
|
|
userMid = data.get('userMid')
|
||
|
|
if tech:
|
||
|
|
data['tech'] = ','.join(str(x) for x in tech)
|
||
|
|
if tolerance:
|
||
|
|
data['tolerance'] = time_str_to_int(tolerance)
|
||
|
|
partial = kwargs.pop('partial', False) # True:所有字段全部更新, False:仅更新提供的字段
|
||
|
|
instance = self.get_object()
|
||
|
|
with transaction.atomic():
|
||
|
|
# 检查是否更改拥有者
|
||
|
|
flag = False
|
||
|
|
if userMid and instance.userMid != userMid:
|
||
|
|
flag = True
|
||
|
|
new_user = UserProfile.objects.filter(MainId=userMid).select_for_update().first() # 新的拥有者
|
||
|
|
old_user = UserProfile.objects.filter(MainId=instance.userMid).select_for_update().first() # 旧的拥有者
|
||
|
|
serializer = self.get_serializer(instance, data=data, partial=partial)
|
||
|
|
serializer.is_valid(raise_exception=True)
|
||
|
|
self.perform_update(serializer)
|
||
|
|
if flag:
|
||
|
|
if not new_user:
|
||
|
|
transaction.set_rollback(True)
|
||
|
|
return CCAIResponse("用户已被删除!", BAD)
|
||
|
|
else:
|
||
|
|
new_user.company.add(instance)
|
||
|
|
if old_user:
|
||
|
|
old_user.company.remove(instance)
|
||
|
|
|
||
|
|
if getattr(instance, '_prefetched_objects_cache', None):
|
||
|
|
# If 'prefetch_related' has been applied to a queryset, we need to
|
||
|
|
# forcibly invalidate the prefetch cache on the instance.
|
||
|
|
instance._prefetched_objects_cache = {}
|
||
|
|
|
||
|
|
return CCAIResponse(data="success")
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, update company Info failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("修改公司信息失败列表失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getActiveUser", url_name="getActiveUser")
|
||
|
|
def getActiveUser(self, request):
|
||
|
|
"""
|
||
|
|
获取主账号可用用户列表,供公司拥有者选择
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
users = UserProfile.objects.filter(is_sub=2, is_active=1, MainId__isnull=False).values("id", "name", "username", "MainId")
|
||
|
|
return CCAIResponse(users)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, getActiveUser failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取可选择的公司拥有者列表失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getCompanyList", url_name="getCompanyList")
|
||
|
|
def getCompanyList(self, request):
|
||
|
|
"""
|
||
|
|
后台用户获得公司列表
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
if 2 == request.user.label:
|
||
|
|
companies = Company.objects.all().values('id', 'name')
|
||
|
|
result = [item for item in companies]
|
||
|
|
else:
|
||
|
|
return CCAIResponse()
|
||
|
|
return CCAIResponse(result)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, getUserCompanyInfo failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取用户公司信息失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getMainUserList", url_name="getMainUserList")
|
||
|
|
def getMainUserList(self, request):
|
||
|
|
"""
|
||
|
|
获取主账户id,username,name,MainId
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
keyword = request.GET.get('keyword')
|
||
|
|
query = Q(is_sub=2)
|
||
|
|
if keyword:
|
||
|
|
query &= (Q(username__icontains=keyword) | Q(name__icontains=keyword))
|
||
|
|
mainUser = UserProfile.objects.filter(query).values('id', 'username', 'name', 'MainId')
|
||
|
|
return CCAIResponse(mainUser)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, getMainUser list failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取主用户列表失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getUserCompanyInfo", url_name="getUserCompanyInfo")
|
||
|
|
def getUserCompanyInfo(self, request):
|
||
|
|
try:
|
||
|
|
params = request.GET
|
||
|
|
companyMid = params.get('companyMid')
|
||
|
|
query = Q(MainId=companyMid)
|
||
|
|
try:
|
||
|
|
company = Company.objects.get(query)
|
||
|
|
except ObjectDoesNotExist:
|
||
|
|
return CCAIResponse('缺少公司参数', BAD)
|
||
|
|
data = CompanySerializer(company).data
|
||
|
|
if data.get('tech'):
|
||
|
|
data['tech'] = [int(x) for x in data['tech'].split(',')]
|
||
|
|
if 'tolerance' in data:
|
||
|
|
data['tolerance'] = time_int_to_str(data['tolerance'])
|
||
|
|
return CCAIResponse(data)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, getUserCompanyInfo failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取用户公司信息失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="getTechnologyTree", url_name="getTechnologyTree")
|
||
|
|
def getTechnologyTree(self, request):
|
||
|
|
"""
|
||
|
|
技术领域树
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
dataDictionary = DataDictionary.objects.get(DictionaryCode='TechArea')
|
||
|
|
dataDictionaryDetail = DataDictionaryDetail.objects.filter(
|
||
|
|
DataDictionaryId=dataDictionary.DataDictionaryId).values('id', 'DataDictionaryDetailId', 'ParentId',
|
||
|
|
'DictionaryCode', 'DictionaryValue', 'ParentCode',
|
||
|
|
'FullName')
|
||
|
|
data = DictDetailSerializer(dataDictionaryDetail, many=True)
|
||
|
|
tree_dict = {}
|
||
|
|
for item in data.data:
|
||
|
|
if item["parent_id"] is None:
|
||
|
|
item["children"] = []
|
||
|
|
top_permission = copy.deepcopy(item)
|
||
|
|
tree_dict[item["dict_detail_id"]] = top_permission
|
||
|
|
else:
|
||
|
|
children_permission = copy.deepcopy(item)
|
||
|
|
tree_dict[item["dict_detail_id"]] = children_permission
|
||
|
|
|
||
|
|
tree_data = []
|
||
|
|
for i in tree_dict:
|
||
|
|
if tree_dict[i]["parent_id"]:
|
||
|
|
pid = tree_dict[i]["parent_id"]
|
||
|
|
parent = tree_dict[pid]
|
||
|
|
parent.setdefault("children", []).append(tree_dict[i])
|
||
|
|
# from operator import itemgetter
|
||
|
|
# parent["children"] = sorted(parent["children"], key=itemgetter("id"))
|
||
|
|
else:
|
||
|
|
tree_data.append(tree_dict[i])
|
||
|
|
return CCAIResponse(tree_data, status=OK)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, getUserCompanyInfo failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("获取用户公司信息失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="download", url_name="download")
|
||
|
|
def download(self, request):
|
||
|
|
"""
|
||
|
|
导入模板下载
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
# 查询公司的项目列表
|
||
|
|
companymid = request.GET.get('companyMid')
|
||
|
|
if not companymid:
|
||
|
|
return CCAIResponse('Missing or invalid company information', BAD)
|
||
|
|
company = Company.objects.filter(MainId=companymid).first()
|
||
|
|
if not company:
|
||
|
|
return CCAIResponse('Company param error', BAD)
|
||
|
|
|
||
|
|
users = UserProfile.objects.filter(is_sub=2, is_active=1, MainId__isnull=False).values("id", "name", "username", "MainId")
|
||
|
|
username_user = [str((item['name'] if item['name'] else '') + '(' + item['username'] + ')') for item in users] # 使用用户姓名(账号) 做唯一
|
||
|
|
|
||
|
|
title_data = ["*公司名称", "*拥有者", "企业统一信用代码", "高企编码", "企业员工总数"]
|
||
|
|
name = str(int(time.time() * 10000)) # 时间戳命名
|
||
|
|
workbook = openpyxl.Workbook()
|
||
|
|
worksheet = workbook.active
|
||
|
|
worksheet.title = "公司导入模板"
|
||
|
|
|
||
|
|
# 添加隐藏的选项参考表
|
||
|
|
worksheet2 = workbook.create_sheet("选项参考表")
|
||
|
|
worksheet2.sheet_state = "hidden" # 将工作表隐藏起来
|
||
|
|
worksheet2.cell(1, 1, '拥有者参考')
|
||
|
|
|
||
|
|
# 写入拥有者参考数据
|
||
|
|
for idx, project in enumerate(username_user, start=2): # 从第二行开始写入数据
|
||
|
|
worksheet2.cell(idx, 1, str(project))
|
||
|
|
|
||
|
|
for index, item in enumerate(title_data, start=1):
|
||
|
|
worksheet.cell(1, index, item)
|
||
|
|
worksheet['A1'].comment = Comment("必填项,请输入正确的公司名称!", 'Author')
|
||
|
|
worksheet['B1'].comment = Comment("必填项,请从提供的选项中选择!", 'Author')
|
||
|
|
|
||
|
|
# 创建一个数据有效性验证对象
|
||
|
|
usersDv = DataValidation(type="list", formula1=f'=选项参考表!$A$2:$A${len(username_user) + 1}', showErrorMessage=True, errorTitle="输入错误",
|
||
|
|
error="请从给定的选项中选择")
|
||
|
|
|
||
|
|
# 数据有效性验证应用
|
||
|
|
worksheet.add_data_validation(usersDv)
|
||
|
|
|
||
|
|
usersDv.add(CellRange("B2:B10000"))
|
||
|
|
|
||
|
|
# 设置第一列的数据格式为文本类型
|
||
|
|
worksheet.column_dimensions['A'].number_format = '@'
|
||
|
|
worksheet.column_dimensions['C'].number_format = '@'
|
||
|
|
worksheet.column_dimensions['D'].number_format = '@'
|
||
|
|
|
||
|
|
# worksheet.cell(2, 10).value = '=H2*I2'
|
||
|
|
# for row in range(2, 10000):
|
||
|
|
# worksheet.cell(row, 10).value = '=IF(ISBLANK(H{}) OR ISBLANK(I{}), "", H{}*I{})'.format(row, row, row, row)
|
||
|
|
|
||
|
|
workbook.save(filename=name + ".xlsx")
|
||
|
|
fileName = name + ".xlsx"
|
||
|
|
file = open(fileName, 'rb')
|
||
|
|
s_name = "公司导入模板.xlsx"
|
||
|
|
response = FileResponse(file)
|
||
|
|
response['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' # 规定返回xlsx
|
||
|
|
response['Content-Disposition'] = f'attachment;filename="{s_name}"'
|
||
|
|
response['file_name'] = fileName
|
||
|
|
|
||
|
|
# 异步删除文件
|
||
|
|
threadPool.submit(asyncDeleteFile, request, fileName)
|
||
|
|
|
||
|
|
return response
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, get company template file failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("下载公司导入模板失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
@action(methods=["post"], detail=False, permission_classes=[IsAuthenticated],
|
||
|
|
url_path="import_excel", url_name="import_excel")
|
||
|
|
def import_excel(self, request):
|
||
|
|
"""导入excel表数据"""
|
||
|
|
try:
|
||
|
|
data = req_operate_by_user(request)
|
||
|
|
file_name = data.get('file_name')
|
||
|
|
|
||
|
|
if not file_name:
|
||
|
|
return CCAIResponse('Missing params', BAD)
|
||
|
|
|
||
|
|
|
||
|
|
users = UserProfile.objects.filter(is_sub=2, is_active=1, MainId__isnull=False).values("id", "name", "username", "MainId")
|
||
|
|
username_user = {str((item['name'] if item['name'] else '') + '(' + item['username'] + ')'): item['MainId'] for item in users} # 使用用户姓名(账号) 做唯一
|
||
|
|
|
||
|
|
company_list = []
|
||
|
|
excel_file_list = []
|
||
|
|
|
||
|
|
file_paths = file_name.split(",")
|
||
|
|
for key in range(len(file_paths)):
|
||
|
|
if file_paths[key] == '' or file_paths[key] is None:
|
||
|
|
continue
|
||
|
|
excel_file = file_paths[key].replace(settings.SHOW_UPLOAD_PATH, settings.FILE_PATH)
|
||
|
|
excel_file_list.append(excel_file)
|
||
|
|
|
||
|
|
# 打开工作文件
|
||
|
|
workbook = openpyxl.load_workbook(excel_file, data_only=True)
|
||
|
|
table = workbook['公司导入模板']
|
||
|
|
# table = workbook.active
|
||
|
|
rows = table.max_row # 总行数
|
||
|
|
check_value = [table.cell(row=1, column=i).value for i in range(1, 4)] # 获取第一行的值
|
||
|
|
if check_value[0] != '*公司名称' and check_value[1] != '*拥有者' and check_value[2] != '*企业统一信用代码':
|
||
|
|
return CCAIResponse("文件不符合模板标准", SERVER_ERROR)
|
||
|
|
user_data = [] # 项目编号列
|
||
|
|
for row in islice(table.iter_rows(values_only=True), 1, None):
|
||
|
|
if row[1]:
|
||
|
|
user_data.append(row[0]) # 项目编号列
|
||
|
|
|
||
|
|
try:
|
||
|
|
columns = ["companyName", "userName", "EUCC", "hightechCode", "employeesCount"]
|
||
|
|
columns_name = ["企业名称", "拥有者", "企业同一信用代码", "高企编码", "员工人数"]
|
||
|
|
errorTable = ErrorTable(columns)
|
||
|
|
# 循环外层控制事务,因为物料记录的创建依赖与项目分摊的创建
|
||
|
|
with transaction.atomic():
|
||
|
|
for rindex, row in enumerate(islice(table.iter_rows(values_only=True), 1, None)):
|
||
|
|
# 跳过空白隐藏行
|
||
|
|
if all(cell is None for cell in row):
|
||
|
|
continue
|
||
|
|
|
||
|
|
row_value = [r for r in row]
|
||
|
|
check_index = [0, 1,]
|
||
|
|
# 校验必填项
|
||
|
|
skip = False
|
||
|
|
for index in check_index: # 前2项为必填项
|
||
|
|
if row[index] is None or row[index] == '':
|
||
|
|
skip = True
|
||
|
|
errorTable.add_one_row(row_value, f'{columns_name[index]}为必填项')
|
||
|
|
break
|
||
|
|
if skip:
|
||
|
|
skip = False
|
||
|
|
continue
|
||
|
|
|
||
|
|
if str(row[1]) not in username_user:
|
||
|
|
errorTable.add_one_row(row_value, f'用户错误')
|
||
|
|
continue
|
||
|
|
|
||
|
|
# 获取对应的用户
|
||
|
|
userMid = username_user[str(row[1])]
|
||
|
|
try:
|
||
|
|
user = UserProfile.objects.get(MainId=userMid)
|
||
|
|
except UserProfile.DoesNotExist:
|
||
|
|
errorTable.add_one_row(row_value, f'用户错误')
|
||
|
|
continue
|
||
|
|
# 新增公司
|
||
|
|
companyMid = uuid.uuid4().__str__() # 公司mid
|
||
|
|
company = Company()
|
||
|
|
company.name = str(row_value[0])
|
||
|
|
company.MainId = companyMid
|
||
|
|
company.userMid = userMid
|
||
|
|
if row_value[2]:
|
||
|
|
company.EUCC = str(row_value[2])
|
||
|
|
if row_value[3]:
|
||
|
|
company.hightechCode = str(row_value[3])
|
||
|
|
company.employeesCount = int(row_value[4]) if row_value[4] else 0
|
||
|
|
|
||
|
|
company.save()
|
||
|
|
user.company.add(company)
|
||
|
|
|
||
|
|
if errorTable.has_data(): # 存在错误信息,回滚并返回所有错误行的提示信息
|
||
|
|
transaction.set_rollback(True)
|
||
|
|
return CCAIResponse(errorTable.get_table(), 200)
|
||
|
|
|
||
|
|
except MyCustomError as e:
|
||
|
|
return CCAIResponse(f'文件读取第{rindex}行数据多于标题列', BAD)
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, 文件路径:%s 记录公司导入错误日志: \n%s" % (request.user.id, excel_file, traceback.format_exc()))
|
||
|
|
return CCAIResponse('数据有误,请检查后重新导入', BAD)
|
||
|
|
|
||
|
|
try:
|
||
|
|
for file_path in excel_file_list:
|
||
|
|
# 异步删除文件
|
||
|
|
threadPool.submit(asyncDeleteFile, request, file_path)
|
||
|
|
# if os.path.exists(file_path): # 如果文件存在
|
||
|
|
# # 删除文件,可使用以下两种方法。
|
||
|
|
# os.remove(file_path)
|
||
|
|
# # 删除空目录,不是空目录时候rmdir不会删除
|
||
|
|
# # try:
|
||
|
|
# # os.rmdir(file_path)
|
||
|
|
# # except Exception as e:
|
||
|
|
# # logger.error("user: %s, rmdir highTech failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, import_excel view create failed: \n%s" % (
|
||
|
|
request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("导入存入失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
return CCAIResponse(data="success")
|
||
|
|
except Exception as e:
|
||
|
|
err_logger.error("user: %s, import aigc file failed: \n%s" % (request.user.id, traceback.format_exc()))
|
||
|
|
return CCAIResponse("导入公司名单失败", SERVER_ERROR)
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
class CompanyNameListAPIView(APIView):
|
||
|
|
authentication_classes = (JSONWebTokenAuthentication,)
|
||
|
|
permission_classes = (IsAuthenticated,)
|
||
|
|
|
||
|
|
'''
|
||
|
|
获取公司名称列表
|
||
|
|
'''
|
||
|
|
# throttle_classes = (AnonRateThrottle, UserRateThrottle)
|
||
|
|
|
||
|
|
def get(self, request, format=None):
|
||
|
|
blurry_company_info_req = ''
|
||
|
|
try:
|
||
|
|
params = request.GET
|
||
|
|
company_name = params.get('company_name')
|
||
|
|
|
||
|
|
rows = []
|
||
|
|
qixinbao_failed = False
|
||
|
|
if company_name:
|
||
|
|
blurry_company_info_req = getBlurryCompanyInfo(request, company_name, 0)
|
||
|
|
if blurry_company_info_req:
|
||
|
|
base_info = blurry_company_info_req.json()
|
||
|
|
if base_info['status'] == '200':
|
||
|
|
companys = base_info['data']['items']
|
||
|
|
for company in companys:
|
||
|
|
dict = {'value': company['name']}
|
||
|
|
rows.append(dict)
|
||
|
|
|
||
|
|
# rows = [
|
||
|
|
# {'value':"深圳市骏鼎达新材料股份有限公司"},
|
||
|
|
# {'value':"东莞市骏鼎达新材料科技有限公司"},
|
||
|
|
# {'value':"昆山骏鼎达电子科技有限公司"},
|
||
|
|
# {'value':"苏州骏鼎达新材料科技有限公司"},
|
||
|
|
# {'value':"江门骏鼎达新材料科技有限公司"},
|
||
|
|
# {'value':"深圳市骏鼎达新材料股份有限公司重庆分公司"},
|
||
|
|
# {'value':"深圳市骏鼎达新材料股份有限公司武汉分公司"},
|
||
|
|
# {'value':"龙川县骏鼎达新材料有限公司"},
|
||
|
|
# {'value':"佛山市骏鼎达五金有限公司"},
|
||
|
|
# {'value':"駿鼎達國際有限公司"}
|
||
|
|
# ]
|
||
|
|
|
||
|
|
return CCAIResponse(rows)
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
logger.error("user: %s, get blurry company failed: %s, detail: %s" % (request.user.id, traceback.format_exc(), blurry_company_info_req))
|
||
|
|
return CCAIResponse("获取地区失败", SERVER_ERROR)
|