尚品汇
@ -1,9 +0,0 @@
|
|||||||
import wx
|
|
||||||
|
|
||||||
class voice_frame(wx.Frame):
|
|
||||||
def __init__(self,Id):
|
|
||||||
super().__init__()
|
|
||||||
panel = wx.Panel(self)
|
|
||||||
box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
|
|
@ -1,299 +0,0 @@
|
|||||||
import wx.richtext as rt
|
|
||||||
import os
|
|
||||||
import wx
|
|
||||||
import time
|
|
||||||
import multiprocessing
|
|
||||||
|
|
||||||
from Client.Transmission.Process_Client import ProcessClient
|
|
||||||
|
|
||||||
|
|
||||||
class ChatFrame(wx.Frame, ProcessClient):
|
|
||||||
def __init__(self, Id):
|
|
||||||
wx.Frame.__init__(self, None, size=(800, 600), title="账号: " + str(Id))
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
self.userid = Id
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
ChatMain_Panel = wx.Panel(self, style=wx.BORDER_SUNKEN)
|
|
||||||
ChatMain_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
ChatMain_Panel.SetSizer(ChatMain_box)
|
|
||||||
|
|
||||||
Function_Panel = wx.Panel(ChatMain_Panel, style=wx.BORDER_RAISED)
|
|
||||||
Function_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
Function_Panel.SetSizer(Function_box)
|
|
||||||
Function_Panel.SetBackgroundColour(wx.Colour(240, 240, 240))
|
|
||||||
|
|
||||||
image_chat = r'./Client/image/chat.png'
|
|
||||||
Chat_bitmap = wx.Bitmap(image_chat, wx.BITMAP_TYPE_PNG)
|
|
||||||
Chat_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=Chat_bitmap, style=wx.BORDER_RAISED)
|
|
||||||
Chat_bitmap_static.SetToolTip("聊天")
|
|
||||||
Function_box.Add(Chat_bitmap_static, 1, wx.EXPAND, 0)
|
|
||||||
Chat_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_chat_button)
|
|
||||||
|
|
||||||
Function_box.AddSpacer(20) # 调整这个数字以改变间距大小
|
|
||||||
|
|
||||||
image_connect = r'./Client/image/connect.png'
|
|
||||||
connect_bitmap = wx.Bitmap(image_connect, wx.BITMAP_TYPE_PNG)
|
|
||||||
connect_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=connect_bitmap, style=wx.BORDER_RAISED)
|
|
||||||
connect_bitmap_static.SetToolTip("通讯录")
|
|
||||||
Function_box.Add(connect_bitmap_static, 1, wx.EXPAND, 0)
|
|
||||||
connect_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_connect_button)
|
|
||||||
|
|
||||||
Function_box.AddSpacer(20) # 调整这个数字以改变间距大小
|
|
||||||
|
|
||||||
image_find = r'./Client/image/find.png'
|
|
||||||
find_bitmap = wx.Bitmap(image_find, wx.BITMAP_TYPE_PNG)
|
|
||||||
find_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=find_bitmap, style=wx.BORDER_RAISED)
|
|
||||||
find_bitmap_static.SetToolTip("查找")
|
|
||||||
Function_box.Add(find_bitmap_static, 1, wx.EXPAND, 0)
|
|
||||||
find_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_find_button)
|
|
||||||
|
|
||||||
Function_box.AddSpacer(280) # 调整这个数字以改变间距大小
|
|
||||||
|
|
||||||
image_site = r'./Client/image/site.png'
|
|
||||||
site_bitmap = wx.Bitmap(image_site, wx.BITMAP_TYPE_PNG)
|
|
||||||
site_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=site_bitmap, style=wx.BORDER_RAISED)
|
|
||||||
site_bitmap_static.SetToolTip("设置")
|
|
||||||
Function_box.Add(site_bitmap_static, 1, wx.EXPAND, 0)
|
|
||||||
site_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_site_button)
|
|
||||||
|
|
||||||
Function_box.Fit(Function_Panel) # 调整面板大小以适应图像
|
|
||||||
|
|
||||||
ChatMain_box.Add(Function_Panel, 0, wx.EXPAND | wx.ALL, 5)
|
|
||||||
|
|
||||||
operate_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
self.chat_page = self.ChatPage(ChatMain_Panel) # 将 ChatMain_Panel 作为 ChatPage 的 parent
|
|
||||||
operate_box.Add(self.chat_page, 1, wx.EXPAND, 5)
|
|
||||||
self.chat_page.Hide()
|
|
||||||
|
|
||||||
self.Process_client_send("File_operate", "read_data", None)
|
|
||||||
|
|
||||||
self.connect_page = self.ConnectPage(ChatMain_Panel)
|
|
||||||
operate_box.Add(self.connect_page, 1, wx.EXPAND, 5)
|
|
||||||
self.connect_page.Hide()
|
|
||||||
|
|
||||||
self.site_page = self.SitePage(ChatMain_Panel)
|
|
||||||
operate_box.Add(self.site_page, 1, wx.EXPAND, 5)
|
|
||||||
self.site_page.Hide()
|
|
||||||
|
|
||||||
self.find_page = self.FindPage(ChatMain_Panel)
|
|
||||||
operate_box.Add(self.find_page, 1, wx.EXPAND, 5)
|
|
||||||
self.find_page.Hide()
|
|
||||||
|
|
||||||
ChatMain_box.Add(operate_box, 1, wx.EXPAND, 5)
|
|
||||||
|
|
||||||
self.chat_page.Show()
|
|
||||||
|
|
||||||
ChatMain_Panel.SetSizer(ChatMain_box)
|
|
||||||
|
|
||||||
def click_chat_button(self, event):
|
|
||||||
self.chat_page.Hide()
|
|
||||||
self.connect_page.Hide()
|
|
||||||
self.site_page.Hide()
|
|
||||||
self.find_page.Hide()
|
|
||||||
self.chat_page.Show()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def click_connect_button(self, event):
|
|
||||||
self.chat_page.Hide()
|
|
||||||
self.connect_page.Hide()
|
|
||||||
self.site_page.Hide()
|
|
||||||
self.find_page.Hide()
|
|
||||||
self.connect_page.Show()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def click_site_button(self, event):
|
|
||||||
self.chat_page.Hide()
|
|
||||||
self.connect_page.Hide()
|
|
||||||
self.site_page.Hide()
|
|
||||||
self.find_page.Hide()
|
|
||||||
self.site_page.Show()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def click_find_button(self, event):
|
|
||||||
self.chat_page.Hide()
|
|
||||||
self.connect_page.Hide()
|
|
||||||
self.site_page.Hide()
|
|
||||||
self.find_page.Hide()
|
|
||||||
self.find_page.Show()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'Chat_main']:
|
|
||||||
match data['function']:
|
|
||||||
case 'ChatPage_add_Contact_person':
|
|
||||||
data = data['content']
|
|
||||||
Contact = data['Contact']
|
|
||||||
Remark = data['Remark']
|
|
||||||
Time = data['UpDataTime']
|
|
||||||
state = data['state']
|
|
||||||
if state:
|
|
||||||
wx.CallAfter(self.chat_page.ChatPage_add_Contact_person, Contact, Remark)
|
|
||||||
case 'Chat_screen_show':
|
|
||||||
Contact = None
|
|
||||||
data = data['content']
|
|
||||||
send = data['Send']
|
|
||||||
receive = data['Receive']
|
|
||||||
Type = data['Type']
|
|
||||||
content = data['Content']
|
|
||||||
UpDataTime = data['Time']
|
|
||||||
if send == str(self.userid):
|
|
||||||
Contact = receive
|
|
||||||
elif receive == str(self.userid):
|
|
||||||
Contact = send
|
|
||||||
wx.CallAfter(self.chat_page.Chat_screen_show, Contact, send, receive, Type, content, UpDataTime)
|
|
||||||
|
|
||||||
class ChatPage(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN)
|
|
||||||
|
|
||||||
ChatPage_main_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
self.chat_page_map = {}
|
|
||||||
self.chat_page_ids = []
|
|
||||||
self.current_chat_page = None # 新增的属性用于跟踪当前显示的聊天面板
|
|
||||||
|
|
||||||
self.ChatPage_Listbook = wx.Listbook(self, style=wx.LB_LEFT)
|
|
||||||
self.ChatPage_Listbook.Bind(wx.EVT_LISTBOOK_PAGE_CHANGED, self.on_page_changed)
|
|
||||||
|
|
||||||
ChatPage_main_box.Add(self.ChatPage_Listbook, 1, wx.EXPAND, 0)
|
|
||||||
self.SetSizer(ChatPage_main_box)
|
|
||||||
|
|
||||||
def ChatPage_add_Contact_person(self, Id, Remark):
|
|
||||||
contact_page = wx.Panel(self.ChatPage_Listbook)
|
|
||||||
self.ChatPage_Listbook.AddPage(contact_page, Remark)
|
|
||||||
chat_page = self.ChatPage_add_Contact_tab(Id)
|
|
||||||
|
|
||||||
self.chat_page_map[Id] = chat_page
|
|
||||||
self.chat_page_ids.append(Id)
|
|
||||||
# 隐藏当前的聊天面板
|
|
||||||
if self.current_chat_page:
|
|
||||||
self.current_chat_page.Hide()
|
|
||||||
# 将新的聊天面板添加到ChatPage_main_box中
|
|
||||||
self.GetSizer().Add(chat_page, 5, wx.EXPAND)
|
|
||||||
# 显示新的聊天面板
|
|
||||||
chat_page.Show()
|
|
||||||
# 更新当前显示的聊天面板
|
|
||||||
self.current_chat_page = chat_page
|
|
||||||
chat_page.Show()
|
|
||||||
# 重新布局
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def ChatPage_add_Contact_tab(self, Id):
|
|
||||||
chat_panel = wx.Panel(self)
|
|
||||||
chat_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
chat_panel.contact_id = Id
|
|
||||||
|
|
||||||
chat_receive_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
chat_panel.chat_receive_text = rt.RichTextCtrl(chat_panel,
|
|
||||||
style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER | wx.WANTS_CHARS)
|
|
||||||
chat_receive_box.Add(chat_panel.chat_receive_text, 1, wx.EXPAND, 0)
|
|
||||||
chat_box.Add(chat_receive_box, 2, wx.EXPAND, 0)
|
|
||||||
|
|
||||||
toolbar = wx.ToolBar(chat_panel)
|
|
||||||
toolbar.SetToolBitmapSize((16, 16)) # Set the size of the toolbar icons
|
|
||||||
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/picture.png')))
|
|
||||||
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/file.png')))
|
|
||||||
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/speech.png')))
|
|
||||||
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/video.png')))
|
|
||||||
toolbar.Realize()
|
|
||||||
toolbar.SetSize((-1, 30)) # Set the size of the toolbar
|
|
||||||
chat_box.Add(toolbar, 0, wx.EXPAND)
|
|
||||||
|
|
||||||
chat_send_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
chat_panel.chat_send_text = wx.TextCtrl(chat_panel, style=wx.TE_MULTILINE)
|
|
||||||
chat_send_box.Add(chat_panel.chat_send_text, 1, wx.EXPAND, 0)
|
|
||||||
chat_box.Add(chat_send_box, 1, wx.EXPAND, 0)
|
|
||||||
|
|
||||||
send_button = wx.Button(chat_panel, label='发送') # Create a send button
|
|
||||||
send_button.Bind(wx.EVT_BUTTON, self.on_send_button_click)
|
|
||||||
chat_send_box.Add(send_button, 0, wx.EXPAND | wx.LEFT, 5) # Add the button to the send box
|
|
||||||
|
|
||||||
chat_panel.SetSizer(chat_box)
|
|
||||||
|
|
||||||
return chat_panel
|
|
||||||
|
|
||||||
def Chat_screen_show(self, Contact, send, receive, Type, data, UpDataTime):
|
|
||||||
chat_panel = self.chat_page_map[Contact]
|
|
||||||
if Type == 'text':
|
|
||||||
# 确定对齐方式
|
|
||||||
if Contact == receive:
|
|
||||||
alignment = wx.TEXT_ALIGNMENT_RIGHT
|
|
||||||
else:
|
|
||||||
alignment = wx.TEXT_ALIGNMENT_LEFT
|
|
||||||
# 开始设置对齐
|
|
||||||
chat_panel.chat_receive_text.BeginAlignment(alignment)
|
|
||||||
# 按每30个字符分割消息内容并写入
|
|
||||||
contents = [data[i:i + 30] for i in range(0, len(data), 30)]
|
|
||||||
contents.append(UpDataTime) # 添加时间戳
|
|
||||||
for content in contents:
|
|
||||||
chat_panel.chat_receive_text.WriteText(content + '\n') # WriteText处理换行
|
|
||||||
# 结束对齐设置
|
|
||||||
chat_panel.chat_receive_text.EndAlignment()
|
|
||||||
# 添加额外的新行(如果需要)
|
|
||||||
chat_panel.chat_receive_text.Newline()
|
|
||||||
|
|
||||||
# 在添加完所有消息后
|
|
||||||
chat_panel.chat_receive_text.ShowPosition(chat_panel.chat_receive_text.GetLastPosition())
|
|
||||||
chat_panel.Refresh()
|
|
||||||
chat_panel.Update()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def on_send_button_click(self, event):
|
|
||||||
button = event.GetEventObject()
|
|
||||||
chat_panel = button.GetParent()
|
|
||||||
send_text = chat_panel.chat_send_text.GetValue() # 正确获取输入框内容
|
|
||||||
contact_id = str(chat_panel.contact_id) # 获取联系人ID
|
|
||||||
if send_text == '':
|
|
||||||
return
|
|
||||||
|
|
||||||
self.Chat_screen_show(contact_id, None, contact_id, 'text', send_text,
|
|
||||||
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
|
||||||
|
|
||||||
data = {"Type": "text", "content": send_text}
|
|
||||||
|
|
||||||
content = {"genre": '聊天记录', "target": contact_id, "content": data}
|
|
||||||
|
|
||||||
top_frame = self.GetTopLevelParent()
|
|
||||||
|
|
||||||
top_frame.Process_client_send('Session_server', 'send_server', content)
|
|
||||||
chat_panel.chat_send_text.SetValue('') # 清空输入框
|
|
||||||
event.Skip()
|
|
||||||
|
|
||||||
def on_page_changed(self, event):
|
|
||||||
# 获取当前选定的页面的索引
|
|
||||||
current_page_index = self.ChatPage_Listbook.GetSelection()
|
|
||||||
# 通过索引从chat_page_ids列表中获取对应的Id
|
|
||||||
current_page_id = self.chat_page_ids[current_page_index]
|
|
||||||
# 从chat_page_map中找到对应的聊天面板
|
|
||||||
new_chat_page = self.chat_page_map[current_page_id]
|
|
||||||
# 隐藏旧的聊天面板
|
|
||||||
if self.current_chat_page:
|
|
||||||
self.current_chat_page.Hide()
|
|
||||||
# 显示新的聊天面板
|
|
||||||
new_chat_page.Show()
|
|
||||||
# 更新当前显示的聊天面板
|
|
||||||
self.current_chat_page = new_chat_page
|
|
||||||
# 重新布局
|
|
||||||
self.Layout()
|
|
||||||
# 处理完事件后,不要忘记调用event.Skip(),以便事件可以继续传播到其他处理器
|
|
||||||
event.Skip()
|
|
||||||
|
|
||||||
class ConnectPage(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
wx.Panel.__init__(self, parent)
|
|
||||||
print("联系人")
|
|
||||||
|
|
||||||
class SitePage(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
wx.Panel.__init__(self, parent)
|
|
||||||
print("设置")
|
|
||||||
|
|
||||||
class FindPage(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
wx.Panel.__init__(self, parent)
|
|
||||||
print("查找")
|
|
@ -1,270 +0,0 @@
|
|||||||
import json
|
|
||||||
import multiprocessing
|
|
||||||
import os
|
|
||||||
|
|
||||||
import wx
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
from Client.Transmission.Process_Client import ProcessClient
|
|
||||||
from .Chat_main import ChatFrame
|
|
||||||
|
|
||||||
|
|
||||||
def open_chat_window(Id):
|
|
||||||
app = wx.App()
|
|
||||||
ChatFrame(Id).Show()
|
|
||||||
app.MainLoop()
|
|
||||||
|
|
||||||
|
|
||||||
class LoginFrame(wx.Frame, ProcessClient):
|
|
||||||
def __init__(self):
|
|
||||||
wx.Frame.__init__(self, None, id=-1, title='登录', pos=wx.DefaultPosition, size=(380, 300))
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
# 创建菜单栏
|
|
||||||
menu_bar = wx.MenuBar()
|
|
||||||
|
|
||||||
# 登录菜单
|
|
||||||
login_menu = wx.Menu()
|
|
||||||
menu_bar.Append(login_menu, "登录")
|
|
||||||
|
|
||||||
# 更多菜单
|
|
||||||
more_menu = wx.Menu()
|
|
||||||
self.register_id = wx.NewId()
|
|
||||||
self.set_server_id = wx.NewId()
|
|
||||||
more_menu.Append(self.register_id, "注册账号")
|
|
||||||
more_menu.Append(self.set_server_id, "服务器设置")
|
|
||||||
menu_bar.Append(more_menu, "更多")
|
|
||||||
|
|
||||||
self.SetMenuBar(menu_bar)
|
|
||||||
|
|
||||||
# 创建状态栏
|
|
||||||
self.status_bar = self.CreateStatusBar(2)
|
|
||||||
self.server_status = False # 服务器状态
|
|
||||||
status_thread = threading.Thread(target=self.update_status_bar(None), daemon=True)
|
|
||||||
status_thread.start()
|
|
||||||
|
|
||||||
# 启动定时器,每秒钟触发一次
|
|
||||||
self.timer = wx.Timer(self)
|
|
||||||
self.Bind(wx.EVT_TIMER, self.update_status_bar, self.timer)
|
|
||||||
self.timer.Start(1000) # 设置定时器间隔为1000毫秒(1秒
|
|
||||||
|
|
||||||
# 获取菜单点击事件
|
|
||||||
self.Bind(wx.EVT_MENU, self.click_menu, id=self.register_id)
|
|
||||||
self.Bind(wx.EVT_MENU, self.click_menu, id=self.set_server_id)
|
|
||||||
self.Bind(wx.EVT_MENU_OPEN, self.click_menu_title)
|
|
||||||
|
|
||||||
# 创建注册面板
|
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
self.login_panel = LoginPanel(self)
|
|
||||||
self.register_panel = RegisterPanel(self)
|
|
||||||
self.sizer.Add(self.login_panel, 1, wx.EXPAND)
|
|
||||||
self.sizer.Add(self.register_panel, 1, wx.EXPAND)
|
|
||||||
|
|
||||||
self.login_panel.Hide()
|
|
||||||
self.register_panel.Hide()
|
|
||||||
|
|
||||||
self.login_panel.Show()
|
|
||||||
|
|
||||||
# 主页按钮绑定
|
|
||||||
self.Bind(wx.EVT_BUTTON, self.send_login_button, self.login_panel.LoginPanel_login_label)
|
|
||||||
self.Bind(wx.EVT_BUTTON, self.send_register_button, self.register_panel.RegisterPanel_login_label)
|
|
||||||
|
|
||||||
self.SetSizer(self.sizer)
|
|
||||||
|
|
||||||
def update_status_bar(self, event):
|
|
||||||
if self.server_status:
|
|
||||||
self.status_bar.SetStatusText("服务器\t已连接", 0)
|
|
||||||
else:
|
|
||||||
self.status_bar.SetStatusText("服务器\t未连接", 0)
|
|
||||||
|
|
||||||
self.status_bar.SetStatusText("时间\t" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 1)
|
|
||||||
|
|
||||||
def click_menu_title(self, event):
|
|
||||||
menu = event.GetMenu()
|
|
||||||
menu_title = menu.GetTitle()
|
|
||||||
if menu_title == "登录":
|
|
||||||
self.login_panel.Hide()
|
|
||||||
self.register_panel.Hide()
|
|
||||||
self.login_panel.Show()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
# 点击菜单检测
|
|
||||||
def click_menu(self, event):
|
|
||||||
menu_id = event.GetId()
|
|
||||||
if menu_id == self.register_id:
|
|
||||||
self.login_panel.Hide()
|
|
||||||
self.register_panel.Hide()
|
|
||||||
self.register_panel.Show()
|
|
||||||
self.Layout()
|
|
||||||
elif menu_id == self.set_server_id:
|
|
||||||
self.login_panel.Hide()
|
|
||||||
self.register_panel.Hide()
|
|
||||||
self.Layout()
|
|
||||||
|
|
||||||
def login_page_receive(self, receive_content):
|
|
||||||
if receive_content["genre"] == '登录':
|
|
||||||
match receive_content["data"]['status']:
|
|
||||||
case 0:
|
|
||||||
self.Process_client_send("File_operate", "detection_data", receive_content["data"]['account'])
|
|
||||||
wx.MessageBox('登录成功正在获取数据', '登录', wx.OK | wx.ICON_INFORMATION)
|
|
||||||
case -1:
|
|
||||||
wx.MessageBox('重复登录', '登录', wx.OK | wx.ICON_INFORMATION)
|
|
||||||
case 1:
|
|
||||||
wx.MessageBox('密码错误', '登录', wx.OK | wx.ICON_INFORMATION)
|
|
||||||
case 2:
|
|
||||||
wx.MessageBox('未找到该账号', '登录', wx.OK | wx.ICON_INFORMATION)
|
|
||||||
elif receive_content["genre"] == '注册':
|
|
||||||
wx.MessageBox(
|
|
||||||
f'注册成功\n网名 : {receive_content["data"]['NetName']} \n账号 : {receive_content["data"]['Id']} \n密码 : {receive_content["data"]['Password']}',
|
|
||||||
'注册', wx.OK | wx.ICON_INFORMATION)
|
|
||||||
|
|
||||||
def send_login_button(self, event):
|
|
||||||
if self.server_status:
|
|
||||||
account = self.login_panel.LoginPanel_account_text.GetValue().strip()
|
|
||||||
password = self.login_panel.LoginPanel_password_text.GetValue().strip()
|
|
||||||
content = {'account': account, 'password': password}
|
|
||||||
target = "服务器"
|
|
||||||
genre = "登录"
|
|
||||||
data = {"genre": genre, "target": target, "content": content}
|
|
||||||
if account and password:
|
|
||||||
self.Process_client_send("Session_server", "send_server", data)
|
|
||||||
|
|
||||||
|
|
||||||
def send_register_button(self, event):
|
|
||||||
if self.server_status:
|
|
||||||
account = self.register_panel.RegisterPanel_account_text.GetValue().strip()
|
|
||||||
password = self.register_panel.RegisterPanel_password_text.GetValue().strip()
|
|
||||||
content = {'account': account, 'password': password}
|
|
||||||
target = "服务器"
|
|
||||||
genre = "注册"
|
|
||||||
data = {"genre": genre, "target": target, "content": content}
|
|
||||||
if account and password:
|
|
||||||
self.Process_client_send("Session_server", "send_server", data)
|
|
||||||
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'Login']:
|
|
||||||
match data['function']:
|
|
||||||
case 'server_status':
|
|
||||||
self.server_status = data['content']
|
|
||||||
case 'login_page_receive':
|
|
||||||
self.login_page_receive(data['content'])
|
|
||||||
case '更新完成':
|
|
||||||
multiprocessing.Process(target=open_chat_window, args=(data['content'],)).start()
|
|
||||||
self.Destroy()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LoginPanel(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
super().__init__(parent)
|
|
||||||
# 主盒子
|
|
||||||
LoginPanel_main_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
# 顶部盒子,目前只放了软件名
|
|
||||||
LoginPanel_top_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子
|
|
||||||
LoginPanel_show_title = wx.StaticText(self, label='登录')
|
|
||||||
LoginPanel_show_title.SetFont(wx.Font(30, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
LoginPanel_top_box.Add(LoginPanel_show_title, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10)
|
|
||||||
LoginPanel_main_box.Add(LoginPanel_top_box, 0, wx.EXPAND)
|
|
||||||
|
|
||||||
# 中部盒子,放账号和密码
|
|
||||||
LoginPanel_content_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
# 账号
|
|
||||||
LoginPanel_account_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
LoginPanel_account_label = wx.StaticText(self, label=' 账号:')
|
|
||||||
LoginPanel_account_label.SetFont(
|
|
||||||
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
LoginPanel_account_box.Add(LoginPanel_account_label, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
self.LoginPanel_account_text = wx.TextCtrl(self, size=(300, 30))
|
|
||||||
self.LoginPanel_account_text.SetHint('请输入账号')
|
|
||||||
LoginPanel_account_box.Add(self.LoginPanel_account_text, 1, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
LoginPanel_content_box.Add(LoginPanel_account_box)
|
|
||||||
# 添加空白控件来增加间距
|
|
||||||
LoginPanel_content_box.Add(wx.StaticText(self, label=''), 0, wx.ALL, 5)
|
|
||||||
# 密码
|
|
||||||
LoginPanel_password_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
LoginPanel_password_label = wx.StaticText(self, label=' 密码:')
|
|
||||||
LoginPanel_password_label.SetFont(
|
|
||||||
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
LoginPanel_password_box.Add(LoginPanel_password_label, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
self.LoginPanel_password_text = wx.TextCtrl(self, size=(300, 30))
|
|
||||||
self.LoginPanel_password_text.SetHint('请输入密码')
|
|
||||||
LoginPanel_password_box.Add(self.LoginPanel_password_text, 1, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
LoginPanel_content_box.Add(LoginPanel_password_box)
|
|
||||||
LoginPanel_main_box.Add(LoginPanel_content_box, 0, wx.EXPAND)
|
|
||||||
|
|
||||||
# 底部盒子
|
|
||||||
LoginPanel_bottom_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
# 登录按钮
|
|
||||||
LoginPanel_login_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子布局
|
|
||||||
self.LoginPanel_login_label = wx.Button(self, size=(200, 50), label='登录')
|
|
||||||
LoginPanel_login_box.AddStretchSpacer() # 添加一个可伸缩的空间,将登录按钮推到垂直中间
|
|
||||||
LoginPanel_login_box.Add(self.LoginPanel_login_label, 0, wx.ALIGN_CENTER_HORIZONTAL) # 将登录按钮添加到垂直盒子中
|
|
||||||
LoginPanel_login_box.AddStretchSpacer() # 再次添加一个可伸缩的空间,将登录按钮推到垂直中间
|
|
||||||
LoginPanel_bottom_box.Add(LoginPanel_login_box, 1,
|
|
||||||
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL) # 将垂直盒子添加到底部盒子中,设置垂直和水平居中对齐
|
|
||||||
LoginPanel_main_box.Add(LoginPanel_bottom_box, 1, wx.EXPAND) # 将底部盒子添加到主盒子中,使其填满剩余空间
|
|
||||||
|
|
||||||
self.SetSizer(LoginPanel_main_box)
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterPanel(wx.Panel):
|
|
||||||
def __init__(self, parent):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
# 主盒子
|
|
||||||
RegisterPanel_main_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
# 顶部盒子,目前只放了软件名
|
|
||||||
RegisterPanel_top_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子
|
|
||||||
RegisterPanel_show_title = wx.StaticText(self, label='注册')
|
|
||||||
RegisterPanel_show_title.SetFont(
|
|
||||||
wx.Font(30, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
RegisterPanel_top_box.Add(RegisterPanel_show_title, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10)
|
|
||||||
RegisterPanel_main_box.Add(RegisterPanel_top_box, 0, wx.EXPAND)
|
|
||||||
|
|
||||||
# 中部盒子,放账号和密码
|
|
||||||
RegisterPanel_content_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
# 账号
|
|
||||||
RegisterPanel_account_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
RegisterPanel_account_label = wx.StaticText(self, label=' 用户名:')
|
|
||||||
RegisterPanel_account_label.SetFont(
|
|
||||||
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
RegisterPanel_account_box.Add(RegisterPanel_account_label, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
self.RegisterPanel_account_text = wx.TextCtrl(self, size=(300, 30))
|
|
||||||
self.RegisterPanel_account_text.SetHint('请输入用户名')
|
|
||||||
RegisterPanel_account_box.Add(self.RegisterPanel_account_text, 1, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
RegisterPanel_content_box.Add(RegisterPanel_account_box)
|
|
||||||
# 添加空白控件来增加间距
|
|
||||||
RegisterPanel_content_box.Add(wx.StaticText(self, label=''), 0, wx.ALL, 5)
|
|
||||||
# 密码
|
|
||||||
RegisterPanel_password_box = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
RegisterPanel_password_label = wx.StaticText(self, label=' 密码: ')
|
|
||||||
RegisterPanel_password_label.SetFont(
|
|
||||||
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
|
||||||
RegisterPanel_password_box.Add(RegisterPanel_password_label, 0, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
self.RegisterPanel_password_text = wx.TextCtrl(self, size=(300, 30))
|
|
||||||
self.RegisterPanel_password_text.SetHint('请输入密码')
|
|
||||||
RegisterPanel_password_box.Add(self.RegisterPanel_password_text, 1, wx.ALIGN_CENTER_VERTICAL)
|
|
||||||
RegisterPanel_content_box.Add(RegisterPanel_password_box)
|
|
||||||
RegisterPanel_main_box.Add(RegisterPanel_content_box, 0, wx.EXPAND)
|
|
||||||
|
|
||||||
# 底部盒子
|
|
||||||
RegisterPanel_bottom_box = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
# 登录按钮
|
|
||||||
RegisterPanel_register_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子布局
|
|
||||||
self.RegisterPanel_login_label = wx.Button(self, size=(200, 50), label='确认')
|
|
||||||
RegisterPanel_register_box.AddStretchSpacer() # 添加一个可伸缩的空间,将登录按钮推到垂直中间
|
|
||||||
RegisterPanel_register_box.Add(self.RegisterPanel_login_label, 0,
|
|
||||||
wx.ALIGN_CENTER_HORIZONTAL) # 将登录按钮添加到垂直盒子中
|
|
||||||
RegisterPanel_register_box.AddStretchSpacer() # 再次添加一个可伸缩的空间,将登录按钮推到垂直中间
|
|
||||||
RegisterPanel_bottom_box.Add(RegisterPanel_register_box, 1,
|
|
||||||
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL) # 将垂直盒子添加到底部盒子中,设置垂直和水平居中对齐
|
|
||||||
RegisterPanel_main_box.Add(RegisterPanel_bottom_box, 1, wx.EXPAND) # 将底部盒子添加到主盒子中,使其填满剩余空间
|
|
||||||
|
|
||||||
self.SetSizer(RegisterPanel_main_box)
|
|
@ -1,2 +0,0 @@
|
|||||||
from .Chat_main import *
|
|
||||||
from .Login import *
|
|
@ -1,103 +0,0 @@
|
|||||||
import os
|
|
||||||
import csv
|
|
||||||
import time
|
|
||||||
|
|
||||||
from .Process_Client import ProcessClient
|
|
||||||
|
|
||||||
|
|
||||||
class FileOperate(ProcessClient):
|
|
||||||
def __init__(self, user_id):
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
|
|
||||||
self.user_id = user_id
|
|
||||||
|
|
||||||
self.root_path = None
|
|
||||||
self.Account_path = None
|
|
||||||
self.Contacts_path = None
|
|
||||||
self.History_path = None
|
|
||||||
self.file_root_path = None
|
|
||||||
self.other_file_path = None
|
|
||||||
self.image_file_path = None
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
def detection_data(self, Id):
|
|
||||||
self.user_id = Id
|
|
||||||
self.root_path = rf'.\{Id}'
|
|
||||||
self.Account_path = self.root_path + r'\Account.csv'
|
|
||||||
self.Contacts_path = self.root_path + r'\Contacts.csv'
|
|
||||||
self.History_path = self.root_path + r'\History.csv'
|
|
||||||
self.file_root_path = self.root_path + r'\file'
|
|
||||||
self.other_file_path = self.file_root_path + r'\other'
|
|
||||||
self.image_file_path = self.file_root_path + r'\image'
|
|
||||||
if not os.path.isdir(self.root_path):
|
|
||||||
os.mkdir(self.root_path)
|
|
||||||
if not os.path.isdir(self.file_root_path):
|
|
||||||
os.mkdir(self.file_root_path)
|
|
||||||
os.mkdir(self.other_file_path)
|
|
||||||
os.mkdir(self.image_file_path)
|
|
||||||
if not os.path.exists(self.Account_path):
|
|
||||||
with open(self.Account_path, 'w', encoding='utf-8') as f:
|
|
||||||
pass
|
|
||||||
with open(self.Account_path, 'r+', encoding='utf-8') as info:
|
|
||||||
data = csv.DictReader(info)
|
|
||||||
if os.path.getsize(self.Account_path) == 0: # 检查文件大小是否为0
|
|
||||||
date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(0))
|
|
||||||
else:
|
|
||||||
for d in data:
|
|
||||||
date = d['UpDataTime']
|
|
||||||
|
|
||||||
target = "服务器"
|
|
||||||
genre = "数据更新"
|
|
||||||
data = {"genre": genre, "target": target, "content": date}
|
|
||||||
self.Process_client_send("Session_server", "send_server", data)
|
|
||||||
|
|
||||||
def read_data(self):
|
|
||||||
with open(self.Contacts_path, 'r', encoding='utf-8') as Contacts:
|
|
||||||
data = csv.reader(Contacts)
|
|
||||||
next(data)
|
|
||||||
for i in data:
|
|
||||||
content = {'Contact': i[0], 'Remark': i[1], 'state': i[2], 'UpDataTime': i[3]}
|
|
||||||
self.Process_client_send("Chat_main", "ChatPage_add_Contact_person", content)
|
|
||||||
with open(self.History_path, 'r', encoding='utf-8') as History_path:
|
|
||||||
data = csv.reader(History_path)
|
|
||||||
next(data)
|
|
||||||
for i in data:
|
|
||||||
content = {'Send': i[0], 'Receive': i[1], 'Type': i[2], 'Content': i[3], 'Time': i[4]}
|
|
||||||
self.Process_client_send("Chat_main", "Chat_screen_show", content)
|
|
||||||
|
|
||||||
def save_data(self, data):
|
|
||||||
target = list(data.keys())[0]
|
|
||||||
data = list(data.values())[0]
|
|
||||||
match target:
|
|
||||||
case 'Account':
|
|
||||||
with open(self.Account_path, 'w+', encoding='utf-8', newline='') as file:
|
|
||||||
csv_file = csv.writer(file)
|
|
||||||
csv_file.writerow(list(data.keys()))
|
|
||||||
csv_file.writerow(list(data.values()))
|
|
||||||
case 'Contacts':
|
|
||||||
with open(self.Contacts_path, 'a+', encoding='utf-8', newline='') as file:
|
|
||||||
csv_file = csv.writer(file)
|
|
||||||
if os.path.getsize(self.Contacts_path) == 0: # 检查文件大小是否为0
|
|
||||||
csv_file.writerow(list(data.keys()))
|
|
||||||
csv_file.writerow(list(data.values()))
|
|
||||||
case 'History':
|
|
||||||
with open(self.History_path, 'a+', encoding='utf-8', newline='') as file:
|
|
||||||
csv_file = csv.writer(file)
|
|
||||||
if os.path.getsize(self.History_path) == 0: # 检查文件大小是否为0
|
|
||||||
csv_file.writerow(list(data.keys()))
|
|
||||||
csv_file.writerow(list(data.values()))
|
|
||||||
case '更新完成':
|
|
||||||
self.Process_client_send("ALL", "更新完成", eval(data))
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'File_operate']:
|
|
||||||
match data['function']:
|
|
||||||
case 'detection_data':
|
|
||||||
self.detection_data(data['content'])
|
|
||||||
case 'save_data':
|
|
||||||
self.save_data(data['content'])
|
|
||||||
case 'read_data':
|
|
||||||
self.read_data()
|
|
@ -1,31 +0,0 @@
|
|||||||
import json
|
|
||||||
import threading
|
|
||||||
from multiprocessing.connection import Client
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessClient:
|
|
||||||
def __init__(self):
|
|
||||||
self.Process_port = 8727
|
|
||||||
self.Process_server = 'localhost'
|
|
||||||
self.Process_client_Client = Client((self.Process_server, self.Process_port))
|
|
||||||
Process_client_recv = threading.Thread(target=self.Process_client_recv)
|
|
||||||
Process_client_recv.start()
|
|
||||||
|
|
||||||
def Process_client_send(self, target, function, content):
|
|
||||||
data = {"target": target, "function": function, "content": content}
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
self.Process_client_Client.send(data_json)
|
|
||||||
|
|
||||||
def Process_client_recv(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data_json = self.Process_client_Client.recv()
|
|
||||||
data = json.loads(data_json)
|
|
||||||
self.Process_client_pick(data)
|
|
||||||
|
|
||||||
except ConnectionResetError as e:
|
|
||||||
print("连接已关闭: " + str(e))
|
|
||||||
break
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
pass
|
|
@ -1,52 +0,0 @@
|
|||||||
import json
|
|
||||||
import multiprocessing
|
|
||||||
from multiprocessing.connection import Listener
|
|
||||||
import threading
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessServer:
|
|
||||||
def __init__(self):
|
|
||||||
try:
|
|
||||||
self.Process_port = 8727
|
|
||||||
self.Process_server = 'localhost'
|
|
||||||
self.Process_server_listener = Listener((self.Process_server, self.Process_port))
|
|
||||||
self.Process_client_link_dick = {}
|
|
||||||
Process_client_link_Thread = threading.Thread(target=self.Process_client_link)
|
|
||||||
Process_client_link_Thread.start()
|
|
||||||
except:
|
|
||||||
print("进程通信端口绑定失败")
|
|
||||||
|
|
||||||
def Process_client_link(self):
|
|
||||||
while True:
|
|
||||||
client_connect = self.Process_server_listener.accept()
|
|
||||||
client_Thread_recv = threading.Thread(target=self.Process_client_recv, args=(client_connect,))
|
|
||||||
client_Thread_recv.start()
|
|
||||||
|
|
||||||
def Process_client_recv(self, client_Thread_recv):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data_json = client_Thread_recv.recv()
|
|
||||||
data = json.loads(data_json)
|
|
||||||
if data['target'] == 'Server':
|
|
||||||
if data['function'] == 'Name':
|
|
||||||
self.Process_client_link_dick[data['content']] = client_Thread_recv
|
|
||||||
else:
|
|
||||||
self.Process_client_pick(data)
|
|
||||||
except ConnectionResetError as e:
|
|
||||||
print("进程关闭" + str(e))
|
|
||||||
|
|
||||||
def Process_client_send(self, target, function, content):
|
|
||||||
connect = self.Process_client_link_dick[target]
|
|
||||||
data = {"target": target, "function": function, "content": content}
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
connect.send(data_json)
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] == 'ALL':
|
|
||||||
for value in self.Process_client_link_dick.values():
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
value.send(data_json)
|
|
||||||
else:
|
|
||||||
if data['target'] in self.Process_client_link_dick.keys():
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
self.Process_client_link_dick[data['target']].send(data_json)
|
|
@ -1,85 +0,0 @@
|
|||||||
import multiprocessing
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import socket
|
|
||||||
import json
|
|
||||||
import threading
|
|
||||||
from .Process_Client import ProcessClient
|
|
||||||
|
|
||||||
|
|
||||||
class Session_server(ProcessClient):
|
|
||||||
def __init__(self):
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
self.socker_ip = "127.0.0.1"
|
|
||||||
self.socker_port = 7868
|
|
||||||
self.server_socket = None
|
|
||||||
self.server_status = False # 服务器状态
|
|
||||||
self.link_server_Thread = threading.Thread(target=self.link_server)
|
|
||||||
self.link_server_Thread.start()
|
|
||||||
self.receive_server_Thread = threading.Thread(target=self.receive_server)
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
def link_server(self):
|
|
||||||
while True:
|
|
||||||
if not self.server_status:
|
|
||||||
time.sleep(1)
|
|
||||||
if self.server_socket is not None:
|
|
||||||
self.server_socket = None
|
|
||||||
try:
|
|
||||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.server_socket.connect((self.socker_ip, self.socker_port))
|
|
||||||
self.server_status = True
|
|
||||||
if not self.receive_server_Thread.is_alive():
|
|
||||||
self.receive_server_Thread.start()
|
|
||||||
except Exception as a:
|
|
||||||
self.server_status = False
|
|
||||||
print("连接错误:" + str(a))
|
|
||||||
finally:
|
|
||||||
self.Process_client_send("ALL", "server_status", self.server_status)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def receive_server(self):
|
|
||||||
while self.server_status:
|
|
||||||
try:
|
|
||||||
receive_content_json = self.server_socket.recv(1024).decode('utf-8')
|
|
||||||
receive_content = json.loads(receive_content_json)
|
|
||||||
self.content_pick(receive_content)
|
|
||||||
except Exception as a:
|
|
||||||
print("客户端接收错误:" + str(a))
|
|
||||||
self.server_status = False
|
|
||||||
self.Process_client_send("ALL", "server_status", self.server_status)
|
|
||||||
|
|
||||||
def send_server(self, genre, target, content):
|
|
||||||
if self.server_status:
|
|
||||||
try:
|
|
||||||
data = {"genre": genre, "target": target, "data": content,
|
|
||||||
"datetime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
|
|
||||||
data_json = json.dumps(data) + '\n'
|
|
||||||
self.server_socket.send(data_json.encode("utf-8"))
|
|
||||||
except Exception as a:
|
|
||||||
print("发送错误:" + str(a))
|
|
||||||
self.server_status = False
|
|
||||||
self.Process_client_send("ALL", "server_status", self.server_status)
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'Session_server']:
|
|
||||||
match data['function']:
|
|
||||||
case 'server_status':
|
|
||||||
self.server_status = data['content']
|
|
||||||
case 'send_server':
|
|
||||||
self.send_server(data['content']['genre'], data['content']['target'], data['content']['content'])
|
|
||||||
|
|
||||||
def content_pick(self, data):
|
|
||||||
match data['genre']:
|
|
||||||
case '注册' | '登录':
|
|
||||||
self.Process_client_send("Login", "login_page_receive", data)
|
|
||||||
case '数据更新':
|
|
||||||
self.Process_client_send("File_operate", "save_data", data['data'])
|
|
||||||
case '聊天记录':
|
|
||||||
if data['data']['Type'] == 'text':
|
|
||||||
self.Process_client_send("File_operate", "save_data", {"History": data['data']})
|
|
||||||
if data['target'] == '接收':
|
|
||||||
self.Process_client_send("Chat_main", "Chat_screen_show", data['data'])
|
|
@ -1,4 +0,0 @@
|
|||||||
from .Process_Server import *
|
|
||||||
from .Process_Client import *
|
|
||||||
from .Session_server import *
|
|
||||||
from .File_operate import *
|
|
@ -1,16 +0,0 @@
|
|||||||
from .Page import *
|
|
||||||
from .Transmission import *
|
|
||||||
|
|
||||||
|
|
||||||
class start_all:
|
|
||||||
def __init__(self):
|
|
||||||
ProcessServer()
|
|
||||||
|
|
||||||
Session_server()
|
|
||||||
|
|
||||||
FileOperate(None)
|
|
||||||
|
|
||||||
app = wx.App()
|
|
||||||
LoginFrame().Show()
|
|
||||||
app.MainLoop()
|
|
||||||
|
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 7.1 KiB |
@ -1,181 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import pymssql
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
from .Process_Client import *
|
|
||||||
|
|
||||||
|
|
||||||
class database(ProcessClient):
|
|
||||||
def __init__(self):
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
self.database_server = 'localhost'
|
|
||||||
self.database_user = 'Chat'
|
|
||||||
self.database_password = '123456'
|
|
||||||
self.database_port = 8972
|
|
||||||
self.database_name = 'Chat'
|
|
||||||
self.database_state = False
|
|
||||||
self.database_conn = None
|
|
||||||
self.database_cursor = None
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
self.link_database_thread = threading.Thread(target=self.link_database)
|
|
||||||
self.link_database_thread.start()
|
|
||||||
|
|
||||||
# 创建一个互斥锁对象
|
|
||||||
self.lock = threading.Lock()
|
|
||||||
|
|
||||||
def link_database(self):
|
|
||||||
while not self.database_state:
|
|
||||||
time.sleep(1)
|
|
||||||
try:
|
|
||||||
self.database_conn = pymssql.connect(server=self.database_server,
|
|
||||||
user=self.database_user,
|
|
||||||
password=self.database_password,
|
|
||||||
port=self.database_port,
|
|
||||||
database=self.database_name)
|
|
||||||
self.database_cursor = self.database_conn.cursor()
|
|
||||||
self.database_state = True
|
|
||||||
except pymssql.Error as a:
|
|
||||||
print(a)
|
|
||||||
|
|
||||||
def check_account_state(self, client_id, Id: int, password):
|
|
||||||
if self.database_state:
|
|
||||||
try:
|
|
||||||
state = 2
|
|
||||||
self.database_cursor.execute(f"select Id,Password from Account where Id = {Id}")
|
|
||||||
request_data = self.database_cursor.fetchall()
|
|
||||||
if len(request_data) != 0:
|
|
||||||
if request_data[0][1] == password:
|
|
||||||
state = 0
|
|
||||||
else:
|
|
||||||
state = 1
|
|
||||||
|
|
||||||
content = {"account": Id, "status": state}
|
|
||||||
data = {"client_id": client_id, "target": "客户端", "genre": "登录", "data": content}
|
|
||||||
self.Process_client_send('Session_client', 'send_client', data)
|
|
||||||
|
|
||||||
except pymssql as a:
|
|
||||||
self.database_state = False
|
|
||||||
print(a)
|
|
||||||
|
|
||||||
def sign_account(self, client_id, NetName, Password):
|
|
||||||
if self.database_state:
|
|
||||||
# 获取锁
|
|
||||||
self.lock.acquire()
|
|
||||||
try:
|
|
||||||
self.database_cursor.execute("insert into Account(NetName, Password)"
|
|
||||||
f"values ('{NetName}','{Password}')")
|
|
||||||
self.database_conn.commit()
|
|
||||||
self.database_cursor.execute(f"SELECT SCOPE_IDENTITY() AS LastInsertedId;")
|
|
||||||
Id = self.database_cursor.fetchone()[0]
|
|
||||||
# 释放锁
|
|
||||||
self.lock.release()
|
|
||||||
info = {"Id": int(Id), "NetName": NetName, "Password": Password}
|
|
||||||
|
|
||||||
content = {"client_id": client_id, "target": "客户端", "genre": "注册", "data": info}
|
|
||||||
self.Process_client_send('Session_client', 'send_client', content)
|
|
||||||
|
|
||||||
except pymssql as a:
|
|
||||||
self.lock.release()
|
|
||||||
self.database_state = False
|
|
||||||
return False
|
|
||||||
|
|
||||||
def alter_state_database(self, Id: int, sate):
|
|
||||||
if self.database_state:
|
|
||||||
try:
|
|
||||||
self.database_cursor.execute(f"update Account set State = N'{sate}' where Id = {Id}")
|
|
||||||
self.database_conn.commit()
|
|
||||||
except pymssql as a:
|
|
||||||
self.database_state = False
|
|
||||||
print(a)
|
|
||||||
|
|
||||||
def detection_data(self, Id, date):
|
|
||||||
datas = []
|
|
||||||
|
|
||||||
self.database_cursor.execute(f"select Id,Password,NetName,UpDataTime from Account where Id = {Id}")
|
|
||||||
Account_database = self.database_cursor.fetchall()
|
|
||||||
Account_content = {'Id': Account_database[0][0],
|
|
||||||
'Password': Account_database[0][1],
|
|
||||||
'NetName': Account_database[0][2],
|
|
||||||
'UpDataTime': Account_database[0][3].strftime('%Y-%m-%d %H:%M:%S')}
|
|
||||||
if Account_content['UpDataTime'] == date:
|
|
||||||
content = {"client_id": Id, "target": "客户端", "genre": "数据更新", "data": {"更新完成": Id}}
|
|
||||||
self.Process_client_send('Session_client', 'send_client', content)
|
|
||||||
return
|
|
||||||
|
|
||||||
Account_data = {"Account": Account_content}
|
|
||||||
datas.append(Account_data)
|
|
||||||
|
|
||||||
self.database_cursor.execute(
|
|
||||||
f"select ContactsId,Remark,State,UpDataTime from Contacts where UserId = {Id} and UpDataTime > '{date}'")
|
|
||||||
Contacts_database = self.database_cursor.fetchall()
|
|
||||||
for Contact in Contacts_database:
|
|
||||||
Contacts_content = {'Contact': Contact[0],
|
|
||||||
'Remark': Contact[1],
|
|
||||||
'State': Contact[2],
|
|
||||||
'UpDataTime': Contact[3].strftime('%Y-%m-%d %H:%M:%S')}
|
|
||||||
Contacts_data = {"Contacts": Contacts_content}
|
|
||||||
datas.append(Contacts_data)
|
|
||||||
|
|
||||||
self.database_cursor.execute(f"select * from History where Send = {Id} or Receive = {Id} and Time > '{date}'")
|
|
||||||
History_database = self.database_cursor.fetchall()
|
|
||||||
for History in History_database:
|
|
||||||
content = {
|
|
||||||
'Send': History[0],
|
|
||||||
'Receive': History[1],
|
|
||||||
'Type': History[2],
|
|
||||||
'Content': History[3],
|
|
||||||
'Time': History[4].strftime('%Y-%m-%d %H:%M:%S')}
|
|
||||||
History_data = {"History": content}
|
|
||||||
datas.append(History_data)
|
|
||||||
|
|
||||||
datas.append({"更新完成": Id})
|
|
||||||
|
|
||||||
for data in datas:
|
|
||||||
time.sleep(0.1)
|
|
||||||
content = {"client_id": Id, "target": "客户端", "genre": "数据更新", "data": data}
|
|
||||||
self.Process_client_send('Session_client', 'send_client', content)
|
|
||||||
|
|
||||||
def update_History(self, Send, Receive, Type, Content, Time):
|
|
||||||
if self.database_state:
|
|
||||||
try:
|
|
||||||
self.database_cursor.execute(f"insert into History(Send, Receive, Type, Content,Time)"
|
|
||||||
f"select {Send},{Receive},'{Type}',N'{Content}','{Time}'")
|
|
||||||
self.database_conn.commit()
|
|
||||||
except pymssql as a:
|
|
||||||
self.database_state = False
|
|
||||||
print(a)
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'Database_formula']:
|
|
||||||
match data['function']:
|
|
||||||
case 'check_account_state':
|
|
||||||
|
|
||||||
self.check_account_state(data['content']['client_id'],
|
|
||||||
data['content']['account'],
|
|
||||||
data['content']['password'])
|
|
||||||
|
|
||||||
case 'sign_account':
|
|
||||||
|
|
||||||
self.sign_account(data['content']['client_id'],
|
|
||||||
data['content']['account'],
|
|
||||||
data['content']['password'])
|
|
||||||
|
|
||||||
case 'alter_state_database':
|
|
||||||
self.alter_state_database(data['content']['Id'],
|
|
||||||
data['content']['sate'])
|
|
||||||
|
|
||||||
case 'detection_data':
|
|
||||||
self.detection_data(data['content']['client_id'],
|
|
||||||
data['content']['date'])
|
|
||||||
|
|
||||||
case 'update_History':
|
|
||||||
self.update_History(data['content']['Send'],
|
|
||||||
data['content']['Receive'],
|
|
||||||
data['content']['Type'],
|
|
||||||
data['content']['Content'],
|
|
||||||
data['content']['Time'])
|
|
@ -1,30 +0,0 @@
|
|||||||
import json
|
|
||||||
import threading
|
|
||||||
from multiprocessing.connection import Client
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessClient:
|
|
||||||
def __init__(self):
|
|
||||||
self.Process_port = 3244
|
|
||||||
self.Process_server = 'localhost'
|
|
||||||
self.Process_client_Client = Client((self.Process_server, self.Process_port))
|
|
||||||
Process_client_recv = threading.Thread(target=self.Process_client_recv)
|
|
||||||
Process_client_recv.start()
|
|
||||||
|
|
||||||
def Process_client_send(self, target, function, content):
|
|
||||||
data = {"target": target, "function": function, "content": content}
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
self.Process_client_Client.send(data_json)
|
|
||||||
|
|
||||||
def Process_client_recv(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data_json = self.Process_client_Client.recv()
|
|
||||||
data = json.loads(data_json)
|
|
||||||
self.Process_client_pick(data)
|
|
||||||
except EOFError:
|
|
||||||
print("连接已关闭")
|
|
||||||
break
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
pass
|
|
@ -1,49 +0,0 @@
|
|||||||
import json
|
|
||||||
import multiprocessing
|
|
||||||
from multiprocessing.connection import Listener
|
|
||||||
import threading
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessServer:
|
|
||||||
def __init__(self):
|
|
||||||
try:
|
|
||||||
self.Process_port = 3244
|
|
||||||
self.Process_server = 'localhost'
|
|
||||||
self.Process_server_listener = Listener((self.Process_server, self.Process_port))
|
|
||||||
self.Process_client_link_dick = {}
|
|
||||||
Process_client_link_Thread = threading.Thread(target=self.Process_client_link)
|
|
||||||
Process_client_link_Thread.start()
|
|
||||||
except:
|
|
||||||
print("进程通信端口绑定失败")
|
|
||||||
|
|
||||||
def Process_client_link(self):
|
|
||||||
while True:
|
|
||||||
client_connect = self.Process_server_listener.accept()
|
|
||||||
client_Thread_recv = threading.Thread(target=self.Process_client_recv, args=(client_connect,))
|
|
||||||
client_Thread_recv.start()
|
|
||||||
|
|
||||||
def Process_client_recv(self, client_Thread_recv):
|
|
||||||
while True:
|
|
||||||
data_json = client_Thread_recv.recv()
|
|
||||||
data = json.loads(data_json)
|
|
||||||
if data['target'] == 'Server':
|
|
||||||
if data['function'] == 'Name':
|
|
||||||
self.Process_client_link_dick[data['content']] = client_Thread_recv
|
|
||||||
else:
|
|
||||||
self.Process_client_pick(data)
|
|
||||||
|
|
||||||
def Process_client_send(self, target, function, content):
|
|
||||||
connect = self.Process_client_link_dick[target]
|
|
||||||
data = {"target": target, "function": function, "content": content}
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
connect.send(data_json)
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] == 'ALL':
|
|
||||||
for value in self.Process_client_link_dick.values():
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
value.send(data_json)
|
|
||||||
else:
|
|
||||||
if data['target'] in self.Process_client_link_dick.keys():
|
|
||||||
data_json = json.dumps(data)
|
|
||||||
self.Process_client_link_dick[data['target']].send(data_json)
|
|
@ -1,127 +0,0 @@
|
|||||||
import os
|
|
||||||
import random
|
|
||||||
import string
|
|
||||||
import time
|
|
||||||
import socket
|
|
||||||
import json
|
|
||||||
import threading
|
|
||||||
from .Process_Client import *
|
|
||||||
|
|
||||||
|
|
||||||
class link_client(ProcessClient):
|
|
||||||
def __init__(self):
|
|
||||||
ProcessClient.__init__(self)
|
|
||||||
self.server_host = "127.0.0.1"
|
|
||||||
self.server_port = 7868
|
|
||||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.server_socket.bind((self.server_host, self.server_port))
|
|
||||||
self.server_socket.listen()
|
|
||||||
self.client_socket_dict = {}
|
|
||||||
self.client_max_id = 0
|
|
||||||
|
|
||||||
current_file_path = __file__
|
|
||||||
current_file_name = os.path.basename(current_file_path).split('.')[0]
|
|
||||||
self.Process_client_send("Server", "Name", current_file_name)
|
|
||||||
|
|
||||||
self.link_client_Thread = threading.Thread(target=self.link_client)
|
|
||||||
self.link_client_Thread.start()
|
|
||||||
|
|
||||||
def link_client(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
client_socket, client_address = self.server_socket.accept()
|
|
||||||
self.client_max_id += 1
|
|
||||||
client_id = ''.join(random.choice(string.ascii_letters) for _ in range(10)) + str(self.client_max_id)
|
|
||||||
self.client_socket_dict[client_id] = client_socket
|
|
||||||
recv_client_Thread = threading.Thread(target=self.recv_client, args=(client_socket,), daemon=True)
|
|
||||||
recv_client_Thread.start()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def send_client(self, client_id, genre, target, content):
|
|
||||||
client_socket = self.client_socket_dict[client_id]
|
|
||||||
try:
|
|
||||||
data = {"genre": genre, "target": target, "data": content,
|
|
||||||
"datetime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
|
|
||||||
data_json = json.dumps(data) + '\n'
|
|
||||||
client_socket.send(data_json.encode("utf-8"))
|
|
||||||
except:
|
|
||||||
client_socket.close()
|
|
||||||
|
|
||||||
def pick_data(self, client_id, data):
|
|
||||||
match data['genre']:
|
|
||||||
case '登录':
|
|
||||||
content = {'client_id': client_id, 'account': data['data']['account'],
|
|
||||||
'password': data['data']['password']}
|
|
||||||
self.Process_client_send("Database_formula", "check_account_state", content)
|
|
||||||
case '注册':
|
|
||||||
content = {'client_id': client_id, 'account': data['data']['account'],
|
|
||||||
'password': data['data']['password']}
|
|
||||||
self.Process_client_send("Database_formula", "sign_account", content)
|
|
||||||
case '数据更新':
|
|
||||||
content = {'client_id': client_id, 'date': data['data']}
|
|
||||||
self.Process_client_send("Database_formula", "detection_data", content)
|
|
||||||
case '聊天记录':
|
|
||||||
Send = client_id
|
|
||||||
Receive = data['target']
|
|
||||||
Time = data['datetime']
|
|
||||||
data = data['data']
|
|
||||||
Type = data['Type']
|
|
||||||
Content = data['content']
|
|
||||||
content = {'Send': Send, 'Receive': Receive, 'Time': Time, 'Type': Type, 'Content': Content}
|
|
||||||
self.Process_client_send("Database_formula", "update_History", content)
|
|
||||||
self.send_client(Send, "聊天记录", "发送", content)
|
|
||||||
if Receive in self.client_socket_dict:
|
|
||||||
self.send_client(Receive, "聊天记录", "接收", content)
|
|
||||||
|
|
||||||
def recv_client(self, client_socket):
|
|
||||||
state = True
|
|
||||||
while state:
|
|
||||||
try:
|
|
||||||
data_json = client_socket.recv(1024).decode('utf-8')
|
|
||||||
data = json.loads(data_json)
|
|
||||||
client_Id = self.find_client(client_socket, None)
|
|
||||||
self.pick_data(client_Id, data)
|
|
||||||
except:
|
|
||||||
try:
|
|
||||||
client_socket.close()
|
|
||||||
finally:
|
|
||||||
state = False
|
|
||||||
self.find_client(client_socket, None)
|
|
||||||
client_id = self.find_client(client_socket, None)
|
|
||||||
del self.client_socket_dict[client_id]
|
|
||||||
if client_id.isdigit():
|
|
||||||
self.Process_client_send("Database_formula", "alter_state_database",
|
|
||||||
{"Id": client_id, "sate": 0})
|
|
||||||
|
|
||||||
def Process_client_pick(self, data):
|
|
||||||
if data['target'] in ['ALL', 'Session_client']:
|
|
||||||
match data['function']:
|
|
||||||
case 'send_client':
|
|
||||||
client_id = data['content']['client_id']
|
|
||||||
genre = data['content']['genre']
|
|
||||||
target = data['content']['target']
|
|
||||||
content = data['content']['data']
|
|
||||||
if data['content']['genre'] == '登录':
|
|
||||||
if content['account'] not in self.client_socket_dict:
|
|
||||||
if content['status'] == 0:
|
|
||||||
client_socket = self.find_client(None, client_id)
|
|
||||||
del self.client_socket_dict[client_id]
|
|
||||||
client_id = content['account']
|
|
||||||
self.client_socket_dict[client_id] = client_socket
|
|
||||||
if client_id.isdigit():
|
|
||||||
self.Process_client_send("Database_formula", "alter_state_database",
|
|
||||||
{"Id": client_id, "sate": 1})
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
self.send_client(client_id, genre, target, content)
|
|
||||||
|
|
||||||
def find_client(self, client_socket, client_id):
|
|
||||||
if client_id is None:
|
|
||||||
for key, value in self.client_socket_dict.items():
|
|
||||||
if value == client_socket:
|
|
||||||
return key
|
|
||||||
elif client_socket is None:
|
|
||||||
for key, value in self.client_socket_dict.items():
|
|
||||||
if key == client_id:
|
|
||||||
return value
|
|
@ -1,4 +0,0 @@
|
|||||||
from .Process_Server import *
|
|
||||||
from .Process_Client import *
|
|
||||||
from .Session_client import *
|
|
||||||
from .Database_formula import *
|
|
@ -1,11 +0,0 @@
|
|||||||
from .Transmission import *
|
|
||||||
|
|
||||||
|
|
||||||
class Server_main:
|
|
||||||
def __init__(self):
|
|
||||||
ProcessServer()
|
|
||||||
database()
|
|
||||||
link_client()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
from Client import start_all
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
start_all()
|
|
@ -1,4 +0,0 @@
|
|||||||
from Server import Server_main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
Server_main()
|
|
@ -1,6 +0,0 @@
|
|||||||
from Client import start_all
|
|
||||||
from Server import Server_main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
Server_main()
|
|
||||||
start_all()
|
|
113
web/shang_shopping/css/index.css
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*基础设置*/
|
||||||
|
.container{
|
||||||
|
width:1190px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* region 顶部导航条 */
|
||||||
|
.top_bar{
|
||||||
|
height:30px;
|
||||||
|
line-height:30px;
|
||||||
|
background-color:#ECECEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*左侧导航区*/
|
||||||
|
.nav_left{
|
||||||
|
font-size: 0;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_left a,.nav_left span{
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_left .welcome{
|
||||||
|
margin-right:28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_left .login{
|
||||||
|
padding-right:10px;
|
||||||
|
border-right: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_left .register{
|
||||||
|
margin-left:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*右侧导航区*/
|
||||||
|
.nav_right .list{
|
||||||
|
margin:0 auto;
|
||||||
|
height: 30px;
|
||||||
|
line-height:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_right .list li{
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_right .list li a{
|
||||||
|
font-size: 12px;
|
||||||
|
padding:0 15px;
|
||||||
|
border-right: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_right .list li:first-child a{
|
||||||
|
padding-left:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_right .list li:last-child a{
|
||||||
|
padding-right:0;
|
||||||
|
border:0;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* endregion 顶部导航条结束 */
|
||||||
|
|
||||||
|
/* region 头部区域 */
|
||||||
|
.header .header_logo{
|
||||||
|
height:120px;
|
||||||
|
line-height: 120px;
|
||||||
|
font-size:0;
|
||||||
|
}
|
||||||
|
.header .header_search form{
|
||||||
|
margin-top: 42px;
|
||||||
|
font-size:0;
|
||||||
|
}
|
||||||
|
.header .header_search input{
|
||||||
|
width:508px;
|
||||||
|
height:34px;
|
||||||
|
border:1px solid #DD302D;
|
||||||
|
}
|
||||||
|
.header .header_search button{
|
||||||
|
width:80px;
|
||||||
|
height:36px;
|
||||||
|
background-color:#DD302D;
|
||||||
|
vertical-align: top;
|
||||||
|
background-image: url("../images/serch_icon.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
/* endregion 头部区域结束 */
|
||||||
|
|
||||||
|
/* region 主导航 */
|
||||||
|
.main_nav{
|
||||||
|
height:48px;
|
||||||
|
border-bottom: 1px solid #DD302D;
|
||||||
|
}
|
||||||
|
.main_nav .all-type{
|
||||||
|
height:48px;
|
||||||
|
width:190px;
|
||||||
|
background-color:#DD302D;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
.main_nav .main_nav_list li{
|
||||||
|
float:left;
|
||||||
|
color:#333333;
|
||||||
|
text-align:center;
|
||||||
|
line-height:48px;
|
||||||
|
margin:0 10px ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* endregion 主导航结束 */
|
57
web/shang_shopping/css/reset.css
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*清除盒子边框设置*/
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: PingFangSC-Medium, sans-serif;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*文字默认颜色*/
|
||||||
|
span{
|
||||||
|
color:#666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*超链接设置*/
|
||||||
|
a:link{
|
||||||
|
color:#666666;
|
||||||
|
}
|
||||||
|
a:visited{
|
||||||
|
color:#666666;
|
||||||
|
}
|
||||||
|
a:hover{
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*清除浮动效果*/
|
||||||
|
.float_clear::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*左浮动*/
|
||||||
|
.float_left{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*右浮动*/
|
||||||
|
.float_right{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*a标签*/
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight:500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*列表*/
|
||||||
|
ul,dl,ol{
|
||||||
|
list-style-type:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*按钮*/
|
||||||
|
button{
|
||||||
|
border-style:none;
|
||||||
|
}
|
BIN
web/shang_shopping/images/appliance_banner07.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
web/shang_shopping/images/baner4.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
web/shang_shopping/images/banner1.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
web/shang_shopping/images/banner2.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
web/shang_shopping/images/banner3.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
web/shang_shopping/images/banner主图.png
Normal file
After Width: | Height: | Size: 314 KiB |
BIN
web/shang_shopping/images/icon_huoche.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
web/shang_shopping/images/icon_众筹_nor.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
web/shang_shopping/images/icon_加油卡_nor.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
web/shang_shopping/images/icon_彩票_nor.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
web/shang_shopping/images/icon_机票_nor.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
web/shang_shopping/images/icon_游戏_nor.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
web/shang_shopping/images/icon_理财_nor.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
web/shang_shopping/images/icon_电影票_nor.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
web/shang_shopping/images/icon_白条_nor.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
web/shang_shopping/images/icon_礼品卡_nor.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
web/shang_shopping/images/icon_话费_nor.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
web/shang_shopping/images/icon_酒店_nor.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
web/shang_shopping/images/logo.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
web/shang_shopping/images/seckill.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
web/shang_shopping/images/serch_icon.png
Normal file
After Width: | Height: | Size: 637 B |
BIN
web/shang_shopping/images/冰箱.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
web/shang_shopping/images/微波炉.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
web/shang_shopping/images/电饭煲.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
web/shang_shopping/images/电饭煲2.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
web/shang_shopping/images/空气炸锅.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
web/shang_shopping/images/精灵图-侧边功能.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
web/shang_shopping/images/精灵图-其他.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
web/shang_shopping/images/编组.png
Normal file
After Width: | Height: | Size: 61 KiB |
75
web/shang_shopping/index.html
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang = "zh_CN">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv = "Content-Type" content = "text/html;charset=utf-8">
|
||||||
|
<title>购物网</title>
|
||||||
|
<!--引入重置样式-->
|
||||||
|
<link rel="stylesheet" href="./css/reset.css">
|
||||||
|
<!--引入样式-->
|
||||||
|
<link rel="stylesheet" href="./css/index.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!--顶部导航条-->
|
||||||
|
<div class="top_bar">
|
||||||
|
<!--版心-->
|
||||||
|
<div class="container float_clear">
|
||||||
|
<!--左侧导航区-->
|
||||||
|
<div class="nav_left float_left">
|
||||||
|
<span class="welcome">欢迎您</span>
|
||||||
|
<a href="#" class="login">请登录</a>
|
||||||
|
<a href="#" class="register">免费注册</a>
|
||||||
|
</div>
|
||||||
|
<!--右侧导航区-->
|
||||||
|
<div class="nav_right float_right">
|
||||||
|
<ul class="list">
|
||||||
|
<li><a href="#">我的订单</a></li>
|
||||||
|
<li><a href="#">我的购物车</a></li>
|
||||||
|
<li><a href="#">我的信息</a></li>
|
||||||
|
<li><a href="#">会员中心</a></li>
|
||||||
|
<li><a href="#">企业采购</a></li>
|
||||||
|
<li><a href="#">关注购物网</a></li>
|
||||||
|
<li><a href="#">合作招商</a></li>
|
||||||
|
<li><a href="#">商家后台</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--头部区域-->
|
||||||
|
<div class="header">
|
||||||
|
<!--版心-->
|
||||||
|
<div class="container float_clear">
|
||||||
|
<!--图标区-->
|
||||||
|
<div class="header_logo float_left">
|
||||||
|
<img src="./images/logo.png" alt="LOGO">
|
||||||
|
</div>
|
||||||
|
<!--搜索区-->
|
||||||
|
<div class="header_search float_right">
|
||||||
|
<form action="#">
|
||||||
|
<input type="text">
|
||||||
|
<button></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--主导航-->
|
||||||
|
<div class="main_nav">
|
||||||
|
<!--版心-->
|
||||||
|
<div class="container float_clear">
|
||||||
|
<div class="all-type float_left">全部商品分类</div>
|
||||||
|
<ul class="main_nav_list float_left">
|
||||||
|
<li><a href="#" >超市</a></li>
|
||||||
|
<li><a href="#" >优惠卷</a></li>
|
||||||
|
<li><a href="#" >买啥</a></li>
|
||||||
|
<li><a href="#" >家电</a></li>
|
||||||
|
<li><a href="#" >生鲜</a></li>
|
||||||
|
<li><a href="#" >PLUS会员</a></li>
|
||||||
|
<li><a href="#" >进口好物</a></li>
|
||||||
|
<li><a href="#" >品牌闪购</a></li>
|
||||||
|
<li><a href="#" >拍卖</a></li>
|
||||||
|
<li><a href="#" >五金商店</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|