second commit

main
unknown 6 months ago
parent e74141ac37
commit 6529363ff9

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="crm/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
</list>
</option>
</component>
</module>

@ -0,0 +1,17 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="3">
<item index="0" class="java.lang.String" itemvalue="mysqlclient" />
<item index="1" class="java.lang.String" itemvalue="cffi" />
<item index="2" class="java.lang.String" itemvalue="ez-setup" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (Django_CRM_System-master)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (Django_CRM_System-master)" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Django_CRM_System-master.iml" filepath="$PROJECT_DIR$/.idea/Django_CRM_System-master.iml" />
</modules>
</component>
</project>

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SalesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'sales'

@ -0,0 +1,66 @@
from django.db import models
# Create your models here.
class ModelManager(models.Manager):
def get_queryset(self):
return super(ModelManager, self).get_queryset().filter(isValid=1)
# 营销机会模型
class SaleChance(models.Model):
# 信息来源
chanceSource = models.CharField(max_length=300, db_column='chance_source')
# 客户id
customerId = models.IntegerField(db_column='customer_id')
# 客户名称
customerName = models.CharField(max_length=100, db_column='customer_name')
# 成功几率
cgjl = models.IntegerField(db_column='cgjl')
# 概要
overview = models.CharField(max_length=300, db_column='overview')
# 联系人
linkMan = models.CharField(max_length=20, db_column='link_man')
# 联系电话
linkPhone = models.CharField(max_length=20, db_column='link_phone')
# 描述
description = models.CharField(max_length=1000, db_column='description')
# 创建人
createMan = models.CharField(max_length=20, db_column='create_man')
# 分配给谁
assignMan = models.CharField(max_length=20, db_column='assign_man')
# 分配时间
assignTime = models.DateTimeField(db_column='assign_time')
# 状态1-如果有分配就是已分配状态0-未分配
state = models.CharField(max_length=20, db_column='state')
# 开发状态0=未开发 1=开发中 2=开完完成 3=开发失败
devResult = models.CharField(max_length=20, db_column='dev_result')
isValid = models.IntegerField(db_column='is_valid', default=1)
createDate = models.DateTimeField(db_column='create_date', auto_now_add=True)
updateDate = models.DateTimeField(max_length=20, db_column='update_date')
objects = ModelManager()
class Meta:
db_table = 't_sale_chance'
# 客户计划模型
class CusDevPlan(models.Model):
# 关联营销机会
saleChance = models.ForeignKey(SaleChance, db_constraint=False,
db_column='sale_chance_id',
on_delete=models.DO_NOTHING)
# 计划内容
planItem = models.CharField(max_length=300, db_column='plan_item')
# 计划时间
planDate = models.DateTimeField(max_length=20, db_column='plan_date')
# 执行效果
exeAffect = models.CharField(max_length=100, db_column='exe_affect')
isValid = models.IntegerField(db_column='is_valid')
createDate = models.DateTimeField(db_column='create_date')
updateDate = models.DateTimeField(max_length=20, db_column='update_date')
objects = ModelManager()
class Meta:
db_table = 't_cus_dev_plan'

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,38 @@
from django.urls import path, include
from . import views
app_name = 'sales'
urlpatterns = [
path('index/', views.sales_index, name='sales_index'),
path('list/', views.select_sale_chance_list, name='select_sale_chance_list'),
# 添加/修改营销机会
path('create_or_update/', views.create_or_update_sales,
name='create_or_update_sales'),
path('customer/', views.select_customer, name='select_customer'),
path('create/', views.create_sale_chance, name='create_sale_chance'),
path('update/', views.update_sale_chance, name='update_sale_chance'),
# 删除营销机会
path('delete/', views.delete_sale_chance, name='delete_sale_chance'),
path('cus_dev_plan/index/', views.cus_dev_plan_index, name='cus_dev_plan_index'),
path('cus_dev_plan/detail/', views.cus_dev_plan_index_detail,
name='cus_dev_plan_index_detail'),
path('cus_dev_plan/list/', views.select_cus_dev_plan_list,
name='select_cus_dev_plan_list'),
# 添加/修改/删除开发计划
path('cus_dev_plan/create_or_update/', views.create_or_update_cus_dev_plan,
name='create_or_update_cus_dev_plan'),
path('cus_dev_plan/create/', views.create_cus_dev_plan,
name='create_cus_dev_plan'),
path('cus_dev_plan/update/', views.update_cus_dev_plan,
name='update_cus_dev_plan'),
path('cus_dev_plan/delete/', views.delete_cus_dev_plan,
name='delete_cus_dev_plan'),
path('cus_dev_plan/dev_result/', views.update_dev_result,
name='update_dev_result'),
]

