Django項目:CRM(客戶關系管理系統)--84--74PerfectCRM實現CRM權限和權限組限制訪問URL


 

 

 

 

  1 #models.py
  2 
  3 # ————————01PerfectCRM基本配置ADMIN————————
  4 
  5 from django.db import models
  6 # Create your models here.
  7 
  8 """
  9 #運行 Terminal
 10 #    生成 數據表
 11 #    python manage.py makemigrations
 12 #   數據表 遷移
 13 #    python manage.py migrate
 14 """
 15 
 16 """01校區表"""
 17 class Branch(models.Model):
 18     name = models.CharField(max_length=128,unique=True) #校區名#CharField作用是保存文本,定長的變量類型
 19     addr = models.CharField(max_length=128) #地址
 20     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
 21         return self.name #返回 #校區名
 22     class Meta: #通過一個內嵌類 "class Meta" 給你的 model 定義元數據
 23         verbose_name_plural =  "01校區表" #verbose_name_plural給你的模型類起一個更可讀的名字
 24 
 25 """02班級表"""
 26 class ClassList(models.Model):
 27     #ForeignKey就是表與表之間的某種約定的關系  #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
 28     branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校區    關聯到  校區表
 29     course = models.ForeignKey("Course",on_delete=models.CASCADE) #課程   關聯到   課程表
 30 
 31     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 32     contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE)  # 合同表
 33     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 34 
 35     class_type_choices = ( #上課形式
 36                           (0,'面授(脫產)'),
 37                           (1,'面授(周末)'),
 38                           (2,'網絡班'),)
 39     #PositiveSmallIntegerField正小整數 0 ~ 32767 #choices是Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
 40     class_type = models.SmallIntegerField(choices=class_type_choices)#上課形式
 41 
 42     #PositiveSmallIntegerField正小整數 0 ~ 32767
 43     semester = models.PositiveSmallIntegerField(verbose_name="學期") #課程的第幾期
 44 
 45     #ManyToManyField多對多和外鍵工作方式相同,只不過我們處理的是QuerySet而不是模型實例。
 46     teachers = models.ManyToManyField("UserProfile") # 老師   關聯到    賬號表
 47 
 48     start_date = models.DateField(verbose_name="開班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中顯示的字段名稱
 49 
 50     # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中顯示的字段名稱 #Django可空#數據庫可以為空
 51     end_date = models.DateField(verbose_name="結業日期",blank=True,null=True)
 52 
 53     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
 54         return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化輸出字符串 #校區#課程# 學期
 55     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
 56         unique_together=('branch','course','semester')  #聯合索引
 57         verbose_name_plural = "02班級表" #verbose_name_plural給你的模型類起一個更可讀的名字
 58 
 59 """03課程表,可以報名那些課程"""
 60 class Course(models.Model):
 61     name = models.CharField(max_length=64,unique=True)#課程名 #CharField作用是保存文本,定長的變量類型
 62     price = models.PositiveSmallIntegerField(verbose_name="學費")#學費#PositiveSmallIntegerField正小整數 0 ~ 32767
 63     period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整數 0 ~ 32767
 64     outline = models.TextField() #課程大綱  #文本類型
 65     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
 66         return self.name #返回 #課程名
 67     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
 68         verbose_name_plural =  "03課程表"#verbose_name_plural給你的模型類起一個更可讀的名字
 69 
 70 '''04客戶信息表'''
 71 class Customer(models.Model):
 72     name = models.CharField(max_length=32,blank=True,null=True)#客戶名#CharField定長文本 #名字最長32 # Django可空 #數據庫可以為空
 73     qq = models.CharField(max_length=64,unique=True) #QQ號#CharField定長文本 #名字最長64 #唯一,不能重復
 74     qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定長文本 #名字最長64 # Django可空 #數據庫可以為空
 75     phone = models.CharField(max_length=64,blank=True,null=True)#手機號 #CharField定長文本 #名字最長64 # Django可空 #數據庫可以為空
 76 
 77     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 78     id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份證號')#身份證號
 79     email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='郵箱')#email
 80     sex_choices=((0,'保密'),(1,''),(2,''))
 81     sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性別')
 82     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 83 
 84     # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
 85     status_choices = ((0, '已報名'), (1, '未報名'), (2, '已退學'))
 86     status = models.SmallIntegerField(choices=status_choices, default=1)  # 學員狀態
 87     # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
 88 
 89     source_choices = ( #客戶渠道來源 (內存生成)
 90                       (0,'轉介紹'),
 91                       (1,'QQ群'),
 92                       (2,'官網'),
 93                       (3,'百度推廣'),
 94                       (4,'51CTO'),
 95                       (5,'知乎'),
 96                       (6,'市場推廣'),)
 97     #PositiveSmallIntegerField正小整數 0 ~ 32767(省空間)#choices是Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
 98     source = models.SmallIntegerField(choices=source_choices)#客戶渠道來源
 99 
