Mia Cheng 1 éve
szülő
commit
2e36e1b256
5 módosított fájl, 861 hozzáadás és 445 törlés
  1. 1 1
      app/api/article.py
  2. 240 44
      app/api/classes.py
  3. 2 0
      app/api/news.py
  4. 177 17
      app/api/registration.py
  5. 441 383
      app/api/users.py

+ 1 - 1
app/api/article.py

@@ -46,7 +46,7 @@ async def get_article(
     group_sort : Optional[str] = None,
     category : Optional[str] = None,
     tags : Optional[str] = None,
-    recommend: int = Form(default=None),
+    recommend: Optional[int] = None,
     page_num : Optional[int] = None,
     page_amount : Optional[int] = None
 ):

+ 240 - 44
app/api/classes.py

@@ -3,7 +3,7 @@ from typing import List,Optional
 from fastapi.responses import FileResponse
 from random import randint
 from fastapi.security import OAuth2PasswordRequestForm
-from app.models.models import User,Favorite_course,Article_list,Class_date,Attend_record,One_day_class,Outter_class_list
+from app.models.models import User,User_information,Favorite_course,Article_list,Class_date,Attend_record,One_day_class,Outter_class_list
 from app.models.models import Class_list,Schools,Class_detail,Class_name,Registration,Group_name,Online_course
 from app.api import deps
 from sqlalchemy.orm import Session
@@ -23,6 +23,8 @@ import json
 from itertools import chain
 from tortoise import fields
 
+from datetime import datetime
+
 classes = APIRouter()
 
 async def check_token(access_token: str):
@@ -161,7 +163,8 @@ async def insert_event(
     number_limit: int = Form(default=0),
     remark : str = Form(default='詳細 請至觀看課程資訊 查看'),
     ATM_address: str = Form(default=''),
-    access_token:str = Form(default=None)
+    access_token:str = Form(default=None),
+    fee_payment: str = Form(default=''),
 ):    
     try:
 
@@ -189,7 +192,8 @@ async def insert_event(
             registration_way=registration_way,
             remark=remark,
             ATM_address=ATM_address,
-            create_user_id = user_id
+            create_user_id = user_id,
+            fee_payment = fee_payment
         )
         try:
             await Class_date.create(
@@ -209,37 +213,54 @@ async def insert_event(
 @classes.post("/auto_create_session")
 async def auto_create_session(
     class_event_id : int = Form(default=0),
-    week_day_str : str = Form(default="[]")
+    week_day_str : str = Form(default="[]"),
+    start_week_time : str = Form(default="[]"),
+    end_week_time : str = Form(default="[]"),
+
 ):
     try:
         week_day = eval(week_day_str)
-
+        start_week_time= eval(start_week_time)
+        end_week_time= eval(end_week_time)
         #print(week_day)
         
         class_obj = await Class_list.get(id = class_event_id)
         time_stemp = class_obj.start_time
         
+        session = 1
+        
+        session_list = await Class_detail.filter(class_list_id=class_event_id).delete()
+        
         while time_stemp <= class_obj.end_time:
             if week_day[time_stemp.weekday()]:
-                time_del =  class_obj.end_time.hour - time_stemp.hour
-                time_del_minutes =  class_obj.end_time.minute - time_stemp.minute
-                time_end =  time_stemp + timedelta(hours=time_del,minutes=time_del_minutes)
+                s_start_time = time_stemp.date().strftime("%Y-%m-%d")+" "+start_week_time[time_stemp.weekday()]
+                s_end_time  = time_stemp.date().strftime("%Y-%m-%d")+" "+end_week_time[time_stemp.weekday()]
+
+                #time_del =  class_obj.end_time.hour - time_stemp.hour
+                #time_del_minutes =  class_obj.end_time.minute - time_stemp.minute
+
+
+                #time_end =  time_stemp + timedelta(hours=time_del,minutes=time_del_minutes)
                 #print(time_end,class_obj.end_time.hour)
 
-                session_list = await Class_detail.filter(class_list_id=class_event_id).all()
-                session = 0
-                if session_list != []:
-                    for session_obj in session_list:
-                        if session < session_obj.sessions:
-                            session = session_obj.sessions
+                
+                day1 = datetime.strptime(s_start_time, '%Y-%m-%d %H:%M:%S')
+                day2 = datetime.strptime(s_end_time, '%Y-%m-%d %H:%M:%S')
+                time_difference = day2 - day1
+                total_minutes = int(time_difference.total_seconds() // 60)
+                hour=total_minutes//60 + round((total_minutes%60)/60,1)
 
                 new_session = await Class_detail.create(
                     class_list_id=class_event_id,
-                    start_time=time_stemp,
-                    end_time=time_end,
-                    sessions=session +1,
+                    #start_time=time_stemp,
+                    #end_time=time_end,
+                    start_time=s_start_time,
+                    end_time=s_end_time,
+                    hour = hour,
+                    sessions=session,
                     content = ""
                 ) 
+                session+=1
 
             time_stemp = time_stemp + timedelta(days=1) 
 
@@ -262,12 +283,17 @@ async def insert_session(
                 if session < session_obj.sessions:
                     session = session_obj.sessions
 
+        time_difference = end_time - start_time
+        total_minutes = int(time_difference.total_seconds() // 60)
+        hour=total_minutes//60 + round((total_minutes%60)/60,1)
+        print(round((total_minutes%60)/60,1))
         new_session = await Class_detail.create(
             class_list_id=class_event_id,
             start_time=start_time,
             end_time=end_time,
             sessions=session +1,
-            content = content
+            content = content,
+            hour = hour
         )
         
         return {"msg": "success", "code": 200, "new_session_id": new_session.id}
@@ -354,7 +380,7 @@ async def update_class_name(
         if group_id != 0 :
             class_name.group_id = group_id
 
-        if is_inner :
+        if is_inner is not None:
             class_name.is_inner = is_inner
 
         if cover_img_file != '':
@@ -368,10 +394,10 @@ async def update_class_name(
         if group_sort != '':
             class_name.group_sort = group_sort
 
-        if recommend:
+        if recommend  is not None:
             class_name.recommend = recommend
 
-        if is_check:
+        if is_check is not None:
             class_name.is_check = is_check
 
         if special_class_list_name:
@@ -403,7 +429,9 @@ async def update_event(
     registration_end:  datetime = Form(default=datetime.now()),
     number_limit: int = Form(default=0),
     remark :  str = Form(default=''),
-    ATM_address :str = Form(default='')
+    ATM_address :str = Form(default=''),
+    fee_payment : str = Form(default='')
+
 ):
     try:
         class_obj = await Class_list.get(id=id)
@@ -450,6 +478,11 @@ async def update_event(
         if ATM_address.strip() != '':
             class_obj.ATM_address = ATM_address
 
+        if fee_payment.strip() != '':
+            class_obj.fee_payment = fee_payment
+
+ 
+
         try :
             class_date_obj = await Class_date.get(class_list_id=id)
 
@@ -670,6 +703,17 @@ async def search_event(
                 state["result"] = {
                     "state" : "fail to get data"
                 }
+        else:
+            class_list = Class_list.filter(Q_word).all().order_by("-start_time")
+            # 获取模型类中的所有字段
+            model_fields = [attr for attr in dir(Class_list) if isinstance(getattr(Class_list, attr), fields.Field)]
+            try:
+                state = await check_date_state(class_event_id=class_name_id)
+            except:
+                state["result"] = {
+                    "state" : "fail to get data"
+                }
+
                 
     
         class_list = await class_list.all()
@@ -772,14 +816,23 @@ async def get_school(
         return {"msg": str(e), "code": 500}
     
 @classes.get("/get_group_name")
-async def get_school_group():
+async def get_school_group(
+id : Optional[int] = 0
+):
     try:
-        school_group_list = await Group_name.all()
+        if id==0:
+            school_group_list = await Group_name.all()
+            print(school_group_list)
+        else:
+            school_group_list = [await Group_name.get(id=id)]
+            print(school_group_list)
         school_groups = []
         for school_obj in school_group_list:
             school_data = {
                 "group_id": school_obj.id,
-                "group_name": school_obj.group_name
+                "group_name": school_obj.group_name,
+                "describe": school_obj.describe
+
             }
             school_groups.append(school_data)
 
@@ -787,6 +840,30 @@ async def get_school_group():
     except Exception as e:
         return {"msg": str(e), "code": 500}
 
+@classes.post("/update_group_name")
+async def update_school_group(
+    id : int = Form(default=0),
+    group_name : str = Form(default=''),
+    describe : str = Form(default=''),
+):
+    try:
+        group_name_obj = await Group_name.get(id=id)
+
+        if group_name.strip() != '':
+            group_name_obj.group_name = group_name
+        
+        if describe.strip() != '':
+            group_name_obj.describe = describe
+        
+        await group_name_obj.save()
+        
+        return {"msg": "success", "code": 200}
+    except Exception as e:
+        return {"msg": str(e), "code": 500}
+
+   
+
+
 @classes.get("/get_class_name")
 async def get_class_name(
     location_id : Optional[int] = None ,
@@ -804,8 +881,9 @@ async def get_class_name(
 ):
     try:
         class_name_list = Class_name.all()
+        
         Q_word = Q()
-
+	
         if group_id:
             Q_word = Q_word & Q(group_id = group_id)
 
@@ -829,7 +907,8 @@ async def get_class_name(
             Q_word = Q_word & Q(is_inner = is_inner)
 
         if is_check!=None:
-            Q_word = Q_word & Q(is_check = is_check)
+            Q_word = Q_word & Q(is_check = is_check) 
+     
 
         user_id = None
         if access_token:
@@ -1150,11 +1229,13 @@ async def update_online_course(
 @classes.get("/get_online_courese")
 async def get_online_courese(
     online_courese_id : Optional[int] = None,
-    category:Optional[int] = None,
+    category:Optional[str] = None,
     group_id : Optional[int] = None,
     page_num : Optional[int] = None,
-    page_amount : Optional[int] = None
-    
+    page_amount : Optional[int] = None,
+    org :Optional[str] = None,
+    no_org:Optional[str] = None,
+    key_word:Optional[str] = None,
 ):
     try:
         online_courese_list = Online_course.all()
@@ -1163,20 +1244,41 @@ async def get_online_courese(
         if group_id:
             Q_word = Q_word & Q(group_id = group_id)
 
-        if category:
-            for tmp_word in category.split(",") :
-                Q_word = Q_word | Q(category__icontains=tmp_word) 
+        
 
         if online_courese_id :
             Q_word = Q_word & Q(id = online_courese_id)
 
-        count = await online_courese_list.all().count()
+        if org :
+            Q_word = Q_word & Q(org = org)
+        if no_org:
+            no_org_condition = Q(org__isnull=True) | ~Q(org=no_org)
+            Q_word = Q_word & no_org_condition
+            
+
+        if category:
+            category_conditions = Q()
+            for tmp_word in category.split(",") :
+                category_conditions |= Q(category__icontains=tmp_word)
+                Q_word = Q_word & category_conditions
+                #Q_word = Q_word | Q(category__icontains=tmp_word) 
+        if key_word:
+            key_word_condition = Q(title__icontains=key_word) | Q(category__icontains=key_word) | Q(content__icontains=key_word)
+            Q_word = Q_word & key_word_condition
+
+
+        count = await online_courese_list.all().filter(Q_word).count()
+
+        
+
 
         if page_num and page_amount:
             online_courese_list = online_courese_list.offset((page_num-1)*page_amount).limit(page_amount)
 
-        online_courese_list = await online_courese_list.all().order_by("id")
+        online_courese_list = await online_courese_list.all().filter(Q_word).order_by("id")
+
         
+
         online_coureses = []
         for online_coures_obj in online_courese_list:
             online_coures_data = online_coures_obj.show_data()
@@ -1281,7 +1383,47 @@ async def get_group_classes_and_articles(
         return {"msg": "success", "code": 200,"class_num" : class_count,"classes": classes_name,"article_num":article_count,"articles": article_objs}
     
     except Exception as e:
-        return {"msg": str(e), "code": 500}    
+        return {"msg": str(e), "code": 500}
+
+   
+@classes.post("/add_attend_record_by_event")
+async def add_attend_record(
+    class_id : int = Form(default=0),
+):
+    try:
+        if not class_id:
+            return {"msg": "Please input right ","code":500}
+        
+        try:
+            class_detail_obj = await Class_detail.filter(class_list_id = class_id).all()
+            
+            if not isinstance(class_detail_obj, list):
+                class_detail_obj = [class_detail_obj]
+
+            registration_obj = await Registration.filter(event_id = class_id,is_del = 0,).all()
+            
+            if not isinstance(registration_obj, list):
+                registration_obj = [registration_obj]
+
+            if not class_detail_obj:
+                return {"msg": "no this class_detail_id  session","code":500}
+        except:
+            return {"msg": "get class_detail_id error","code":500}
+        
+        for obj in class_detail_obj:
+            for obj1 in registration_obj:
+                new_record = await Attend_record.get_or_create(
+                            class_detail_id = obj.id,
+                            user_id = obj1.user_id,
+                            is_attend = 0
+                        )
+
+       
+        return {"msg": "success", "code": 200}
+
+    except Exception as e:
+        return {"msg": str(e), "code": 500} 
+    
     
 @classes.post("/add_attend_record")
 async def add_attend_record(
@@ -1300,7 +1442,9 @@ async def add_attend_record(
         except:
             return {"msg": "get class_detail_id error","code":500}
         
-        new_record = await Attend_record.get_or_create(
+        msg = ""
+
+        new_record,created = await Attend_record.get_or_create(
             class_detail_id = class_detail_id,
             user_id = user_id,
             defaults = {
@@ -1308,17 +1452,54 @@ async def add_attend_record(
             }
         )
 
-        return {"msg": "success", "code": 200,"new_record_id":new_record[0].id}
+        if not created:
+            try:
+                new_record.is_attend = is_attend
+                await new_record.save()
+                msg = "update success"
+            except:
+                msg = "update fail"
+        else:
+            msg = "created success"
+
+        await count_point(user_id=user_id)
+
+        return {"msg": msg, "code": 200,"new_record_id":new_record.id}
 
     except Exception as e:
         return {"msg": str(e), "code": 500} 
-    
+
+@classes.post("/count_point")    
+async def count_point(user_id:int = None):
+    try:
+        if user_id :
+            hour = 0.0
+            user_attend_record = await Attend_record.filter(user_id = user_id,is_attend = 1)
+            for tmp in user_attend_record:
+                class_detail = await Class_detail.get(id= tmp.class_detail_id)
+                hour += float(class_detail.hour)
+
+            user = await User.get(id = user_id)
+            user.points = int(hour/3)
+            await user.save()
+
+            return {"msg":"success record point", "code": 200}
+            
+        else :
+            return {"msg":"no user_id", "code": 500}
+        
+    except Exception as e:
+        return {"msg": str(e), "code": 500}  
+
 @classes.post("/delete_attend_record")
 async def delete_attend_record(
     id : int = 0
 ):
     try :
+        record = await Attend_record.get(id=id)
+        await count_point(user_id=record.user_id)
         await Attend_record.filter(id=id).delete()
+
         return {"msg": "success", "code": 200}
     except Exception as e:
         return {"msg": str(e), "code": 500} 
@@ -1346,6 +1527,7 @@ async def update_attend_record(
             tmp.is_attend = is_attend
 
         await tmp.save()
+        await count_point(user_id=tmp.user_id)
 
         return {"msg": "success", "code": 200}
     except Exception as e:
@@ -1382,12 +1564,26 @@ async def get_attend_record(
         attend_records = []
 
         for obj in attend_record_list:
+            class_detail_list = await Class_detail.filter(id = obj.class_detail_id)
+            #registration_list = await Registration.filter(event_id = class_detail_list[0].class_list_id,user_id =obj.user_id)
+            user_list = await User.filter(id = obj.user_id)
+            user_information_list = await User_information.filter(user_id = obj.user_id)
+            #if len(registration_list)==0:
+            #    continue	
             data = {
-                "id" :obj.id,
-                "class_detail_id" :obj.class_detail_id,
-                "user_id" :obj.user_id,
-                "is_attend" :obj.is_attend
-            }
+			"id" :obj.id,
+			"event_id":class_detail_list[0].class_list_id,
+                	"class_detail_id" :obj.class_detail_id,
+                	"user_id" :obj.user_id,
+                	"is_attend" :obj.is_attend,
+                	#"reg_confirm" : registration_list[0].reg_confirm,
+                	#"payment_status": registration_list[0].payment_status,
+                      	#"five_digits": registration_list[0].five_digits,
+                      	"real_name": user_information_list[0].name,
+                      	"phone": user_information_list[0].phone,
+                      	"email": user_list[0].email
+            	}
+            
             attend_records.append(data)
 
         return {"msg": "success", "code": 200,"attend_record_list":attend_records}

+ 2 - 0
app/api/news.py

@@ -105,6 +105,7 @@ async def insert_news(
     URL :str = Form(default=''),
     tags : str = Form(default='[]'),
     files_url = Depends(create_upload_files),
+    create_time :str = Form(default=datetime.now()),
     cover_img_file:UploadFile = File(default='')
 ):
     try:
@@ -122,6 +123,7 @@ async def insert_news(
             title=title,
             category=category,
             content=content,
+            create_time = create_time,
             files = str(files_url),
             URL = URL,
             tags = tags,

+ 177 - 17
app/api/registration.py

@@ -67,6 +67,85 @@ async def check_permissions(user_id):
 
 #     return {'user': user_id}
 
+@registration.get("/get_registration_class")
+async def get_registration_class(
+   event_id : Optional[int] = None,
+   check_user_id = Depends(check_token)
+):
+    
+    #inform_list =  await Registration.filter(event_id=event_id,is_del=0,reg_confirm=1).all() #use for 8/25 after
+    check_list1 = await User.get(id = check_user_id).all()
+    check_list2 = await Class_list.get(id = event_id).all()
+   
+    if 2!=check_list1.is_superuser:
+        if check_list2.create_user_id !=check_user_id:
+            return {"msg": "permissions denied", "code": 200,"registrations":[]}
+
+    inform_list =  await Registration.filter(event_id=event_id,is_del=0).all()
+    class_data =[]
+    for infor in inform_list:
+      
+        reg_data = {
+                    
+                    "event_id" : infor.event_id,
+                    "user_id" : infor.user_id,
+		    "is_attend" : infor.is_attend,
+		    "payment_status":infor.payment_status,
+		    "five_digits":infor.five_digits,
+		    "reg_confirm":infor.reg_confirm,
+
+
+
+                }
+        user = await User.get(id=infor.user_id)
+        inform = await User_information.get(user_id=infor.user_id)
+        reg_data["real_name"] = inform.name
+        reg_data["phone"] = inform.phone
+        reg_data["email"] = user.email
+
+        class_data.append(reg_data )
+
+    return {"msg": "success", "code": 200,"registrations":class_data}
+
+@registration.post("/update_registration_class")
+async def update_registration_class(
+    event_id : Optional[int] ,
+    user_id : Optional[int] ,
+    is_attend : int = Form(default=None),
+    payment_status : int = Form(default=None),
+    reg_confirm : int = Form(default=None),
+    five_digits : str = Form(default=None),
+    check_user_id = Depends(check_token),
+):
+    
+    #inform_list =  await Registration.filter(event_id=event_id,is_del=0,reg_confirm=1,user_id=user_id).all() #use for 8/25 after
+    inform_list =  await Registration.filter(event_id=event_id,is_del=0,user_id=user_id).all()
+
+    check_list1 = await User.get(id = check_user_id).all()
+    check_list2 = await Class_list.get(id = event_id).all()
+   
+    if 2!=check_list1.is_superuser:
+        if check_list2.create_user_id !=check_user_id:
+            return {"msg": "permissions denied", "code": 500}
+
+    class_data =[]
+    for infor in inform_list:
+        if is_attend is not None:
+            infor.is_attend = is_attend
+        if payment_status is not None:
+            infor.payment_status = payment_status
+        if reg_confirm is not None:
+            infor.reg_confirm = reg_confirm
+
+        if five_digits is not None:
+            if  len(five_digits)==5: 
+                infor.five_digits = five_digits
+            else:
+                return {"msg": "five_digits must be five_digits", "code": 500}
+        await infor.save()
+
+    return {"msg": "success", "code": 200, "user_id": infor.user_id,"event_id": infor.event_id}
+
 @registration.get("/get_registration")
 async def get_registration(
     user_id = Depends(check_token),
@@ -278,24 +357,27 @@ async def get_user_information(
     get_all : int = 0,
     get_detail_information : int = 1
 ):
-    try: 
+    try:
         if not user_id :
             return  {"msg": "no access", "code": 200}
         
         try:
-            if get_all:
+            if get_all == 1:
                 user_list = await User.all()
             else:
-                user_list = await User.filter(id = user_id)
+                user_list = await User.filter(id = user_id).all()
         except:
             return  {"msg": "user table run fail", "code": 500}
 
         user_inform_list = []
+        
         for user_obj in user_list:
+            
             user_inform = {
                     "user_id" : user_obj.id,
                     "user_name" : user_obj.username,
-                    "email" : user_obj.email
+                    "email" : user_obj.email,
+                    "is_superuser" :user_obj.is_superuser
                 }
 
             if get_detail_information:
@@ -321,6 +403,27 @@ async def get_user_information(
     except Exception as e:
         return {"msg": str(e), "code": 500}
 
+@registration.post("/update_superuser")
+async def update_superuser(
+	
+	change_id : int ,
+	is_superuser : int ,
+	user_id = Depends(check_token),
+):
+    if not user_id :
+        return  {"msg": "no exit", "code": 200}
+    user = await User.get(id=user_id)
+
+    if user.is_superuser != 2:
+        return  {"msg": "no access", "code": 200}
+    user_list = await User.filter(id = change_id).all()
+    for infor in user_list:
+        if is_superuser is not None:
+            infor.is_superuser = is_superuser
+        await infor.save()
+    return {"msg": "success", "code": 200}
+
+
 @registration.get("/change_class_reg_number")
 async def change_class_reg_number(
     event_id: int = 0,
@@ -337,7 +440,8 @@ async def change_class_reg_number(
             except Exception as e:
                 return {"msg": "no this class' number limit", "code": 200}
             
-            if class_date.amount_left ==0 and reduce_number>0:
+            #if class_date.amount_left ==0 and reduce_number>0:
+            if class_date.amount_left ==0:
                 return {"msg": "class is full", "code": 200,"amount_left":-1}
             elif class_date.amount_left == class_date.number_limit and reduce_number<0:
                 return {"msg": "class is empty", "code": 200,"amount_left":class_date.amount_left }
@@ -362,7 +466,6 @@ async def input_registration(
             await Class_list.get(id = event_id)
         except Exception as e:
             return {"msg": "no this event", "code": 500}
-
         # if check_if_id_exeit(User_information,user_inform_id):
         #     return {"msg": "no user information", "code": 200}
         
@@ -372,24 +475,59 @@ async def input_registration(
             await User_information.get(user_id=user_id)
         except:
             return  {"msg": "no user information", "code": 500}
+        try:
+            existing_registration = await Registration.get(
+                event_id=event_id,
+                user_id=user_id
+            )
+            new_registration = existing_registration 
+            is_register = 0
+        except:
+            existing_registration = None
         
-        new_registration = await Registration.get_or_create(
-            event_id = event_id,
-            user_id = user_id,
-            defaults = {
-                "reg_confirm" : 0,
-                "is_del" : 0 ,
-                "create_time" : datetime.now()
-            }
-        )
+        if existing_registration is None:
+            is_register = 1
 
-        if new_registration[1]:
+        if is_register:
             amount_left_obj = await change_class_reg_number(event_id=event_id)
             msg = amount_left_obj["msg"]
         else:
             msg = "already registrate"
 
-        return {"msg": msg, "code": 200,"new_registration_id":new_registration[0].id,"is_already_exist":not new_registration[1]}
+        if msg == 'success':
+            new_registration = await Registration.create(
+                	event_id=event_id,
+                	user_id=user_id,
+                	reg_confirm=0,
+                	is_del=0,
+                	create_time=datetime.now(),
+			is_attend = 0,
+                	payment_status = 0
+
+           )
+            return {"msg": msg, "code": 200,"new_registration_id":new_registration.id,"is_already_exist":not is_register}
+        else:
+            return {"msg": msg, "code": 200,"new_registration_id":None,"is_already_exist":not is_register}
+
+        
+        #new_registration = await Registration.get_or_create(
+        #    event_id = event_id,
+        #    user_id = user_id,
+        #    defaults = {
+        #        "reg_confirm" : 0,
+        #        "is_del" : 0 ,
+        #        "create_time" : datetime.now(),
+	#	
+        #    }
+        #)
+        #print(new_registration)      
+
+        #if new_registration[1]:
+        
+
+        #return {"msg": msg, "code": 200,"new_registration_id":new_registration[0].id,"is_already_exist":not new_registration[1]}
+        #return {"msg": msg, "code": 200,"new_registration_id":new_registration.id,"is_already_exist":not is_register}
+
     except Exception as e:
         return {"msg": str(e), "code": 500}
     
@@ -544,5 +682,27 @@ async def get_user_resume(
         data = user_resume.show_data()
         
         return {"msg": "success" , "code": 200,"user_resume":data}
+    except Exception as e:
+        return {"msg": str(e), "code": 500} 
+        
+@registration.post("/delete_user")
+async def get_user_resume(
+    
+    user_id : Optional[int] = None,
+    check_user_id = Depends(check_token)
+):
+    try:
+        #inform_list =  await Registration.filter(event_id=event_id,is_del=0,reg_confirm=1).all() #use for 8/25 after
+        check_list1 = await User.get(id = check_user_id).all()
+   
+        if 2!=check_list1.is_superuser:
+            if check_list2.create_user_id !=check_user_id:
+                return {"msg": "permissions denied", "code": 200,"registrations":[]}
+        
+        await User.filter(user_id = user_id).delete()
+
+        
+        
+        return {"msg": "success" , "code": 200}
     except Exception as e:
         return {"msg": str(e), "code": 500} 

+ 441 - 383
app/api/users.py

@@ -1,383 +1,441 @@
-from fastapi import APIRouter, Form, Depends, HTTPException, Body
-from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
-from app.models.models import User, UserPydantic
-from app.api import deps
-from sqlalchemy.orm import Session
-from typing import Any, Dict, Optional
-import secrets
-from fastapi_login.exceptions import InvalidCredentialsException
-from fastapi_login import LoginManager
-from datetime import timedelta,datetime
-from app.config import settings
-from pathlib import Path
-from jose import jwt
-import emails
-from emails.template import JinjaTemplate
-import logging
-import bcrypt
-
-from app.crud import crud_users
-import smtplib
-from email.mime.text import MIMEText
-from google.oauth2 import id_token
-from google.auth.transport import requests
-from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
-from fastapi.security.utils import get_authorization_scheme_param
-
-
-
-users = APIRouter()
-
-SECRET: str = secrets.token_urlsafe(32)
-manager = LoginManager(SECRET, '/login',default_expiry=timedelta(hours=72))
-
-
-@manager.user_loader()
-async def query_user(user_id: str):
-    """
-    Get a user from the db
-    :param user_id: E-Mail of the user
-    :return: None or the user object
-    """
-    # result = await User.filter(email=user_id,is_active=1).first()
-    result = await User.filter(email=user_id).first()
-
-    if not result:
-        print('無此筆資料')
-        return None
-    return result
-
-
-#@manager.user_loader()
-async def query_user_username(user_id: str):
-    """
-    Get a user from the db
-    :param user_id: E-Mail of the user
-    :return: None or the user object
-    """
-    result = await User.filter(username=user_id).first()
-    if not result:
-        print('無此筆資料')
-        return None
-
-    return result
-
-
-@users.post("/login")
-async def login(data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(deps.get_db), position: str=Form(default='')):
-
-    email = data.username
-    password = data.password
-
-    user = await query_user(email)
-    user_pydantic = UserPydantic.from_orm(user)
-    user_dict = user_pydantic.dict(exclude_unset=True)
-    access_token = manager.create_access_token(
-        data={'sub': email}
-    )
-
-    if not user:
-        # you can return any response or error of your choice
-        return {"message":"查無此人"}
-
-    # elif password != user.password:
-    #     raise InvalidCredentialsException
-    else:
-        user_dict.update({"token":access_token})
-        token_update = user.update_from_dict(user_dict)
-        await user.save()
-        stored_hashed_password = user.password.encode('utf-8')
-        if bcrypt.checkpw(password.encode('utf-8'),stored_hashed_password):
-            return {'msg':'登入成功','code':'200','access_token': access_token,'username':user.username,'email':user.email,'points':user.points}
-        else:
-            return {"message": "Invalid username or password"}
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="https://oauth2.googleapis.com/token")
-
-CLIENT_ID = settings.CLIENT_ID
-@users.post("/login/google/access-token")
-async def login(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), position: str = Form(default=''),
-    ) -> Any:
-    """
-    OAuth2 compatible token login, get an access token for future requests
-    """
-    access_token = manager.create_access_token(
-        data={'sub': username}
-    )
-    user = await User.filter(email=email).first() # 確認信箱是否已存在
-    if not user:
-        u = await User.create(username=username, password=password, email=email,token=access_token, is_superuser=0, points=0,is_active =1)
-        create_user = u
-    # if user:
-    #     print('已用相同信箱註冊過,再開一個GMAIL帳號')
-    #     u = await User.create(username=username, password=password,email=email)
-    user_pydantic = UserPydantic.from_orm(user)
-    user_dict = user_pydantic.dict(exclude_unset=True)
-    user_dict.update({"token": access_token})
-    token_update = user.update_from_dict(user_dict)
-    await user.save()
-
-    return_msg = {
-        "access_token": access_token,
-        "token_type": "bearer",
-        'code':'200',
-    }
-    return return_msg
-    # if add_time_code:
-    #     available_ser_no = crud.serial_number.available(db, ser_no=add_time_code)
-    #     print(available_ser_no)
-    #     if available_ser_no:
-    #         user_in = schemas.UserUpdate(available_time=user.available_time + available_ser_no.time)
-    #         crud.user.update(db, db_obj=user, obj_in=user_in)
-    #
-    #         ser_no_in = schemas.SerialNumberUpdate(code=available_ser_no.code, is_used=True,
-    #                                                used_datetime=str(datetime.now()), owner_id=user.id)
-    #         crud.serial_number.update(db, db_obj=available_ser_no, obj_in=ser_no_in)
-    #         print(available_ser_no.time, type(available_ser_no.time))
-    #         return_msg['time_added'] = available_ser_no.time
-    #     else:
-    #         return_msg['time_added'] = -1
-    # return return_msg
-
-@users.post("/logout")
-async def logout():
-
-    return {"msg":"logout success","code":200}
-
-@users.post("/add") # 寄認證信
-async def add(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), re_password: str = Form(default='')):
-    if username and password and email:
-        user_email = await query_user(email)
-        user_username = await query_user_username(username)
-
-        if user_email or user_username:
-            return {"msg":"該信箱或使用者名稱已存在","code":403}
-        # elif user_username:
-        #     return {"msg":"該使用者名稱已存在","code":403}
-        else:
-            if password == re_password:
-                # access_token = manager.create_access_token(
-                #     data={'sub': email}
-                # )
-                print('前',settings.SECRET_KEY)
-                expiration_time = datetime.utcnow() + timedelta(hours=0.5)
-                access_token = jwt.encode({'email':email,'exp':expiration_time}, settings.SECRET_KEY, algorithm="HS256")
-                hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
-                u = await User.create(username=username, password=hashed_password, email=email,is_superuser=0,token=access_token,points=0,is_active=1)
-                if u:
-                    # message = '註冊認證'
-                    message = f"請點擊以下連結完成註冊流程:\n\nhttps://cmm.ai:8088/api/verify?token={access_token}"
-                    subject = '註冊信'
-                    print(message)
-                    send_email(email,access_token,subject,message)
-
-                    return {"msg": "已寄送註冊信", "code": 200}
-                else:
-                    return {"msg": "未寄出註冊信", "code":403}
-            else:
-                return {"msg":"確認密碼錯誤","code":403}
-
-    return {"msg": "create user failed", "code": 403}
-
-
-@users.get("/verify") # 註冊認證確認
-async def verify_email(token:str):
-    try:
-        print(token)
-        print('後',settings.SECRET_KEY)
-        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
-        print('解密結果',payload)
-        email = payload["email"]
-        # is_active True
-        user = await User.filter(email=email,is_active=0).first()
-        if user:
-            user_pydantic = UserPydantic.from_orm(user)
-            user_dict = user_pydantic.dict(exclude_unset=True)
-            user_dict.update({"is_active": 1})
-            is_active_update = user.update_from_dict(user_dict)
-            await user.save()
-            result = '信箱驗證成功'
-        else:
-            result = '信箱驗證失敗'
-
-        return {"message": result}
-    except:
-        raise  HTTPException(status_code=400)
-    # except jwt.ExpiredSignatureError:
-    #     raise HTTPException(status_code=400, detail="token已失效")
-    # except jwt.DecodeError:
-    #     raise HTTPException(status_code=400, detail="無效token")
-
-
-def generate_password_reset_token(email: str) -> str:
-    delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
-    now = datetime.utcnow()
-    expires = now + delta
-    exp = expires.timestamp()
-    encoded_jwt = jwt.encode(
-        {"exp": exp, "nbf": now, "sub": email}, settings.SECRET_KEY, algorithm="HS256",)
-    print(encoded_jwt)
-    return encoded_jwt
-
-def verify_password_reset_token(token: str):
-    try:
-        decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
-        print(decoded_token)
-        return decoded_token["sub"]
-    except jwt.JWTError:
-        return None
-
-
-def send_email(
-    email_to: str,
-    token: str,
-    subject_template: str = "",
-    html_template: str = "",
-    environment: Dict[str, Any] = {},
-):
-    # message = emails.Message(
-    #     subject=JinjaTemplate(subject_template),
-    #     html=JinjaTemplate(html_template),
-    #     mail_from=(settings.EMAILS_FROM_NAME, settings.EMAILS_FROM_EMAIL),
-    # )
-
-    message = emails.Message(
-        subject=JinjaTemplate(subject_template),
-        html=JinjaTemplate(html_template),
-        mail_from=(settings.EMAILS_FROM_NAME, settings.EMAILS_FROM_EMAIL),
-    )
-    smtp_options = {"host": settings.SMTP_HOST, "port": settings.SMTP_PORT}
-    if settings.SMTP_TLS:
-        smtp_options["tls"] = True
-    if settings.SMTP_USER:
-        smtp_options["user"] = settings.SMTP_USER
-    if settings.SMTP_PASSWORD:
-        smtp_options["password"] = settings.SMTP_PASSWORD
-    response = message.send(to=email_to, render=environment, smtp=smtp_options)
-    print('RResponse',response)
-    return {"message":f"send email result: {response}"}
-    # logging.info(f"send email result: {response}")
-    # email_content = MIMEText(message)
-    # email_content["Subject"] = subject
-    # email_content["From"] = 'zooey@choozmo.com'
-    # email_content["To"] = email_to
-    # try:
-    #     print('測試成功')
-    #     # Connect to the SMTP server
-    #     smtp_server = smtplib.SMTP(settings.SMTP_HOST, settings.SMTP_PORT)
-    #     smtp_server.starttls()
-    #
-    #     # Login to the email account
-    #     smtp_server.login(settings.SMTP_HOST, settings.SMTP_PASSWORD)
-    #
-    #     # Send the email
-    #     smtp_server.sendmail(settings.SMTP_HOST, email_to, email_content.as_string())
-    #
-    #     # Close the connection
-    #     smtp_server.quit()
-    #
-    #     return {"message": "Email sent successfully."}
-    # except Exception as e:
-    #     print('測試失敗')
-
-
-def create_singup_url():
-    url=''
-    return url
-
-def send_reset_password_email(email_to: str, email: str, token: str) -> None:
-    subject = f"Password recovery for user {email}"
-    with open(Path(settings.EMAIL_TEMPLATES_DIR) / "reset_password.html") as f:
-        template_str = f.read()
-    server_host = settings.SERVER_HOST
-    link = f"{server_host}/reset-password?token={token}"
-    message = '重新設定密碼'
-    send_email(
-        email_to=email_to,
-        subject_template=subject,
-        html_template=template_str,
-        environment={
-            "project_name": settings.PROJECT_NAME,
-            "username": email,
-            "email": email_to,
-            "valid_hours": settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS,
-            "link": link,
-        },
-    )
-
-
-@users.post("/password-recovery/{email}")
-async def recover_password(email:str):
-    user = await User.filter(email=email).first()
-    if not user:
-        raise HTTPException(
-            status_code=404,
-            detail="The user with this username does not exist in the system.",
-        )
-    password_reset_token = generate_password_reset_token(email=email)
-    send_reset_password_email(
-        email_to=user.email, email=email, token=password_reset_token
-    )
-    return {"msg": "Password recovery email sent"}
-
-
-from pydantic import BaseModel
-
-
-class Msg(BaseModel):
-    msg: str
-@users.post("/reset-password/", response_model=Msg)
-async def reset_password(
-    token: str = Body(...),
-    new_password: str = Body(...),
-    db: Session = Depends(deps.get_db),
-) -> Any:
-    """
-    Reset password
-    """
-    email = verify_password_reset_token(token)
-    print(email)
-    if not email:
-        raise HTTPException(status_code=400, detail="Invalid token")
-    # user = await query_user(email)
-    user = await User.filter(email=email).first()
-
-    if not user:
-        raise HTTPException(
-            status_code=404,
-            detail="The user with this username does not exist in the system.",
-        )
-    # elif not crud.user.is_active(user):
-    #     raise HTTPException(status_code=400, detail="Inactive user")
-    hashed_password = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
-    user.password = hashed_password
-    # db.add(user)
-    db.commit()
-    print(user.password)
-    db.close()
-    return {"msg": "Password updated successfully"}
-
-
-
-@users.get("/delete_user/{id}")
-async def delete(id: int):
-    if id:
-        await User.filter(id=id).delete()
-        return {"msg": "success", "code": 200}
-
-    return {"msg": "failed", "code": 400}
-
-
-@users.get("/information")
-async def get_information(token:str):
-    result = await User.filter(token=token).first()
-    return {"msg":result, "code":200}
-
-@users.get("/protect")    
-def protected_route(user=Depends(manager)):
-    if user is None:
-        return {'message': "no access"}
-    return {'user': user}
-
-
-
+from fastapi import APIRouter, Form, Depends, HTTPException, Body
+from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
+from app.models.models import User, UserPydantic
+from app.api import deps
+from sqlalchemy.orm import Session
+from typing import Any, Dict, Optional
+import secrets
+from fastapi_login.exceptions import InvalidCredentialsException
+from fastapi_login import LoginManager
+from datetime import timedelta,datetime
+from app.config import settings
+from pathlib import Path
+from jose import jwt
+import emails
+from emails.template import JinjaTemplate
+import logging
+import bcrypt
+
+from app.crud import crud_users
+import smtplib
+from email.mime.text import MIMEText
+from google.oauth2 import id_token
+from google.auth.transport import requests
+from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
+from fastapi.security.utils import get_authorization_scheme_param
+import rpyc
+
+
+users = APIRouter()
+
+SECRET: str = secrets.token_urlsafe(32)
+manager = LoginManager(SECRET, '/login',default_expiry=timedelta(hours=72))
+
+
+
+
+async def check_token(access_token: str):
+
+    result = await User.filter(token=access_token).first()
+    
+    if not result:
+        print("no access")
+        return None
+    
+    user_id = result.id
+
+    return user_id
+
+
+
+
+@manager.user_loader()
+async def query_user(user_id: str):
+    """
+    Get a user from the db
+    :param user_id: E-Mail of the user
+    :return: None or the user object
+    """
+    # result = await User.filter(email=user_id,is_active=1).first()
+    result = await User.filter(email=user_id).first()
+
+    if not result:
+        print('無此筆資料')
+        return None
+    return result
+
+
+#@manager.user_loader()
+async def query_user_username(user_id: str):
+    """
+    Get a user from the db
+    :param user_id: E-Mail of the user
+    :return: None or the user object
+    """
+    result = await User.filter(username=user_id).first()
+    if not result:
+        print('無此筆資料')
+        return None
+
+    return result
+
+
+@users.post("/login")
+async def login(data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(deps.get_db), position: str=Form(default='')):
+
+    email = data.username
+    password = data.password
+
+    user = await query_user(email)
+    user_pydantic = UserPydantic.from_orm(user)
+    user_dict = user_pydantic.dict(exclude_unset=True)
+    access_token = manager.create_access_token(
+        data={'sub': email}
+    )
+
+    if not user:
+        # you can return any response or error of your choice
+        return {"message":"查無此人"}
+
+    # elif password != user.password:
+    #     raise InvalidCredentialsException
+    else:
+        user_dict.update({"token":access_token})
+        token_update = user.update_from_dict(user_dict)
+        await user.save()
+        stored_hashed_password = user.password.encode('utf-8')
+        if bcrypt.checkpw(password.encode('utf-8'),stored_hashed_password):
+            return {'msg':'登入成功','code':'200','access_token': access_token,'username':user.username,'email':user.email,'points':user.points}
+        else:
+            return {"message": "Invalid username or password"}
+
+oauth2_scheme = OAuth2PasswordBearer(tokenUrl="https://oauth2.googleapis.com/token")
+
+CLIENT_ID = settings.CLIENT_ID
+@users.post("/login/google/access-token")
+async def login(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), position: str = Form(default=''),
+    ) -> Any:
+    """
+    OAuth2 compatible token login, get an access token for future requests
+    """
+    access_token = manager.create_access_token(
+        data={'sub': username}
+    )
+    user = await User.filter(email=email).first() # 確認信箱是否已存在
+    if not user:
+        u = await User.create(username=username, password=password, email=email,token=access_token, is_superuser=0, points=0,is_active =1)
+        create_user = u
+    # if user:
+    #     print('已用相同信箱註冊過,再開一個GMAIL帳號')
+    #     u = await User.create(username=username, password=password,email=email)
+    user_pydantic = UserPydantic.from_orm(user)
+    user_dict = user_pydantic.dict(exclude_unset=True)
+    user_dict.update({"token": access_token})
+    token_update = user.update_from_dict(user_dict)
+    await user.save()
+
+    return_msg = {
+        "access_token": access_token,
+        "token_type": "bearer",
+        'code':'200',
+    }
+    return return_msg
+    # if add_time_code:
+    #     available_ser_no = crud.serial_number.available(db, ser_no=add_time_code)
+    #     print(available_ser_no)
+    #     if available_ser_no:
+    #         user_in = schemas.UserUpdate(available_time=user.available_time + available_ser_no.time)
+    #         crud.user.update(db, db_obj=user, obj_in=user_in)
+    #
+    #         ser_no_in = schemas.SerialNumberUpdate(code=available_ser_no.code, is_used=True,
+    #                                                used_datetime=str(datetime.now()), owner_id=user.id)
+    #         crud.serial_number.update(db, db_obj=available_ser_no, obj_in=ser_no_in)
+    #         print(available_ser_no.time, type(available_ser_no.time))
+    #         return_msg['time_added'] = available_ser_no.time
+    #     else:
+    #         return_msg['time_added'] = -1
+    # return return_msg
+
+@users.post("/logout")
+async def logout():
+
+    return {"msg":"logout success","code":200}
+
+@users.post("/add") # 寄認證信
+async def add(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), re_password: str = Form(default='')):
+    if username and password and email:
+        user_email = await query_user(email)
+        user_username = await query_user_username(username)
+
+        if user_email or user_username:
+            return {"msg":"該信箱或使用者名稱已存在","code":403}
+        # elif user_username:
+        #     return {"msg":"該使用者名稱已存在","code":403}
+        else:
+            if password == re_password:
+                # access_token = manager.create_access_token(
+                #     data={'sub': email}
+                # )
+                print('前',settings.SECRET_KEY)
+                expiration_time = datetime.utcnow() + timedelta(hours=0.5)
+                access_token = jwt.encode({'email':email,'exp':expiration_time}, settings.SECRET_KEY, algorithm="HS256")
+                hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
+                u = await User.create(username=username, password=hashed_password, email=email,is_superuser=0,token=access_token,points=0,is_active=0)
+                if u:
+                    # message = '註冊認證'
+                    message = f"請點擊以下連結完成註冊流程:\n\nhttps://cmm.ai:8088/api/verify?token={access_token}"
+                    subject = '註冊信'
+                    print(message)
+                    send_email(email,access_token,subject,message)
+
+                    return {"msg": "已寄送註冊信", "code": 200}
+                else:
+                    return {"msg": "未寄出註冊信", "code":403}
+            else:
+                return {"msg":"確認密碼錯誤","code":403}
+
+    return {"msg": "create user failed", "code": 403}
+
+
+@users.get("/verify") # 註冊認證確認
+async def verify_email(token:str):
+    try:
+        print(token)
+        print('後',settings.SECRET_KEY)
+        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
+        print('解密結果',payload)
+        email = payload["email"]
+        # is_active True
+        user = await User.filter(email=email,is_active=0).first()
+        if user:
+            user_pydantic = UserPydantic.from_orm(user)
+            user_dict = user_pydantic.dict(exclude_unset=True)
+            user_dict.update({"is_active": 1})
+            is_active_update = user.update_from_dict(user_dict)
+            await user.save()
+            result = '信箱驗證成功'
+        else:
+            result = '信箱驗證失敗'
+
+        return {"message": result}
+    except:
+        raise  HTTPException(status_code=400)
+    # except jwt.ExpiredSignatureError:
+    #     raise HTTPException(status_code=400, detail="token已失效")
+    # except jwt.DecodeError:
+    #     raise HTTPException(status_code=400, detail="無效token")
+
+
+def generate_password_reset_token(email: str) -> str:
+    delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
+    now = datetime.utcnow()
+    expires = now + delta
+    exp = expires.timestamp()
+    encoded_jwt = jwt.encode(
+        {"exp": exp, "nbf": now, "sub": email}, settings.SECRET_KEY, algorithm="HS256",)
+    print(encoded_jwt)
+    return encoded_jwt
+
+def verify_password_reset_token(token: str):
+    try:
+        decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
+        print(decoded_token)
+        return decoded_token["sub"]
+    except jwt.JWTError:
+        return None
+
+
+def send_email(
+    email_to: str,
+    token: str,
+    subject_template: str = "",
+    html_template: str = "",
+    environment: Dict[str, Any] = {},
+):
+    # message = emails.Message(
+    #     subject=JinjaTemplate(subject_template),
+    #     html=JinjaTemplate(html_template),
+    #     mail_from=(settings.EMAILS_FROM_NAME, settings.EMAILS_FROM_EMAIL),
+    # )
+
+    
+    subject=subject_template
+    html=html_template
+    mailobj={}
+    mailobj['toaddr']=email_to
+    mailobj['title']=subject
+    mailobj['totext']=html
+
+    conn = rpyc.connect("192.168.192.80", 12345)
+    conn.root.mailto(mailobj)
+    return {"message":f"send email"}
+
+
+    #message = emails.Message(
+    #    subject=JinjaTemplate(subject_template),
+    #    html=JinjaTemplate(html_template),
+    #    mail_from=(settings.EMAILS_FROM_NAME, settings.EMAILS_FROM_EMAIL),
+    #)
+    #smtp_options = {"host": settings.SMTP_HOST, "port": settings.SMTP_PORT}
+    #if settings.SMTP_TLS:
+    #    smtp_options["tls"] = True
+    #if settings.SMTP_USER:
+    #    smtp_options["user"] = settings.SMTP_USER
+    #if settings.SMTP_PASSWORD:
+    #    smtp_options["password"] = settings.SMTP_PASSWORD
+    #response = message.send(to=email_to, render=environment, smtp=smtp_options)
+    #print('RResponse',response)
+    #return {"message":f"send email result: {response}"}
+
+
+
+
+
+    # logging.info(f"send email result: {response}")
+    # email_content = MIMEText(message)
+    # email_content["Subject"] = subject
+    # email_content["From"] = 'zooey@choozmo.com'
+    # email_content["To"] = email_to
+    # try:
+    #     print('測試成功')
+    #     # Connect to the SMTP server
+    #     smtp_server = smtplib.SMTP(settings.SMTP_HOST, settings.SMTP_PORT)
+    #     smtp_server.starttls()
+    #
+    #     # Login to the email account
+    #     smtp_server.login(settings.SMTP_HOST, settings.SMTP_PASSWORD)
+    #
+    #     # Send the email
+    #     smtp_server.sendmail(settings.SMTP_HOST, email_to, email_content.as_string())
+    #
+    #     # Close the connection
+    #     smtp_server.quit()
+    #
+    #     return {"message": "Email sent successfully."}
+    # except Exception as e:
+    #     print('測試失敗')
+
+
+def create_singup_url():
+    url=''
+    return url
+
+def send_reset_password_email(email_to: str, email: str, token: str) -> None:
+    subject = f"Password recovery for user {email}"
+    with open(Path(settings.EMAIL_TEMPLATES_DIR) / "reset_password.html") as f:
+        template_str = f.read()
+    server_host = settings.SERVER_HOST
+    link = f"{server_host}/reset-password?token={token}"
+    message = '重新設定密碼'
+    send_email(
+        email_to=email_to,
+        subject_template=subject,
+        html_template=template_str,
+        environment={
+            "project_name": settings.PROJECT_NAME,
+            "username": email,
+            "email": email_to,
+            "valid_hours": settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS,
+            "link": link,
+        },
+    )
+
+
+@users.post("/password-recovery/{email}")
+async def recover_password(email:str):
+    user = await User.filter(email=email).first()
+    if not user:
+        raise HTTPException(
+            status_code=404,
+            detail="The user with this username does not exist in the system.",
+        )
+    password_reset_token = generate_password_reset_token(email=email)
+    send_reset_password_email(
+        email_to=user.email, email=email, token=password_reset_token
+    )
+    return {"msg": "Password recovery email sent"}
+
+
+from pydantic import BaseModel
+
+
+class Msg(BaseModel):
+    msg: str
+@users.post("/reset-password/", response_model=Msg)
+async def reset_password(
+    token: str = Body(...),
+    new_password: str = Body(...),
+    db: Session = Depends(deps.get_db),
+) -> Any:
+    """
+    Reset password
+    """
+    email = verify_password_reset_token(token)
+    print(email)
+    if not email:
+        raise HTTPException(status_code=400, detail="Invalid token")
+    # user = await query_user(email)
+    user = await User.filter(email=email).first()
+
+    if not user:
+        raise HTTPException(
+            status_code=404,
+            detail="The user with this username does not exist in the system.",
+        )
+    # elif not crud.user.is_active(user):
+    #     raise HTTPException(status_code=400, detail="Inactive user")
+    hashed_password = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
+    user.password = hashed_password
+    # db.add(user)
+    db.commit()
+    print(user.password)
+    db.close()
+    return {"msg": "Password updated successfully"}
+
+
+
+@users.get("/delete_user/{id}")
+async def delete(
+id: int,
+user_id = Depends(check_token)
+):
+    if not user_id :
+        return  {"msg": "no exit", "code": 200}
+    user = await User.get(id=user_id)
+
+    if user.is_superuser != 2:
+        return  {"msg": "no access", "code": 200}
+
+    if id:
+        await User.filter(id=id).delete()
+        return {"msg": "success", "code": 200}
+
+    return {"msg": "failed", "code": 400}
+
+
+@users.get("/information")
+async def get_information(token:str):
+    result = await User.filter(token=token).first()
+    return {"msg":result, "code":200}
+
+@users.get("/protect")    
+def protected_route(user=Depends(manager)):
+    if user is None:
+        return {'message': "no access"}
+    return {'user': user}
+
+
+
+@users.get("/check_user")
+async def check_user(
+user_id = Depends(check_token)
+):
+    user = await User.get(id=user_id)
+
+    return {"msg": "success", "code": 200,"is_super":user.is_superuser}
+
+
+
+
+
+