@ -0,0 +1,319 @@
from datetime import datetime
from django.shortcuts import render
import pymysql
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET
from customer.models import Customer, LinkMan
from sales.models import SaleChance, CusDevPlan
from system.models import TUser
@xframe_options_exempt
@require_GET
def sales_index(request):
"""跳转营销管理首页"""
return render(request, 'sales/sale_chance.html')
@require_GET
def select_sale_chance_list(request):
try:
page_num = request.GET.get('page') # 页号
page_size = request.GET.get('limit') # 页容量
state = request.GET.get('state')
# 客户名称
customerName = request.GET.get('customerName')
# 创建人
createMan = request.GET.get('createMan')
# 开发状态(客户开发计划使用)
devResult = request.GET.get('devResult')
if customerName:
users = SaleChance.objects.filter(isValid=1, customerName=customerName).values()
elif createMan:
users = SaleChance.objects.filter(isValid=1, createMan=createMan).values()
elif state:
users = SaleChance.objects.filter(isValid=1, state=state).values()
elif devResult:
users = SaleChance.objects.filter(isValid=1, devResult=devResult).values()
else:
users = SaleChance.objects.filter(isValid=1).values()
paginator = Paginator(users, page_size)
users_list = paginator.page(page_num).object_list
context = {
'code': 0,
'msg': '',
'count': len(users),
'data': list(users_list)
}
return JsonResponse(context)
except Exception as e:
return JsonResponse({'code': 400, 'msg': 'error'})
@xframe_options_exempt
@require_GET
def create_or_update_sales(request):
"""跳转添加/修改营销机会页面"""
# 获取营销机会主键
saleChanceId = request.GET.get('saleChanceId')
context = None
if saleChanceId:
# 根据营销机会主键查询
sc = SaleChance.objects.get(pk=saleChanceId)
context = {'sc': sc}
return render(request, 'sales/add_update.html', context)
@require_GET
def select_customer(request):
"""查询客户"""
customer = Customer.objects.values("id", 'name') \
.filter(isValid=1).order_by('-id').all()
return JsonResponse(list(customer), safe=False)
@csrf_exempt
@require_GET
def create_sale_chance(request):
"""添加营销机会和联系人"""
try:
# 接收参数
customerId = request.GET.get('customer')
customerName = request.GET.get('customerName')
chanceSource = request.GET.get('chanceSource')
linkMan = request.GET.get('linkMan')
linkPhone = request.GET.get('linkPhone')
cgjl = request.GET.get('cgjl')
overview = request.GET.get('overview')
description = request.GET.get('description')
assignMan = request.GET.get('assignMan')
# 如果有联系人还要添加联系人表数据
if linkMan:
lm = LinkMan(cusId=customerId, linkName=linkMan, phone=linkPhone)
lm.save()
# 如果有分配人,添加分配时间,分配状态为已分配
if assignMan != '0':
sc = SaleChance(customerId=customerId, customerName=customerName,
chanceSource=chanceSource, linkMan=linkMan,
linkPhone=linkPhone,
cgjl=cgjl, overview=overview, description=description,
assignMan=assignMan, assignTime=datetime.now(), state=1,
devResult=0,
createMan=request.session.get('user')['username'])
else:
sc = SaleChance(customerId=customerId, customerName=customerName,
chanceSource=chanceSource, linkMan=linkMan,
linkPhone=linkPhone,
cgjl=cgjl, overview=overview, description=description,
state=0, devResult=0,
createMan=request.session.get('user')['username'])
# 插入数据
sc.save()
# 返回提示信息
return JsonResponse({'code': 200, 'msg': '添加成功'})
except Exception as e:
return JsonResponse({'code': 400, 'msg': '添加失败'})
@csrf_exempt
@require_GET
def update_sale_chance(request):
"""修改营销机会和联系人"""
try:
# 接收参数
id = request.GET.get('id')
customerId = request.GET.get('customer')
customerName = request.GET.get('customerName')
chanceSource = request.GET.get('chanceSource')
linkMan = request.GET.get('linkMan')
linkPhone = request.GET.get('linkPhone')
cgjl = request.GET.get('cgjl')
overview = request.GET.get('overview')
description = request.GET.get('description')
assignMan = request.GET.get('assignMan')
# 根据主键查询营销机会
sc = SaleChance.objects.get(pk=id)
# 如果有联系人还要修改联系人表数据
if linkMan != sc.linkMan:
LinkMan.objects.filter(cusId=customerId) \
.update(linkName=linkMan, phone=linkPhone, updateDate=datetime.now())
# 如果用户取消了分配人,要改变分配状态为未分配
if assignMan == '0':
sc.state = 0
sc.assignMan = None
sc.assignTime = None
else:
sc.state = 1
sc.assignMan = assignMan
sc.assignTime = datetime.now()
# 重新赋值
sc.customerId = customerId
sc.customerName = customerName
sc.chanceSource = chanceSource
sc.linkMan = linkMan
sc.linkPhone = linkPhone
sc.cgjl = cgjl
sc.overview = overview
sc.description = description
sc.updateDate = datetime.now()
# 保存
sc.save()
# 返回提示信息
return JsonResponse({'code': 200, 'msg': '修改成功'})
except Exception as e:
return JsonResponse({'code': 400, 'msg': '修改失败'})
@csrf_exempt
@require_GET
def delete_sale_chance(request):
"""删除营销机会"""
try:
# 接收参数
ids = request.GET.get('ids')
id_list = list(map(int, ids.split(",")))
SaleChance.objects.filter(pk__in=id_list).delete()
return JsonResponse({'code': 200, 'msg': '删除成功'})
except Exception as e:
return JsonResponse({'code': 400, 'msg': '删除失败'})
@xframe_options_exempt
@require_GET
def cus_dev_plan_index(request):
"""跳转营销机会管理首页"""
return render(request, 'sales/cus_dev_plan.html')
@xframe_options_exempt
@require_GET
def cus_dev_plan_index_detail(request):
"""跳转客户开发计划详情页"""
# 接收参数
saleChanceId = request.GET.get('saleChanceId')
# 根据主键查询营销机会
sc = SaleChance.objects.get(pk=saleChanceId)
context = {'sc': sc}
return render(request, 'sales/cus_dev_plan_detail.html', context)
@require_GET
def select_cus_dev_plan_list(request):
"""查询客户开发计划详细列表"""
try:
# 获取第几页
page_num = request.GET.get('page', 1)
# 获取每页多少条
page_size = request.GET.get('limit', 10)
# 获取客户营销机会主键
saleChanceId = request.GET.get('saleChanceId')
# 查询
cdp_list = CusDevPlan.objects.extra(select={'planDate': 'date_format(plan_date, "%%Y-%%m-%%d")'}) \
.values('id', 'planItem', 'planDate', 'exeAffect', 'saleChance') \
.filter(saleChance=saleChanceId).order_by('-id')
# 初始化分页对象
p = Paginator(cdp_list, page_size)
# 获取指定页数的数据
data = p.page(page_num).object_list
# 返回总条数
count = p.count
# 返回数据,按照 layuimini 要求格式构建
context = {
'code': 0,
'msg': '',
'count': count,
'data': list(data)
}
return JsonResponse(context)
except Exception as e:
return JsonResponse({'code': 400, 'msg': 'error'})
@xframe_options_exempt
@require_GET
def create_or_update_cus_dev_plan(request):
"""跳转客户开发计划添加/修改页面"""
# 获取营销机会主键
saleChanceId = request.GET.get('saleChanceId')
# 获取客户开发计划主键
id = request.GET.get('id')
context = {'saleChanceId': saleChanceId}
if id:
cusDevPlan = CusDevPlan.objects.get(pk=id)
context['cusDevPlan'] = cusDevPlan
return render(request, 'sales/cus_dev_plan_add_update.html', context)
@csrf_exempt
@require_GET
def create_cus_dev_plan(request):
"""添加客户开发计划"""
# 接收参数
data = request.GET.dict()
# 弹出营销机会主键
saleChanceId = data.pop('saleChanceId')
# 删除主键
del data['id']
# 获取营销机会对象
sc = SaleChance.objects.get(pk=saleChanceId)
data['saleChance'] = sc
# 添加客户开发计划
CusDevPlan.objects.create(**data)
# 修改营销机会的开发状态为开发中
sc.devResult = 1
sc.updateDate = datetime.now()
sc.save()
return JsonResponse({'code': 200, 'msg': '添加成功'})
@csrf_exempt
@require_GET
def update_cus_dev_plan(request):
"""修改客户开发计划"""
# 接收参数
data = request.GET.dict()
# 弹出营销机会主键
saleChanceId = data.pop('saleChanceId')
# 删除主键
id = data.pop('id')
# 修改时间
data['updateDate'] = datetime.now()
# 修改客户开发计划
CusDevPlan.objects.filter(pk=id).update(**data)
return JsonResponse({'code': 200, 'msg': '修改成功'})
@csrf_exempt
@require_GET
def delete_cus_dev_plan(request):
"""删除客户开发计划"""
# 获取主键
id = request.GET.get('id')
# 逻辑删除客户开发计划
CusDevPlan.objects.filter(pk=id).update(isValid=0, updateDate=datetime.now())
return JsonResponse({'code': 200, 'msg': '删除成功'})
@csrf_exempt
@require_GET
def update_dev_result(request):
"""开发成功或者开发失败"""
# 接收参数
saleChanceId = request.GET.get('saleChanceId')
devResult = request.GET.get('devResult')
SaleChance.objects.filter(pk=saleChanceId).update(devResult=devResult,
updateDate=datetime.now())
return JsonResponse({'code': 200, 'msg': '操作成功'})

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

