parent
b2df486ee1
commit
5ccff4d2fc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CustomerConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'customer'
|
@ -0,0 +1,139 @@
|
||||
# Generated by Django 3.2.9 on 2024-05-29 16:44
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.db.models.manager
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Customer',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('khno', models.CharField(max_length=20, unique=True)),
|
||||
('name', models.CharField(max_length=20)),
|
||||
('area', models.CharField(max_length=20)),
|
||||
('cusManager', models.CharField(db_column='cus_manager', max_length=30)),
|
||||
('level', models.CharField(max_length=30)),
|
||||
('myd', models.CharField(max_length=30)),
|
||||
('xyd', models.CharField(max_length=30)),
|
||||
('address', models.CharField(max_length=100)),
|
||||
('postCode', models.CharField(db_column='post_code', max_length=10)),
|
||||
('phone', models.CharField(max_length=18)),
|
||||
('fax', models.CharField(max_length=20)),
|
||||
('website', models.CharField(db_column='web_site', max_length=50)),
|
||||
('yyzzzch', models.CharField(max_length=50)),
|
||||
('fr', models.CharField(max_length=20)),
|
||||
('zczj', models.CharField(max_length=20)),
|
||||
('nyye', models.CharField(max_length=20)),
|
||||
('khyh', models.CharField(max_length=20)),
|
||||
('khzh', models.CharField(max_length=20)),
|
||||
('dsdjh', models.CharField(max_length=20)),
|
||||
('gsdjh', models.CharField(max_length=20)),
|
||||
('state', models.IntegerField(default=0)),
|
||||
('isValid', models.IntegerField(db_column='is_valid', default=1)),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_customer',
|
||||
},
|
||||
managers=[
|
||||
('all', django.db.models.manager.Manager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomerLoss',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cusNo', models.CharField(db_column='cus_no', max_length=40)),
|
||||
('cusName', models.CharField(db_column='cus_name', max_length=20)),
|
||||
('cusManager', models.CharField(db_column='cus_manager', max_length=20)),
|
||||
('lastOrderTime', models.DateTimeField(db_column='last_order_time')),
|
||||
('confirmLossTime', models.DateTimeField(db_column='confirm_loss_time')),
|
||||
('state', models.IntegerField()),
|
||||
('lossReason', models.CharField(db_column='loss_reason', max_length=1000)),
|
||||
('isValid', models.IntegerField(db_column='is_valid', default=1)),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_customer_loss',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomerOrders',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('orderNo', models.DateTimeField(db_column='order_no')),
|
||||
('orderDate', models.DateTimeField(auto_now_add=True, db_column='order_date')),
|
||||
('address', models.CharField(db_column='address', max_length=120)),
|
||||
('totalPrice', models.FloatField(db_column='total_price')),
|
||||
('state', models.IntegerField(choices=[(0, '未回款'), (1, '已回款')])),
|
||||
('isValid', models.IntegerField(db_column='is_valid')),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
('customer', models.ForeignKey(db_column='cus_id', on_delete=django.db.models.deletion.DO_NOTHING, to='customer.customer')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_customer_order',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LinkMan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cusId', models.IntegerField(db_column='cus_id')),
|
||||
('linkName', models.CharField(db_column='link_name', max_length=20)),
|
||||
('sex', models.CharField(max_length=4)),
|
||||
('zhiwei', models.CharField(db_column='zhiwei', max_length=20)),
|
||||
('officePhone', models.CharField(db_column='office_phone', max_length=20)),
|
||||
('phone', models.CharField(db_column='phone', max_length=20)),
|
||||
('isValid', models.IntegerField(db_column='is_valid', default=1)),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_customer_linkman',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrdersDetail',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('goodsName', models.CharField(db_column='goods_name', max_length=100)),
|
||||
('goodsNum', models.IntegerField(db_column='goods_num')),
|
||||
('unit', models.CharField(db_column='unit', max_length=10)),
|
||||
('price', models.FloatField(db_column='price')),
|
||||
('sum', models.FloatField(db_column='sum')),
|
||||
('isValid', models.IntegerField(db_column='is_valid')),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
('order', models.ForeignKey(db_column='order_id', on_delete=django.db.models.deletion.DO_NOTHING, to='customer.customerorders')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_order_details',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomerReprieve',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('measure', models.CharField(db_column='measure', max_length=1000)),
|
||||
('isValid', models.IntegerField(db_column='is_valid', default=1)),
|
||||
('createDate', models.DateTimeField(auto_now_add=True, db_column='create_date')),
|
||||
('updateDate', models.DateTimeField(auto_now_add=True, db_column='update_date')),
|
||||
('customerLoss', models.ForeignKey(db_column='loss_id', db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, to='customer.customerloss')),
|
||||
],
|
||||
options={
|
||||
'db_table': 't_customer_reprieve',
|
||||
},
|
||||
),
|
||||
]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
@ -0,0 +1,35 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from . import views
|
||||
|
||||
app_name = 'customer'
|
||||
|
||||
urlpatterns = [
|
||||
# 首页
|
||||
path('index/', views.customer_index, name='customer_index'),
|
||||
path('select_customer_list/', views.select_customer_list, name='select_customer_list'),
|
||||
|
||||
path('create_or_update_customer_page/', views.create_or_update_customer_page, name='create_or_update_customer_page'),
|
||||
path('create_or_update_customer/', views.create_or_update_customer, name='create_or_update_customer'),
|
||||
|
||||
path('delete/', views.delete_customer, name='delete_customer'),
|
||||
|
||||
path('order/index/', views.order_index, name='order_index'),
|
||||
path('order/list/', views.select_orderlist_by_customerid, name='select_orderlist_by_customerid'),
|
||||
|
||||
path('order/detail/index/', views.order_detail_index, name='order_detail_index'),
|
||||
path('order/detail/list/', views.select_orderdetail_by_orderid, name='select_orderdetail_by_orderid'),
|
||||
|
||||
path('loss/index/', views.loss_index, name='loss_index'),
|
||||
path('loss/list/', views.select_loss_list, name='select_loss_list'),
|
||||
|
||||
path('loss/detail/index/', views.loss_detail_index, name='loss_detail_index'),
|
||||
path('loss/reprieve/list/', views.select_reprieve_by_lossid, name='select_reprieve_by_lossid'),
|
||||
|
||||
path('loss/reprieve/index/', views.reprieve_index, name='reprieve_index'),
|
||||
path('loss/reprieve/create/', views.create_reprieve, name='create_reprieve'),
|
||||
path('loss/reprieve/update/', views.update_reprieve, name='update_reprieve'),
|
||||
path('loss/reprieve/delete/', views.delete_reprieve, name='delete_reprieve'),
|
||||
|
||||
path('loss/confirm/', views.update_lossreason_by_lossid, name='update_lossreason_by_lossid'),
|
||||
]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ReportConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'report'
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
@ -0,0 +1,14 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
app_name = 'report'
|
||||
|
||||
urlpatterns = [
|
||||
path('<str:template>/index/', views.report_index, name='report_index'),
|
||||
path('contribute/', views.select_contribute, name='select_contribute'),
|
||||
path('composition/', views.select_composition, name='select_composition'),
|
||||
path('serve/', views.select_serve, name='select_serve'),
|
||||
|
||||
path('loss/index/', views.loss_index, name='loss_index'),
|
||||
path('loss/list/', views.select_loss_list, name='select_loss_list'),
|
||||
]
|
@ -0,0 +1,99 @@
|
||||
from django.shortcuts import render
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Sum, Count, Case, When, Value
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import render
|
||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
from django.views.decorators.http import require_GET
|
||||
from customer.models import Customer
|
||||
from serve.models import CustomerServe
|
||||
|
||||
from customer.views import loss_index, select_loss_list
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@xframe_options_exempt
|
||||
@require_GET
|
||||
def report_index(request, template):
|
||||
"""统计报表子菜单首页"""
|
||||
'''
|
||||
contribute 客户贡献分析首页
|
||||
composition 客户构成分析首页
|
||||
serve 客户服务分析首页
|
||||
loss 客户流失分析首页
|
||||
'''
|
||||
return render(request, 'report/%s.html' % template)
|
||||
|
||||
|
||||
@require_GET
|
||||
def select_contribute(request):
|
||||
"""查询客户贡献"""
|
||||
try:
|
||||
|
||||
# """
|
||||
# SELECT c.id, c.name, sum(od.sum) sum FROM t_customer c
|
||||
# LEFT JOIN t_customer_order co ON c.id = co.cus_id
|
||||
# LEFT JOIN t_order_details od ON co.id = od.order_id
|
||||
# WHERE c.is_valid = 1 AND c.id = 1 GROUP BY c.id, c.name;
|
||||
# """
|
||||
# 获取第几页
|
||||
page_num = request.GET.get('page', 1) # 添加默认值,防止没有参数导致的异常错误
|
||||
# 获取每页多少条
|
||||
page_size = request.GET.get('limit', 10) # 添加默认值,防止没有参数导致的异常错误
|
||||
customer_list = Customer.objects.values('id', 'name') \
|
||||
.annotate(sum=Sum('customerorders__ordersdetail__sum')) \
|
||||
.order_by('-sum')
|
||||
# 按条件查询
|
||||
# 客户名称
|
||||
customerName = request.GET.get('customerName')
|
||||
if customerName:
|
||||
customer_list = customer_list.filter(name__icontains=customerName)
|
||||
# 金额区间
|
||||
type = request.GET.get('type')
|
||||
if type == '1':
|
||||
customer_list = customer_list.filter(sum__gte=0, sum__lte=1000)
|
||||
elif type == '2':
|
||||
customer_list = customer_list.filter(sum__gt=1000, sum__lte=3000)
|
||||
elif type == '3':
|
||||
customer_list = customer_list.filter(sum__gt=3000, sum__lte=5000)
|
||||
elif type == '4':
|
||||
customer_list = customer_list.filter(sum__gt=5000)
|
||||
# 初始化分页对象
|
||||
p = Paginator(customer_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:
|
||||
pass
|
||||
|
||||
|
||||
@require_GET
|
||||
def select_composition(request):
|
||||
"""查询客户构成数据"""
|
||||
level = Customer.objects.values('level') \
|
||||
.annotate(amount=Count('level')).order_by('level')
|
||||
return JsonResponse(list(level), safe=False)
|
||||
|
||||
|
||||
@require_GET
|
||||
def select_serve(request):
|
||||
"""查询客户服务类型数据"""
|
||||
serve = CustomerServe.objects.values('serveType') \
|
||||
.annotate(type=Case(When(serveType=6, then=Value("咨询")),
|
||||
When(serveType=7, then=Value("建议")),
|
||||
When(serveType=8, then=Value("投诉"))), amount=Count('serveType')) \
|
||||
.order_by('serveType')
|
||||
return JsonResponse(list(serve), safe=False)
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue