fix: about.html, name change

simpleUI 2021.4.1 --> 2021.8.1
add: unfold function on tasklist.html;
test raw sql query
This commit is contained in:
raiots 2021-08-18 21:44:26 +08:00
parent a194cb664d
commit 177ff0ea9a
13 changed files with 125 additions and 29 deletions

View File

@ -139,6 +139,7 @@ AUTH_USER_MODEL = 'users.User'
# 它确定库是否会在数据导入中使用数据库事务,以确保安全。 # 它确定库是否会在数据导入中使用数据库事务,以确保安全。
IMPORT_EXPORT_USE_TRANSACTIONS = True IMPORT_EXPORT_USE_TRANSACTIONS = True
SITE_NAME = '任务管理工具'
# SimpleUI 配置 # SimpleUI 配置
# 离线模式 # 离线模式
@ -149,7 +150,7 @@ SIMPLEUI_HOME_INFO = False
SIMPLEUI_HOME_QUICK = True SIMPLEUI_HOME_QUICK = True
SIMPLEUI_HOME_ACTION = True SIMPLEUI_HOME_ACTION = True
SIMPLEUI_ANALYSIS = False SIMPLEUI_ANALYSIS = False
SIMPLEUI_HOME_TITLE = '任务管理系统' SIMPLEUI_HOME_TITLE = SITE_NAME
# SIMPLEUI_HOME_PAGE = 'https://www.baidu.com' # 可用于嵌入其他链接,这里可以直接方便的嵌入报表链接 # SIMPLEUI_HOME_PAGE = 'https://www.baidu.com' # 可用于嵌入其他链接,这里可以直接方便的嵌入报表链接
SIMPLEUI_HOME_ICON = 'el el-icon-platform-eleme' SIMPLEUI_HOME_ICON = 'el el-icon-platform-eleme'
# ICON 支持element-ui和fontawesome egfa fa-user # ICON 支持element-ui和fontawesome egfa fa-user

View File

@ -15,12 +15,13 @@ Including another URLconf
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from TasksManager.settings import SITE_NAME
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('apps.tasks.urls', namespace='tasks')), path('', include('apps.tasks.urls', namespace='tasks')),
] ]
admin.site.site_header = '任务进度管理系统' admin.site.site_header = SITE_NAME
admin.site.site_title = '任务进度管理系统' admin.site.site_title = SITE_NAME
admin.site.index_title = u'任务进度管理系统' admin.site.index_title = SITE_NAME

View File

@ -28,6 +28,7 @@ class TodoInline(admin.StackedInline):
model = models.Todo model = models.Todo
extra = 0 extra = 0
# classes = ['collapse'] # classes = ['collapse']
#TODO 选择年度任务时排序 https://www.codenong.com/40740869/
class TaskAdmin(ImportExportModelAdmin): class TaskAdmin(ImportExportModelAdmin):
@ -151,6 +152,8 @@ class TodoAdmin(ImportExportModelAdmin):
'duty_group', 'duty_group',
'main_executor', 'main_executor',
'list_sub_executor', 'list_sub_executor',
'predict_work',
'evaluate_factor',
'maturity', 'maturity',
'real_work', 'real_work',
'complete_note', 'complete_note',
@ -164,7 +167,7 @@ class TodoAdmin(ImportExportModelAdmin):
# raw_id_fields = ("sub_executor",) # raw_id_fields = ("sub_executor",)
search_fields = ('todo_topic',) search_fields = ('todo_topic',)
ordering = ('related_task', ) ordering = ('related_task', )
readonly_fields = [ "attachment"] readonly_fields = ["attachment"]
def approval_state(self, obj): def approval_state(self, obj):
return format_html('<span style="color:{};">{}</span>', 'green', obj.approval) return format_html('<span style="color:{};">{}</span>', 'green', obj.approval)

View File

@ -8,13 +8,31 @@ class LoginForm(forms.Form):
remember = forms.BooleanField(required=False) remember = forms.BooleanField(required=False)
# TODO 数据不可为空
class TodoForm(forms.ModelForm): class TodoForm(forms.ModelForm):
required_css_class = 'required' required_css_class = 'required'
# (confused by Form & ModelForm https://stackoverflow.com/questions/2303268/djangos-forms-form-vs-forms-modelform)
# maturity = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control'}), choices=(
# ('0%', '0%'),
# ('10%', '10%'),
# ('50%', '50%'),
# ('90%', '90%'),
# ('100%', '100%')
# ))
# real_work = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
# sub_executor = forms.MultipleChoiceField(widget=forms.SelectMultiple(attrs={'class': 'form-control'}))
class Meta: class Meta:
model = Todo model = Todo
fields = ['maturity', 'real_work', 'evaluate_factor', 'complete_note'] fields = ['maturity', 'real_work', 'sub_executor', 'evaluate_factor', 'complete_note']
labels ={'text': ''} widgets = {'complete_note': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
widgets = {'rows': '3'} # 'evaluate_factor': forms.NumberInput(attrs={'class': 'form-control'}),
}
# TODO 数据不可为空 def __init__(self, *args, **kwargs):
super(TodoForm, self).__init__(*args, **kwargs)
# self.fields['sub_executor'].widget.attrs['class'] = 'form-control'
fields = ['maturity', 'real_work', 'sub_executor', 'evaluate_factor', 'complete_note']
for i in fields:
self.fields[i].widget.attrs['class'] = 'form-control'

41
apps/tasks/my_query.py Normal file
View File

@ -0,0 +1,41 @@
from django.db import connection
def my_annotate():
query1 = '''
CREATE TEMPORARY TABLE work_cal AS
SELECT tasks_todo_sub_executor.*, tasks_todo.*
FROM tasks_todo_sub_executor
INNER JOIN tasks_todo
ON tasks_todo_sub_executor.todo_id = tasks_todo.id
ORDER BY user_id;
'''
query2 = '''
-- 计算每个工作包协办人数量并插入临时表
UPDATE work_cal SET sub_executor_count = (
SELECT COUNT(*) FROM tasks_todo_sub_executor
WHERE work_cal.todo_id = tasks_todo_sub_executor.todo_id);
'''
query3 = '''
SELECT exe_id, SUM(total_pre_work), SUM(total_real_work) FROM
(
-- 承办任务
SELECT main_executor_id AS exe_id, SUM(predict_work * evaluate_factor) AS total_pre_work,
SUM(real_work * tasks_todo.evaluate_factor) AS total_real_work
FROM tasks_todo
GROUP BY exe_id
UNION ALL
-- 协办任务
SELECT user_id AS exe_id, SUM(predict_work * (1 -evaluate_factor) / sub_executor_count) AS total_pre_work,
SUM(real_work * (1 - evaluate_factor) / sub_executor_count) AS total_real_work
FROM work_cal
GROUP BY exe_id
) AS init
GROUP BY exe_id
'''
cursor = connection.cursor()
cursor.execute(query1)
cursor.execute(query2)
cursor.execute(query3)
raw = cursor.fetchall()
return raw

View File

@ -6,21 +6,31 @@ from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Sum, F, FloatField, Count, Q from django.db.models import Sum, F, FloatField, Count, Q
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.http import HttpResponse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
import django.utils.timezone as timezone import django.utils.timezone as timezone
from django.views import View from django.views import View
from django.db import connection
# Create your views here. # Create your views here.
from apps.tasks.models import Todo, Task from apps.tasks.models import Todo, Task
from apps.tasks.forms import TodoForm from apps.tasks.forms import TodoForm
from apps.users.models import User from apps.users.models import User
from . import my_query
from functools import reduce from functools import reduce
import pandas as pd import pandas as pd
class IndexView(View): class IndexView(View):
# TODO 解决系统时间变化,日期不刷新的问题
# https://stackoverflow.com/questions/63072235/django-localdate-doesnt-return-correct-date
# https://stackoverflow.com/questions/13225890/django-default-timezone-now-saves-records-using-old-time
@method_decorator(login_required) @method_decorator(login_required)
def get(self, request, year=timezone.now().year, month=timezone.now().month): def get(self, request, year=timezone.now().year, month=timezone.now().month):
raw = my_query.my_annotate()
# return HttpResponse(raw)
basic_users = User.objects.filter(department=request.user.department).annotate( basic_users = User.objects.filter(department=request.user.department).annotate(
main_executor_count=Count('main_executor', main_executor_count=Count('main_executor',
filter=Q(main_executor__deadline__year=year, main_executor__deadline__month=month) filter=Q(main_executor__deadline__year=year, main_executor__deadline__month=month)

View File

@ -3,7 +3,7 @@ defusedxml==0.7.1
diff-match-patch==20200713 diff-match-patch==20200713
Django==3.1.12 Django==3.1.12
django-import-export==2.5.0 django-import-export==2.5.0
django-simpleui==2021.4.1 django-simpleui==2021.8.1
et-xmlfile==1.0.1 et-xmlfile==1.0.1
MarkupPy==1.14 MarkupPy==1.14
numpy==1.20.2 numpy==1.20.2

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ABOUT - Raiot</title> <title>ABOUT - Raiot</title>
<link rel="stylesheet" href="{% static 'tasks/nes.min.font.css' %}"> <link rel="stylesheet" href="{% static 'tasks/nes.min.css' %}">
<style> <style>
@charset "utf-8"; @charset "utf-8";
@import url({% static 'tasks/about_font.css' %}); @import url({% static 'tasks/about_font.css' %});
@ -142,7 +142,7 @@
<header class=""> <header class="">
<div class="container"> <div class="container">
<div class="nav-brand"> <div class="nav-brand">
<a href="https://github.com/Anankke/SSPanel-Uim"> <a href="#">
<h1>STAFF</h1> <h1>STAFF</h1>
</a> </a>
<p>©&nbsp;2021 RAIOT</p> <p>©&nbsp;2021 RAIOT</p>

View File

@ -9,7 +9,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>任务管理系统</title> <title>任务管理工具</title>
<!-- Google Font: Source Sans Pro --> <!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="{% static 'tasks/dist/css/googlefont.css' %}"> <link rel="stylesheet" href="{% static 'tasks/dist/css/googlefont.css' %}">
@ -32,7 +32,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
<div class="container-xl"> <div class="container-xl">
<a href="{% url 'tasks:index' %}" class="navbar-brand"> <a href="{% url 'tasks:index' %}" class="navbar-brand">
<img src="{% static 'tasks/dist/img/AdminLTELogo.png' %}" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8"> <img src="{% static 'tasks/dist/img/AdminLTELogo.png' %}" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">
<span class="brand-text font-weight-light">任务管理系统</span> <span class="brand-text font-weight-light">任务管理工具</span>
</a> </a>
<button class="navbar-toggler order-1" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler order-1" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
@ -191,7 +191,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
<li class="nav-tabs"> <li class="nav-tabs">
<a>欢迎,</a> <a>欢迎,</a>
<b style="color: cadetblue">{{ user.real_name }}</b> <b style="color: cadetblue">{{ user.real_name }}</b>
<a>。 本系统为非涉密应用系统,禁止处理秘密级及以上信息!!!</a> <a>。 本软件为非涉密应用工具,禁止处理秘密级及以上信息!!!</a>
</li> </li>
<li class="navbar-tabs"> <li class="navbar-tabs">
<a href="{% url 'tasks:logout' %}">&nbsp;登出</a> <a href="{% url 'tasks:logout' %}">&nbsp;登出</a>

View File

@ -83,7 +83,6 @@
<small></small> <small></small>
</span> </span>
</div> </div>
<!-- /.info-box-content --> <!-- /.info-box-content -->
</div> </div>
<!-- /.info-box --> <!-- /.info-box -->
@ -287,6 +286,7 @@
<div class="card-header"> <div class="card-header">
<h3 class="card-title">部门工作统计表</h3> <h3 class="card-title">部门工作统计表</h3>
</div> </div>
{# TODO 更换为绩效考核表 分季度按人显示工作量及完成质量#}
<!-- /.card-header --> <!-- /.card-header -->
<div class="card-body"> <div class="card-body">
<div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"></div><div class="col-sm-12 col-md-6"></div></div><div class="row"><div class="col-sm-12"><table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info"> <div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"></div><div class="col-sm-12 col-md-6"></div></div><div class="row"><div class="col-sm-12"><table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">

View File

@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>任务管理系统</title> <title>任务管理工具</title>
<!-- Google Font: Source Sans Pro --> <!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="{% static 'tasks/dist/css/googlefont.css' %}"> <link rel="stylesheet" href="{% static 'tasks/dist/css/googlefont.css' %}">

View File

@ -33,6 +33,12 @@
<!-- /.card-header --> <!-- /.card-header -->
<div class="card-body p-0"> <div class="card-body p-0">
<table class="table table-striped" style="word-break: break-all; overflow: auto" cellspacing="0"> <table class="table table-striped" style="word-break: break-all; overflow: auto" cellspacing="0">
<div class="row">
<div class="col-12" style="background-color: #f2f2f2">
<button type="button" id="unfold" onclick="alert1()" class="btn btn-default float-right"><i class="far fa-credit-card"></i> 展开
</button>
</div>
</div>
<thead> <thead>
<tr style="background-color: #f2f2f2"> <tr style="background-color: #f2f2f2">
<th style="width: 140px; text-align:center; vertical-align: middle;">任务属性</th> <th style="width: 140px; text-align:center; vertical-align: middle;">任务属性</th>
@ -111,14 +117,30 @@
<!-- /.content --> <!-- /.content -->
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
<script> <script>
function setHeight(element) { function setHeight(element) {
$(element).css({'height':'auto','overflow-y':'hidden'}).height(element.scrollHeight); $(element).css({'height':'auto','overflow-y':'hidden'}).height(element.scrollHeight);
} }
$('textarea').each(function () { $('textarea').each(function () {
setHeight(this); setHeight(this);
}).on('input', function () { }).on('input', function () {
setHeight(this); setHeight(this);
}); });
</script>
{% endblock %} </script>
{% endblock %}
{% block script %}
<script>
$('#unfold').click(function (element){
$(element).css({'height':'auto','overflow-y':'hidden'}).height(element.scrollHeight);
$('textarea').each(function () {
setHeight(this);
}).on('input', function () {
setHeight(this);
});
})
</script>
{% endblock %}

View File

@ -61,7 +61,7 @@
<h3 style="text-align: center; letter-spacing: 30px">我的承办</h3> <h3 style="text-align: center; letter-spacing: 30px">我的承办</h3>
<HR width="50%" color=#e2e4e6 SIZE=3> <HR width="50%" color=#e2e4e6 SIZE=3>
<tr> <tr>
<th style="width: 70px; text-align:center; vertical-align: middle;">序号</th> <th style="width: 100px; text-align:center; vertical-align: middle;">序号</th>
<th style="width: 300px; text-align:center; vertical-align: middle;">工作事项</th> <th style="width: 300px; text-align:center; vertical-align: middle;">工作事项</th>
<th style="width: 100px; text-align:center; vertical-align: middle;">完成时间</th> <th style="width: 100px; text-align:center; vertical-align: middle;">完成时间</th>
<th style="width: 240px; text-align:center; vertical-align: middle;">工作要求及交付物</th> <th style="width: 240px; text-align:center; vertical-align: middle;">工作要求及交付物</th>