@ -0,0 +1,6 @@
from django.apps import AppConfig
class ServeConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'serve'

@ -0,0 +1,49 @@
from django.db import models
# Create your models here.
from django.db import models
class ModelManager(models.Manager):
def get_queryset(self):
return super(ModelManager, self).get_queryset().filter(isValid=1)
# 服务模型
class CustomerServe(models.Model):
# 服务类型 咨询/建议/投诉
serveType = models.CharField(db_column='serve_type', max_length=50)
# 概要
overview = models.CharField(db_column='overview', max_length=500)
# 客户
customer = models.CharField(db_column='customer', max_length=30)
# 新创建/已分配/已处理/已归档
state = models.CharField(db_column='state', max_length=10)
# 服务请求
serviceRequest = models.CharField(db_column='service_request', max_length=500)
# 创建人
createPeople = models.CharField(db_column='create_people', max_length=100)
# 分配人
assigner = models.CharField(db_column='assigner', max_length=100)
# 分配日期
assignTime = models.DateTimeField(db_column='assign_time')
# 服务处理
serviceProce = models.CharField(db_column='service_proce', max_length=500)
# 服务处理人
serviceProcePeople = models.CharField(db_column='service_proce_people',
max_length=50)
# 服务处理日期
serviceProceTime = models.DateTimeField(db_column='service_proce_time')
# 服务处理结果
serviceProceResult = models.CharField(db_column='service_proce_result',
max_length=500)
# 客户满意度
myd = models.CharField(db_column='myd', max_length=50)
isValid = models.IntegerField(db_column='is_valid', default=1)
createDate = models.DateTimeField(db_column='create_date', auto_now_add=True)
updateDate = models.DateTimeField(db_column='update_date', auto_now_add=True)
objects = ModelManager()
class Meta:
db_table = 't_customer_serve'

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,12 @@
from django.urls import path
from . import views
app_name = 'serve'
urlpatterns = [
path('<str:template>/index/', views.serve_index, name='serve_index'),
path('list/', views.select_serve_list, name='select_serve_list'),
path('<str:template>/workflow/', views.serve_workflow, name='serve_workflow'),
path('create/', views.create_serve, name='create_serve'),
path('update/', views.update_serve, name='update_serve'),
]

@ -0,0 +1,121 @@
from datetime import datetime
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
from django.shortcuts import render
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET
from serve.models import CustomerServe
# Create your views here.
@xframe_options_exempt
@require_GET
def serve_index(request, template):
"""跳转服务管理各个功能首页"""
context = {'username': request.session.get('user')['username']}
'''
create 创建 assign 分配
handle 处理
feedback 反馈 archive 归档
'''
return render(request, 'serve/%s.html' % template, context)
@require_GET
def select_serve_list(request):
"""工作流程中多个页面的公共查询"""
try:
# 获取第几页
page_num = request.GET.get('page', 1)
# 获取每页多少条
page_size = request.GET.get('limit', 10)
# 查询
select_dict = {
'assignTime': 'select DATE_FORMAT(assign_time, "%%Y-%%m-%%d-%%H:%%i:%%s")',
'serviceProceTime': 'select DATE_FORMAT(service_proce_time, "%%Y-%%m-%%d-%%H:%%i:%%s")',
'createDate': 'select DATE_FORMAT(create_date, "%%Y-%%m-%%d-%%H:%%i:%%s")',
'updateDate': 'select DATE_FORMAT(update_date, "%%Y-%%m-%%d-%%H:%%i:%%s")',
}
queryset = CustomerServe.objects.extra(select=select_dict) \
.values().order_by('-id').all()
# 条件查询
# 服务状态1 新创建 / 2 已分配 / 3 已处理 / 4 已反馈
state = request.GET.get('state')
if state:
queryset = queryset.filter(state=state)
# 客户
customer = request.GET.get('customer')
if customer:
queryset = queryset.filter(customer__icontains=customer)
# 服务类型6 咨询 / 7 投诉 / 8 建议
serveType = request.GET.get('serveType')
if serveType:
queryset = queryset.filter(serveType=serveType)
# 初始化分页对象
p = Paginator(queryset, page_size)
# 获取指定页数的数据
data = p.page(page_num).object_list
# 返回总条数
count = p.count
# 返回数据,按照 layuimini 要求格式构建
context = {
'code': 0,
'msg': '',
'count': count,
'data': list(data)
}
return JsonResponse(context)
except Exception as e:
return JsonResponse({'code': 400, 'msg': 'error'})
@xframe_options_exempt
@require_GET
def serve_workflow(request, template):
"""工作流程中多个子页面的公共函数"""
context = {'username': request.session.get('user')['username']}
# 获取服务主键
id = request.GET.get('id')
if id:
context['cs'] = CustomerServe.objects.get(pk=id)
return render(request, 'serve/%s_serve.html' % template, context)
@csrf_exempt
@require_GET
def create_serve(request):
"""创建服务"""
# 接收参数
data = request.GET.dict()
# 添加
CustomerServe.objects.create(**data)
return JsonResponse({'code': 200, 'msg': '创建成功'})
@csrf_exempt
@require_GET
def update_serve(request):
"""修改服务公共函数"""
# 接收参数
serve = request.GET.dict()
# 弹出主键
id = serve.pop('id')
# 获取分配状态
state = serve.get('state')
# 如果是 2 已分配,修改分配时间
if state == '2':
serve['assignTime'] = datetime.now()
# 如果是 3 已处理,修改处理时间
elif state == '3':
serve['serviceProceTime'] = datetime.now()
# 当条记录修改时间
serve['updateDate'] = datetime.now()
CustomerServe.objects.filter(pk=id).update(**serve)
return JsonResponse({'code': 200, 'message': '操作成功'})
Loading…
Cancel
Save