100     #CharField定長文本#verbose_name是Admin中顯示的字段名稱#名字最長64 # Django可空 #數據庫可以為空
101     referral_from = models.CharField(verbose_name="轉介紹人qq",max_length=64,blank=True,null=True) #來自誰介紹的
102 
103     #ForeignKey就是表與表之間的某種約定的關系#verbose_name是Admin中顯示的字段名稱 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
104     consult_courses = models.ForeignKey("Course",verbose_name="咨詢課程", on_delete=models.CASCADE) #關聯到 課程表
105 
106     content= models.TextField(verbose_name="咨詢詳情") #TextField無限制長度的文本#verbose_name是Admin中顯示的字段名稱
107 
108     #ManyToManyField多對多和外鍵工作方式相同,只不過我們處理的是QuerySet而不是模型實例。
109     tags = models.ManyToManyField("Tag",blank=True)#多對多關聯到 標簽表
110 
111     #ForeignKey就是表與表之間的某種約定的關系  #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
112     consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #關聯到  賬號表
113 
114     memo = models.TextField(blank=True,null=True)#備注#TextField無限制長度的文本#Django可空#數據庫可以為空
115 
116     #DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
117     date =  models.DateTimeField(auto_now_add=True)#創建時間(數據庫自增)
118 
119     def __str__(self): #__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
120         return self.qq  #返回 #QQ號
121 
122     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
123         verbose_name_plural =  "04客戶表" #verbose_name_plural給你的模型類起一個更可讀的名字
124 
125 # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
126 #合同模版
127 class ContractTemplate(models.Model):
128     name=models.CharField('合同名稱',max_length=64,unique=True)
129     template=models.TextField()
130 
131     def __str__(self):
132         return self.name
133     class Meta:
134         verbose_name_plural='合同表'
135 # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
136 
137 
138 """05客戶跟進表"""
139 class CustomerFollowUp(models.Model):
140 
141     #ForeignKey就是表與表之間的某種約定的關系 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
142     customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客戶名 #關聯到  客戶信息表
143 
144     content = models.TextField(verbose_name="跟進內容")#跟進的內容#TextField無限制長度的文本#verbose_name是Admin中顯示的字段名稱
145 
146     #ForeignKey就是表與表之間的某種約定的關系  #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
147     consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #關聯到  賬號表
148 
149     intention_choices =(  #報名狀態
150                         (0,'2周內報名'),
151                         (1,'1個月內報名'),
152                         (2,'近期無報名計划'),
153                         (3,'已在其它機構報名'),
154                         (4,'已報名'),
155                         (5,'已拉黑'),)
156     #PositiveSmallIntegerField正小整數 0 ~ 32767(省空間)#choices是Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
157     intention=models.SmallIntegerField(choices=intention_choices) #報名狀態
158 
159     #DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
160     date =  models.DateTimeField(auto_now_add=True)#創建時間(數據庫自增)
161 
162     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
163         return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ號#報名狀態
164     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
165         verbose_name_plural =  "05客戶跟進表"#verbose_name_plural給你的模型類起一個更可讀的名字
166 
167 """06學員報名信息表"""
168 class Enrollment(models.Model):
169     # ForeignKey就是表與表之間的某種約定的關系#verbose_name是Admin中顯示的字段名稱 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
170     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#學員名字 #關聯到  客戶信息表
171     enrolled_class = models.ForeignKey("ClassList",verbose_name="所報班級",on_delete=models.CASCADE)#關聯到  班級表
172     consultant = models.ForeignKey("UserProfile",verbose_name="課程顧問",on_delete=models.CASCADE) #關聯到  賬號表
173 
174     # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
175     contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同審核")  # 合同審核
176     # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
177 
178     #BooleanField布爾值類型#default=False默認(True)不允許出現空字符#verbose_name是Admin中顯示的字段名稱
179     contract_agreed = models.BooleanField(default=False,verbose_name="學員已經同意合同")#學員看合同
180     contract_approved = models.BooleanField(default=False,verbose_name="合同已經審核") #誰審核
181 
182     # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
183     Pay_cost= models.BooleanField(default=False,verbose_name="繳費") #繳費狀態#是不是交定金
184     # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
185 
186     # DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
187     date = models.DateTimeField(auto_now_add=True)#創建時間(數據庫自增)
188 
189     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
190         # ————————57PerfectCRM實現admin批量生成上課記錄————————
191         # return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#學員名字#所報班級
192         return " 學員:%s |QQ: %s |班級:%s" %(self.customer.name,self.customer,self.enrolled_class)#返回#格式化字符串#學員名字#所報班級
193         # ————————57PerfectCRM實現admin批量生成上課記錄————————
194     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
195         unique_together =  ("customer","enrolled_class")#聯合索引
196         verbose_name_plural =  "06學員報名信息表"#verbose_name_plural給你的模型類起一個更可讀的名字
197 
198 """07繳費記錄表"""
199 class Payment(models.Model):
200     #ForeignKey就是表與表之間的某種約定的關系#verbose_name是Admin中顯示的字段名稱 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
201     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#學員名字        關聯到  客戶信息表
202     course = models.ForeignKey("Course",verbose_name="所報課程",on_delete=models.CASCADE)#關聯到  課程表
203 
204     #PositiveSmallIntegerField正小整數 0 ~ 32767 #verbose_name是Admin中顯示的字段名稱#默認值=500
205     amount = models.PositiveIntegerField(verbose_name="數額",default=500)#繳費數額
206 
207     #ForeignKey就是表與表之間的某種約定的關系#CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
208     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#繳費給誰 關聯到  賬號表 #財務人員
209 
210     #DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
211     date=models.DateTimeField(auto_now_add=True)#創建時間(數據庫自增)
212 
213     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
214         return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#學員名字#繳費數額
215     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
216         verbose_name_plural = "07繳費記錄表"#verbose_name_plural給你的模型類起一個更可讀的名字
217 
218 """08每節課上課紀錄表"""
219 class CourseRecord(models.Model):
220     # ForeignKey就是表與表之間的某種約定的關系#verbose_name是Admin中顯示的字段名稱 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
221     from_class = models.ForeignKey("ClassList",verbose_name="班級",on_delete=models.CASCADE) #那個班級
222 
223     #PositiveSmallIntegerField正小整數 0 ~ 32767 #verbose_name是Admin中顯示的字段名稱
224     day_num = models.PositiveSmallIntegerField(verbose_name="第幾節(天)") #第幾節課
225 
226     # ForeignKey就是表與表之間的某種約定的關系 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
227     teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老師是誰    關聯到    賬號表
228 
229     #BooleanField布爾值類型#default=True默認(True)不允許出現空字符
230     has_homework = models.BooleanField(default=True) #有沒有作業
231 
232     # CharField定長文本#名字最長128#Django可空#數據庫可以為空
233     homework_title = models.CharField(max_length=128,blank=True,null=True) #作業標題
234 
235     #TextField無限制長度的文本#Django可空#數據庫可以為空
236     homework_content = models.TextField(blank=True,null=True) #作業內容
237 
238     #TextField無限制長度的文本#verbose_name是Admin中顯示的字段名稱
239     outline =models.TextField(verbose_name="本節課程大綱") #課程主要講什么
240 
241     # DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
242     date = models.DateField(auto_now_add=True)#創建時間(數據庫自增)
243 
244     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
245         return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班級#第幾節(天)
246     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
247         unique_together = ("from_class","day_num") #聯合索引
248         verbose_name_plural = "08每節課上課紀錄表" #verbose_name_plural給你的模型類起一個更可讀的名字
249 
250 """09學習紀錄"""
251 class StudyRecord(models.Model):
252     # ForeignKey就是表與表之間的某種約定的關系 #CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
253     student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#學生名字   關聯到    學員報名信息表
254     course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#開課記錄   # 關聯到    每節課上課紀錄表
255 
256     attendance_choices = (# 本節課上課狀態記錄
257                             (0,"已簽到"),
258                             (1,"遲到"),
259                             (2,"缺勤"),
260                             (3,"早退"),)
261     #PositiveSmallIntegerField正小整數 0 ~ 32767(省空間)#choices是Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
262     attendance = models.SmallIntegerField(choices=attendance_choices) # 本節課上課狀態記錄
263 
264     # ————————63PerfectCRM實現CRM講師下載作業————————
265     delivery = models.BooleanField(default=False,verbose_name="交作業") #有沒有交付作業
266     # ————————63PerfectCRM實現CRM講師下載作業————————
267 
268 
269     # ————————61PerfectCRM實現CRM學生上傳作業————————
270     homework_link = models.TextField(blank=True,null=True)#作業鏈接 #TextField無限制長度的文本#Django可空#數據庫可以為空
271     # ————————61PerfectCRM實現CRM學生上傳作業————————
272 
273     score_choices = (#學習成績
274                      (100,"A+"),
275                      (90,"A"),
276                      (85,"B+"),
277                      (80,"B"),
278                      (75,"B-"),
279                      (70,"C+"),
280                      (65,"C"),
281                      (40,"C-"),
282                      (-20,"D"),
283                      (-50,"COPY"),
284                      (0,"N/A"),)
285     #PositiveSmallIntegerField正小整數 0 ~ 32767(省空間)#choices是Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
286     score = models.SmallIntegerField(choices=score_choices) #學習成績
287 
288 
289     memo = models.TextField(blank=True,null=True)#TextField無限制長度的文本#Django可空#數據庫可以為空
290 
291     # DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add創建時間(只讀)
292     date = models.DateField(auto_now_add=True)#創建時間(數據庫自增)
293 
294     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
295         return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#學生名字#開課記錄#學習成績
296     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
297         unique_together = ('student','course_record')#聯合索引#學生名字#開課記錄
298         verbose_name_plural =  "09學習紀錄"#verbose_name_plural給你的模型類起一個更可讀的名字
299 
300 # ————————34PerfectCRM實現CRM自定義用戶————————
301 # """10賬號表"""
302 # class UserProfile(models.Model):
303 #     from django.contrib.auth.models import User  # 使用django內置的用戶表
304 #
305 #     #OneToOneField一對一  #User是django Admin里的賬號表#CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
306 #     user = models.OneToOneField(User,on_delete=models.CASCADE)# 用戶名 #創建外鍵,關聯django用戶表
307 #
308 #     name = models.CharField(max_length=32) #賬號名(擴展用戶字段)#CharField定長文本
309 #
310 #     #ManyToManyField多對多和外鍵工作方式相同,只不過我們處理的是QuerySet而不是模型實例。#Django可空
311 #     roles = models.ManyToManyField("Role",blank=True) #角色(權限)   # 雙向一對多==多對多
312 #
313 #     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
314 #         return self.name #返回 #賬號名
315 #     class Meta: #通過一個內嵌類 "class Meta" 給你的 model 定義元數據
316 #         verbose_name_plural = "10賬號表"#verbose_name_plural給你的模型類起一個更可讀的名字
317 # ————————34PerfectCRM實現CRM自定義用戶————————
318 
319 # ————————34PerfectCRM實現CRM自定義用戶————————
320 #10賬號表,創建用戶和超級用戶
321 from django.contrib.auth.models import BaseUserManager
322 class UserProfileManager(BaseUserManager):
323     def create_user(self, email, name, password=None):
324         """
325       創建並保存一個用戶用給定的郵件,日期
326       出生和密碼。
327         """
328         if not email:#沒有email 報錯
329             raise ValueError('用戶必須有一個電子郵件地址')
330 
331         user = self.model(
332             email=self.normalize_email(email),#驗證郵箱格式
333             name=name,
334         )
335         user.set_password(password)#加密
336         user.is_active = True
337         user.save(using=self._db)
338         return user
339     def create_superuser(self, email, name, password):
340         """
341       創建並保存一個超級用戶具有給定郵件,日期
342       出生和密碼。
343         """
344         user = self.create_user(email,
345             password=password,
346             name=name
347         )
348         user.is_active = True
349         user.is_superuser = True
350         user.save(using=self._db)
351         return user
352 
353 """10賬號表"""
354 """
355 
356 #刪除數據庫
357 
358 #調用objects = UserProfileManager()#創建賬號 #關聯這個函數
359 
360 #運行 Terminal
361 #    生成 數據表
362 #    python manage.py makemigrations
363 #   數據表 遷移
364 #    python manage.py migrate
365 Django Admin里賬號密碼重置方法
366 #運行 Terminal  
367 python manage.py createsuperuser
368 
369 Email address:          admin@qq.com
370 用戶名 :                 admin
371 Password:               admin123456
372 Password (again):       admin123456
373 """
374 from django.contrib.auth.models import AbstractBaseUser
375 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
376 from django.utils.translation import ugettext_lazy as _  # 語言國際化
377 from django.utils.safestring import mark_safe
378 from django.contrib.auth.models import PermissionsMixin
379 # class UserProfile(AbstractBaseUser):
380 class UserProfile(AbstractBaseUser,PermissionsMixin):
381 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
382     email=models.EmailField(
383         verbose_name='郵箱賬號',
384         max_length=255,
385         unique=True#唯一  #登陸賬號
386     )
387     name=models.CharField(max_length=32,verbose_name='用戶名')
388 
389 
390     # ————————72PerfectCRM實現CRM動態菜單和角色————————
391     branch = models.ForeignKey( "Branch", verbose_name="所屬校區", blank=True, null=True, on_delete=models.CASCADE )
392     roles = models.ManyToManyField( 'Role', verbose_name="角色", blank=True )
393     memo = models.TextField( blank=True, null=True, default=None, verbose_name="備注" )
394     from django.utils import timezone
395     date_joined = models.DateTimeField( verbose_name="創建時間", default=timezone.now )
396     # ————————72PerfectCRM實現CRM動態菜單和角色————————
397 
398     # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
399     password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密碼</a>'''))
400     # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
401 
402     is_active = models.BooleanField(default=True,verbose_name='合法賬號')#權限#合法賬號
403     is_superuser = models.BooleanField(default=False,verbose_name='超級賬號') #超級賬號
404     objects = UserProfileManager()#創建賬號 #關聯這個函數
405     USERNAME_FIELD ='email'#指定做為  #登陸賬號
406     REQUIRED_FIELDS = ['name']#必填字段
407 
408 
409     # ————————60PerfectCRM實現CRM學生上課記錄————————
410     stu_account = models.ForeignKey( "Customer", verbose_name='關聯學員帳號', blank=True, null=True, on_delete=models.CASCADE,
411                                      help_text='報名成功后創建關聯帳戶' )
412     # ————————60PerfectCRM實現CRM學生上課記錄————————
413 
414     def get_full_name(self):
415         return self.email
416     def get_short_name(self):
417         #用戶確認的電子郵件地址
418         return self.email
419     def __str__(self):
420         return self.name
421     def has_perm(self,perm,obj=None):
422         #指明用戶是否被認為活躍的。以反選代替刪除帳號。
423         #最簡單的可能的答案:是的,總是
424         return True   #有效 賬號
425     def has_module_perms(self, app_label):
426         #指明用戶是否可以登錄到這個管理站點。
427         # 最簡單的可能的答案:是的,總是
428         return True #職員狀態
429     @property
430     def is_staff(self):
431         '''“用戶的員工嗎?”'''
432         #最簡單的可能的答案:所有管理員都是員工
433         return self.is_superuser#是不是超級用戶狀態
434 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表單   #settings.py
435 # ————————34PerfectCRM實現CRM自定義用戶————————
436 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
437     class Meta:
438         verbose_name_plural = '10CRM賬戶表'
439         permissions = (
440             ('crm_010101_all_table_data_list_GET', '010101_全部查看數據_GET'),
441             ('crm_010102_all_table_data_list_POST', '010102_全部查看數據_POST'),
442             ('crm_010103_all_table_add_GET', '010103_全部添加數據_GET'),
443             ('crm_010104_all_table_add_POST', '010104_全部添加數據_POST'),
444             ('crm_010105_all_table_change_GET', '010105_全部修改數據_GET'),
445             ('crm_010106_all_table_change_POST', '010106_全部修改數據_POST'),
446             ('crm_010107_all_table_delete_GET', '010107_全部刪除數據_GET'),
447             ('crm_010108_all_table_delete_POST', '010108_全部刪除數據_POST'),
448             ('crm_010109_all_password_reset_GET', '010109_全部密碼重置_GET'),
449             ('crm_010110_all_password_reset_POST', '010110_全部密碼重置_POST'),
450 
451             ('crm_010201_only_view_Branch_GET', '010201_只能查看校區表_GET'),
452             ('crm_010202_only_view_Branch_POST', '010202_只能查看校區表_POST'),
453             ('crm_010203_only_add_Branch_GET', '010203_只能添加校區表_GET'),
454             ('crm_010204_only_add_Branch_POST', '010204_只能添加校區表_POST'),
455             ('crm_010205_only_change_Branch_GET', '010205_只能修改校區表_GET'),
456             ('crm_010206_only_change_Branch_POST', '010206_只能修改校區表_POST'),
457             ('crm_010207_only_delete_Branch_GET', '010207_只能刪除校區表_GET'),
458             ('crm_010208_only_delete_Branch_POST', '010208_只能刪除校區表_POST'),
459 
460             ('crm_010301_only_view_ClassList_GET', '010301_只能查看班級表_GET'),
461             ('crm_010302_only_view_ClassList_POST', '010302_只能查看班級表_POST'),
462             ('crm_010303_only_add_ClassList_GET', '010303_只能添加班級表_GET'),
463             ('crm_010304_only_add_ClassList_POST', '010304_只能添加班級表_POST'),
464             ('crm_010305_only_change_ClassList_GET', '010305_只能修改班級表_GET'),
465             ('crm_010306_only_change_ClassList_POST', '010306_只能修改班級表_POST'),
466             ('crm_010307_only_delete_ClassList_GET', '010307_只能刪除班級表_GET'),
467             ('crm_010308_only_delete_ClassList_POST', '010308_只能刪除班級表_POST'),
468 
469             ('crm_010401_only_view_Course_GET', '010401_只能查看課程表_GET'),
470             ('crm_010402_only_view_Course_POST', '010402_只能查看課程表_POST'),
471             ('crm_010403_only_add_Course_GET', '010403_只能添加課程表_GET'),
472             ('crm_010404_only_add_Course_POST', '010404_只能添加課程表_POST'),
473             ('crm_010405_only_change_Course_GET', '010405_只能修改課程表_GET'),
474             ('crm_010406_only_change_Course_POST', '010406_只能修改課程表_POST'),
475             ('crm_010407_only_delete_Course_GET', '010407_只能刪除課程表_GET'),
476             ('crm_010408_only_delete_Course_POST', '010408_只能刪除課程表_POST'),
477 
478             ('crm_010501_only_view_Customer_GET', '010501_只能查看客戶表_GET'),
479             ('crm_010502_only_view_Customer_POST', '010502_只能查看客戶表_POST'),
480             ('crm_010503_only_add_Customer_GET', '010503_只能添加客戶表_GET'),
481             ('crm_010504_only_add_Customer_POST', '010504_只能添加客戶表_POST'),
482             ('crm_010505_only_change_Customer_GET', '010505_只能修改客戶表_GET'),
483             ('crm_010506_only_change_Customer_POST', '010506_只能修改客戶表_POST'),
484             ('crm_010507_only_delete_Customer_GET', '010507_只能刪除客戶表_GET'),
485             ('crm_010508_only_delete_Customer_POST', '010508_只能刪除客戶表_POST'),
486 
487             ('crm_010601_only_view_CustomerFollowUp_GET', '010601_只能查看跟進表_GET'),
488             ('crm_010602_only_view_CustomerFollowUp_POST', '010602_只能查看跟進表_POST'),
489             ('crm_010603_only_add_CustomerFollowUp_GET', '010603_只能添加跟進表_GET'),
490             ('crm_010604_only_add_CustomerFollowUp_POST', '010604_只能添加跟進表_POST'),
491             ('crm_010605_only_change_CustomerFollowUp_GET', '010605_只能修改跟進表_GET'),
492             ('crm_010606_only_change_CustomerFollowUp_POST', '010606_只能修改跟進表_POST'),
493             ('crm_010607_only_delete_CustomerFollowUp_GET', '010607_只能刪除跟進表_GET'),
494             ('crm_010608_only_delete_CustomerFollowUp_POST', '010608_只能刪除跟進表_POST'),
495 
496             ('crm_010701_only_view_Enrollment_GET', '010701_只能查看報名表_GET'),
497             ('crm_010702_only_view_Enrollment_POST', '010702_只能查看報名表_POST'),
498             ('crm_010703_only_add_Enrollment_GET', '010703_只能添加報名表_GET'),
499             ('crm_010704_only_add_Enrollment_POST', '010704_只能添加報名表_POST'),
500             ('crm_010705_only_change_Enrollment_GET', '010705_只能修改報名表_GET'),
501             ('crm_010706_only_change_Enrollment_POST', '010706_只能修改報名表_POST'),
502             ('crm_010707_only_delete_Enrollment_GET', '010707_只能刪除報名表_GET'),
503             ('crm_010708_only_delete_Enrollment_POST', '010708_只能刪除報名表_POST'),
504 
505             ('crm_010801_only_view_Payment_GET', '010801_只能查看繳費表_GET'),
506             ('crm_010802_only_view_Payment_POST', '010802_只能查看繳費表_POST'),
507             ('crm_010803_only_add_Payment_GET', '010803_只能添加繳費表_GET'),
508             ('crm_010804_only_add_Payment_POST', '010804_只能添加繳費表_POST'),
509             ('crm_010805_only_change_Payment_GET', '010805_只能修改繳費表_GET'),
510             ('crm_010806_only_change_Payment_POST', '010806_只能修改繳費表_POST'),
511             ('crm_010807_only_delete_Payment_GET', '010807_只能刪除繳費表_GET'),
512             ('crm_010808_only_delete_Payment_POST', '010808_只能刪除繳費表_POST'),
513 
514             ('crm_010901_only_view_CourseRecord_GET', '010901_只能查看上課表_GET'),
515             ('crm_010902_only_view_CourseRecord_POST', '010902_只能查看上課表_POST'),
516             ('crm_010903_only_add_CourseRecord_GET', '010903_只能添加上課表_GET'),
517             ('crm_010904_only_add_CourseRecord_POST', '010904_只能添加上課表_POST'),
518             ('crm_010905_only_change_CourseRecord_GET', '010905_只能修改上課表_GET'),
519             ('crm_010906_only_change_CourseRecord_POST', '010906_只能修改上課表_POST'),
520             ('crm_010907_only_delete_CourseRecord_GET', '010907_只能刪除上課表_GET'),
521             ('crm_010908_only_delete_CourseRecord_POST', '010908_只能刪除上課表_POST'),
522 
523             ('crm_011001_only_view_StudyRecord_GET', '011001_只能查看學習表_GET'),
524             ('crm_011002_only_view_StudyRecord_POST', '011002_只能查看學習表_POST'),
525             ('crm_011003_only_add_StudyRecord_GET', '011003_只能添加學習表_GET'),
526             ('crm_011004_only_add_StudyRecord_POST', '011004_只能添加學習表_POST'),
527             ('crm_011005_only_change_StudyRecord_GET', '011005_只能修改學習表_GET'),
528             ('crm_011006_only_change_StudyRecord_POST', '011006_只能修改學習表_POST'),
529             ('crm_011007_only_delete_StudyRecord_GET', '011007_只能刪除學習表_GET'),
530             ('crm_011008_only_delete_StudyRecord_POST', '011008_只能刪除學習表_POST'),
531 
532             ('crm_011101_only_view_UserProfile_GET', '011101_只能查看賬號表_GET'),
533             ('crm_011102_only_view_UserProfile_POST', '011102_只能查看賬號表_POST'),
534             ('crm_011103_only_add_UserProfile_GET', '011103_只能添加賬號表_GET'),
535             ('crm_011104_only_add_UserProfile_POST', '011104_只能添加賬號表_POST'),
536             ('crm_011105_only_change_UserProfile_GET', '011105_只能修改賬號表_GET'),
537             ('crm_011106_only_change_UserProfile_POST', '011106_只能修改賬號表_POST'),
538             ('crm_011107_only_delete_UserProfile_GET', '011107_只能刪除賬號表_GET'),
539             ('crm_011108_only_delete_UserProfile_POST', '011108_只能刪除賬號表_POST'),
540 
541             ('crm_011201_only_view_Role_GET', '011201_只能查看角色表_GET'),
542             ('crm_011202_only_view_Role_POST', '011202_只能查看角色表_POST'),
543             ('crm_011203_only_add_Role_GET', '011203_只能添加角色表_GET'),
544             ('crm_011204_only_add_Role_POST', '011204_只能添加角色表_POST'),
545             ('crm_011205_only_change_Role_GET', '011205_只能修改角色表_GET'),
546             ('crm_011206_only_change_Role_POST', '011206_只能修改角色表_POST'),
547             ('crm_011207_only_delete_Role_GET', '011207_只能刪除角色表_GET'),
548             ('crm_011208_only_delete_Role_POST', '011208_只能刪除角色表_POST'),
549 
550             ('crm_011301_only_view_Tag_GET', '011301_只能查看標簽表_GET'),
551             ('crm_011302_only_view_Tag_POST', '011302_只能查看標簽表_POST'),
552             ('crm_011303_only_add_Tag_GET', '011303_只能添加標簽表_GET'),
553             ('crm_011304_only_add_Tag_POST', '011304_只能添加標簽表_POST'),
554             ('crm_011305_only_change_Tag_GET', '011305_只能修改標簽表_GET'),
555             ('crm_011306_only_change_Tag_POST', '011306_只能修改標簽表_POST'),
556             ('crm_011307_only_delete_Tag_GET', '011307_只能刪除標簽表_GET'),
557             ('crm_011308_only_delete_Tag_POST', '011308_只能刪除標簽表_POST'),
558 
559             ('crm_011401_only_view_FirstLayerMenu_GET', '011401_只能查看一層菜單_GET'),
560             ('crm_011402_only_view_FirstLayerMenu_POST', '011402_只能查看一層菜單_POST'),
561             ('crm_011403_only_add_FirstLayerMenu_GET', '011403_只能添加一層菜單_GET'),
562             ('crm_011404_only_add_FirstLayerMenu_POST', '011404_只能添加一層菜單_POST'),
563             ('crm_011405_only_change_FirstLayerMenu_GET', '011405_只能修改一層菜單_GET'),
564             ('crm_011406_only_change_FirstLayerMenu_POST', '011406_只能修改一層菜單_POST'),
565             ('crm_011407_only_delete_FirstLayerMenu_GET', '011407_只能刪除一層菜單_GET'),
566             ('crm_011408_only_delete_FirstLayerMenu_POST', '011408_只能刪除一層菜單_POST'),
567 
568             ('crm_011501_only_view_SubMenu_GET', '011501_只能查看二層菜單_GET'),
569             ('crm_011502_only_view_SubMenu_POST', '011502_只能查看二層菜單_POST'),
570             ('crm_011503_only_add_SubMenu_GET', '011503_只能添加二層菜單_GET'),
571             ('crm_011504_only_add_SubMenu_POST', '011504_只能添加二層菜單_POST'),
572             ('crm_011505_only_change_SubMenu_GET', '011505_只能修改二層菜單_GET'),
573             ('crm_011506_only_change_SubMenu_POST', '011506_只能修改二層菜單_POST'),
574             ('crm_011507_only_delete_SubMenu_GET', '011507_只能刪除二層菜單_GET'),
575             ('crm_011508_only_delete_SubMenu_POST', '011508_只能刪除二層菜單_POST'),
576 
577             ('crm_011601_only_view_Groups_GET', '011601_只能查看權限組_GET'),
578             ('crm_011602_only_view_Groups_POST', '011602_只能查看權限組_POST'),
579             ('crm_011603_only_add_Groups_GET', '011603_只能添加權限組_GET'),
580             ('crm_011604_only_add_Groups_POST', '011604_只能添加權限組_POST'),
581             ('crm_011605_only_change_Groups_GET', '011605_只能修改權限組_GET'),
582             ('crm_011606_only_change_Groups_POST', '011606_只能修改權限組_POST'),
583             ('crm_011607_only_delete_Groups_GET', '011607_只能刪除權限組_GET'),
584             ('crm_011608_only_delete_Groups_POST', '011608_只能刪除權限組_POST'),
585 
586             ('crm_011701_own_password_reset_GET', '011701_自己密碼重置_GET'),
587             ('crm_011702_own_password_reset_POST', '011702_自己密碼重置_POST'),
588 
589             ('crm_020101_all_not_audit_GET', '020101_銷售查看全部的客戶未審核_GET'),
590             ('crm_020103_all_enrollment_GET', '020103_銷售給全部的客戶報名課程_GET'),
591             ('crm_020104_all_enrollment_POST', '020104_銷售給全部的客戶報名課程_POST'),
592             ('crm_020105_all_contract_review_GET', '020105_銷售給全部的客戶審核合同_GET'),
593             ('crm_020116_all_contract_review_POST', '020116_銷售給全部的客戶審核合同_POST'),
594 
595             ('crm_020201_own_enrollment_GET', '020201_銷售給自己的客戶報名課程_GET'),
596             ('crm_020202_own_enrollment_POST', '020202_銷售給自己的客戶報名課程_POST'),
597             ('crm_020203_own_contract_review_GET', '020203_銷售給自己的客戶審核合同_GET'),
598             ('crm_020204_own_contract_review_POST', '020204_銷售給自己的客戶審核合同_POST'),
599 
600             ('crm_030101_all_not_payment_GET', '030101_財務查看全部的客戶未繳費_GET'),
601             ('crm_030102_all_not_payment_POST', '030102_財務查看全部的客戶未繳費_POST'),
602             ('crm_030103_all_already_payment_GET', '030103_財務查看全部的客戶已繳費_GET'),
603             ('crm_030104_all_already_payment_POST', '030104_財務查看全部的客戶已繳費_POST'),
604             ('crm_030105_all_payment_GET', '030105_財務進行全部的客戶繳費_GET'),
605             ('crm_030106_all_payment_POST', '030106_財務進行全部的客戶繳費_POST'),
606 
607             ('crm_040101_own_student_course_GET', '040101_學生查看自己的課程_GET'),
608             ('crm_040102_own_student_course_POST', '040102_學生查看自己的課程_POST'),
609             ('crm_040103_own_studyrecords_GET', '040103_學生自己的上課記錄_GET'),
610             ('crm_040104_own_studyrecords_POST', '040104_學生自己的上課記錄_POST'),
611             ('crm_040105_own_homework_detail_GET', '040105_學生自己的作業詳情_GET'),
612             ('crm_040106_own_homework_detail_POST', '040106_學生自己的作業詳情_POST'),
613 
614             ('crm_050101_own_teacher_class_GET', '050101_講師查看自己的班級_GET'),
615             ('crm_050102_own_teacher_class_POST', '050102_講師查看自己的班級_POST'),
616             ('crm_050103_own_teacher_class_detail_GET', '050103_講師查看自己的課節詳情_GET'),
617             ('crm_050104_own_teacher_class_detail_POST', '050104_講師查看自己的課節詳情_POST'),
618             ('crm_050105_own_teacher_lesson_detail_GET', '050105_講師查看自己的課節學員_GET'),
619             ('crm_050106_own_teacher_lesson_detail_POST', '050106_講師查看自己的課節學員_POST'),
620             ('crm_050107_own_howk_down_GET', '050107_講師自己的學員作業下載_GET'),
621             ('crm_050108_own_howk_down_POST', '050108_講師自己的學員作業下載_POST'),
622 
623             ('crm_060101_own_coursetop_details_GET', '060101_講師查看自己的班級排名詳情_GET'),
624             ('crm_060102_own_coursetop_details_POST', '060102_講師查看自己的班級排名詳情_POST'),
625             ('crm_060103_own_coursetop_score_GET', '060103_講師查看自己的班級分數排行_GET'),
626             ('crm_060104_own_coursetop_score_POST', '060104_講師查看自己的班級排分數排行_POST'),
627             ('crm_060105_own_coursetop_homework_GET', '060105_講師查看自己的班級作業排行_GET'),
628             ('crm_060106_own_coursetop_homework_POST', '060106_講師查看自己的班級作業排行_POST'),
629             ('crm_060107_own_coursetop_attendance_GET', '060107_講師查看自己的班級出勤排行_GET'),
630             ('crm_060108_own_coursetop_attendance_POST', '060108_講師查看自己的班級出勤排行_POST'),
631 
632         )
633 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
634 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
635 """15權限組"""
636 from django.contrib.auth.models import Group
637 class Groups(Group):
638     class Meta:
639         verbose_name_plural = '15權限組'
640 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
641 
642 
643 """11角色表"""
644 class Role(models.Model):
645     name = models.CharField(unique=True,max_length=32)#角色名#CharField定長文本#角色名不可以重復#最長度=32字節
646 
647     # ————————72PerfectCRM實現CRM動態菜單和角色————————
648     menus = models.ManyToManyField('FirstLayerMenu',verbose_name='一層菜單',blank=True)
649     # ————————72PerfectCRM實現CRM動態菜單和角色————————
650 
651     def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
652         return self.name#返回 #角色名
653     class Meta: #通過一個內嵌類 "class Meta" 給你的 model 定義元數據
654         verbose_name_plural = "11角色表" #verbose_name_plural給你的模型類起一個更可讀的名字
655 
656 
657 """12標簽表"""
658 class Tag(models.Model):
659     name =  models.CharField(max_length=64,unique=True) #標簽名#CharField定長文本#最長度=64字節#不可以重復
660     def __str__(self): #__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
661         return self.name #返回 #標簽名
662     class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
663         verbose_name_plural =  "12標簽表" #verbose_name_plural給你的模型類起一個更可讀的名字
664 
665 # ————————01PerfectCRM基本配置ADMIN————————
666 
667 
668 # ————————72PerfectCRM實現CRM動態菜單和角色————————
669 """13一層菜單名"""
670 class FirstLayerMenu(models.Model):
671     '''第一層側邊欄菜單'''
672     name = models.CharField('一層菜單名',max_length=64)
673     url_type_choices = ((0,'相關的名字'),(1,'固定的URL'))
674     url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
675     url_name = models.CharField(max_length=64,verbose_name='一層菜單路徑')
676     order = models.SmallIntegerField(default=0,verbose_name='菜單排序')
677     sub_menus = models.ManyToManyField('SubMenu',blank=True)
678 
679     def __str__(self):
680         return self.name
681 
682     class Meta:
683         verbose_name_plural = "13第一層菜單"
684 
685 """14二層菜單名"""
686 class SubMenu(models.Model):
687     '''第二層側邊欄菜單'''
688     name = models.CharField('二層菜單名', max_length=64)
689     url_type_choices = ((0,'相關的名字'),(1,'固定的URL'))
690     url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
691     url_name = models.CharField(max_length=64, verbose_name='二層菜單路徑')
692     order = models.SmallIntegerField(default=0, verbose_name='菜單排序')
693 
694     def __str__(self):
695         return self.name
696 
697     class Meta:
698         verbose_name_plural = "14第二層菜單"
699 # ————————72PerfectCRM實現CRM動態菜單和角色————————
#models.py

 

 

 

 

 

 

  1 # permission_list.py
  2 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
  3 from permissions import CJ  # 自定義權限鈎子
  4 
  5 # 權限樣式 app_權限名字
  6 perm_dic = {
  7 
  8     'crm_010101_all_table_data_list_GET': ['table_data_list', 'GET', [], {}, ],
  9     # ('crm_010101_all_table_data_list_GET', '010101_全部查看數據_GET'),
 10     'crm_010102_all_table_data_list_POST': ['table_data_list', 'POST', [], {}, ],
 11     # ('crm_010102_all_table_data_list_POST', '010102_查全部看數據_POST'),
 12     'crm_010103_all_table_add_GET': ['table_add', 'GET', [], {}, ],
 13     # ('crm_010103_all_table_add_GET', '010103_全部添加數據_GET'),
 14     'crm_010104_all_table_add_POST': ['table_add', 'POST', [], {}, ],
 15     # ('crm_010104_all_table_add_POST', '010104_全部添加數據_POST'),
 16     'crm_010105_all_table_change_GET': ['table_change', 'GET', [], {}, ],
 17     # ('crm_010105_all_table_change_GET', '010105_全部修改數據_GET'),
 18     'crm_010106_all_table_change_POST': ['table_change', 'POST', [], {}, ],
 19     # ('crm_010106_all_table_change_POST', '010106_全部修改數據_POST'),
 20     'crm_010107_all_table_delete_GET': ['table_delete', 'GET', [], {}, ],
 21     # ('crm_010107_all_table_delete_GET', '010107_全部刪除數據_GET'),
 22     'crm_010108_all_table_delete_POST': ['table_delete', 'POST', [], {}, ],
 23     # ('crm_010108_all_table_delete_POST', '010108_全部刪除數據_POST'),
 24     'crm_010109_all_password_reset_GET': ['password_reset', 'GET', [], {}, ],
 25     # ('crm_010109_all_password_reset_GET', '010109_全部密碼重置_GET'),
 26     'crm_010110_all_password_reset_POST': ['password_reset', 'POST', [], {}, ],
 27     # ('crm_010110_all_password_reset_POST', '010110_全部密碼重置_POST'),
 28 
 29     'crm_010201_only_view_Branch_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Branch],
 30     # ('crm_010201_only_view_Branch_GET', '010201_只能查看校區表_GET'),
 31     'crm_010202_only_view_Branch_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Branch],
 32     # ('crm_010202_only_view_Branch_POST', '010202_只能查看校區表_POST'),
 33     'crm_010203_only_add_Branch_GET': ['table_add', 'GET', [], {}, CJ.JM_Branch],
 34     # ('crm_010203_only_add_Branch_GET', '010203_只能添加校區表_GET'),
 35     'crm_010204_only_add_Branch_POST': ['table_add', 'POST', [], {}, CJ.JM_Branch],
 36     # ('crm_010204_only_add_Branch_POST', '010204_只能添加校區表_POST'),
 37     'crm_010205_only_change_Branch_GET': ['table_change', 'GET', [], {}, CJ.JM_Branch],
 38     # ('crm_010205_only_change_Branch_GET', '010205_只能修改校區表_GET'),
 39     'crm_010206_only_change_Branch_POST': ['table_change', 'POST', [], {}, CJ.JM_Branch],
 40     #  ('crm_010206_only_change_Branch_POST', '010206_只能修改校區表_POST'),
 41     'crm_010207_only_delete_Branch_GET': ['table_delete', 'GET', [], {}, CJ.JM_Branch],
 42     # ('crm_010207_only_delete_Branch_GET', '010207_只能刪除校區表_GET'),
 43     'crm_010208_only_delete_Branch_POST': ['table_delete', 'POST', [], {}, CJ.JM_Branch],
 44     # ('crm_010208_only_delete_Branch_POST', '010208_只能刪除校區表_POST'),
 45 
 46     'crm_010301_only_view_ClassList_GET': ['table_data_list', 'GET', [], {}, CJ.JM_ClassList],
 47     # ('crm_010301_only_view_ClassList_GET', '010301_只能查看班級表_GET'),
 48     'crm_010302_only_view_ClassList_POST': ['table_data_list', 'POST', [], {}, CJ.JM_ClassList],
 49     # ('crm_010302_only_view_ClassList_POST', '010302_只能查看班級表_POST'),
 50     'crm_010303_only_add_ClassList_GET': ['table_add', 'GET', [], {}, CJ.JM_ClassList],
 51     # ('crm_010303_only_add_ClassList_GET', '010303_只能添加班級表_GET'),
 52     'crm_010304_only_add_ClassList_POST': ['table_add', 'POST', [], {}, CJ.JM_ClassList],
 53     # ('crm_010304_only_add_ClassList_POST', '010304_只能添加班級表_POST'),
 54     'crm_010305_only_change_ClassList_GET': ['table_change', 'GET', [], {}, CJ.JM_ClassList],
 55     # ('crm_010305_only_change_ClassList_GET', '010305_只能修改班級表_GET'),
 56     'crm_010306_only_change_ClassList_POST': ['table_change', 'POST', [], {}, CJ.JM_ClassList],
 57     # ('crm_010306_only_change_ClassList_POST', '010306_只能修改班級表_POST'),
 58     'crm_010307_only_delete_ClassList_GET': ['table_delete', 'GET', [], {}, CJ.JM_ClassList],
 59     # ('crm_010307_only_delete_ClassList_GET', '010307_只能刪除班級表_GET'),
 60     'crm_010308_only_delete_ClassList_POST': ['table_delete', 'POST', [], {}, CJ.JM_ClassList],
 61     # ('crm_010308_only_delete_ClassList_POST', '010308_只能刪除班級表_POST'),
 62 
 63     'crm_010401_only_view_Course_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Course],
 64     # ('crm_010401_only_view_Course_GET', '010401_只能查看課程表_GET'),
 65     'crm_010402_only_view_Course_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Course],
 66     # ('crm_010402_only_view_Course_POST', '010402_只能查看課程表_POST'),
 67     'crm_010403_only_add_Course_GET': ['table_add', 'GET', [], {}, CJ.JM_Course],
 68     # ('crm_010403_only_add_Course_GET', '010403_只能添加課程表_GET'),
 69     'crm_010404_only_add_Course_POST': ['table_add', 'POST', [], {}, CJ.JM_Course],
 70     # ('crm_010404_only_add_Course_POST', '010404_只能添加課程表_POST'),
 71     'crm_010405_only_change_Course_GET': ['table_change', 'GET', [], {}, CJ.JM_Course],
 72     # ('crm_010405_only_change_Course_GET', '010405_只能修改課程表_GET'),
 73     'crm_010406_only_change_Course_POST': ['table_change', 'POST', [], {}, CJ.JM_Course],
 74     # ('crm_010406_only_change_Course_POST', '010406_只能修改課程表_POST'),
 75     'crm_010407_only_delete_Course_GET': ['table_delete', 'GET', [], {}, CJ.JM_Course],
 76     # ('crm_010407_only_delete_Course_GET', '010407_只能刪除課程表_GET'),
 77     'crm_010408_only_delete_Course_POST': ['table_delete', 'POST', [], {}, CJ.JM_Course],
 78     # ('crm_010408_only_delete_Course_POST', '010408_只能刪除課程表_POST'),
 79 
 80     'crm_010501_only_view_Customer_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Customer],
 81     # ('crm_010501_only_view_Customer_GET', '010501_只能查看客戶表_GET'),
 82     'crm_010502_only_view_Customer_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Customer],
 83     #  ('crm_010502_only_view_Customer_POST', '010502_只能查看客戶表_POST'),
 84     'crm_010503_only_add_Customer_GET': ['table_add', 'GET', [], {}, CJ.JM_Customer],
 85     # ('crm_010503_only_add_Customer_GET', '010503_只能添加客戶表_GET'),
 86     'crm_010504_only_add_Customer_POST': ['table_add', 'POST', [], {}, CJ.JM_Customer],
 87     # ('crm_010504_only_add_Customer_POST', '010504_只能添加客戶表_POST'),
 88     'crm_010505_only_change_Customer_GET': ['table_change', 'GET', [], {}, CJ.JM_Customer],
 89     # ('crm_010505_only_change_Customer_GET', '010505_只能修改客戶表_GET'),
 90     'crm_010506_only_change_Customer_POST': ['table_change', 'POST', [], {}, CJ.JM_Customer],
 91     # ('crm_010506_only_change_Customer_POST', '010506_只能修改客戶表_POST'),
 92     'crm_010507_only_delete_Customer_GET': ['table_delete', 'GET', [], {}, CJ.JM_Customer],
 93     # ('crm_010507_only_delete_Customer_GET', '010507_只能刪除客戶表_GET'),
 94     'crm_010508_only_delete_Customer_POST': ['table_delete', 'POST', [], {}, CJ.JM_Customer],
 95     # ('crm_010508_only_delete_Customer_POST', '010508_只能刪除客戶表_POST'),
 96 
 97     'crm_010601_only_view_CustomerFollowUp_GET': ['table_data_list', 'GET', [], {}, CJ.JM_CustomerFollowUp],
 98     # ('crm_010601_only_view_CustomerFollowUp_GET', '010601_只能查看跟進表_GET'),
 99     'crm_010602_only_view_CustomerFollowUp_POST': ['table_data_list', 'POST', [], {}, CJ.JM_CustomerFollowUp],
100     # ('crm_010602_only_view_CustomerFollowUp_POST', '010602_只能查看跟進表_POST'),
101     'crm_010603_only_add_CustomerFollowUp_GET': ['table_add', 'GET', [], {}, CJ.JM_CustomerFollowUp],
102     # ('crm_010603_only_add_CustomerFollowUp_GET', '010603_只能添加跟進表_GET'),
103     'crm_010604_only_add_CustomerFollowUp_POST': ['table_add', 'POST', [], {}, CJ.JM_CustomerFollowUp],
104     # ('crm_010604_only_add_CustomerFollowUp_POST', '010604_只能添加跟進表_POST'),
105     'crm_010605_only_change_CustomerFollowUp_GET': ['table_change', 'GET', [], {}, CJ.JM_CustomerFollowUp],
106     # ('crm_010605_only_change_CustomerFollowUp_GET', '010605_只能修改跟進表_GET'),
107     'crm_010606_only_change_CustomerFollowUp_POST': ['table_change', 'POST', [], {}, CJ.JM_CustomerFollowUp],
108     # ('crm_010606_only_change_CustomerFollowUp_POST', '010606_只能修改跟進表_POST'),
109     'crm_010607_only_delete_CustomerFollowUp_GET': ['table_delete', 'GET', [], {}, CJ.JM_CustomerFollowUp],
110     # ('crm_010607_only_delete_CustomerFollowUp_GET', '010607_只能刪除跟進表_GET'),
111     'crm_010608_only_delete_CustomerFollowUp_POST': ['table_delete', 'POST', [], {}, CJ.JM_CustomerFollowUp],
112     # ('crm_010608_only_delete_CustomerFollowUp_POST', '010608_只能刪除跟進表_POST'),
113 
114     'crm_010701_only_view_Enrollment_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Enrollment],
115     # ('crm_010701_only_view_Enrollment_GET', '010701_只能查看報名表_GET'),
116     'crm_010702_only_view_Enrollment_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Enrollment],
117     # ('crm_010702_only_view_Enrollment_POST', '010702_只能查看報名表_POST'),
118     'crm_010703_only_add_Enrollment_GET': ['table_add', 'GET', [], {}, CJ.JM_Enrollment],
119     # ('crm_010703_only_add_Enrollment_GET', '010703_只能添加報名表_GET'),
120     'crm_010704_only_add_Enrollment_POST': ['table_add', 'POST', [], {}, CJ.JM_Enrollment],
121     # ('crm_010704_only_add_Enrollment_POST', '010704_只能添加報名表_POST'),
122     'crm_010705_only_change_Enrollment_GET': ['table_change', 'GET', [], {}, CJ.JM_Enrollment],
123     # ('crm_010705_only_change_Enrollment_GET', '010705_只能修改報名表_GET'),
124     'crm_010706_only_change_Enrollment_POST': ['table_change', 'POST', [], {}, CJ.JM_Enrollment],
125     # ('crm_010706_only_change_Enrollment_POST', '010706_只能修改報名表_POST'),
126     'crm_010707_only_delete_Enrollment_GET': ['table_delete', 'GET', [], {}, CJ.JM_Enrollment],
127     # ('crm_010707_only_delete_Enrollment_GET', '010707_只能刪除報名表_GET'),
128     'crm_010708_only_delete_Enrollment_POST': ['table_delete', 'POST', [], {}, CJ.JM_Enrollment],
129     # ('crm_010708_only_delete_Enrollment_POST', '010708_只能刪除報名表_POST'),
130 
131     'crm_010801_only_view_Payment_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Payment],
132     # ('crm_010801_only_view_Payment_GET', '010801_只能查看繳費表_GET'),
133     'crm_010802_only_view_Payment_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Payment],
134     # ('crm_010802_only_view_Payment_POST', '010802_只能查看繳費表_POST'),
135     'crm_010803_only_add_Payment_GET': ['table_add', 'GET', [], {}, CJ.JM_Payment],
136     # ('crm_010803_only_add_Payment_GET', '010803_只能添加繳費表_GET'),
137     'crm_010804_only_add_Payment_POST': ['table_add', 'POST', [], {}, CJ.JM_Payment],
138     # ('crm_010804_only_add_Payment_POST', '010804_只能添加繳費表_POST'),
139     'crm_010805_only_change_Payment_GET': ['table_change', 'GET', [], {}, CJ.JM_Payment],
140     # ('crm_010805_only_change_Payment_GET', '010805_只能修改繳費表_GET'),
141     'crm_010806_only_change_Payment_POST': ['table_change', 'POST', [], {}, CJ.JM_Payment],
142     # ('crm_010806_only_change_Payment_POST', '010806_只能修改繳費表_POST'),
143     'crm_010807_only_delete_Payment_GET': ['table_delete', 'GET', [], {}, CJ.JM_Payment],
144     # ('crm_010807_only_delete_Payment_GET', '010807_只能刪除繳費表_GET'),
145     'crm_010808_only_delete_Payment_POST': ['table_delete', 'POST', [], {}, CJ.JM_Payment],
146     # ('crm_010808_only_delete_Payment_POST', '010808_只能刪除繳費表_POST'),
147 
148     'crm_010901_only_view_CourseRecord_GET': ['table_data_list', 'GET', [], {}, CJ.JM_CourseRecord],
149     # ('crm_010901_only_view_CourseRecord_GET', '010901_只能查看上課表_GET'),
150     'crm_010902_only_view_CourseRecord_POST': ['table_data_list', 'POST', [], {}, CJ.JM_CourseRecord],
151     # ('crm_010902_only_view_CourseRecord_POST', '010902_只能查看上課表_POST'),
152     'crm_010903_only_add_CourseRecord_GET': ['table_add', 'GET', [], {}, CJ.JM_CourseRecord],
153     # ('crm_010903_only_add_CourseRecord_GET', '010903_只能添加上課表_GET'),
154     'crm_010904_only_add_CourseRecord_POST': ['table_add', 'POST', [], {}, CJ.JM_CourseRecord],
155     # ('crm_010904_only_add_CourseRecord_POST', '010904_只能添加上課表_POST'),
156     'crm_010905_only_change_CourseRecord_GET': ['table_change', 'GET', [], {}, CJ.JM_CourseRecord],
157     # ('crm_010905_only_change_CourseRecord_GET', '010905_只能修改上課表_GET'),
158     'crm_010906_only_change_CourseRecord_POST': ['table_change', 'POST', [], {}, CJ.JM_CourseRecord],
159     # ('crm_010906_only_change_CourseRecord_POST', '010906_只能修改上課表_POST'),
160     'crm_010907_only_delete_CourseRecord_GET': ['table_delete', 'GET', [], {}, CJ.JM_CourseRecord],
161     # ('crm_010907_only_delete_CourseRecord_GET', '010907_只能刪除上課表_GET'),
162     'crm_010908_only_delete_CourseRecord_POST': ['table_delete', 'POST', [], {}, CJ.JM_CourseRecord],
163     # ('crm_010908_only_delete_CourseRecord_POST', '010908_只能刪除上課表_POST'),
164 
165     'crm_011001_only_view_StudyRecord_GET': ['table_data_list', 'GET', [], {}, CJ.JM_StudyRecord],
166     # ('crm_011001_only_view_StudyRecord_GET', '011001_只能查看學習表_GET'),
167     'crm_011002_only_view_StudyRecord_POST': ['table_data_list', 'POST', [], {}, CJ.JM_StudyRecord],
168     # ('crm_011002_only_view_StudyRecord_POST', '011002_只能查看學習表_POST'),
169     'crm_011003_only_add_StudyRecord_GET': ['table_add', 'GET', [], {}, CJ.JM_StudyRecord],
170     # ('crm_011003_only_add_StudyRecord_GET', '011003_只能添加學習表_GET'),
171     'crm_011004_only_add_StudyRecord_POST': ['table_add', 'POST', [], {}, CJ.JM_StudyRecord],
172     # ('crm_011004_only_add_StudyRecord_POST', '011004_只能添加學習表_POST'),
173     'crm_011005_only_change_StudyRecord_GET': ['table_change', 'GET', [], {}, CJ.JM_StudyRecord],
174     # ('crm_011005_only_change_StudyRecord_GET', '011005_只能修改學習表_GET'),
175     'crm_011006_only_change_StudyRecord_POST': ['table_change', 'POST', [], {}, CJ.JM_StudyRecord],
176     # ('crm_011006_only_change_StudyRecord_POST', '011006_只能修改學習表_POST'),
177     'crm_011007_only_delete_StudyRecord_GET': ['table_delete', 'GET', [], {}, CJ.JM_StudyRecord],
178     # ('crm_011007_only_delete_StudyRecord_GET', '011007_只能刪除學習表_GET'),
179     'crm_011008_only_delete_StudyRecord_POST': ['table_delete', 'POST', [], {}, CJ.JM_StudyRecord],
180     # ('crm_011008_only_delete_StudyRecord_POST', '011008_只能刪除學習表_POST'),
181 
182     'crm_011101_only_view_UserProfile_GET': ['table_data_list', 'GET', [], {}, CJ.JM_UserProfile],
183     # ('crm_011101_only_view_UserProfile_GET', '011101_只能查看賬號表_GET'),
184     'crm_011102_only_view_UserProfile_POST': ['table_data_list', 'POST', [], {}, CJ.JM_UserProfile],
185     # ('crm_011102_only_view_UserProfile_POST', '011102_只能查看賬號表_POST'),
186     'crm_011103_only_add_UserProfile_GET': ['table_add', 'GET', [], {}, CJ.JM_UserProfile],
187     # ('crm_011103_only_add_UserProfile_GET', '011103_只能添加賬號表_GET'),
188     'crm_011104_only_add_UserProfile_POST': ['table_add', 'POST', [], {}, CJ.JM_UserProfile],
189     # ('crm_011104_only_add_UserProfile_POST', '011104_只能添加賬號表_POST'),
190     'crm_011105_only_change_UserProfile_GET': ['table_change', 'GET', [], {}, CJ.JM_UserProfile],
191     # ('crm_011105_only_change_UserProfile_GET', '011105_只能修改賬號表_GET'),
192     'crm_011106_only_change_UserProfile_POST': ['table_change', 'POST', [], {}, CJ.JM_UserProfile],
193     # ('crm_011106_only_change_UserProfile_POST', '011106_只能修改賬號表_POST'),
194     'crm_011107_only_delete_UserProfile_GET': ['table_delete', 'GET', [], {}, CJ.JM_UserProfile],
195     # ('crm_011107_only_delete_UserProfile_GET', '011107_只能刪除賬號表_GET'),
196     'crm_011108_only_delete_UserProfile_POST': ['table_delete', 'POST', [], {}, CJ.JM_UserProfile],
197     # ('crm_011108_only_delete_UserProfile_POST', '011108_只能刪除賬號表_POST'),
198 
199     'crm_011201_only_view_Role_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Role],
200     # ('crm_011201_only_view_Role_GET', '011201_只能查看角色表_GET'),
201     'crm_011202_only_view_Role_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Role],
202     # ('crm_011202_only_view_Role_POST', '011202_只能查看角色表_POST'),
203     'crm_011203_only_add_Role_GET': ['table_add', 'GET', [], {}, CJ.JM_Role],
204     # ('crm_011203_only_add_Role_GET', '011203_只能添加角色表_GET'),
205     'crm_011204_only_add_Role_POST': ['table_add', 'POST', [], {}, CJ.JM_Role],
206     # ('crm_011204_only_add_Role_POST', '011204_只能添加角色表_POST'),
207     'crm_011205_only_change_Role_GET': ['table_change', 'GET', [], {}, CJ.JM_Role],
208     # ('crm_011205_only_change_Role_GET', '011205_只能修改角色表_GET'),
209     'crm_011206_only_change_Role_POST': ['table_change', 'POST', [], {}, CJ.JM_Role],
210     # ('crm_011206_only_change_Role_POST', '011206_只能修改角色表_POST'),
211     'crm_011207_only_delete_Role_GET': ['table_delete', 'GET', [], {}, CJ.JM_Role],
212     # ('crm_011207_only_delete_Role_GET', '011207_只能刪除角色表_GET'),
213     'crm_011208_only_delete_Role_POST': ['table_delete', 'POST', [], {}, CJ.JM_Role],
214     # ('crm_011208_only_delete_Role_POST', '011208_只能刪除角色表_POST'),
215 
216     'crm_011301_only_view_Tag_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Tag],
217     # ('crm_011301_only_view_Tag_GET', '011301_只能查看標簽表_GET'),
218     'crm_011302_only_view_Tag_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Tag],
219     # ('crm_011302_only_view_Tag_POST', '011302_只能查看標簽表_POST'),
220     'crm_011303_only_add_Tag_GET': ['table_add', 'GET', [], {}, CJ.JM_Tag],
221     # ('crm_011303_only_add_Tag_GET', '011303_只能添加標簽表_GET'),
222     'crm_011304_only_add_Tag_POST': ['table_add', 'POST', [], {}, CJ.JM_Tag],
223     # ('crm_011304_only_add_Tag_POST', '011304_只能添加標簽表_POST'),
224     'crm_011305_only_change_Tag_GET': ['table_change', 'GET', [], {}, CJ.JM_Tag],
225     # (('crm_011305_only_change_Tag_GET', '011305_只能修改標簽表_GET')
226     'crm_011306_only_change_Tag_POST': ['table_change', 'POST', [], {}, CJ.JM_Tag],
227     # ('crm_011306_only_change_Tag_POST', '011306_只能修改標簽表_POST'),
228     'crm_011307_only_delete_Tag_GET': ['table_delete', 'GET', [], {}, CJ.JM_Tag],
229     # ('crm_011307_only_delete_Tag_GET', '011307_只能刪除標簽表_GET'),
230     'crm_011308_only_delete_Tag_POST': ['table_delete', 'POST', [], {}, CJ.JM_Tag],
231     # ('crm_011308_only_delete_Tag_POST', '011308_只能刪除標簽表_POST'),
232 
233     'crm_011401_only_view_FirstLayerMenu_GET': ['table_data_list', 'GET', [], {}, CJ.JM_FirstLayerMenu],
234     # ('crm_011401_only_view_FirstLayerMenu_GET', '011401_只能查看一層菜單_GET'),
235     'crm_011402_only_view_FirstLayerMenu_POST': ['table_data_list', 'POST', [], {}, CJ.JM_FirstLayerMenu],
236     # ('crm_011402_only_view_FirstLayerMenu_POST', '011402_只能查看一層菜單_POST'),
237     'crm_011403_only_add_FirstLayerMenu_GET': ['table_add', 'GET', [], {}, CJ.JM_FirstLayerMenu],
238     # ('crm_011403_only_add_FirstLayerMenu_GET', '011403_只能添加一層菜單_GET'),
239     'crm_011404_only_add_FirstLayerMenu_POST': ['table_add', 'POST', [], {}, CJ.JM_FirstLayerMenu],
240     # ('crm_011404_only_add_FirstLayerMenu_POST', '011404_只能添加一層菜單_POST'),
241     'crm_011405_only_change_FirstLayerMenu_GET': ['table_change', 'GET', [], {}, CJ.JM_FirstLayerMenu],
242     # ('crm_011405_only_change_FirstLayerMenu_GET', '011405_只能修改一層菜單_GET'),
243     'crm_011406_only_change_FirstLayerMenu_POST': ['table_change', 'POST', [], {}, CJ.JM_FirstLayerMenu],
244     # ('crm_011406_only_change_FirstLayerMenu_POST', '011406_只能修改一層菜單_POST'),
245     'crm_011407_only_delete_FirstLayerMenu_GET': ['table_delete', 'GET', [], {}, CJ.JM_FirstLayerMenu],
246     # ('crm_011407_only_delete_FirstLayerMenu_GET', '011407_只能刪除一層菜單_GET'),
247     'crm_011408_only_delete_FirstLayerMenu_POST': ['table_delete', 'POST', [], {}, CJ.JM_FirstLayerMenu],
248     # ('crm_011408_only_delete_FirstLayerMenu_POST', '011408_只能刪除一層菜單_POST'),
249 
250     'crm_011501_only_view_SubMenu_GET': ['table_data_list', 'GET', [], {}, CJ.JM_SubMenu],
251     # ('crm_011501_only_view_SubMenu_GET', '011501_只能查看二層菜單_GET'),
252     'crm_011502_only_view_SubMenu_POST': ['table_data_list', 'POST', [], {}, CJ.JM_SubMenu],
253     # ('crm_011502_only_view_SubMenu_POST', '011502_只能查看二層菜單_POST'),
254     'crm_011503_only_add_SubMenu_GET': ['table_add', 'GET', [], {}, CJ.JM_SubMenu],
255     # ('crm_011503_only_add_SubMenu_GET', '011503_只能添加二層菜單_GET'),
256     'crm_011504_only_add_SubMenu_POST': ['table_add', 'POST', [], {}, CJ.JM_SubMenu],
257     # ('crm_011504_only_add_SubMenu_POST', '011504_只能添加二層菜單_POST'),
258     'crm_011505_only_change_SubMenu_GET': ['table_change', 'GET', [], {}, CJ.JM_SubMenu],
259     # ('crm_011505_only_change_SubMenu_GET', '011505_只能修改二層菜單_GET'),
260     'crm_011506_only_change_SubMenu_POST': ['table_change', 'POST', [], {}, CJ.JM_SubMenu],
261     # ('crm_011506_only_change_SubMenu_POST', '011506_只能修改二層菜單_POST'),
262     'crm_011507_only_delete_SubMenu_GET': ['table_delete', 'GET', [], {}, CJ.JM_SubMenu],
263     # ('crm_011507_only_delete_SubMenu_GET', '011507_只能刪除二層菜單_GET'),
264     'crm_011508_only_delete_SubMenu_POST': ['table_delete', 'POST', [], {}, CJ.JM_SubMenu],
265     # ('crm_011508_only_delete_SubMenu_POST', '011508_只能刪除二層菜單_POST'),
266 
267     'crm_011601_only_view_Groups_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Groups],
268     # ('crm_011601_only_view_Groups_GET', '011601_只能查看權限組_GET'),
269     'crm_011602_only_view_Groups_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Groups],
270     # ('crm_011602_only_view_Groups_POST', '011602_只能查看權限組_POST'),
271     'crm_011603_only_add_Groups_GET': ['table_add', 'GET', [], {}, CJ.JM_Groups],
272     # ('crm_011603_only_add_Groups_GET', '011603_只能添加權限組_GET'),
273     'crm_011604_only_add_Groups_POST': ['table_add', 'POST', [], {}, CJ.JM_Groups],
274     # ('crm_011604_only_add_Groups_POST', '011604_只能添加權限組_POST'),
275     'crm_011605_only_change_Groups_GET': ['table_change', 'GET', [], {}, CJ.JM_Groups],
276     #  ('crm_011605_only_change_Groups_GET', '011605_只能修改權限組_GET'),
277     'crm_011606_only_change_Groups_POST': ['table_change', 'POST', [], {}, CJ.JM_Groups],
278     # ('crm_011606_only_change_Groups_POST', '011606_只能修改權限組_POST'),
279     'crm_011607_only_delete_Groups_GET': ['table_delete', 'GET', [], {}, CJ.JM_Groups],
280     # ('crm_011607_only_delete_Groups_GET', '011607_只能刪除權限組_GET'),
281     'crm_011608_only_delete_Groups_POST': ['table_delete', 'POST', [], {}, CJ.JM_Groups],
282     # ('crm_011608_only_delete_Groups_POST', '011608_只能刪除權限組_POST'),
283 
284     'crm_011701_own_password_reset_GET': ['password_reset', 'GET', [], {}, CJ.own_password_reset],
285     # ('crm_011701_own_password_reset_GET', '011701_自己密碼重置_GET'),
286     'crm_011702_own_password_reset_POST': ['password_reset', 'POST', [], {}, CJ.own_password_reset],
287     # ('crm_011702_own_password_reset_POST', '011702_自己密碼重置_POST'),
288 
289     'crm_020101_all_not_audit_GET': ['not_audit', 'GET', [], {}, ],
290     # ('crm_020101_all_not_audit_GET', '020101_銷售查看全部的客戶未審核_GET'),
291     'crm_020103_all_enrollment_GET': ['enrollment', 'GET', [], {}, ],
292     # ('crm_020103_all_enrollment_GET', '020103_銷售給全部的客戶報名課程_GET'),
293     'crm_020104_all_enrollment_POST': ['enrollment', 'POST', [], {}, ],
294     # ('crm_020104_all_enrollment_POST', '020104_銷售給全部的客戶報名課程_POST'),
295     'crm_020105_all_contract_review_GET': ['contract_review', 'GET', [], {}, ],
296     # ('crm_020105_all_contract_review_GET', '020105_銷售給全部的客戶審核合同_GET'),
297     'crm_020116_all_contract_review_POST': ['contract_review', 'POST', [], {}, ],
298     # ('crm_020116_all_contract_review_POST', '020116_銷售給全部的客戶審核合同_POST'),
299 
300     'crm_020201_own_enrollment_GET': ['enrollment', 'GET', [], {}, CJ.own_enrollment],
301     # ('crm_020201_own_enrollment_GET', '020201_銷售給自己的客戶報名課程_GET'),
302     'crm_020202_own_enrollment_POST': ['enrollment', 'POST', [], {}, CJ.own_enrollment],
303     # ('crm_020202_own_enrollment_POST', '020202_銷售給自己的客戶報名課程_POST'),
304     'crm_020203_own_contract_review_GET': ['contract_review', 'GET', [], {}, CJ.own_contract_review],
305     # ('crm_020203_own_contract_review_GET', '020203_銷售給自己的客戶審核合同_GET'),
306     'crm_020204_own_contract_review_POST': ['contract_review', 'POST', [], {}, CJ.own_contract_review],
307     # ('crm_020204_own_contract_review_POST', '020204_銷售給自己的客戶審核合同_POST'),
308 
309     'crm_030101_all_not_payment_GET': ['not_payment', 'GET', [], {}, ],
310     # ('crm_030101_all_not_payment_GET', '030101_財務查看全部的客戶未繳費_GET'),
311     'crm_030102_all_not_payment_POST': ['not_payment', 'GET', [], {}, ],
312     # ('crm_030102_all_not_payment_POST', '030102_財務查看全部的客戶未繳費_POST'),
313     'crm_030103_all_already_payment_GET': ['already_payment', 'GET', [], {}, ],
314     # ('crm_030103_all_already_payment_GET', '030103_財務查看全部的客戶已繳費_GET'),
315     'crm_030104_all_already_payment_POST': ['already_payment', 'GET', [], {}, ],
316     # ('crm_030104_all_already_payment_POST', '030104_財務查看全部的客戶已繳費_POST'),
317     'crm_030105_all_payment_GET': ['payment', 'GET', [], {}, ],
318     # ('crm_030105_all_payment_GET', '030105_財務進行全部的客戶繳費_GET'),
319     'crm_030106_all_payment_POST': ['payment', 'POST', [], {}, ],
320     # ('crm_030106_all_payment_POST', '030106_財務進行全部的客戶繳費_POST'),
321 
322     'crm_040101_own_student_course_GET': ['student_course', 'GET', [], {}, ],
323     # ('crm_040101_own_student_course_GET', '040101_學生查看自己的課程_GET'),
324     'crm_040102_own_student_course_POST': ['student_course', 'POST', [], {}, ],
325     # ('crm_040102_own_student_course_POST', '040102_學生查看自己的課程_POST'),
326     'crm_040103_own_studyrecords_GET': ['studyrecords', 'GET', [], {}, CJ.own_studyrecords],
327     # ('crm_040103_own_studyrecords_GET', '040103_學生自己的上課記錄_GET'),
328     'crm_040104_own_studyrecords_POST': ['studyrecords', 'POST', [], {}, CJ.own_studyrecords],
329     # ('crm_050104_own_studyrecords_POST', '040104_學生自己的上課記錄_POST'),
330     'crm_040105_own_homework_detail_GET': ['homework_detail', 'GET', [], {}, CJ.own_homework_detail],
331     # ('crm_040105_own_homework_detail_GET', '040105_學生自己的作業詳情_GET'),
332     'crm_040106_own_homework_detail_POST': ['homework_detail', 'POST', [], {}, CJ.own_homework_detail],
333     # ('crm_040106_own_homework_detail_POST', '040106_學生自己的作業詳情_POST'),
334 
335     'crm_050101_own_teacher_class_GET': ['teacher_class', 'GET', [], {}, ],
336     # ('crm_050101_own_teacher_class_GET', '050101_講師查看自己的班級_GET'),
337     'crm_05102_own_teacher_class_POST': ['teacher_class', 'POST', [], {}, ],
338     # ('crm_050102_own_teacher_class_POST', '050102_講師查看自己的班級_POST'),
339     'crm_050103_own_teacher_class_detail_GET': ['teacher_class_detail', 'GET', [], {}, CJ.own_teacher_class_detail],
340     # ('crm_050103_own_teacher_class_detail_GET', '050103_講師查看自己的課節詳情_GET'),
341     'crm_050104_own_teacher_class_detail_POST': ['teacher_class_detail', 'POST', [], {}, CJ.own_teacher_class_detail],
342     # ('crm_050104_own_teacher_class_detail_POST', '050104_講師查看自己的課節詳情_POST'),
343     'crm_050105_own_teacher_lesson_detail_GET': ['teacher_lesson_detail', 'GET', [], {}, CJ.own_teacher_lesson_detail],
344     # ('crm_050105_own_teacher_lesson_detail_GET', '050105_講師查看自己的課節學員_GET'),
345     'crm_050106_own_teacher_lesson_detail_POST': ['teacher_lesson_detail', 'POST', [], {}, CJ.own_teacher_lesson_detail],
346     # ('crm_050106_own_teacher_lesson_detail_POST', '050106_講師查看自己的課節學員_POST'),
347     'crm_050107_own_howk_down_GET': ['howk_down', 'GET', [], {}, CJ.own_howk_down],
348     # ('crm_050107_own_howk_down_GET', '050107_講師自己的學員作業下載_GET'),
349     'crm_050108_own_howk_down_POST': ['howk_down', 'POST', [], {}, CJ.own_howk_down],
350     # ('crm_050108_own_howk_down_POST', '050108_講師自己的學員作業下載_POST'),
351 
352     'crm_060101_own_coursetop_details_GET': ['coursetop_details', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
353     # ('crm_060101_own_coursetop_details_GET', '060101_講師查看自己的班級排名詳情_GET'),
354     'crm_060102_own_coursetop_details_POST': ['coursetop_details', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
355     # ('crm_060102_own_coursetop_details_POST', '060102_講師查看自己的班級排名詳情_POST'),
356     'crm_060103_own_coursetop_score_GET': ['coursetop_score', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
357     # ('crm_060103_own_coursetop_score_GET', '060103_講師查看自己的班級分數排行_GET'),
358     'crm_060104_own_coursetop_score_POST': ['coursetop_score', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
359     # ('crm_060104_own_coursetop_score_POST', '060104_講師查看自己的班級排分數排行_POST'),
360     'crm_060105_own_coursetop_homework_GET': ['coursetop_homework', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
361     # ('crm_060105_own_coursetop_homework_GET', '060105_講師查看自己的班級作業排行_GET'),
362     'crm_060106_own_coursetop_homework_POST': ['coursetop_homework', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
363     # ('crm_060106_own_coursetop_homework_POST', '060106_講師查看自己的班級作業排行_POST'),
364     'crm_060107_own_coursetop_attendance_GET': ['coursetop_attendance', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
365     # ('crm_060107_own_coursetop_attendance_GET', '060107_講師查看自己的班級出勤排行_GET'),
366     'crm_060108_own_coursetop_attendance_POST': ['coursetop_attendance', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
367     # ('crm_060108_own_coursetop_attendance_POST', '060108_講師查看自己的班級出勤排行_POST'),
368 
369 
370 }
371 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
# permission_list.py

 

 

 

 

  1 # CJ.py
  2 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
  3 import re #正則
  4 from crm import models #數據庫
  5 
  6 # ————————01大類權限————————
  7 #010201_只能查看校區表_GET
  8 def JM_Branch(request,*args,**kwargs):
  9     url_path = request.path  # 獲取URL
 10     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
 11     url_model_name=url_list[2]
 12     model_name = 'branch'
 13     if url_model_name == model_name: #防止其他表通過權限
 14         return True
 15     else:
 16         return False
 17 
 18 # 010301_只能查看班級表_GET
 19 def JM_ClassList(request, *args, **kwargs):
 20     url_path = request.path  # 獲取URL
 21     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
 22     url_model_name = url_list[2]
 23     model_name = 'classlist'
 24     if url_model_name == model_name:  # 防止其他表通過權限
 25         return True
 26     else:
 27         return False
 28 
 29 # 010401_只能查看課程表_GET
 30 def JM_Course(request, *args, **kwargs):
 31     url_path = request.path  # 獲取URL
 32     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
 33     url_model_name = url_list[2]
 34     model_name = 'course'
 35     if url_model_name == model_name:  # 防止其他表通過權限
 36         return True
 37     else:
 38         return False
 39 
 40 # 010501_只能查看客戶表_GET
 41 def JM_Customer(request, *args, **kwargs):
 42     url_path = request.path  # 獲取URL
 43     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
 44     url_model_name = url_list[2]
 45     model_name = 'customer'
 46     if url_model_name == model_name:  # 防止其他表通過權限
 47         return True
 48     else:
 49         return False
 50 
 51 
 52 #010601_只能查看跟進表_GET
 53 def JM_CustomerFollowUp(request,*args,**kwargs):
 54     url_path = request.path  # 獲取URL
 55     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
 56     url_model_name=url_list[2]
 57     model_name = 'customerfollowup'
 58     if url_model_name == model_name: #防止其他表通過權限
 59         return True
 60     else:
 61         return False
 62 
 63 # 010701_只能查看報名表_GET
 64 def JM_Enrollment(request, *args, **kwargs):
 65     url_path = request.path  # 獲取URL
 66     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
 67     url_model_name = url_list[2]
 68     model_name = 'enrollment'
 69     if url_model_name == model_name:  #防止其他表通過權限
 70         return True
 71     else:
 72         return False
 73 
 74 # 010801_只能查看繳費表_GET
 75 def JM_Payment(request, *args, **kwargs):
 76     url_path = request.path  # 獲取URL
 77     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
 78     url_model_name = url_list[2]
 79     model_name = 'payment'
 80     if url_model_name == model_name:  #防止其他表通過權限
 81         return True
 82     else:
 83         return False
 84 
 85 
 86 #010901_只能查看上課表_GET
 87 def JM_CourseRecord(request,*args,**kwargs):
 88     url_path = request.path  # 獲取URL
 89     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
 90     url_model_name=url_list[2]
 91     model_name = 'courserecord'
 92     if url_model_name == model_name: #防止其他表通過權限
 93         return True
 94     else:
 95         return False
 96 
 97 
 98 # 011001_只能查看學習表_GET
 99 def JM_StudyRecord(request, *args, **kwargs):
100     url_path = request.path  # 獲取URL
101     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
102     url_model_name = url_list[2]
103     model_name = 'studyrecord'
104     if url_model_name == model_name:  #防止其他表通過權限
105         return True
106     else:
107         return False
108 
109 
110 # 011101_只能查看賬號表_GET
111 def JM_UserProfile(request, *args, **kwargs):
112     url_path = request.path  # 獲取URL
113     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
114     url_model_name = url_list[2]
115     model_name = 'userprofile'
116     if url_model_name == model_name:  #防止其他表通過權限
117         return True
118     else:
119         return False
120 
121 
122 #011201_只能查看角色表_GET
123 def JM_Role(request,*args,**kwargs):
124     url_path = request.path  # 獲取URL
125     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
126     url_model_name=url_list[2]
127     model_name = 'role'
128     if url_model_name == model_name: #防止其他表通過權限
129         return True
130     else:
131         return False
132 
133 
134 
135 #010301_只能查看班級表_GET
136 def JM_Tag(request,*args,**kwargs):
137     url_path = request.path  # 獲取URL
138     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
139     url_model_name=url_list[2]
140     model_name = 'tag'
141     if url_model_name == model_name: #防止其他表通過權限
142         return True
143     else:
144         return False
145 
146 
147 #011401_只能查看一層菜單_GET
148 def JM_FirstLayerMenu(request,*args,**kwargs):
149     url_path = request.path  # 獲取URL
150     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
151     url_model_name=url_list[2]
152     model_name = 'firstlayermenu'
153     if url_model_name == model_name: #防止其他表通過權限
154         return True
155     else:
156         return False
157 
158 
159 # 011501_只能查看二層菜單_GET
160 def JM_SubMenu(request, *args, **kwargs):
161     url_path = request.path  # 獲取URL
162     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
163     url_model_name = url_list[2]
164     model_name = 'submenu'
165     if url_model_name == model_name:  #防止其他表通過權限
166         return True
167     else:
168         return False
169 
170 
171 #011601_只能查看權限組_GET
172 def JM_Groups(request,*args,**kwargs):
173     url_path = request.path  # 獲取URL
174     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
175     url_model_name=url_list[2]
176     model_name = 'groups'
177     if url_model_name == model_name: #防止其他表通過權限
178         return True
179     else:
180         return False
181 
182 #011701_自己密碼重置_GET
183 def own_password_reset(request,*args,**kwargs):
184     url_path = request.path  # 獲取URL 路徑
185     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
186     url_model_name = url_list[4]    #字符串
187     url_parameter =int(url_list[3])  #字符串轉數字
188     model_name = 'password_reset'  #字符串
189     if url_model_name == model_name:  #防止其他表通過權限
190         if url_parameter == request.user.id:  # 參數 等於 #當前登陸的ID
191             return True
192         else:
193             return False
194     else:
195         return False
196  # ————————01大類權限————————
197 
198  # ————————02大類權限————————
199 #020103_銷售給自己的客戶報名課程_GET
200 #銷售 #客戶招生#報名流程一 下一步
201 def own_enrollment(request,*args,**kwargs):
202     url_path = request.path #獲取URL 路徑
203     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
204     url_model_name= url_list[3]
205     url_parameter =int(url_list[2])
206     model_name = 'enrollment'
207     if url_model_name==model_name: #防止其他表通過權限
208         if request.user.id: #如果有ID
209             list= request.user.customer_set.all()#獲取ID 的客戶表
210             list_id=[]
211             for obtain in list:#循環客戶表ID
212                 results=obtain.id
213                 list_id.append(results)#生成列表
214         if url_parameter in list_id: #對比URL參數 在不在 客戶表ID里
215             return True
216         else:
217             return False
218     else:
219         return False
220 
221 
222 #020107_銷售給自己的客戶審核合同_GET
223 #銷售 # 報名流程三  審核
224 def own_contract_review(request,*args,**kwargs):
225     url_path = request.path #獲取URL 路徑
226     url_list=re.findall('(\w+)',url_path) #正者表達式 獲取參數
227     url_model_name= url_list[1]  #字符串
228     url_parameter =int(url_list[2]) #字符串轉數字
229     model_name='contract_review' #字符串
230     if url_model_name==model_name: #防止其他表通過權限
231         if request.user.id: #如果有ID
232             list= request.user.enrollment_set.all()#獲取ID 的客戶表
233             list_id=[]  #數字列表
234             for obtain in list:#循環客戶表ID
235                 results=obtain.id
236                 list_id.append(results)#生成列表
237         if url_parameter in list_id: #對比URL參數 在不在 列表里
238             return True
239         else:
240             return False
241     else:
242         return False
243 
244 # ————————02大類權限————————
245 
246 # ————————04大類權限————————
247 # 040103_學生自己的上課記錄_GET
248 def own_studyrecords(request, *args, **kwargs):
249     url_path = request.path  # 獲取URL 路徑 /bpm/studyrecords/6/
250     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
251     url_model_name = url_list[1]
252     url_parameter = int( url_list[2] )
253     model_name = 'studyrecords'
254     if url_model_name == model_name:  # 防止其他表通過權限
255         if request.user.id:  # 如果有ID
256             list = request.user.stu_account.enrollment_set.all()  # 根據ID關聯學生的報名ID
257             list_id = []
258             for obtain in list:
259                 results = obtain.id
260                 list_id.append( results )  # 生成列表
261         if url_parameter in list_id:  # 對比URL參數 在不在 ID列表里
262             return True
263         else:
264             return False
265     else:
266         return False
267 
268 
269 # 040105_學生自己的作業詳情_GET
270 def own_homework_detail(request, *args, **kwargs):
271     url_path = request.path  # 獲取URL 路徑 /bpm/homework_detail/2/25/
272     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
273     url_model_name = url_list[1]  #字符串
274     url_parameter =(int(url_list[2]),)  #元組
275     url_parameter2 = int(url_list[3]),  #元組
276     model_name = 'homework_detail'#字符串
277     if url_model_name == model_name: #防止其他表通過權限
278         if request.user.id:  # 如果有ID
279             list_id = request.user.stu_account.enrollment_set.values_list('id')  # 根據登陸ID關聯學生的報名ID
280         if url_parameter in list_id:  # 對比URL參數 在不在 ID列表里
281             StudyRecord_id = models.StudyRecord.objects.filter(student_id=url_parameter).values_list('id')
282             if url_parameter2 in StudyRecord_id: # 對比URL參數2 在不在 ID列表里
283                 return True
284             else:
285                 return False
286         else:
287             return False
288     else:
289         return False
290 
291 # ————————04大類權限————————
292 
293 # ————————05大類權限————————
294 # 050103_講師查看自己的課節詳情_GET
295 def own_teacher_class_detail(request, *args, **kwargs):
296     url_path = request.path  # 獲取URL 路徑 /bpm/teacher_class_detail/1/
297     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
298     url_model_name = url_list[1]
299     url_parameter = (int(url_list[2]),)  # <class 'tuple'> (1,)
300     model_name = 'teacher_class_detail'
301     if url_model_name == model_name: #防止其他表通過權限
302         if request.user.id:  # 如果有ID
303             list_id = request.user.classlist_set.values_list('id')  # 根據ID獲取班級ID
304         if url_parameter in list_id:  # 對比URL參數 在不在 ID列表里
305             return True
306         else:
307             return False
308     else:
309         return False
310 
311 # 050105_講師查看自己的課節學員_GET
312 def own_teacher_lesson_detail(request, *args, **kwargs):
313     url_path = request.path  # 獲取URL 路徑 /bpm/teacher_lesson_detail/2/2/
314     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
315     url_model_name = url_list[1]        #字符串
316     url_parameter = int(url_list[2]),    #元組
317     url_parameter2 = (int(url_list[3]),) #元組
318     model_name = 'teacher_lesson_detail'#字符串
319     if url_model_name == model_name: #防止其他表通過權限
320         if request.user.id:  # 如果有ID
321             list_id= request.user.classlist_set.values_list( 'id' ) # 元組列表 #根據登陸ID 反查班級ID列表
322         if url_parameter in list_id :  # 對比URL參數 在不在 ID列表里
323             CourseRecord_id = models.CourseRecord.objects.filter( from_class_id=url_parameter ).values_list( 'id' )# 元組列表
324             if url_parameter2 in CourseRecord_id: # 對比URL參數2 在不在 ID列表里
325                 return True
326             else:
327                 return False
328         else:
329             return False
330     else:
331         return False
332 
333 # 050107_講師自己的學員作業下載_GET
334 def own_howk_down(request, *args, **kwargs):
335     url_path = request.path  # 獲取URL 路徑 /bpm/homeworks/3/3/17/
336     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
337     url_model_name = url_list[1] #字符串
338     url_parameter = (int(url_list[2]),)  #元組# <class 'tuple'> (1,)
339     url_parameter2 = (int(url_list[3]),) #元組
340     model_name = 'homeworks' #字符串
341     if url_model_name == model_name: #防止其他表通過權限
342         if request.user.id:  # 如果有ID
343             list_id = request.user.classlist_set.values_list( 'id' ) # 元組列表 #根據登陸ID 反查班級ID列表
344         if url_parameter in list_id :  # 對比URL參數 在不在 ID列表里
345             CourseRecord_id = models.CourseRecord.objects.filter( from_class_id=url_parameter ).values_list( 'id' )
346             if url_parameter2 in CourseRecord_id: # 對比URL參數2 在不在 ID列表里
347                 return True
348             else:
349                 return False
350         else:
351             return False
352     else:
353         return False
354 
355 # ————————05大類權限————————
356 
357 # ————————06大類權限————————
358 
359 # 060101_講師查看自己的班級排名詳情_GET
360 def JM_crm_classlist_teachers(request, *args, **kwargs):
361     url_path = request.path  # 獲取URL 路徑 /bpm/coursetop_details/3/
362     url_list = re.findall( '(\w+)', url_path )  # 正者表達式 獲取參數
363     url_model_name = (url_list[1],)#字符串元組
364     url_parameter = (int(url_list[2]),)  # 元組 #<class 'tuple'> (1,)
365     model_name =[('coursetop_details',),('coursetop_score',),('coursetop_homework',),('coursetop_attendance',),]
366     if url_model_name in model_name: #防止其他表通過權限
367         if request.user.id:  # 如果有ID
368             list_id = request.user.classlist_set.values_list('id')  # 根據ID獲取班級ID
369             print('list_id::',list_id)
370         if url_parameter in list_id:  # 對比URL參數 在不在 ID列表里
371             return True
372         else:
373             return False
374     else:
375         return False
376 
377 # ————————06大類權限————————
378 
379 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
# CJ.py

 

 

 

 

 

 

 

 

 

  1 # permission.py
  2 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
  3 from django.urls import resolve # resolve解析URL
  4 from django.shortcuts import render,redirect,HttpResponse #頁面返回
  5 from permissions.permission_list import perm_dic #權限字典
  6 
  7 def perm_check(*args,**kwargs):
  8     print( '執行perm_check:', *args, **kwargs )
  9     request = args[0]#
 10     # print(request) #<WSGIRequest: GET '/king_admin/crm/firstlayermenu/4/change/'>
 11 
 12     resolve_url_obj = resolve(request.path)#反解URL路徑#獲取當前的URL# resolve解析URL#生成實例
 13     print('反解URL路徑:',resolve_url_obj)#ResolverMatch(func=permissions.permission.inner, args=('crm', 'firstlayermenu', '4'), kwargs={}, url_name=table_change, app_names=[], namespaces=[])
 14     current_url_name = resolve_url_obj.url_name  # 當前url的url_name
 15     print('當前用戶:',request.user,'當前url的url_name:',current_url_name)#admin2 當前url的url_name: table_change
 16 
 17     permission_list= request.user.user_permissions.values_list('codename') # 根據 登陸的ID 獲取 擁有的權限列表
 18     print('擁有的權限列表',permission_list)
 19 
 20     permission_group = request.user.groups.all().values_list('permissions__codename')    # 根據 登陸的ID 獲取 擁有的組
 21     print('擁有的權限組',permission_group)
 22 
 23     match_key = None
 24     match_results = [False,] #后面會覆蓋,加個False是為了讓all(match_results)不出錯
 25 
 26     for permission_key,permission_val in  perm_dic.items():#從權限字典中取相關字段 #crm_table_index':['1','table_index','GET',[],{},],
 27         # print('循環權限表',((permission_key),))
 28         if ((permission_key),) in permission_list or ((permission_key),) in permission_group:#權限列表是元組
 29             per_url_name = permission_val[0] #URL
 30             per_method  = permission_val[1] #GET #POST #請求方法
 31             perm_args = permission_val[2]  # 列表參數
 32             perm_kwargs = permission_val[3]# 字典參數
 33             custom_perm_func = None if len(permission_val) == 4 else permission_val[4] #url判斷 #自定義權限鈎子
 34             # 'crm_can_access_my_clients':['table_list','GET',[],{'perm_check':33,'arg2':'test'}, custom_perm_logic.only_view_own_customers],
 35             # print('URL:',per_url_name,'請求方法:',per_method,'列表參數:',perm_args,'字典參數:',perm_kwargs,'自定義權限鈎子:',custom_perm_func)
 36 
 37 
 38             if per_url_name == current_url_name: #權限字典的 URL  ==當前請求的url #crm_table_index':['URL','請求方法',[列表參數],{字典參數},],
 39                 if per_method == request.method: #權限字典的 請求方法 == 當前請求的方法  #crm_table_index':['URL','請求方法',[列表參數],{字典參數},],
 40                     #逐個匹配參數,看每個參數時候都能對應的上。
 41                     args_matched = False #參數匹配 #僅供參數
 42                     for item in perm_args: #循環列表參數 #crm_table_index':['URL','請求方法',[列表參數],{字典參數},],
 43                         request_method_func = getattr(request,per_method) #反射 #請求方法 #GET #POST
 44                         if request_method_func.get(item,None):# 如果request字典中有此參數
 45                             args_matched = True
 46                         else:
 47                             print("參數不匹配......")
 48                             args_matched = False
 49                             break  # 有一個參數不能匹配成功,則判定為假,退出該循環。
 50                     else:
 51                         args_matched = True #沒有執行 break 表示 列表匹配成功 #防止列表沒有使用參數時出錯
 52 
 53                     #匹配有特定值的參數
 54                     kwargs_matched = False
 55                     for k,v in perm_kwargs.items(): #循環字典參數#crm_table_index':['URL','請求方法',[列表參數],{字典參數},],
 56                         request_method_func = getattr(request, per_method) #反射 #請求方法 #GET #POST
 57                         arg_val = request_method_func.get(k, None)  # request字典中有此參數
 58                         print("perm kwargs check:",arg_val,type(arg_val),v,type(v))
 59                         if arg_val == str(v): #匹配上了特定的參數 及對應的 參數值, 比如,需要request 對象里必須有一個叫 user_id=3的參數
 60                             kwargs_matched = True
 61                         else:
 62                             kwargs_matched = False
 63                             break # 有一個參數不能匹配成功,則判定為假,退出該循環。
 64                     else:
 65                         kwargs_matched = True
 66 
 67 
 68                     #自定義權限鈎子
 69                     perm_func_matched = False
 70                     if custom_perm_func: #如果有定義
 71                         if custom_perm_func(request,args,kwargs):#def only_view_own_customers(request,*args,**kwargs):
 72                             perm_func_matched = True
 73                         else:
 74                             perm_func_matched = False #使整條權限失效
 75                             print('自定義權限鈎子沒有通過',perm_func_matched)
 76                     else: #沒有定義權限鈎子,所以默認通過
 77                         perm_func_matched = True
 78 
 79                     match_results = [args_matched,kwargs_matched,perm_func_matched] #列表
 80                     print("匹配結果: ", match_results) # [True, True, True]
 81                     if all(match_results): #都匹配上了 #都返回 True
 82                         match_key = permission_key # 給 match_key = None 賦值
 83                         break  #跳出大循環
 84 
 85     if all(match_results): #如果都匹配成功     #'crm_table_index':['table_index','GET',[],{},],
 86         app_name, *per_name = match_key.split('_') #先給app_name賦一個值,其他的值都給*per_name     'crm_table_index':
 87         print("權限名:",match_key,'權限:',match_results)#crm_010902_only_view_CourseRecord_POST [True, True, True]
 88         print('分割:',app_name, *per_name) #  crm 010902 only view CourseRecord POST
 89         perm_obj = '%s.%s' % (app_name,match_key)#'crm.table_index' #    url(r'^(\w+)/$', views.table_index, name='table_index'),  # 單個具體app頁面
 90         print("生成權限:",perm_obj) #crm.crm_010902_only_view_CourseRecord_POST
 91         if request.user.has_perm(perm_obj):
 92             print('當前用戶有此權限')
 93             return True
 94         else:
 95             print('當前用戶沒有該權限')
 96             return False
 97     else:
 98         print("未匹配到權限項,當前用戶無權限")
 99 
100 def check_permission(func):
101     print('權限func',func)#權限func <function table_data_list at 0x030636A8> #循環 URL name
102     def inner(*args,**kwargs):
103         print('開始權限匹配:',type(args))
104         request = args[0]#請求第一個
105         print('判斷登陸情況:')
106         if request.user.id == None:
107             print('未登陸')
108             return redirect( '/gbacc/gbacc_login/' )#返回登陸頁面
109         else:
110             if request.user.is_superuser == True:
111                 print('超級管理員')
112                 return func( *args, **kwargs )  #直接返回 真
113             print( '已登陸,判斷有perm_check(*args,**kwargs)去執行' )
114             if not perm_check(*args,**kwargs): #如果返回不為真 #沒權限
115                 print('#沒權限',perm_check(*args,**kwargs))
116                 request = args[0]
117                 return HttpResponse('你沒有這個權限')
118             print('有權限',func(*args,**kwargs)) #<HttpResponse status_code=200, "text/html; charset=utf-8">
119             return func(*args,**kwargs)
120     print('inner',inner)
121     return  inner #返回 真或假
122 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
# permission.py

 

 

 

  1 # views
  2 
  3 # ————————02PerfectCRM創建ADMIN頁面————————
  4 from django.shortcuts import render
  5 
  6 # ————————04PerfectCRM實現King_admin注冊功能————————
  7 # from django import conf #配置文件
  8 # print("dj conf:",conf) #配置文件
  9 # print("dj conf:",conf.settings)#配置文件.設置
 10 # ————————04PerfectCRM實現King_admin注冊功能————————
 11 
 12 # ————————04PerfectCRM實現King_admin注冊功能————————
 13 from king_admin import app_config  # 自動調用  動態加載類和函數
 14 # ————————04PerfectCRM實現King_admin注冊功能————————
 15 
 16 # ————————04PerfectCRM實現King_admin注冊功能————————
 17 # from king_admin.base_admin import registered_sites # registered_sites={}
 18 from king_admin import base_admin
 19 # ————————04PerfectCRM實現King_admin注冊功能————————
 20 
 21 # ————————11PerfectCRM實現King_admin基本分頁————————
 22 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger  # 分頁功能
 23 # ————————11PerfectCRM實現King_admin基本分頁————————
 24 
 25 # ————————46PerfectCRM實現登陸后頁面才能訪問————————
 26 from  django.contrib.auth.decorators import login_required
 27 # ————————46PerfectCRM實現登陸后頁面才能訪問————————
 28 
 29 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 30 from permissions.permission import check_permission #權限控制
 31 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 32 
 33 def app_index(request):
 34     # ————————04PerfectCRM實現King_admin注冊功能————————
 35     # for app in conf.settings.INSTALLED_APPS:
 36     #     print(app)#循環打印 配置文件.設置.安裝應用程序#.Perfectcustomer\settings里的INSTALLED_APPS列表
 37     # ————————04PerfectCRM實現King_admin注冊功能————————
 38 
 39     # ————————04PerfectCRM實現King_admin注冊功能————————
 40     # return render(request, 'king_admin/app_index.html')
 41     # print("registered_sites",registered_sites)
 42     # return render(request, 'king_admin/app_index.html')
 43     # ————————04PerfectCRM實現King_admin注冊功能————————
 44 
 45     # ————————04PerfectCRM實現King_admin注冊功能————————
 46     # print("registered_sites", base_admin.registered_sites)
 47     # return render(request, 'king_admin/app_index.html')
 48     # ————————04PerfectCRM實現King_admin注冊功能————————
 49 
 50     # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
 51     print("registered_sites", base_admin.site.registered_sites)
 52     return render(request, 'king_admin/app_index.html', {"site": base_admin.site})
 53 
 54 
 55 # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
 56 
 57 # ————————02PerfectCRM創建ADMIN頁面————————
 58 
 59 # ————————13PerfectCRM實現King_admin分頁頁數————————
 60 # 處理def table_data_list(request,app_name,model_name):里的內容,
 61 def filter_querysets(request, queryset):
 62     condtions = {}  # 定義一個字典用來存過濾的條件
 63     for k, v in request.GET.items():  # 不需要空的,判斷是否為空
 64         # ————————18PerfectCRM實現King_admin搜索關鍵字————————
 65         # ————————17PerfectCRM實現King_admin單列排序————————
 66         # if k=="page":continue##kingadmin分頁功能
 67 
 68         # if k=="page":continue##kingadmin分頁功能 #寫法一
 69         # elif k=="_o":continue##kingadmin排序功能  <a href="?_o={{ column }}">{{ column }}</a>
 70 
 71         # if k in ("page","_o") :continue #kingadmin分頁功能   #kingadmin排序功能   #寫法二
 72 
 73         # if k == "page"or k == "_o": #保留的分頁關鍵字 和  排序關鍵字 #寫法三
 74         #     continue #continue是結束單次循環
 75         # ————————17PerfectCRM實現King_admin單列排序————————
 76         if k in ("page", "_o", "_q"): continue  # kingadmin分頁,排序,搜索#判斷標簽是否存在 自定義的名稱
 77         # ————————18PerfectCRM實現King_admin搜索關鍵字————————
 78 
 79 
 80         # ————————15PerfectCRM實現King_admin多條件過濾————————
 81         if v:
 82             condtions[k] = v  # 進行配對字典
 83             # ————————15PerfectCRM實現King_admin多條件過濾————————
 84     query_res = queryset.filter(**condtions)
 85 
 86     return query_res, condtions
 87 
 88 
 89 # ————————13PerfectCRM實現King_admin分頁頁數————————
 90 
 91 # ————————59PerfectCRM實現king_admin行內編輯————————
 92 from  king_admin import form
 93 
 94 
 95 def batch_update(request, editable_data, admin_obj):
 96     """table objects batch update , for list_editable feature"""
 97     errors = []  # 錯誤信息
 98     for row_data in editable_data:
 99         obj_id = row_data.get('id')  # 獲取這行ID號
100         try:
101             if obj_id:
102                 print("如果有ID編輯數據:", row_data, list(row_data.keys()))
103                 obj = admin_obj.model.objects.get(id=obj_id)  # 獲取編輯的ID
104                 model_form = form.create_form(admin_obj.model, list(row_data.keys()),
105                                               admin_obj, request=request, partial_update=True)  # 進行數據驗證處理
106                 form_obj = model_form(instance=obj, data=row_data)  # 編輯的ID #驗證的內容
107                 if form_obj.is_valid():  # 驗證通過
108                     form_obj.save()  # 保存新內容
109                     print('保存。。。。')
110 
111                 else:
112                     print("可編輯列表形式", row_data, form_obj.errors)
113 
114                     errors.append([form_obj.errors, obj])  # 添加錯誤信息
115 
116                     # for column in row_data:
117                     #     if column != "id":#id no need change
118                     #         #print("-----column",column,row_data[column],type(row_data[column]))
119                     #         if row_data[column] in ('True','False'):
120                     #             if obj._meta.get_field(column).get_internal_type() == "BooleanField":
121                     #                 setattr(obj, column, eval(row_data[column]))
122                     #                 #print("setting column [%s] to [%s]" %(column,row_data[column]), eval(row_data[column]))
123                     #             else:
124                     #                 setattr(obj, column, row_data[column])
125                     #         else:
126                     #             setattr(obj,column,row_data[column])
127                     #
128                     # obj.save()
129 
130         # except Exception as e:
131         except KeyboardInterrupt as e:
132             return False, [e, obj]
133     if errors:
134         return False, errors
135     return True, []
136 
137 
138 # ————————59PerfectCRM實現king_admin行內編輯————————
139 
140 # ————————08PerfectCRM實現King_admin顯示注冊表的字段表頭————————
141 @login_required  # 登陸后頁面才能訪問
142 @check_permission #權限控制
143 def table_data_list(request, app_name, model_name):
144     # 通過2個參數到base_admin里獲取class AdminRegisterException(Exception): 的對象
145     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # base_admin
146 
147     # ————————24PerfectCRM實現King_admin自定義操作數據————————
148     if request.method == "POST":  # 批量操作
149         action = request.POST.get("action_select")  # 要調用的自定制功能函數
150         selected_ids = request.POST.get("selected_ids")  # 前端提交的數據
151         print(selected_ids, type(selected_ids), "selected_ids-----")
152         # if type(selected_ids)!='str':
153         # selected_ids = json.loads(selected_ids)#進行轉換數據
154         print(selected_ids, type(action), action, "selected_ids==========")
155         # print("action:",selected_ids,action)
156         # ————————59PerfectCRM實現king_admin行內編輯————————
157         import json
158         editable_data = request.POST.get("editable_data")  # 獲取前端可編輯的數據
159         print('編輯數據:', editable_data)
160         if editable_data:  # for list editable
161             editable_data = json.loads(editable_data)  # 進行轉換數據
162             # print("editable",editable_data)
163             res_state, errors = batch_update(request, editable_data, admin_obj)  # 進行部分更新操作
164         else:
165             # ————————59PerfectCRM實現king_admin行內編輯————————
166             if selected_ids:
167                 # selected_ids = json.loads(selected_ids)#進行轉換數據
168                 selected_objs = admin_obj.model.objects.filter(id__in=selected_ids.split(','))  # 返回之前所選中的條件
169             else:
170                 raise KeyError('錯誤,沒有選擇對象!')
171 
172             if hasattr(admin_obj, action):
173                 action_func = getattr(admin_obj, action)  # 如果admin_obj 對象中有屬性action 則打印self.action的值,否則打印'not find'
174                 request._admin_action = action  # 添加action內容
175                 print(request._admin_action, action, '<--------')
176             return action_func(request, selected_objs)
177     # ————————24PerfectCRM實現King_admin自定義操作數據————————
178 
179 
180     # ————————09PerfectCRM實現King_admin顯示注冊表的內容————————
181     admin_obj.querysets = admin_obj.model.objects.all()  # 取數據 傳到 前端
182     # ————————09PerfectCRM實現King_admin顯示注冊表的內容————————
183 
184     # ————————11PerfectCRM實現King_admin分頁顯示條數————————
185     # from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger  # 分頁功能#放在頂上導入
186     obj_list = admin_obj.model.objects.all()  # 取數據 傳到 前端  #base_admin  #獲取傳過來的所有對象
187 
188     # ————————13PerfectCRM實現King_admin分頁頁數————————
189     queryset, condtions = filter_querysets(request, obj_list)  # base_admin   # 調用條件過濾
190     # ————————13PerfectCRM實現King_admin分頁頁數————————
191 
192     # ————————18PerfectCRM實現King_admin搜索關鍵字————————
193     queryset = get_queryset_search_result(request, queryset, admin_obj)  ##搜索后
194     # ————————18PerfectCRM實現King_admin搜索關鍵字————————
195 
196     # ————————26PerfectCRM實現King_admin自定義排序————————
197     sorted_queryset = get_orderby(request, queryset, admin_obj)  # 排序后的結果
198     # ————————17PerfectCRM實現King_admin單列排序————————
199     # sorted_queryset = get_orderby(request, queryset) #排序后的結果
200     # ————————15PerfectCRM實現King_admin多條件過濾————————
201     # paginator = Paginator(obj_list,admin_obj.list_per_page)  #kingadmin里class CustomerAdmin(BaseAdmin):
202     # paginator = Paginator(queryset, admin_obj.list_per_page)
203     # ————————15PerfectCRM實現King_admin多條件過濾————————
204     paginator = Paginator(sorted_queryset, admin_obj.list_per_page)
205     # ————————17PerfectCRM實現King_admin單列排序————————
206     # ————————26PerfectCRM實現King_admin自定義排序————————
207 
208 
209     page = request.GET.get('page')
210     try:
211         objs = paginator.page(page)  # 當前的頁面的數據
212     except PageNotAnInteger:
213         # 如果頁面不是一個整數,交付第一頁。
214         objs = paginator.page(1)
215     except EmptyPage:
216         # 如果頁面的范圍(例如9999),交付最后一頁的搜索結果。
217         objs = paginator.page(paginator.num_pages)
218     admin_obj.querysets = objs  # base_admin
219 
220     # ————————13PerfectCRM實現King_admin分頁頁數————————
221     admin_obj.filter_condtions = condtions  # base_admin
222     # ————————13PerfectCRM實現King_admin分頁頁數————————
223 
224     # ————————11PerfectCRM實現King_admin分頁顯示條數————————
225 
226     return render(request, "king_admin/table_data_list.html", locals())
227 
228 
229 # ————————08PerfectCRM實現King_admin顯示注冊表的字段表頭————————
230 
231 
232 
233 
234 # ————————17PerfectCRM實現King_admin單列排序————————
235 # def get_orderby(request,queryset):
236 # order_by_key = request.GET.get("_o")   #獲取URL里有沒有("_o") <a href="?_o={{ column }}">{{ column }}</a>
237 # #頁面剛開始沒有這個值
238 # if order_by_key != None:  #有("_o")這個值 就進行排序
239 #     query_res = queryset.order_by(order_by_key)
240 # else: #沒有就不排序,直接返回
241 #     query_res = queryset
242 # return query_res     #排序時會錯
243 
244 # orderby_key = request.GET.get("_o")
245 # if orderby_key:
246 #     return  queryset.order_by(orderby_key)
247 # return  queryset
248 
249 # 在table_data_list添加
250 # def table_data_list(request,app_name,model_name): #詳細列表
251 # sorted_queryset = get_orderby(request, queryset)
252 # 在filter_querysets添加
253 # if k == "page"or k == "_o": #保留的分頁關鍵字 和  排序關鍵字
254 # ————————17PerfectCRM實現King_admin單列排序————————
255 
256 # ————————26PerfectCRM實現King_admin自定義排序————————
257 def get_orderby(request, queryset, admin_obj):
258     orderby_key = request.GET.get("_o")
259     # order_by_key1=order_by_key.strip()
260     if orderby_key:  # 有獲取到字段
261         query_res = queryset.order_by(orderby_key.strip())  # .strip()默認刪除空白符(包括'\n', '\r',  '\t',  ' ')
262     else:
263         if admin_obj.ordering:  # 查看kingadmin‘有沒有    ordering = '-qq'  # 自定義排序
264             query_res = queryset.order_by("%s" % admin_obj.ordering)
265         else:
266             query_res = queryset.order_by('-id')  # 默認倒序
267     return query_res
268 
269 
270 # 在table_data_list添加
271 # def table_data_list(request,app_name,model_name): #詳細列表
272 # sorted_queryset = get_orderby(request, queryset, admin_obj)  # 排序后的結果
273 # ————————26PerfectCRM實現King_admin自定義排序————————
274 
275 
276 # ————————18PerfectCRM實現King_admin搜索關鍵字————————
277 from django.db.models import Q
278 
279 
280 def get_queryset_search_result(request, queryset, admin_obj):
281     search_key = request.GET.get("_q", "")  # 取定義名,默認為空
282     q_obj = Q()  # 多條件搜索 #from django.db.models import Q
283     q_obj.connector = "OR"  # or/或 條件
284     for column in admin_obj.search_fields:  # 搜索目標crm/kingadmin里class CustomerAdmin(BaseAdmin):search_fields = ('name','qq',)
285         q_obj.children.append(("%s__contains" % column, search_key))  # 運態添加多個條件
286     res = queryset.filter(q_obj)  # 對數據庫進行條件搜索
287     return res  # 返回結果
288 
289 
290 # 在table_data_list添加
291 # def table_data_list(request,app_name,model_name): #詳細列表
292 #      queryset = get_queryset_search_result(request,queryset,admin_obj)
293 # ————————18PerfectCRM實現King_admin搜索關鍵字————————
294 
295 
296 # ————————19PerfectCRM實現King_admin數據修改————————
297 from  king_admin import forms
298 
299 
300 # 修改內容
301 # def table_change(request,app_name,model_name):
302 #     obj_form = forms.CustomerModelForm()  #創建一個空表單
303 #     return render(request,"kingadmin/table_change.html",locals())
304 @login_required  # 登陸后頁面才能訪問
305 @check_permission #權限控制
306 def table_change(request, app_name, model_name, obj_id):
307     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 獲取表對象
308     # kingadmin/forms.py里def CreateModelForm(request,admin_obj):
309     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  ##modelform 生成表單 加驗證
310     # obj_form = model_form()  # 表單
311     obj = admin_obj.model.objects.get(id=obj_id)  # 根據ID獲取數據記錄
312 
313     # ————————28PerfectCRM實現King_admin編輯限制————————
314     # ————————20PerfectCRM實現King_admin數據修改美化————————
315     # #面向對象最重要的概念就是類(Class)和實例(Instance),必須牢記類是抽象的模板,比如Student類,而實例是根據類創建出來的一個個具體的“對象”,每個對象都擁有相同的方法,但各自的數據可能不同。
316     # obj_form = model_form(instance=obj)  # 數據傳入表單
317 
318     if request.method == "GET":  # 如果是 GET 表示 是添加記錄
319         obj_form = model_form(instance=obj)  # 數據傳入表單
320     elif request.method == "POST":  # 如果是 POST 表示 是修改后的數據
321         obj_form = model_form(instance=obj, data=request.POST)  # 更新數據
322         if obj_form.is_valid():
323             obj_form.save()
324     # ————————20PerfectCRM實現King_admin數據修改美化————————
325     # ————————28PerfectCRM實現King_admin編輯限制————————
326 
327     return render(request, "king_admin/table_change.html", locals())
328 
329 
330 # ————————19PerfectCRM實現King_admin數據修改————————
331 
332 
333 # ————————21PerfectCRM實現King_admin查看頁面美化————————
334 # 單個具體app頁面
335 @login_required  # 登陸后頁面才能訪問
336 def table_index(request, app_name):
337     bases = base_admin.site.registered_sites[app_name]  # 取出對應app對象
338     return render(request, 'king_admin/table_index.html', {"site": bases, 'app_name': app_name})
339 
340 
341 # ————————21PerfectCRM實現King_admin查看頁面美化————————
342 
343 # ————————22PerfectCRM實現King_admin數據添加————————
344 from django.shortcuts import redirect  # kingadmin添加內容
345 
346 
347 @login_required  # 登陸后頁面才能訪問
348 @check_permission #權限控制
349 def table_add(request, app_name, model_name):
350     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 獲取表對象
351     # ————————32PerfectCRM實現King_admin添加不進行限制————————
352     admin_obj.is_add_form = True  # 表示為新增表單
353     # ————————32PerfectCRM實現King_admin添加不進行限制————————
354     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  ##modelform 生成表單 加驗證
355     if request.method == "GET":
356         obj_form = model_form()  # 跳轉過來的為空
357     elif request.method == "POST":
358         obj_form = model_form(data=request.POST)  # 創建數據
359 
360         # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
361         password = request.POST.get('password')  # 取前端輸入的密碼
362         email = request.POST.get('email')  # 取前端輸入的郵箱
363         # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
364 
365         if obj_form.is_valid():
366             # ————————32PerfectCRM實現King_admin添加不進行限制————————
367             # obj_form.save()
368             try:
369                 obj_form.save()  # 表單驗證通過保存
370             except Exception as e:
371                 return redirect("/king_admin/%s/%s/" % (app_name, model_name))  # 轉到之前的頁面
372                 # ————————32PerfectCRM實現King_admin添加不進行限制————————
373         if not obj_form.errors:  # 沒有錯誤返回原來的頁面
374 
375             # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
376             if email:
377                 obj = admin_obj.model.objects.filter(email=email).first()  # 對象
378                 obj.set_password(password)  # 加密
379             try:
380                 obj.save()  # 表單驗證通過保存
381             except Exception as e:
382                 return redirect("/king_admin/%s/%s/" % (app_name, model_name))
383             # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
384 
385             # from django.shortcuts import redirect
386             return redirect("/king_admin/%s/%s/" % (app_name, model_name))
387     return render(request, "king_admin/table_add.html", locals())
388 
389 
390 # ————————22PerfectCRM實現King_admin數據添加————————
391 
392 
393 # ————————23PerfectCRM實現King_admin數據刪除————————
394 @login_required  # 登陸后頁面才能訪問
395 @check_permission #權限控制
396 def table_delete(request, app_name, model_name, obj_id):
397     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 表類
398     objs=admin_obj.model.objects.filter(id=obj_id)#類的對象
399 
400     # ————————33PerfectCRM實現King_admin編輯整張表限制————————
401     # if request.method=='POST':
402     #     objs.delete()#刪除
403     #     return redirect("/king_admin/%s/%s/" % (app_name,model_name))#轉到列表頁面
404 
405     app_name=app_name
406     if admin_obj.readonly_table:
407         errors={'鎖定的表單':'該表單:<%s>,已經鎖定,不能刪除當前記錄!'%model_name}
408     else:
409         errors={}
410     if request.method=='POST':
411         if  not admin_obj.readonly_table:
412             objs.delete()#刪除
413             return redirect("/king_admin/%s/%s/" % (app_name,model_name))#轉到列表頁面
414     # ————————33PerfectCRM實現King_admin編輯整張表限制————————
415 
416 
417     return render(request, "king_admin/table_delete.html", locals())  # locals 返回一個包含當前范圍的局部變量字典。
418 
419 
420 # ————————23PerfectCRM實現King_admin數據刪除————————
421 
422 # ————————36PerfectCRM實現King_admin密碼修改————————
423 # 密碼修改
424 @login_required  # 登陸后頁面才能訪問
425 @check_permission #權限控制
426 def password_reset(request, app_name, model_name, obj_id):
427     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 表類
428     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  # modelform 生成表單 加驗證
429     obj = admin_obj.model.objects.get(id=obj_id)  # 類表的對象
430     errors = {}  # 錯誤提示
431     if request.method == 'POST':
432         _password1 = request.POST.get('password1')  # 獲取頁面輸入的值
433         _password2 = request.POST.get('password2')  # 獲取頁面輸入的值
434         if _password1 == _password2:
435             if len(_password1) > 5:
436                 obj.set_password(_password1)  # 繼承Django方法 #加密
437                 obj.save()  # 保存
438                 return redirect(request.path.rstrip('password/') + ('/change/'))  # 替換URL名
439             else:
440                 errors['password_too_short'] = '必須不少於6字符'
441         else:
442             errors['invalid_password'] = '兩次輸入的密碼不一樣'  # 密碼不一致
443 
444     return render(request, "king_admin/password_reset.html", locals())  # locals 返回一個包含當前范圍的局部變量字典。
445 
446 
447 # ————————36PerfectCRM實現King_admin密碼修改————————
448 
449 # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
450 def password_add(request, app_name, model_name):
451     return redirect("/king_admin/%s/%s/add/" % (app_name, model_name))  # 轉到添加頁面
452     # ————————37PerfectCRM實現King_admin添加用戶時密碼加密————————
# views

 

 

 

  1 # sales_views.py
  2 # ————————47PerfectCRM實現CRM客戶報名流程————————
  3 from django.db import IntegrityError  # 主動捕捉錯誤信息
  4 from django.shortcuts import render  # 頁面返回
  5 from crm import models  # 數據庫
  6 from bpm.bpm_auxiliary import bpm_forms  # 自定制 forms
  7 from  django.contrib.auth.decorators import login_required  # 登陸后頁面才能訪問
  8 
  9 # ————————47PerfectCRM實現CRM客戶報名流程————————
 10 from django.core.mail import send_mail
 11 # send_mail的參數分別是  郵件標題,郵件內容,發件箱(settings.py中設置過的那個),收件箱列表(可以發送給多個人),失敗靜默(若發送失敗,報錯提示我們)
 12 import random
 13 import datetime  # 獲取時間#登陸過期
 14 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 15 from permissions.permission import check_permission #權限控制
 16 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 17 # 發送郵件的功能 #驗證碼#密碼
 18 class stmp():
 19     def __init__(self):
 20         self.emaillist = []  # 發送給誰
 21         self.code = None  # 驗證碼#密碼
 22 
 23     def stmps(self, request, email, msg_mail):  # 傳參數#頁面,session #郵箱,發送給誰 #內容
 24         self.emaillist.append(email)  # 將郵箱地址添加到調用Django發送郵件功能
 25         # ——————生成驗證碼——————
 26         _letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小寫字母,去除可能干擾的i,l,o,z
 27         _upper_cases = _letter_cases.upper()  # 大寫字母
 28         _numbers = ''.join(map(str, range(3, 10)))  # 數字
 29         chars = ''.join((_letter_cases, _upper_cases, _numbers))  # 變成一條字符串
 30         list = random.sample(chars, 4)  # 從一條字符串隨機選4個字符變成列表
 31         self.code = ''.join(list)  # 列表變字符串
 32         # ——————生成驗證碼——————
 33         # ——————調用Django發送郵件——————
 34         title = 'PerfectCRM項目自動郵件:%s' % self.code  # 郵件標題#防止一樣的內容被郵箱屏蔽
 35         send_mail(title,  # 郵件標題
 36                   msg_mail,  # 驗證碼內容
 37                   'perfectcrm@sina.cn',  # 發送的郵箱  #根據情況重新配置
 38                   self.emaillist,  # 接受的郵箱
 39                   fail_silently=False,  # 靜默,拋出異常
 40                   )
 41         print('發送郵件成功!沒收到要換標題!檢查發送郵箱的配置!')
 42         # ——————調用Django發送郵件——————
 43 # ————————47PerfectCRM實現CRM客戶報名流程————————
 44 # ————————47PerfectCRM實現CRM客戶報名流程————————
 45 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 46 import random  # 隨機
 47 import string  # 字母 數字
 48 from django.core.cache import cache  # 緩存
 49 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 50 
 51 # 報名填寫 銷售
 52 @login_required  # 登陸后頁面才能訪問
 53 @check_permission #權限控制
 54 def enrollment(request, customer_id):
 55     msgs = {}  # 錯誤信息
 56     customer_obj = models.Customer.objects.get(id=customer_id)  # 取到客戶信息記錄 #返回到頁面#報名人
 57     consultant_obj = models.UserProfile.objects.get(id=request.user.id)  # 報名課程顧問
 58 
 59     stmp_mail = {}  # 郵件發送成功
 60     stmpemail = stmp()  # 實例化發送郵件的功能
 61     email = request.POST.get('email')  # 讓頁面POST提交的值,在頁面GET后仍然存在顯示
 62     if request.method == "POST":
 63         enroll_form = bpm_forms.EnrollmentForm(request.POST)  # 獲取數據
 64         if enroll_form.is_valid():  # 表單驗證
 65 
 66             # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 67             # msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/"
 68             msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/{random_str}/ "
 69             random_str = ''.join(random.sample(string.ascii_lowercase + string.digits, 8))  # 生成8位隨機字符串 #URL使用
 70             url_str = '''customer/registration/{enroll_obj_id}/{random_str}/'''  # 報名鏈接
 71             # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 72 
 73             try:
 74                 enroll_form.cleaned_data['customer'] = customer_obj  # 添加學員對象 記錄 #報名人
 75                 enroll_form.cleaned_data['consultant'] = consultant_obj  # 報名課程顧問
 76                 enroll_obj = models.Enrollment.objects.create(**enroll_form.cleaned_data)  # 創建記錄
 77 
 78                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 79                 # msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#報名記錄對應的id,隨機字符串,報名鏈接
 80                 sort_url = enroll_obj.id  # 獲取報名表對應的ID
 81                 cache.set(enroll_obj.id, random_str, 61000)  # 加入過期時間   #URL使用    # cache緩存
 82                 msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str)  # 報名記錄對應的id,隨機字符串,報名鏈接
 83                 url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str)  # 報名鏈接
 84                 print(url_str)
 85                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
 86             except IntegrityError as e:
 87                 # 取到這條記錄
 88                 enroll_obj = models.Enrollment.objects.get(customer_id=customer_obj.id,
 89                                                            enrolled_class_id=enroll_form.cleaned_data[
 90                                                                'enrolled_class'].id)
 91 
 92                 # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
 93                 if enroll_obj.contract_agreed:#學員已經同意合同,提交了身份證
 94                     #return redirect('/crm/contract_review/%s/'%enroll_obj.id)#跳轉到審核頁面
 95                     return render(request,'bpm_sales/contract_prompt.html',locals())#跳轉提示頁面
 96                 # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
 97 
 98                 enroll_form.add_error('__all__', '記錄已經存在,不能重復創建!')
 99 
100                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
101                 # msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#報名記錄對應的id
102                 cache.set(enroll_obj.id, random_str, 61000)  # 加入過期時間  #URL使用    # cache緩存
103                 msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str)  # 報名記錄對應的id
104                 url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str)  # 報名鏈接
105                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
106 
107             if email:
108                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
109                 # msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s" %enroll_obj.id
110                 msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s/%s" %(enroll_obj.id,random_str)
111                 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
112                 stmpemail.stmps(request, email, msg_mail)  # 發送郵件
113                 stmp_mail['ok'] = "郵件已發送成功!"
114 
115     else:
116         enroll_form = bpm_forms.EnrollmentForm()  # modelform表單
117     return render(request, 'bpm_sales/enrollment.html', locals())
118 # ————————47PerfectCRM實現CRM客戶報名流程————————
119 
120 
121 # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
122 #學員合同簽定
123 
124 # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
125 import os
126 from PerfectCRM import settings
127 import json
128 # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
129 
130 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
131 from django.shortcuts import HttpResponse #頁面返回
132 # def stu_registration(request,enroll_id):
133 def stu_registration(request,enroll_id,random_str):
134     # enroll_obj=models.Enrollment.objects.get(id=enroll_id)#獲取報名記錄
135     if cache.get(enroll_id) == random_str:  # 判斷鏈接失效了沒有
136         enroll_obj = models.Enrollment.objects.get(id=enroll_id)  # 報名記錄
137 # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
138 
139         # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
140         enrolled_path='%s/%s/'%(settings.ENROLLED_DATA,enroll_id)#證件上傳路徑
141         img_file_len=0  #文件
142         if os.path.exists(enrolled_path):#判斷目錄是否存在
143             img_file_list=os.listdir(enrolled_path)#取目錄 下的文件
144             img_file_len=len(img_file_list)
145         # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
146 
147     # ————————49PerfectCRM實現CRM客戶報名流程學生合同表單驗證————————
148         # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
149         if request.method == "POST":
150 
151             # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
152             ret=False
153             data=request.POST.get('data')
154             if data:#如果有刪除動作
155                 del_img_path="%s/%s/%s"%(settings.ENROLLED_DATA,enroll_id,data)#路徑
156                 print(del_img_path,'=-=-=-=-=-=')
157                 os.remove(del_img_path)
158                 ret=True
159                 return HttpResponse(json.dumps(ret))
160             if request.is_ajax():#ajax上傳圖片 #異步提交
161                 print('ajax上傳圖片 #異步提交中。。。 ',request.FILES)
162                 enroll_data_dir="%s/%s"%(settings.ENROLLED_DATA,enroll_id)#路徑  #重要信息不能放在靜態文件中
163                 if not os.path.exists(enroll_data_dir):#如果不存目錄
164                     os.makedirs(enroll_data_dir,exist_ok=True)#創建目錄
165                 for k,file_obj in request.FILES.items():   #循環字典 #上傳的文件
166                     with open("%s/%s"%(enroll_data_dir,file_obj.name),'wb') as f: #打開一個文件#路徑#獲取文件名
167                         for chunk in file_obj.chunks():#循環寫入文件 # chunks塊
168                             f.write(chunk)  #保存文件
169                 return HttpResponse('上傳完成!')
170             # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
171 
172             customer_form = bpm_forms.CustomerForm(request.POST, instance=enroll_obj.customer)  # 生成表單驗證
173             if customer_form.is_valid():  # 表單驗證通過
174                 customer_form.save()  # 保存
175                 enroll_obj.contract_agreed = True  # 同意協議
176                 enroll_obj.save()  # 保存
177                 status = 1  # 修改報名狀態 # 1 已經報名
178                 return render(request, 'bpm_sales/stu_registration.html', locals())
179 
180         else:
181             if enroll_obj.contract_agreed == True:  # 如果協議已經簽訂
182                 status = 1  # 修改報名狀態 # 1 已經報名
183             else:
184                 status = 0
185             customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer)  # 生成表單
186     # customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer)  # 生成表單
187     # ————————49PerfectCRM實現CRM客戶報名流程學生合同表單驗證————————
188 
189         return render(request,'bpm_sales/stu_registration.html',locals())
190         # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
191 # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
192     # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
193     else:
194         return HttpResponse('鏈接失效,非法鏈接,請自重!')
195     # ————————50PerfectCRM實現CRM客戶報名流程學生合同URL隨機碼————————
196 
197 
198 # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
199 from django.shortcuts import redirect
200 #查詢流程提示頁面
201 def contract_prompt(request,enroll_id):
202     enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取對象
203     enroll_form= bpm_forms.EnrollmentForm(instance=enroll_obj)#報名表對象
204     customers_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#學員的信息
205     return render(request,'bpm_sales/contract_prompt.html',locals())
206 
207 # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
208 from bpm.bpm_auxiliary.pagination import Page #分頁
209 # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
210 # #待審核
211 @login_required # 登陸后頁面才能訪問
212 @check_permission #權限控制
213 def not_audit(request):
214     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
215     # sign=models.Enrollment.objects.all()#所有的報名表
216     # print(sign,'sign----->')
217     sign=models.Enrollment.objects.filter(contract_agreed=True,contract_approved=False).all()#所有的報名表
218 
219     page = Page(request.GET.get('p', 1), len(sign)) #當前頁數 默認為1 #總數量
220     sign = sign[page.start:page.end]  # 切片取當前頁的數據
221     page_str = page.page_str('/bpm/not_audit/')  #總頁數 傳入url
222     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
223     return render(request, 'bpm_sales/not_audit.html', locals())#
224 
225 #審核合同
226 @login_required # 登陸后頁面才能訪問
227 @check_permission #權限控制
228 def contract_review(request,enroll_id):
229     enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取對象
230     contract_review = request.user.name #當前登陸人 #合同審核人
231     #payment_form=forms.PaymentForm()#生成表單
232     enroll_form= bpm_forms.EnrollmentForm(instance=enroll_obj)#報名表對象
233     customer_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#學員的信息
234     enrolled_path='%s/%s/'%(settings.ENROLLED_DATA,enroll_id)#證件上傳路徑
235     if os.path.exists(enrolled_path):#判斷目錄是否存在
236         file_list=os.listdir(enrolled_path)#取目錄 下的文件
237         imgs_one=file_list[0]  #圖片1
238         imgs_two=file_list[1]  #圖片2
239     if request.method=="POST":
240         enroll_obj.contract_approved = True  # 審核通過
241         enroll_obj.save() #保存
242         enroll = models.Enrollment.objects.filter(id=enroll_id).update(contract_review=contract_review)#合同審核人
243         print('審核通過。。。')
244         return redirect('/bpm/not_audit/')#跳轉到待審核
245     return render(request, 'bpm_sales/contract_review.html', locals())#
246 #駁回合同
247 def enrollment_rejection(request,enroll_id):
248     enroll_obj=models.Enrollment.objects.get(id=enroll_id)#報名表的對象
249     enroll_obj.contract_agreed=False#修改學員已經同意核同
250     enroll_obj.save() #保存
251     return redirect('/bpm/customer/%s/enrollment/'%enroll_obj.customer.id)#跳轉到enrollment_rejection
252 # ————————52PerfectCRM實現CRM客戶報名流程學生合同審核————————
# sales_views.py

 

 

 

 

 1 # financial_views.py
 2 # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
 3 from crm import models #數據庫
 4 from django.shortcuts import redirect,render   #頁面返回
 5 from bpm.bpm_auxiliary import bpm_forms   #自定制 forms
 6 from  django.contrib.auth.decorators import login_required # 登陸后頁面才能訪問
 7 
 8 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 9 from permissions.permission import check_permission #權限控制
10 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
11 
12 # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
13 from bpm.bpm_auxiliary.pagination import Page #分頁
14 # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
15 
16 # #待繳費
17 @login_required  # 登陸后頁面才能訪問
18 @check_permission #權限控制
19 def not_payment(request):
20 
21     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
22     # sign=models.Enrollment.objects.all()#所有的報名表
23     sign=models.Enrollment.objects.filter(contract_approved=True,Pay_cost=False).all()#所有的報名表
24 
25     page = Page(request.GET.get('p', 1), len(sign)) #當前頁數 默認為1 #總數量
26     sign = sign[page.start:page.end]  # 切片取當前頁的數據
27     page_str = page.page_str('/bpm/not_payment/')  #總頁數 傳入url
28     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
29 
30     return render(request, 'bpm_financial/not_payment.html', locals())#
31 # 已繳費
32 @login_required  # 登陸后頁面才能訪問
33 @check_permission #權限控制
34 def already_payment(request):
35 
36     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
37     # sign=models.Enrollment.objects.all()#所有的報名表
38     sign=models.Enrollment.objects.filter(contract_approved=True,Pay_cost=True).all()#所有的報名表
39 
40     page = Page(request.GET.get('p', 1), len(sign)) #當前頁數 默認為1 #總數量
41     sign = sign[page.start:page.end]  # 切片取當前頁的數據
42     page_str = page.page_str('/bpm/already_payment/')  #總頁數 傳入url
43     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
44 
45     return render(request, 'bpm_financial/already_payment.html', locals())#
46 #繳費視圖
47 @login_required # 登陸后頁面才能訪問
48 @check_permission #權限控制
49 def payment(request,enroll_id):
50     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
51     # sign=models.Payment.objects.all()#所有的報名表#前端對比用戶#繳費記錄
52     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
53     enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取對象
54     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
55     sign=models.Payment.objects.filter(customer=enroll_obj.customer).all()#所有的報名表#前端對比用戶#繳費記錄
56     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
57     errors={}  #錯誤信息
58     if request.method=="POST":
59         payment_amount=request.POST.get('amount')#繳費金額
60         consultant = models.UserProfile.objects.get(id=request.user.id)  #財務人員 #當前登陸人
61         if payment_amount:
62             payment_amount=int(payment_amount)  #轉數字類型
63             if payment_amount<500:
64                 errors['err']='繳費金額不得低於500元!'
65             else: #生成forms
66                 payment_obj=models.Payment.objects.create(
67                     customer=enroll_obj.customer,##客戶表 學員
68                     course=enroll_obj.enrolled_class.course,#所報課程
69                     consultant=consultant,# 財務人員
70                     amount=payment_amount,#繳費金額
71                 )
72                 enroll_obj.Pay_cost=True#已繳費
73                 enroll_obj.save()   #保存
74                 enroll_obj.customer.status=0#修改報名狀態 為已報名#根據數據庫
75                 enroll_obj.customer.save()  #保存
76                 return redirect('/bpm/not_payment')#客戶表
77         else:
78             errors['err']='金額不能為空!'
79     else:
80         payment_form= bpm_forms.PaymentForm()#生成表單
81 
82     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
83     page = Page( request.GET.get( 'p', 1 ), len( sign ) )  # 當前頁數 默認為1 #總數量
84     sign = sign[page.start:page.end]  # 切片取當前頁的數據
85     page_str = page.page_str( '/bpm/payment/%s/'%enroll_id )  # 總頁數 傳入url
86     # ————————68PerfectCRM實現CRM業務流程(bpm)報名繳費分頁————————
87 
88     return render(request, 'bpm_financial/payment.html', locals())
89 # ————————53PerfectCRM實現CRM客戶報名流程繳費————————
# financial_views.py

 

 

 

  1 # student_views.py
  2 # ————————60PerfectCRM實現CRM學生上課記錄————————
  3 from django.shortcuts import render #頁面返回
  4 from crm import models #數據庫
  5 from  django.contrib.auth.decorators import login_required # 登陸后頁面才能訪問
  6 
  7 # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
  8 from bpm.bpm_auxiliary.pagination import Page #分頁
  9 # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 10 
 11 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 12 from permissions.permission import check_permission #權限控制
 13 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 14 
 15 #學生報名的課程
 16 @login_required # 登陸后頁面才能訪問
 17 @check_permission #權限控制
 18 def student_course(request):
 19     if request.user.stu_account:
 20         enrollmentlist=request.user.stu_account.enrollment_set.all()#根據賬號表關聯的ID獲取06學員報名信息表
 21 
 22         # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 23         page = Page(request.GET.get('p', 1), len(enrollmentlist)) #當前頁數 默認為1 #總數量
 24         enrollmentlist = enrollmentlist[page.start:page.end]  # 切片取當前頁的數據
 25         page_str = page.page_str('/bpm/student_course/')  #總頁數 傳入url
 26         # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 27 
 28     return  render(request, 'bpm_student/student_course.html', locals())
 29 
 30 #學生上課記錄列表
 31 @login_required # 登陸后頁面才能訪問
 32 @check_permission #權限控制
 33 def studyrecords(request,enroll_obj_id):
 34     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#根據ID獲取06學員報名信息表
 35     studyrecordlist=enroll_obj.studyrecord_set.all()#根據06學員報名信息表的ID獲取09學習紀錄
 36 
 37     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 38     page = Page(request.GET.get('p', 1), len(studyrecordlist)) #當前頁數 默認為1 #總數量
 39     studyrecordlist = studyrecordlist[page.start:page.end]  # 切片取當前頁的數據
 40     page_str = page.page_str('/bpm/studyrecords/%s/'%enroll_obj_id)  #總頁數 傳入url
 41     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 42 
 43     return render(request,'bpm_student/studyrecords.html',locals())
 44 
 45 # ————————60PerfectCRM實現CRM學生上課記錄————————
 46 
 47 # ————————61PerfectCRM實現CRM學生上傳作業————————
 48 from django.contrib.auth.decorators import login_required #登陸才能訪問
 49 from PerfectCRM import settings #靜態配置文件  #作業上傳 # 上傳路徑
 50 import os,json,time #系統操作
 51 from django.shortcuts import HttpResponse #頁面返回
 52 from django.shortcuts import redirect #頁面返回
 53 #作業詳情
 54 @login_required#登陸才能訪問
 55 @check_permission #權限控制
 56 def homework_detail(request,enroll_obj_id,studyrecord_id):
 57     studyrecord_obj=models.StudyRecord.objects.get(id=studyrecord_id)#取學習記錄 對象
 58     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#取班級對象
 59 
 60     #               作業根目錄    班級ID      上課記錄ID               學習記錄ID
 61     homework_path="{base_dir}/{class_id}/{course_record_id}/{studyercord_id}/".format(
 62         base_dir=settings.HOMEWORK_DATA, #靜態配置文件
 63         class_id=studyrecord_obj.student.enrolled_class_id,#09學習紀錄#學生名字#所報班級ID號
 64         course_record_id=studyrecord_obj.course_record_id,#09學習紀錄#每節課上課紀錄表
 65         studyercord_id=studyrecord_obj.id##09學習紀錄
 66     )
 67     print('homework_path路徑:',studyrecord_obj.student.enrolled_class_id,studyrecord_obj.course_record_id,studyrecord_obj.id)
 68 
 69     if os.path.exists(homework_path):#判斷目錄是否存在
 70         file_lists = []  # 已經上傳的文件列表
 71         for file_name in os.listdir( homework_path ):
 72             f_path = '%s/%s' % (homework_path, file_name)  # 文件名字
 73             modify_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.gmtime( os.stat( f_path ).st_mtime ) )  # 文件上傳時間
 74             file_lists.append( [file_name, os.stat( f_path ).st_size, modify_time] )  # 添加到文件列表#文件名字#文件大小文件上傳時間
 75 
 76 
 77     if request.method=="POST":#上傳
 78         ret=False
 79         data=request.POST.get('data') #ajax
 80         if data:#如果有刪除動作
 81             del_f_path="%s/%s"%(homework_path,data)#文件路徑
 82             print('刪除文件,路徑:',del_f_path)
 83             os.remove(del_f_path) #刪除
 84             ret=True
 85             return HttpResponse(json.dumps(ret))#ret=False
 86         if request.is_ajax():  # ajax上傳圖片 #異步提交
 87             print("POST",request.POST)
 88             if not os.path.isdir( homework_path ):  # 沒有目錄 #isdir返回true,如果路徑名是指現有的目錄。
 89                 os.makedirs( homework_path, exist_ok=True )  # 創建目錄  
 90             for k,v in request.FILES.items():#上傳的文件
 91                 with open('%s/%s'%(homework_path,v.name),'wb') as f:#chunk 寫入文件
 92                     for chunk in v.chunks(): #循環寫文件
 93                         f.write(chunk)
 94             return HttpResponse( json.dumps( {"status": 0, 'mag': "上傳完成!", 'file_lists': file_lists} ) )  # 上傳文件返回
 95 
 96     if request.method=="POST":#上傳
 97         link = request.POST.get( 'link' )  # 讓頁面POST提交的值,在頁面GET后仍然存在顯示
 98         if link:
 99             homework_link=models.StudyRecord.objects.filter( id=studyrecord_id ).update(homework_link=link)
100             return redirect('/bpm/homework_detail/%s/%s/' %(enroll_obj_id,studyrecord_id) )#跳轉到enrollment_rejection
101     return render(request,'bpm_student/homework_detail.html',locals())
102 # ————————61PerfectCRM實現CRM學生上傳作業————————
# student_views.py

 

 

 

 

  1 # teacher_views.py
  2 # ————————62PerfectCRM實現CRM講師講課記錄————————
  3 from django.contrib.auth.decorators import login_required  # 登陸后頁面才能訪問
  4 from django.shortcuts import render  #頁面返回
  5 
  6 # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
  7 from bpm.bpm_auxiliary.pagination import Page #分頁
  8 # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
  9 
 10 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 11 from permissions.permission import check_permission #權限控制
 12 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 13 # 講師班級
 14 @login_required  # 登陸后頁面才能訪問
 15 @check_permission #權限控制
 16 def teacher_class(request):
 17     # user_id=request.user.id #當前登陸的ID
 18     # classlist=models.UserProfile.objects.get(id=user_id).classlist_set.all()#講師所教班級
 19     classes_obj = request.user.classlist_set.all()  # 根據 登陸的ID 獲取02班級表
 20 
 21     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 22     page = Page(request.GET.get('p', 1), len(classes_obj)) #當前頁數 默認為1 #總數量
 23     classes_obj = classes_obj[page.start:page.end]  # 切片取當前頁的數據
 24     page_str = page.page_str('/bpm/teacher_class/')  #總頁數 傳入url
 25     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 26 
 27     return render( request, 'bpm_teacher/teacher_class.html', locals() )
 28 
 29 # 講師班級課節詳情
 30 @login_required  # 登陸后頁面才能訪問
 31 @check_permission #權限控制
 32 def teacher_class_detail(request, class_id):
 33     # user_id=request.user.id #當前登陸的ID
 34     # classes_obj=models.UserProfile.objects.get(id=user_id).classlist_set.get(id=class_id)#所選的班級
 35     classes_obj = request.user.classlist_set.get( id=class_id )  # 根據 登陸的ID 獲取02班級表
 36     courserecordlist = classes_obj.courserecord_set.all()  # 根據 02班級表的ID 獲取09學習紀錄
 37 
 38     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 39     page = Page( request.GET.get( 'p', 1 ), len( courserecordlist ) )  # 當前頁數 默認為1 #總數量
 40     courserecordlist = courserecordlist[page.start:page.end]  # 切片取當前頁的數據
 41     page_str = page.page_str('/bpm/teacher_class_detail/%s/'%class_id) #總頁數 傳入url
 42     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 43 
 44     return render( request, 'bpm_teacher/teacher_classes_detail.html', locals() )
 45 # ————————62PerfectCRM實現CRM講師講課記錄————————
 46 
 47 # ————————63PerfectCRM實現CRM講師下載作業————————
 48 from PerfectCRM import settings  # 系統配置
 49 import os  # 系統操作
 50 # 本節課的學員
 51 @login_required  # 登陸后頁面才能訪問
 52 @check_permission #權限控制
 53 def teacher_lesson_detail(request, class_id, courserecord_id):
 54     # classes_obj=models.UserProfile.objects.get(id=request.user.id).classlist_set.get(id=class_id)#所選的班級
 55     classes_obj = request.user.classlist_set.get( id=class_id ) # 根據 登陸的ID 獲取02班級表
 56     courserecordlist = classes_obj.courserecord_set.get( id=courserecord_id )  # 根據 前端的ID 獲取08每節課上課紀錄表
 57 
 58     # studyrecord_list=models.CourseRecord.objects.get(id=courserecord_id).studyrecord_set.all()#取本節課所有學員
 59     studyrecord_list = courserecordlist.studyrecord_set.all()  # 根據08每節課上課紀錄表 #獲取09學習紀錄 #取本節課所有學員
 60 
 61     for i in studyrecord_list:  # 循環本節課所有學員 交作業的狀態
 62         studyrecord_id = i.id  # 獲取本節課所有學員的ID
 63         if studyrecord_id:  # 有獲取到ID
 64             HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id)  # 作業目錄
 65             if os.path.exists( HOMEWORK_path ):  # 判斷目錄是否存在
 66                 try:#防止后台誤刪文件
 67                     file_list = os.listdir( HOMEWORK_path )  # 取目錄 下的文件
 68                     isfile = os.path.isfile( '%s%s' % (HOMEWORK_path, file_list[0]) )  # 判斷是不是文件
 69                     studyrecord_list.filter( id=studyrecord_id ).update( delivery=isfile )  # 更新交付作業狀態
 70                 except:
 71                     studyrecord_list.filter( id=studyrecord_id ).update( delivery=False )  # file_list 出錯# 更新交付作業狀態
 72             else:
 73                 studyrecord_list.filter( id=studyrecord_id ).update( delivery=False )# 更新交付作業狀態
 74 
 75     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 76     page = Page( request.GET.get( 'p', 1 ), len( studyrecord_list ) )  # 當前頁數 默認為1 #總數量
 77     studyrecord_list = studyrecord_list[page.start:page.end]  # 切片取當前頁的數據
 78     page_str = page.page_str('/bpm/teacher_lesson_detail/%s/%s/'%(class_id,courserecord_id)) # 總頁數 傳入url
 79     # ————————69PerfectCRM實現CRM業務流程(bpm)學生講師分頁————————
 80 
 81     return render( request, 'bpm_teacher/teacher_lesson_detail.html', locals() )
 82 
 83 from django.http import StreamingHttpResponse #頁面返回
 84 from crm import models #數據庫
 85 from django.shortcuts import redirect #頁面返回
 86 # 學員作業下載
 87 @login_required  # 登陸后頁面才能訪問
 88 @check_permission #權限控制
 89 def howk_down(request, class_id, courserecord_id, studyrecord_id):
 90     HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id)  # 作業目錄
 91     print( '下載作業目錄:', HOMEWORK_path )
 92 
 93     def file_iterator(file_path, chunk_size=512):  # 獲取文件 #chunk_size每次讀取的大小 #文件迭代器
 94         with open( file_path, 'rb', ) as f:  # 循環打開 文件#以二進制讀模式打開
 95             while True:  # 如果有文件
 96                 byte = f.read( chunk_size )  # read讀最多大小字節,作為字節返回。#獲取文件大小
 97                 if byte:
 98                     yield byte  # 返回 yield 后的值作為第一次迭代的返回值. 循環下一次,再返回,直到沒有可以返回的。
 99                 else:
100                     break  # 沒有字節就中止
101 
102     if os.path.exists( HOMEWORK_path ):  # 判斷目錄是否存在
103         try:#防止后台誤刪文件
104             file_list = os.listdir( HOMEWORK_path )  # 取目錄 下的文件
105             print( '文件名:', file_list, type( file_list ) )
106             file_path = '%s%s' % (HOMEWORK_path, file_list[0])  # 下載文件路徑
107             print( '下載文件路徑:', file_path )
108             response = StreamingHttpResponse( file_iterator( file_path ) )  # StreamingHttpResponse是將文件內容進行流式傳輸
109             response['Content-Type'] = 'application/octet-stream'  # 文件類型 #應用程序/octet-stream.*( 二進制流,不知道下載文件類型)
110             file_name = 'attachment;filename=%s' % file_list[0]  # 文件名字# 支持中文
111             response['Content-Disposition'] = file_name.encode()  # 支持中文#編碼默認encoding='utf-8'
112             return response  # 返回下載 請求的內容
113         except:
114             models.StudyRecord.objects.get( id=studyrecord_id ).update( delivery=False )  # 更新交付作業狀態 # file_list 出錯
115     return redirect( '/bpm/teacher_lesson_detail/%s/%s/' % (class_id, courserecord_id) )  # 返回##本節課的學員
116 # ————————63PerfectCRM實現CRM講師下載作業————————
# teacher_views.py

 

 

 

  1 # coursetop_views.py
  2 # ————————64PerfectCRM實現CRM課程排名詳情————————
  3 #————班級學生詳情——#計算#{學員ID:分數}——#計算 #{學員ID: [分數, 排名] }————#
  4 #班級學生詳情#計算#{學員ID:分數}
  5 from django.db.models import Sum #返回數組中所有值的和
  6 def get_course_grades(class_obj):#返回整個班級的成績
  7     c=models.StudyRecord.objects.filter(course_record__from_class=class_obj).values_list('student')
  8     a=Sum('score')#Sum返回數組中所有值的和   #學習成績
  9     e=c.annotate(a) #annotate數據庫的數據聚合函數
 10     class_grade_dic=dict(e)#{1: 285, 16: 190}#{學員ID:分數}
 11     print( '全班成績:', class_grade_dic)
 12     return class_grade_dic   #as class_grade_dic
 13 
 14 #班級學生詳情#計算 #{學員ID: [分數, 排名] }
 15 def get_course_ranking(class_grade_dic):#返回整個班級的排名數據
 16     ranking_list = sorted(class_grade_dic.items(),key=lambda x:x[1],reverse=True)#進行排序后的列表#以第2個參數對比#倒序
 17     print('成績排序:',ranking_list)
 18     ranking_dic = {}
 19     for item in ranking_list:
 20         ranking_dic[item[0]] = [item[1], ranking_list.index(item)+1] #循環添加 排名數 到 排序后的列表
 21     print( '全班排名:', ranking_dic)#{1: [285, 1], 10: [280, 2], }#{學員ID: [分數, 排名] }
 22     return ranking_dic
 23 #————班級學生詳情——#計算#{學員ID:分數}——#計算 #{學員ID: [分數, 排名] }————#
 24 
 25 from django.contrib.auth.decorators import login_required  # 登陸后頁面才能訪問
 26 from django.shortcuts import render #頁面返回
 27 from crm import models #數據庫
 28 # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 29 from bpm.bpm_auxiliary.pagination import Page #分頁
 30 # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 31 
 32 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 33 from permissions.permission import check_permission #權限控制
 34 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
 35 
 36 #班級學生詳情
 37 @login_required  # 登陸后頁面才能訪問
 38 @check_permission #權限控制
 39 def coursetop_details(request,class_id):
 40     classes_obj = models.ClassList.objects.get(id=class_id)#通過ID獲取02班級表
 41     enrollmentlist=classes_obj.enrollment_set.all()#通過班級ID,獲取06學員報名信息表
 42 
 43     class_grade_dic=get_course_grades(classes_obj.id)#{學員ID:分數}        #全班成績 # coursetop_tags.py 根據id 找對應的分數
 44     ranking_dic=get_course_ranking(class_grade_dic)#{學員ID: [分數, 排名] } #全班排名 # coursetop_tags.py 根據id 找對應的排名
 45 
 46     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 47     page = Page( request.GET.get( 'p', 1 ), len( enrollmentlist ) )  # 當前頁數 默認為1 #總數量
 48     enrollmentlist = enrollmentlist[page.start:page.end]  # 切片取當前頁的數據
 49     page_str = page.page_str('/bpm/coursetop_details/%s/'%(class_id)) # 總頁數 傳入url
 50     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 51 
 52     return render(request,'bpm_coursetop/coursetop_details.html',locals())
 53 # ————————64PerfectCRM實現CRM課程排名詳情————————
 54 
 55 
 56 
 57 # ————————65PerfectCRM實現CRM課程分數排名————————
 58 #———— 班級學生詳情——#計算 #{排名: (ID, 分數)}#排名查名字————#
 59 def get_ranking_name(class_grade_dic):
 60     lists=[]
 61     ranking_list = sorted(class_grade_dic.items(),key=lambda x:x[1],reverse=True)#進行排序后的列表#以第2個參數對比#倒序
 62     #ranking_list [(1, 285), (10, 280)] #按分高排序的ID順序
 63     for item in ranking_list:
 64         temp={}
 65         temp[ranking_list.index(item) + 1] = item  # 循環添加 排名數 到 排序后的列表
 66         lists.append(temp)
 67     print( '排名查名字:', lists )#[{1: (1, 285)}, {2: (10, 280)}]#[{排名: (學員ID, 分數)}]
 68     return lists
 69 #———— 班級學生詳情——#計算 #{排名: (ID, 分數)}#排名查名字————#
 70 
 71 #班級學生詳情#全班成績排名 #通過#{排名: (ID, 分數)}#排名查名字
 72 @login_required  # 登陸后頁面才能訪問
 73 @check_permission #權限控制
 74 def coursetop_score(request,class_id):
 75     classes_obj = models.ClassList.objects.get(id=class_id)#通過ID獲取02班級表
 76     class_grade_dic=get_course_grades(classes_obj.id)#{學員ID:分數}        #全班成績
 77     lists=get_ranking_name(class_grade_dic)#計算#[{排名: (學員ID, 分數)}]  #按分高排序的ID順序
 78 
 79     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 80     page = Page( request.GET.get( 'p', 1 ), len( lists ) )  # 當前頁數 默認為1 #總數量
 81     lists = lists[page.start:page.end]  # 切片取當前頁的數據
 82     page_str = page.page_str('/bpm/coursetop_score/%s/'%(class_id)) # 總頁數 傳入url
 83     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
 84 
 85     return render(request,'bpm_coursetop/coursetop_score.html',locals())
 86 
 87 # ————————65PerfectCRM實現CRM課程分數排名————————
 88 
 89 # ————————66PerfectCRM實現CRM課程作業排名————————
 90 #————#班級學生詳情#計算#學員已交作業的數量————#
 91 #班級學生詳情#計算#學員已交作業的數量
 92 def get_already_homework(class_id):
 93     score_list = models.StudyRecord.objects.select_related().filter(student=class_id ).values_list( 'score' )#學習成績
 94     number = 0
 95     for score in score_list:
 96         if score != (0,):  # (0,"N/A")
 97             number += 1  #通過 學習成績 不等於0 計算#已交作業的數量
 98     return number
 99 #————#班級學生詳情#計算#學員已交作業的數量————#
100 
101 #班級學生詳情#學員已交作業的數量#作業查名字
102 @login_required  # 登陸后頁面才能訪問
103 @check_permission #權限控制
104 def coursetop_homework(request,class_id):
105     classes_obj = models.ClassList.objects.get(id=class_id)#通過ID獲取02班級表
106     class_grade_dic=get_course_grades(classes_obj.id)#{學員ID:分數}        #全班成績
107     ranking_dic=get_course_ranking(class_grade_dic)#{學員ID: [分數, 排名] } #全班排名
108     enrollmentlist=classes_obj.enrollment_set.all()#通過班級ID,獲取06學員報名信息表
109 
110     dict = {}#{1: 3, 4: 2,}#{學員ID: 數量}
111     for item in enrollmentlist:
112         d = get_already_homework( item.id )#根據06學員報名信息表#學員ID #計算#學員已交作業的數量
113         dict[item.id]= d
114 
115     list = sorted(dict.items(),key=lambda x:x[1])#進行排序后的列表#以第2個參數對比
116     #list[ (4, 2), (16, 2)]    #list[ (學員ID, 數量)]
117 
118     lists=[] #[{1: (19, 0)}, {2: (20, 0)}]#[{排名: (學員ID, 數量)}]
119     for item in list:
120         temp={}
121         temp[list.index( item ) + 1] = item  # 循環添加 排名數 到 排序后的列表 #按已交作業數量少到多排序
122         lists.append(temp)
123     print('已交作業:',lists)
124 
125     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
126     page = Page( request.GET.get( 'p', 1 ), len( lists ) )  # 當前頁數 默認為1 #總數量
127     lists = lists[page.start:page.end]  # 切片取當前頁的數據
128     page_str = page.page_str('/bpm/coursetop_homework/%s/'%(class_id)) # 總頁數 傳入url
129     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
130 
131     return render(request,'bpm_coursetop/coursetop_homework.html',locals())
132 # ————————66PerfectCRM實現CRM課程作業排名————————
133 
134 # ————————67PerfectCRM實現CRM課程出勤排名————————
135 #————#班級學生詳情#學員出勤次數 #出勤次數查名字————#
136 #班級學生詳情#計算#學員出勤次數
137 def get_stu_attendance(enroll_obj_id):
138     attendance_list=models.StudyRecord.objects.select_related().filter(student=enroll_obj_id).values_list('attendance')
139     number=0
140     for attendance in attendance_list:
141         if attendance == (0,) :
142             number += 1
143     return number
144 #————#班級學生詳情#學員出勤次數 #出勤次數查名字————#
145 
146 #班級學生詳情#學員出勤次數 #出勤次數查名字
147 @login_required  # 登陸后頁面才能訪問
148 @check_permission #權限控制
149 def coursetop_attendance(request,class_id):
150     classes_obj = models.ClassList.objects.get(id=class_id)#通過ID獲取02班級表
151     class_grade_dic=get_course_grades(classes_obj.id)#{學員ID:分數}        #全班成績
152     ranking_dic=get_course_ranking(class_grade_dic)#{學員ID: [分數, 排名] } #全班排名
153     enrollmentlist=classes_obj.enrollment_set.all()#通過班級ID,獲取06學員報名信息表
154 
155     dict = {} #{1: 3, 4: 2,}#{學員ID: 次數}
156     for item in enrollmentlist:
157         d = get_stu_attendance( item.id )#根據06學員報名信息表#學員ID #計算#學員學員出勤次數
158         dict[item.id]= d # 循環添加 {學員ID: 次數} #排序后的字典
159 
160     list = sorted(dict.items(),key=lambda x:x[1])#進行排序后的列表#以第2個參數對比 #按出勤次數少到多排序
161     #list[ (4, 2), (16, 2)]    #list[ (學員ID, 次數)]
162 
163     lists=[]#[{1: (19, 3)}, {2: (20, 1)}]#[{排名: (學員ID, 次數)}]
164     for item in list:
165         temp={}
166         temp[list.index( item ) + 1] = item  # 循環添加 排名數 #排序后的列表
167         lists.append(temp)
168     print('全班出勤',lists)
169 
170     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
171     page = Page( request.GET.get( 'p', 1 ), len( lists ) )  # 當前頁數 默認為1 #總數量
172     lists = lists[page.start:page.end]  # 切片取當前頁的數據
173     page_str = page.page_str('/bpm/coursetop_attendance/%s/'%(class_id)) # 總頁數 傳入url
174     # ————————70PerfectCRM實現CRM業務流程(bpm)課程排行分頁————————
175 
176     return render(request,'bpm_coursetop/coursetop_attendance.html',locals())
177 # ————————67PerfectCRM實現CRM課程出勤排名————————
# coursetop_views.py

 

 

 

 

 

  1 # kingadmin.py
  2 # ————————04PerfectCRM實現King_admin注冊功能————————
  3 from crm import models
  4 #print("kingadmin crm",models.Customer)
  5 
  6 # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
  7 # from king_admin.base_admin import register,BaseAdmin
  8 from king_admin.base_admin import site,BaseAdmin
  9 # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
 10 
 11 # ————————24PerfectCRM實現King_admin自定義操作數據————————
 12 from django.shortcuts import render
 13 # ————————24PerfectCRM實現King_admin自定義操作數據————————
 14 
 15 # ————————28PerfectCRM實現King_admin編輯限制————————
 16 from django.forms import ValidationError
 17 from django.shortcuts import render,redirect
 18 # ————————28PerfectCRM實現King_admin編輯限制————————
 19 
 20 
 21 
 22 
 23 # ————————62PerfectCRM實現CRM講師講課記錄————————
 24 # 02班級表
 25 class ClassListAdmin(BaseAdmin):
 26     list_display = ['id', 'branch', 'course', 'class_type', 'semester', 'start_date', 'end_date']  # 顯示字段表頭
 27     list_filter = ['branch', 'course', 'class_type']  # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
 28     filter_horizontal = ['teachers']  #復選框
 29 site.register(models.ClassList,ClassListAdmin)               #02班級表
 30 
 31 # ————————62PerfectCRM實現CRM講師講課記錄————————
 32 
 33 
 34 
 35 
 36 #04客戶信息表
 37 class CustomerAdmin(BaseAdmin):#定制Djanago admin
 38     # ————————54PerfectCRM實現CRM客戶報名鏈接————————
 39     # list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date')  # 顯示字段表頭
 40     list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date','status','enroll')  # 顯示字段表頭
 41     # ————————54PerfectCRM實現CRM客戶報名鏈接————————
 42     # ————————11PerfectCRM實現King_admin分頁顯示條數————————
 43     list_per_page = 2  #分頁條數  # 默認分頁條數10
 44     # ————————11PerfectCRM實現King_admin分頁顯示條數————————
 45     # ————————16PerfectCRM實現King_admin日期過濾————————
 46     # ————————15PerfectCRM實現King_admin多條件過濾————————
 47     # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
 48     # list_filter = ('source','consultant','consult_courses',)
 49     list_filter = ('date','source','consultant','consult_courses',)
 50     # ————————15PerfectCRM實現King_admin多條件過濾————————
 51     # ————————16PerfectCRM實現King_admin日期過濾————————
 52     # ————————18PerfectCRM實現King_admin搜索關鍵字————————
 53     #搜索(不能包含CharField)(注意加 逗號 , )
 54     search_fields = ('name','qq',)
 55     # ————————18PerfectCRM實現King_admin搜索關鍵字————————
 56     # ————————26PerfectCRM實現King_admin自定義排序————————
 57     ordering = '-qq'  #自定義排序,默認'-id'
 58     # ————————26PerfectCRM實現King_admin自定義排序————————
 59     # ————————27PerfectCRM實現King_admin編輯復選框————————
 60     filter_horizontal = ('tags',) #復選框
 61     # ————————27PerfectCRM實現King_admin編輯復選框————————
 62     # ————————33PerfectCRM實現King_admin編輯整張表限制————————
 63     readonly_table=True#默認表單不鎖定
 64     # ————————33PerfectCRM實現King_admin編輯整張表限制————————
 65 
 66     # ————————55PerfectCRM實現CRM客戶報名狀態顏色變化————————
 67     colored_fields = {
 68         'status':{'已報名':"rgba(145, 255, 0, 0.78)",
 69                   '未報名':"#ddd"},}
 70     # ————————55PerfectCRM實現CRM客戶報名狀態顏色變化————————
 71 
 72     # ————————54PerfectCRM實現CRM客戶報名鏈接————————
 73     def enroll(self):
 74         '''報名'''
 75         print("customize field enroll",self)
 76         link_name = "報名"
 77         if self.instance.status == 0:
 78             link_name = "報名新課程"
 79         return '''<a target="_blank" class="btn-link" href="/bpm/customer/%s/enrollment/">點擊%s</a> ''' % (self.instance.id,link_name)
 80                 # url(r'^customer/(\d+)/enrollment/$', sales_views.enrollment, name="enrollment"),  # 客戶招生#報名流程一 下一步
 81                 # target屬性用於表示所鏈接文件打開到的位置 #記住,“”內的文字只是表示一個對象的名子。
 82     enroll.display_name = "報名鏈接"
 83     # ————————54PerfectCRM實現CRM客戶報名鏈接————————
 84 
 85 
 86 
 87     # ————————24PerfectCRM實現King_admin自定義操作數據————————
 88     # from django.shortcuts import render
 89     actions = ['test_actions',]#定制功能    #測試返回到一個新頁面
 90     def test_actions(self,request,arg2):#對應的函數 #request類自己的請求  #arg2類的內容
 91         return render(request,"king_admin/table_index.html")
 92     test_actions.short_description = "測試顯示中文"
 93     # ————————24PerfectCRM實現King_admin自定義操作數據————————
 94 
 95     # ————————28PerfectCRM實現King_admin編輯限制————————
 96     # ————————31PerfectCRM實現King_admin編輯多對多限制————————
 97     # readonly_fields = ('qq', 'consultant',)  # 不可修改
 98     readonly_fields = ('qq', 'consultant','tags',)  # 不可修改
 99     # ————————31PerfectCRM實現King_admin編輯多對多限制————————
100 
101     # ————————29PerfectCRM實現King_admin編輯自定義限制————————
102     def default_form_validation(self,obj):
103         print('validation:制定的',obj.cleaned_data)
104         consult_course=obj.cleaned_data.get('content','')#自制驗證字段
105         if len(consult_course)<10:
106             return ValidationError(#添加錯誤信息 返回
107                                 ("該字段%(field)s 咨詢內容記錄不能少於10個字符"),
108                                 code='invalid',
109                                 params={'field':'content',},
110                             )
111     # ————————29PerfectCRM實現King_admin編輯自定義限制————————
112 
113     # ————————28PerfectCRM實現King_admin編輯限制————————
114 
115     # ————————30PerfectCRM實現King_admin編輯自定義字段驗證————————
116     def clean_name(self,obj,*args,**kwargs):#名稱驗證 單個
117         name=obj.cleaned_data['name']
118         if not name:
119             obj.add_error('name','不能為空!')
120             return ValidationError(#添加錯誤信息 返回
121                                 ("%(field)s:該字段 不能為空"),
122                                 code='invalid',
123                                 params={'field':'name',},
124                             )
125         elif len(name)<5:
126             obj.add_error('name','不能小於5個字符!')
127             #return ValidationError('',)
128             return ValidationError(#添加錯誤信息 返回
129                                 ("%(field)s:該字段 不能小於5個字符!"),
130                                 code='invalid',
131                                 params={'field':'name',},
132                             )
133     # ————————30PerfectCRM實現King_admin編輯自定義字段驗證————————
134 
135 # ————————34PerfectCRM實現CRM自定義用戶————————
136 #10賬號表
137 class UserProfileAdmin(BaseAdmin):#定制Djanago admin
138     list_display = ('id', 'email', 'name')  # 顯示字段表頭
139 
140     # ————————36PerfectCRM實現King_admin密碼修改————————
141     readonly_fields = ('password',)   # 不可修改,限制
142 
143     # ————————72PerfectCRM實現CRM動態菜單和角色————————
144     # filter_horizontal = ('user_permissions','groups') #復選框
145     filter_horizontal = ('user_permissions', 'groups','roles')  # 復選框
146     # ————————72PerfectCRM實現CRM動態菜單和角色————————
147 
148     modelform_exclude_fields=['last_login']#排除#不顯示 #自增日期 #base_admin.py #forms.py
149     # ————————36PerfectCRM實現King_admin密碼修改————————
150 
151 site.register(models.UserProfile, UserProfileAdmin)
152 # ————————34PerfectCRM實現CRM自定義用戶————————
153 
154 # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
155 # register(models.Customer,CustomerAdmin)
156 # register(models.CourseRecord)
157 site.register(models.Customer,CustomerAdmin)
158 # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
159 # site.register(models.CourseRecord)
160 # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
161 # ————————05PerfectCRM實現King_admin注冊功能獲取內存————————
162 
163 # ————————04PerfectCRM實現King_admin注冊功能————————
164 
165 
166 # ————————56PerfectCRM實現CRM客戶報名繳費鏈接————————
167 # 06學員報名信息表
168 class EnrollmentAdmin(BaseAdmin):  # 定制Djanago admin
169     list_display = ('id', 'customer', 'enrolled_class', 'consultant', 'Pay_cost', 'date', 'payment')  # 顯示字段表頭
170 
171     # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
172     list_filter = ('enrolled_class','consultant', 'Pay_cost',) # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
173     # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
174 
175     colored_fields = {
176         'Pay_cost': {True: "rgba(145, 255, 0, 0.78)",
177                      False: "#ddd"}, }
178     def payment(self):
179         link_name = "增加繳費"
180         if self.instance.Pay_cost == False:
181             link_name = "繳費"
182         return '''<a target="_blank" class="btn-link"  href="/bpm/payment/%s/" >點擊%s</a> ''' % (self.instance.id, link_name)
183         # url(r'^payment/(\d+)/$', financial_views.payment, name="payment"),  # 報名流程四    繳費   #財務
184         # target屬性用於表示所鏈接文件打開到的位置 #記住,“”內的文字只是表示一個對象的名子。
185     payment.display_name = "繳費鏈接"
186 site.register(models.Enrollment, EnrollmentAdmin)  # 06學員報名信息表
187 # ————————56PerfectCRM實現CRM客戶報名繳費鏈接————————
188 
189 # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
190 # 07繳費記錄表
191 class PaymentAdmin(BaseAdmin):
192     list_display = ['id', 'customer', 'course', 'amount', 'consultant','date']  # 顯示字段表頭
193     list_filter = ('customer', 'course', 'consultant',)  # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
194 
195 from django.shortcuts import render, HttpResponse, redirect
196 # 08每節課上課紀錄表
197 class CourseRecordAdmin(BaseAdmin):
198     list_display = ['id', 'from_class', 'day_num', 'teacher', 'has_homework', 'homework_title', 'homework_content','outline', 'date']  # 顯示字段表頭
199     list_filter = ('from_class', 'teacher', 'date')  # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
200     def initialize_studyrecords(self, request, queryset):  # 制定功能
201         print('initialize_studyrecords', self, request, queryset)
202         if len(queryset) > 1:
203             return HttpResponse("同時只能選擇一個班級!")
204         print('獲取對應的學員', queryset[0].from_class.enrollment_set.all())  # _set反向查詢
205         new_obj_list = []  # 用於批量創建事務  #防止數據庫事物回滾
206         for enrll_obj in queryset[0].from_class.enrollment_set.all():  # 創建學習記錄
207             #     models.StudyRecord.objects.get_or_create(       #get_or_ #防止報錯
208             #         student=enrll_obj,#對應學員
209             #         course_record=queryset[0],
210             #         attendance=0,#簽到狀態,默認簽到,
211             #         score=0,#成績
212             #     )
213 
214             # 防止數據庫事物回滾    #"""09學習紀錄"""
215             new_obj_list.append(models.StudyRecord(
216                 student=enrll_obj,  # 對應學員
217                 course_record=queryset[0],  # 班級#節課
218                 attendance=0,  # 簽到狀態,默認簽到,
219                 score=0,  # 成績
220             ))
221         try:
222             models.StudyRecord.objects.bulk_create(new_obj_list)  # bulk_create批量創建數據庫事物 #統一最后保存
223         except Exception as e:
224             return HttpResponse('批量創建失敗,本節課可能有相應的上課記錄')
225 
226         return redirect("/king_admin/crm/studyrecord/?course_record=%s" % queryset[0].id)  # 學習記錄 #加上過濾
227 
228     actions = ['initialize_studyrecords', ]
229     initialize_studyrecords.short_description = "創建班級本節上課記錄"  # 顯示別名
230 # 09學習紀錄
231 class StudyRecordAdmin(BaseAdmin):
232     list_display = ['id', 'student', 'course_record', 'attendance', 'score', 'date']  # 顯示字段表頭
233 
234     list_filter = ['course_record', 'attendance', 'score', 'student']  # 過濾器(可以包含ManyToManyField) (注意加 逗號 , )
235 
236     list_editable = ['score', 'attendance']  # 可編輯   #用於上課點名 批改成績
237 
238 site.register(models.Payment, PaymentAdmin)  # 07繳費記錄表
239 site.register(models.CourseRecord, CourseRecordAdmin)  # 08每節課上課紀錄表
240 site.register(models.StudyRecord, StudyRecordAdmin)  # 09學習紀錄
241 # ————————58PerfectCRM實現king_admin批量生成上課記錄————————
242 
243 
244 # ————————72PerfectCRM實現CRM動態菜單和角色————————
245 # 11角色表
246 class RoleAdmin(BaseAdmin):
247     list_display = ['id', 'name']  # 顯示字段表頭
248     filter_horizontal = ['menus']  # 復選框
249 site.register(models.Role,RoleAdmin) #11角色表
250 
251 # 13一層菜單名
252 class FirstLayerMenuAdmin(BaseAdmin):
253     list_display = ['id', 'name', 'url_type', 'url_name', 'order']  # 顯示字段表頭
254 site.register(models.FirstLayerMenu,FirstLayerMenuAdmin)  #13一層菜單名
255 # 14二層菜單名
256 class SubMenuMenuAdmin(BaseAdmin):
257     list_display = ['id', 'name', 'url_type', 'url_name', 'order']  # 顯示字段表頭
258 site.register(models.SubMenu,SubMenuMenuAdmin)   #14二層菜單名
259 # ————————72PerfectCRM實現CRM動態菜單和角色————————
260 
261 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
262 class GroupsAdmin(BaseAdmin):
263     list_display = ['id', 'name']  # 顯示字段表頭
264     filter_horizontal = ['permissions']  # 復選框
265 site.register(models.Groups,GroupsAdmin)   #14二層菜單名
266 # ————————74PerfectCRM實現CRM權限和權限組限制訪問URL————————
# kingadmin.py

 

 

 

 

 

 

 

 

 


 

如果感覺本章博客對您有幫助,請盡情打賞吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM