test
This commit is contained in:
parent
1dc97cafd7
commit
20e76c4ca9
4
app.log
4
app.log
|
|
@ -0,0 +1,4 @@
|
|||
[2025-03-28 09:32:26,371] [DEBUG] Initializing LoginDialog...
|
||||
[2025-03-28 09:32:26,372] [DEBUG] Entering LoginDialog.create_dialog()
|
||||
[2025-03-28 09:32:26,373] [DEBUG] Exiting LoginDialog.create_dialog()
|
||||
[2025-03-28 09:32:26,373] [DEBUG] LoginDialog.show() 호출됨
|
||||
210
main.py
210
main.py
|
|
@ -1,203 +1,39 @@
|
|||
import flet as ft
|
||||
from modules import logger, login, backend, product_filter, export
|
||||
from modules import logger, login
|
||||
from modules.setting_manager import SettingsManager
|
||||
from modules.db_manager import DBeManager
|
||||
import logging
|
||||
|
||||
# 전역 변수 (데모용 데이터 저장)
|
||||
market_list = []
|
||||
sold_products = []
|
||||
filtered_products = []
|
||||
sourced_products = []
|
||||
from modules.db_manager import DBManager
|
||||
from modules.main_window import MainWindow
|
||||
|
||||
def main(page: ft.Page):
|
||||
page.title = "Modern Market and Product Manager"
|
||||
page.window_width = 1000
|
||||
page.window_height = 700
|
||||
|
||||
# 하단 로그 출력용 텍스트 위젯
|
||||
log_display = ft.Text(value="", size=12)
|
||||
# GUI 로그 콜백 (단순 콘솔 출력)
|
||||
def gui_log_callback(formatted_message: str):
|
||||
log_display.value += formatted_message + "\n"
|
||||
page.update()
|
||||
print(formatted_message)
|
||||
|
||||
# 로거, 설정 관리자, SupabaseManager 초기화
|
||||
# 로거, 설정 관리자, DBManager 초기화
|
||||
app_logger = logger.get_logger(gui_callback=gui_log_callback)
|
||||
settings_manager = SettingsManager()
|
||||
supabase_manager = DBeManager(app_logger)
|
||||
db_manager = DBManager(app_logger)
|
||||
|
||||
# 로그인 다이얼로그 실행 (비동기)
|
||||
async def do_login():
|
||||
login_dialog = login.LoginDialog(page, app_logger, settings_manager, supabase_manager)
|
||||
logged_in = await login_dialog.show()
|
||||
if logged_in:
|
||||
page.controls.clear()
|
||||
page.add(ft.Text("로그인 성공! 메인 화면입니다."), log_display)
|
||||
else:
|
||||
page.add(ft.Text("로그인 실패!"), log_display)
|
||||
page.async_run(do_login)
|
||||
|
||||
# 마켓 탭 UI 구성
|
||||
market_tab_content = ft.Column([
|
||||
ft.Row([
|
||||
ft.ElevatedButton("마켓목록 가져오기", on_click=lambda e: load_market_list(page)),
|
||||
ft.ElevatedButton("팔린상품 가져오기", on_click=lambda e: load_sold_products(page)),
|
||||
ft.ElevatedButton("마켓추가하기", on_click=lambda e: add_market(page))
|
||||
]),
|
||||
ft.DataTable(
|
||||
columns=[
|
||||
ft.DataColumn(ft.Text("마켓이름")),
|
||||
ft.DataColumn(ft.Text("마켓 URL")),
|
||||
ft.DataColumn(ft.Text("메모"))
|
||||
],
|
||||
rows=[],
|
||||
expand=True,
|
||||
key="market_table"
|
||||
)
|
||||
], scroll=ft.ScrollMode.AUTO)
|
||||
|
||||
# 상품 탭 UI 구성
|
||||
product_tab_content = ft.Column([
|
||||
ft.Row([
|
||||
ft.ElevatedButton("금지어필터링", on_click=lambda e: filter_forbidden(page)),
|
||||
ft.ElevatedButton("카테고리 필터링", on_click=lambda e: filter_category(page)),
|
||||
ft.Dropdown(
|
||||
label="소싱몰 목록",
|
||||
options=[
|
||||
ft.dropdown.Option("타오바오"),
|
||||
ft.dropdown.Option("1688")
|
||||
],
|
||||
key="sourcing_market"
|
||||
),
|
||||
ft.ElevatedButton("소싱하기", on_click=lambda e: sourcing_products(page)),
|
||||
ft.ElevatedButton("출력", on_click=lambda e: export_products(page))
|
||||
]),
|
||||
ft.DataTable(
|
||||
columns=[
|
||||
ft.DataColumn(ft.Text("상품명")),
|
||||
ft.DataColumn(ft.Text("카테고리")),
|
||||
ft.DataColumn(ft.Text("이미지 URL")),
|
||||
ft.DataColumn(ft.Text("소싱 URL"))
|
||||
],
|
||||
rows=[],
|
||||
expand=True,
|
||||
key="product_table"
|
||||
)
|
||||
], scroll=ft.ScrollMode.AUTO)
|
||||
|
||||
# 금지어 관리 탭 (추후 구현)
|
||||
forbidden_tab_content = ft.Column([
|
||||
ft.Text("금지어 관리 탭 내용 (추후 구현)")
|
||||
])
|
||||
|
||||
# 카테고리 관리 탭 (추후 구현)
|
||||
category_tab_content = ft.Column([
|
||||
ft.Text("카테고리 관리 탭 내용 (추후 구현)")
|
||||
])
|
||||
|
||||
# 메인 탭 생성
|
||||
tabs = ft.Tabs(
|
||||
selected_index=0,
|
||||
tabs=[
|
||||
ft.Tab(text="마켓", content=market_tab_content),
|
||||
ft.Tab(text="상품", content=product_tab_content),
|
||||
ft.Tab(text="금지어 관리", content=forbidden_tab_content),
|
||||
ft.Tab(text="카테고리 관리", content=category_tab_content)
|
||||
],
|
||||
key="main_tabs"
|
||||
)
|
||||
|
||||
# 페이지 레이아웃 구성
|
||||
page.add(tabs, log_display)
|
||||
|
||||
# 로그 추가 함수 (각 모듈에서 호출 가능하도록 page.session에 저장)
|
||||
def append_log(message: str):
|
||||
current = log_display.value
|
||||
log_display.value = current + message + "\n"
|
||||
# 로그인 성공 시 호출될 콜백 함수: 메인윈도우로 전환
|
||||
def on_login_success():
|
||||
page.controls.clear()
|
||||
main_win = MainWindow(page)
|
||||
for ctrl in main_win.controls:
|
||||
page.add(ctrl)
|
||||
page.update()
|
||||
page.session.set("append_log", append_log)
|
||||
|
||||
def load_market_list(page: ft.Page):
|
||||
global market_list
|
||||
page.session.get("append_log")("Fetching market list...")
|
||||
market_list = backend.get_market_list()
|
||||
market_rows = []
|
||||
for m in market_list:
|
||||
row = ft.DataRow(cells=[
|
||||
ft.DataCell(ft.Text(m.get("name", ""))),
|
||||
ft.DataCell(ft.Text(m.get("url", ""))),
|
||||
ft.DataCell(ft.Text(m.get("memo", "")))
|
||||
])
|
||||
market_rows.append(row)
|
||||
market_table: ft.DataTable = page.get_control("market_table")
|
||||
market_table.rows = market_rows
|
||||
page.session.get("append_log")("Market list loaded.")
|
||||
page.update()
|
||||
# 로그인 다이얼로그 생성 및 표시
|
||||
login_dialog = login.LoginDialog(
|
||||
page=page,
|
||||
logger=app_logger,
|
||||
settings_manager=settings_manager,
|
||||
db_manager=db_manager,
|
||||
on_login_success=on_login_success
|
||||
)
|
||||
login_dialog.show()
|
||||
|
||||
def load_sold_products(page: ft.Page):
|
||||
global sold_products, filtered_products, sourced_products
|
||||
page.session.get("append_log")("Fetching sold products for each market...")
|
||||
sold_products = backend.get_sold_products(market_list)
|
||||
filtered_products = sold_products.copy()
|
||||
page.session.get("append_log")("Sold products loaded. Switching to 상품 탭.")
|
||||
update_product_table(page, filtered_products)
|
||||
tabs: ft.Tabs = page.get_control("main_tabs")
|
||||
tabs.selected_index = 1
|
||||
page.update()
|
||||
|
||||
def update_product_table(page: ft.Page, products):
|
||||
product_rows = []
|
||||
for p in products:
|
||||
row = ft.DataRow(cells=[
|
||||
ft.DataCell(ft.Text(p.get("name", ""))),
|
||||
ft.DataCell(ft.Text(p.get("category", ""))),
|
||||
ft.DataCell(ft.Text(p.get("image_url", ""))),
|
||||
ft.DataCell(ft.Text(p.get("sourcing_url", "")))
|
||||
])
|
||||
product_rows.append(row)
|
||||
product_table: ft.DataTable = page.get_control("product_table")
|
||||
product_table.rows = product_rows
|
||||
page.update()
|
||||
|
||||
def add_market(page: ft.Page):
|
||||
page.session.get("append_log")("Add market functionality not implemented yet.")
|
||||
page.update()
|
||||
|
||||
def filter_forbidden(page: ft.Page):
|
||||
global filtered_products
|
||||
page.session.get("append_log")("Filtering products with forbidden words...")
|
||||
filtered_products = product_filter.filter_forbidden_words(filtered_products)
|
||||
update_product_table(page, filtered_products)
|
||||
page.session.get("append_log")("Forbidden words filtering applied.")
|
||||
page.update()
|
||||
|
||||
def filter_category(page: ft.Page):
|
||||
global filtered_products
|
||||
page.session.get("append_log")("Filtering products with forbidden categories...")
|
||||
filtered_products = product_filter.filter_forbidden_categories(filtered_products)
|
||||
update_product_table(page, filtered_products)
|
||||
page.session.get("append_log")("Category filtering applied.")
|
||||
page.update()
|
||||
|
||||
def sourcing_products(page: ft.Page):
|
||||
global sourced_products, filtered_products
|
||||
sourcing_market: ft.Dropdown = page.get_control("sourcing_market")
|
||||
selected_market = sourcing_market.value
|
||||
page.session.get("append_log")(f"Starting sourcing using {selected_market}...")
|
||||
sourced_products = []
|
||||
for product in filtered_products:
|
||||
sourcing_url = backend.sourcing_product(product.get("image_url", ""), selected_market)
|
||||
product["sourcing_url"] = sourcing_url
|
||||
sourced_products.append(product)
|
||||
update_product_table(page, sourced_products)
|
||||
page.session.get("append_log")("Sourcing completed.")
|
||||
page.update()
|
||||
|
||||
def export_products(page: ft.Page):
|
||||
page.session.get("append_log")("Exporting products to Excel...")
|
||||
export.export_to_excel(sourced_products)
|
||||
page.session.get("append_log")("Products exported and folder opened.")
|
||||
page.update()
|
||||
|
||||
if __name__ == "__main__":
|
||||
ft.app(target=main)
|
||||
ft.app(target=main)
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -4,7 +4,7 @@ from datetime import datetime, timezone
|
|||
import logging
|
||||
import traceback
|
||||
|
||||
class DBeManager:
|
||||
class DBManager:
|
||||
"""
|
||||
SupabaseManager는 Supabase 클라이언트를 래핑하여 로그인, 사용자 정보 조회,
|
||||
마지막 로그인 시간 업데이트 등 여러 API 호출을 수행합니다.
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
import flet as ft
|
||||
from flet import (
|
||||
AlertDialog, TextField, Checkbox, ElevatedButton, Text, Column, Row,
|
||||
MainAxisAlignment
|
||||
)
|
||||
import asyncio
|
||||
from flet import AlertDialog, TextField, Checkbox, ElevatedButton, Text, Column, Row, MainAxisAlignment
|
||||
import logging
|
||||
|
||||
class LoginDialog:
|
||||
"""
|
||||
flet 기반 로그인 다이얼로그.
|
||||
|
||||
- 이메일, 비밀번호 입력란
|
||||
- "정보 저장" 체크박스 (체크 시, SettingsManager를 통해 사용자 정보를 저장)
|
||||
- "비밀번호 보기" 체크박스 (비밀번호 입력란 에코 모드 전환)
|
||||
- 로그인 및 비밀번호 찾기 버튼
|
||||
- 이메일, 비밀번호 입력란
|
||||
- "정보 저장" 체크박스 (SettingsManager에 저장)
|
||||
- "비밀번호 보기" 체크박스 (비밀번호 에코 모드 전환)
|
||||
- 로그인 및 비밀번호 찾기 버튼
|
||||
DBManager를 호출해 실제 로그인을 수행하며, 로그인 성공 시 on_login_success 콜백을 호출합니다.
|
||||
"""
|
||||
def __init__(self, page: ft.Page, logger: logging.Logger, settings_manager, supabase_manager):
|
||||
def __init__(self, page: ft.Page, logger: logging.Logger, settings_manager, db_manager, on_login_success):
|
||||
self.page = page
|
||||
self.logger = logger
|
||||
self.settings_manager = settings_manager
|
||||
self.supabase_manager = supabase_manager
|
||||
self.result = None # 로그인 성공 여부 (True/False)
|
||||
self.db_manager = db_manager
|
||||
self.on_login_success = on_login_success
|
||||
self.logger.log("Initializing LoginDialog...", level=logging.DEBUG)
|
||||
self.create_dialog()
|
||||
|
||||
def create_dialog(self):
|
||||
# 입력 필드 및 체크박스
|
||||
self.logger.log("Entering LoginDialog.create_dialog()", level=logging.DEBUG)
|
||||
self.email_field = TextField(label="이메일", width=300)
|
||||
self.password_field = TextField(label="비밀번호", width=300, password=True)
|
||||
self.remember_checkbox = Checkbox(label="정보 저장")
|
||||
|
|
@ -33,64 +30,67 @@ class LoginDialog:
|
|||
|
||||
self.show_password_checkbox.on_change = self.toggle_password
|
||||
|
||||
# 버튼들
|
||||
self.login_button = ElevatedButton("로그인", on_click=self.on_login)
|
||||
self.reset_button = ElevatedButton("비밀번호 찾기", on_click=self.on_reset)
|
||||
|
||||
content = Column([
|
||||
self.email_field,
|
||||
self.password_field,
|
||||
Row([self.remember_checkbox, self.show_password_checkbox]),
|
||||
self.error_text,
|
||||
Row([self.login_button, self.reset_button], alignment=MainAxisAlignment.CENTER)
|
||||
])
|
||||
|
||||
self.dialog = AlertDialog(
|
||||
title=Text("로그인"),
|
||||
content=content,
|
||||
content=Column([
|
||||
self.email_field,
|
||||
self.password_field,
|
||||
Row([self.remember_checkbox, self.show_password_checkbox]),
|
||||
self.error_text,
|
||||
Row([self.login_button, self.reset_button], alignment=MainAxisAlignment.CENTER)
|
||||
]),
|
||||
actions_alignment=MainAxisAlignment.CENTER
|
||||
)
|
||||
self.logger.log("Exiting LoginDialog.create_dialog()", level=logging.DEBUG)
|
||||
|
||||
def show(self):
|
||||
"""
|
||||
로그인 다이얼로그를 페이지에 표시합니다.
|
||||
(비동기 대기를 제거하여, 이벤트 기반으로 사용자 상호작용을 기다립니다.)
|
||||
"""
|
||||
self.logger.log("LoginDialog.show() 호출됨", level=logging.DEBUG)
|
||||
self.page.dialog = self.dialog
|
||||
self.dialog.open = True
|
||||
self.page.update()
|
||||
|
||||
def toggle_password(self, e: ft.ControlEvent):
|
||||
self.logger.log("toggle_password() 호출됨", level=logging.DEBUG)
|
||||
self.password_field.password = not self.show_password_checkbox.value
|
||||
self.page.update()
|
||||
|
||||
def on_login(self, e: ft.ControlEvent):
|
||||
self.logger.log("on_login() 호출됨", level=logging.DEBUG)
|
||||
email = self.email_field.value.strip()
|
||||
password = self.password_field.value.strip()
|
||||
if not email or not password:
|
||||
self.error_text.value = "이메일과 비밀번호를 모두 입력하세요."
|
||||
self.logger.log("on_login(): 입력값 부족", level=logging.WARNING)
|
||||
self.page.update()
|
||||
return
|
||||
# 실제 Supabase 로그인을 시도합니다.
|
||||
result = self.supabase_manager.login(email, password)
|
||||
|
||||
result = self.db_manager.login(email, password)
|
||||
if "error" not in result:
|
||||
self.logger.log(f"로그인 성공: {result}", level=logging.DEBUG)
|
||||
# 마지막 로그인 시간 업데이트
|
||||
self.supabase_manager.update_last_login(result["id"])
|
||||
self.db_manager.update_last_login(result["id"])
|
||||
if self.remember_checkbox.value:
|
||||
user_info = {"email": email, "password": password, "id": result["id"]}
|
||||
self.settings_manager.save_user_info(user_info)
|
||||
self.result = True
|
||||
# 로그인 성공 시 다이얼로그 닫기
|
||||
self.dialog.open = False
|
||||
self.page.dialog = None
|
||||
self.page.update()
|
||||
# 메인 윈도우 전환 콜백 호출
|
||||
if self.on_login_success:
|
||||
self.on_login_success()
|
||||
else:
|
||||
self.error_text.value = f"로그인 실패: {result['error']}"
|
||||
self.logger.log(f"로그인 실패: {result['error']}", level=logging.WARNING)
|
||||
self.page.update()
|
||||
|
||||
def on_reset(self, e: ft.ControlEvent):
|
||||
self.logger.log("on_reset() 호출됨", level=logging.DEBUG)
|
||||
self.error_text.value = "비밀번호 찾기 기능은 구현되지 않았습니다."
|
||||
self.page.update()
|
||||
|
||||
async def show(self) -> bool:
|
||||
"""
|
||||
로그인 다이얼로그를 보여주고, 로그인 성공 시 True를 반환합니다.
|
||||
(비동기적으로 result가 채워질 때까지 기다립니다.)
|
||||
"""
|
||||
while self.result is None:
|
||||
await asyncio.sleep(0.1)
|
||||
return self.result
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
import flet as ft
|
||||
import logging
|
||||
from modules import backend, product_filter, export
|
||||
|
||||
class MainWindow:
|
||||
def __init__(self, page: ft.Page):
|
||||
self.page = page
|
||||
self.logger = logging.getLogger("FletLogger")
|
||||
self.logger.debug("MainWindow initialized")
|
||||
self.market_list = []
|
||||
self.sold_products = []
|
||||
self.filtered_products = []
|
||||
self.sourced_products = []
|
||||
self.controls = self.build_layout()
|
||||
|
||||
def build_layout(self):
|
||||
self.logger.debug("Building main window layout")
|
||||
self.market_table = ft.DataTable(
|
||||
columns=[
|
||||
ft.DataColumn(ft.Text("마켓이름")),
|
||||
ft.DataColumn(ft.Text("마켓 URL")),
|
||||
ft.DataColumn(ft.Text("메모"))
|
||||
],
|
||||
rows=[],
|
||||
expand=True,
|
||||
key="market_table"
|
||||
)
|
||||
market_tab_content = ft.Column([
|
||||
ft.Row([
|
||||
ft.ElevatedButton("마켓목록 가져오기", on_click=self.load_market_list),
|
||||
ft.ElevatedButton("팔린상품 가져오기", on_click=self.load_sold_products),
|
||||
ft.ElevatedButton("마켓추가하기", on_click=self.add_market)
|
||||
]),
|
||||
self.market_table
|
||||
], scroll=ft.ScrollMode.AUTO)
|
||||
|
||||
self.product_table = ft.DataTable(
|
||||
columns=[
|
||||
ft.DataColumn(ft.Text("상품명")),
|
||||
ft.DataColumn(ft.Text("카테고리")),
|
||||
ft.DataColumn(ft.Text("이미지 URL")),
|
||||
ft.DataColumn(ft.Text("소싱 URL"))
|
||||
],
|
||||
rows=[],
|
||||
expand=True,
|
||||
key="product_table"
|
||||
)
|
||||
self.sourcing_market_dropdown = ft.Dropdown(
|
||||
label="소싱몰 목록",
|
||||
options=[
|
||||
ft.dropdown.Option("타오바오"),
|
||||
ft.dropdown.Option("1688")
|
||||
],
|
||||
key="sourcing_market"
|
||||
)
|
||||
product_tab_content = ft.Column([
|
||||
ft.Row([
|
||||
ft.ElevatedButton("금지어필터링", on_click=self.filter_forbidden),
|
||||
ft.ElevatedButton("카테고리 필터링", on_click=self.filter_category),
|
||||
self.sourcing_market_dropdown,
|
||||
ft.ElevatedButton("소싱하기", on_click=self.sourcing_products),
|
||||
ft.ElevatedButton("출력", on_click=self.export_products)
|
||||
]),
|
||||
self.product_table
|
||||
], scroll=ft.ScrollMode.AUTO)
|
||||
|
||||
forbidden_tab_content = ft.Column([ft.Text("금지어 관리 탭 (추후 구현)")])
|
||||
category_tab_content = ft.Column([ft.Text("카테고리 관리 탭 (추후 구현)")])
|
||||
|
||||
self.tabs = ft.Tabs(
|
||||
selected_index=0,
|
||||
tabs=[
|
||||
ft.Tab(text="마켓", content=market_tab_content),
|
||||
ft.Tab(text="상품", content=product_tab_content),
|
||||
ft.Tab(text="금지어 관리", content=forbidden_tab_content),
|
||||
ft.Tab(text="카테고리 관리", content=category_tab_content)
|
||||
],
|
||||
key="main_tabs"
|
||||
)
|
||||
|
||||
self.log_display = ft.Text(value="", size=12)
|
||||
def append_log(message: str):
|
||||
self.log_display.value += message + "\n"
|
||||
self.page.update()
|
||||
self.page.session.set("append_log", append_log)
|
||||
|
||||
layout = [self.tabs, self.log_display]
|
||||
self.logger.debug("Main window layout built")
|
||||
return layout
|
||||
|
||||
def load_market_list(self, e):
|
||||
self.logger.debug("load_market_list() 호출됨")
|
||||
self.page.session.get("append_log")("Fetching market list...")
|
||||
self.market_list = backend.get_market_list()
|
||||
rows = []
|
||||
for m in self.market_list:
|
||||
row = ft.DataRow(cells=[
|
||||
ft.DataCell(ft.Text(m.get("name", ""))),
|
||||
ft.DataCell(ft.Text(m.get("url", ""))),
|
||||
ft.DataCell(ft.Text(m.get("memo", "")))
|
||||
])
|
||||
rows.append(row)
|
||||
self.market_table.rows = rows
|
||||
self.page.session.get("append_log")("Market list loaded.")
|
||||
self.page.update()
|
||||
|
||||
def load_sold_products(self, e):
|
||||
self.logger.debug("load_sold_products() 호출됨")
|
||||
self.page.session.get("append_log")("Fetching sold products for each market...")
|
||||
self.sold_products = backend.get_sold_products(self.market_list)
|
||||
self.filtered_products = self.sold_products.copy()
|
||||
self.page.session.get("append_log")("Sold products loaded. Switching to 상품 탭.")
|
||||
self.update_product_table(self.filtered_products)
|
||||
self.tabs.selected_index = 1
|
||||
self.page.update()
|
||||
|
||||
def update_product_table(self, products):
|
||||
self.logger.debug("update_product_table() 호출됨")
|
||||
rows = []
|
||||
for p in products:
|
||||
row = ft.DataRow(cells=[
|
||||
ft.DataCell(ft.Text(p.get("name", ""))),
|
||||
ft.DataCell(ft.Text(p.get("category", ""))),
|
||||
ft.DataCell(ft.Text(p.get("image_url", ""))),
|
||||
ft.DataCell(ft.Text(p.get("sourcing_url", "")))
|
||||
])
|
||||
rows.append(row)
|
||||
self.product_table.rows = rows
|
||||
self.page.update()
|
||||
|
||||
def add_market(self, e):
|
||||
self.logger.debug("add_market() 호출됨")
|
||||
self.page.session.get("append_log")("Add market functionality not implemented yet.")
|
||||
self.page.update()
|
||||
|
||||
def filter_forbidden(self, e):
|
||||
self.logger.debug("filter_forbidden() 호출됨")
|
||||
self.page.session.get("append_log")("Filtering products with forbidden words...")
|
||||
from modules import product_filter
|
||||
self.filtered_products = product_filter.filter_forbidden_words(self.filtered_products)
|
||||
self.update_product_table(self.filtered_products)
|
||||
self.page.session.get("append_log")("Forbidden words filtering applied.")
|
||||
self.page.update()
|
||||
|
||||
def filter_category(self, e):
|
||||
self.logger.debug("filter_category() 호출됨")
|
||||
self.page.session.get("append_log")("Filtering products with forbidden categories...")
|
||||
from modules import product_filter
|
||||
self.filtered_products = product_filter.filter_forbidden_categories(self.filtered_products)
|
||||
self.update_product_table(self.filtered_products)
|
||||
self.page.session.get("append_log")("Category filtering applied.")
|
||||
self.page.update()
|
||||
|
||||
def sourcing_products(self, e):
|
||||
self.logger.debug("sourcing_products() 호출됨")
|
||||
self.page.session.get("append_log")(f"Starting sourcing using {self.sourcing_market_dropdown.value}...")
|
||||
from modules import backend
|
||||
self.sourced_products = []
|
||||
for product in self.filtered_products:
|
||||
url = backend.sourcing_product(product.get("image_url", ""), self.sourcing_market_dropdown.value)
|
||||
product["sourcing_url"] = url
|
||||
self.sourced_products.append(product)
|
||||
self.update_product_table(self.sourced_products)
|
||||
self.page.session.get("append_log")("Sourcing completed.")
|
||||
self.page.update()
|
||||
|
||||
def export_products(self, e):
|
||||
self.logger.debug("export_products() 호출됨")
|
||||
self.page.session.get("append_log")("Exporting products to Excel...")
|
||||
from modules import export
|
||||
export.export_to_excel(self.sourced_products)
|
||||
self.page.session.get("append_log")("Products exported and folder opened.")
|
||||
self.page.update()
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import flet as ft
|
||||
|
||||
def main(page: ft.Page):
|
||||
page.title = "로그인"
|
||||
|
||||
def login(e):
|
||||
username = username_field.value
|
||||
password = password_field.value
|
||||
|
||||
if username == "test" and password == "password":
|
||||
def close_dlg(e):
|
||||
page.close(dlg_modal)
|
||||
page.update()
|
||||
|
||||
dlg_modal = ft.AlertDialog(
|
||||
modal=True,
|
||||
title=ft.Text("로그인 성공"),
|
||||
content=ft.Text("로그인에 성공했습니다."),
|
||||
actions=[
|
||||
ft.TextButton("확인", on_click=close_dlg),
|
||||
],
|
||||
actions_alignment=ft.MainAxisAlignment.END,
|
||||
)
|
||||
page.open(dlg_modal)
|
||||
page.update()
|
||||
else:
|
||||
page.open(ft.SnackBar(ft.Text("로그인 실패. 사용자 이름 또는 비밀번호가 잘못되었습니다.")))
|
||||
page.update()
|
||||
|
||||
username_field = ft.TextField(label="사용자 이름")
|
||||
password_field = ft.TextField(label="비밀번호", password=True)
|
||||
login_button = ft.ElevatedButton(text="로그인", on_click=login)
|
||||
|
||||
page.add(
|
||||
username_field,
|
||||
password_field,
|
||||
login_button
|
||||
)
|
||||
|
||||
ft.app(target=main)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import flet as ft
|
||||
|
||||
def login_page(page: ft.Page):
|
||||
page.title = "로그인 페이지"
|
||||
|
||||
def login(e):
|
||||
username = username_field.value
|
||||
password = password_field.value
|
||||
|
||||
if username == "test" and password == "password":
|
||||
# 로그인 성공 다이얼로그를 띄운 후 메인 윈도우로 전환
|
||||
def close_dlg(e):
|
||||
# 다이얼로그 닫기
|
||||
page.close(success_dlg)
|
||||
# 메인 윈도우로 전환
|
||||
transition_to_main(page)
|
||||
page.update()
|
||||
|
||||
success_dlg = ft.AlertDialog(
|
||||
modal=True,
|
||||
title=ft.Text("로그인 성공"),
|
||||
content=ft.Text("로그인에 성공했습니다."),
|
||||
actions=[
|
||||
ft.TextButton("확인", on_click=close_dlg),
|
||||
],
|
||||
actions_alignment=ft.MainAxisAlignment.END,
|
||||
)
|
||||
page.open(success_dlg)
|
||||
page.update()
|
||||
else:
|
||||
# 로그인 실패 시 스낵바 표시
|
||||
page.open(ft.SnackBar(ft.Text("로그인 실패. 사용자 이름 또는 비밀번호가 잘못되었습니다.")))
|
||||
page.update()
|
||||
|
||||
username_field = ft.TextField(label="사용자 이름", width=300)
|
||||
password_field = ft.TextField(label="비밀번호", width=300, password=True)
|
||||
login_button = ft.ElevatedButton(text="로그인", on_click=login)
|
||||
|
||||
# 페이지에 로그인 컨트롤 추가
|
||||
page.controls.clear()
|
||||
page.add(
|
||||
username_field,
|
||||
password_field,
|
||||
login_button
|
||||
)
|
||||
page.update()
|
||||
|
||||
def transition_to_main(page: ft.Page):
|
||||
# 메인윈도우 페이지로 전환 (page.controls를 교체)
|
||||
page.controls.clear()
|
||||
main_window(page)
|
||||
|
||||
def main_window(page: ft.Page):
|
||||
page.title = "메인 윈도우"
|
||||
# 메인 윈도우에 표시할 컨텐츠 예시
|
||||
page.add(
|
||||
ft.Text("메인 윈도우 페이지입니다.", style=ft.TextStyle(font_size=24)),
|
||||
ft.Text("여기에 다양한 기능들이 구현됩니다.", style=ft.TextStyle(font_size=16))
|
||||
)
|
||||
page.update()
|
||||
|
||||
def main(page: ft.Page):
|
||||
# 프로그램 시작 시 로그인 페이지 표시
|
||||
login_page(page)
|
||||
|
||||
ft.app(target=main)
|
||||
Loading…
Reference in New Issue