diff --git a/acdr-ui/env/.env b/acdr-ui/env/.env index fe28e99b..0de6b1aa 100644 --- a/acdr-ui/env/.env +++ b/acdr-ui/env/.env @@ -7,10 +7,11 @@ VITE_WX_APPID = 'wxf2c6d4b7361366b4' # h5部署网站的base,配置到 manifest.config.ts 里的 h5.router.base VITE_APP_PUBLIC_BASE=/acdr/ -VITE_SERVER_BASEURL = 'http://47.99.70.12:28184/api' +# VITE_SERVER_BASEURL = 'http://47.99.70.12:28184/api' # VITE_UPLOAD_BASEURL = 'http://47.99.70.12:28184' # VITE_SERVER_BASEURL = 'http://localhost:28184/api' -VITE_WS_BASEURL = 'ws://47.99.70.12:28184/api' +VITE_SERVER_BASEURL = 'http://localhost:48080/app-api' +# VITE_WS_BASEURL = 'ws://47.99.70.12:28184/api' VITE_UPLOAD_BASEURL = 'http://localhost:28184' VITE_OSS_BASEURL = 'http://116.204.119.171:9000/linghe' @@ -25,8 +26,8 @@ SHOPRO_VERSION = v1.8.3 SHOPRO_BASE_URL = http://api-dashboard.yudao.iocoder.cn # 后端接口 - 测试环境(通过 process.env.NODE_ENV = development) -# SHOPRO_DEV_BASE_URL = http://127.0.0.1:48080 -SHOPRO_DEV_BASE_URL = http://47.99.70.12:48080 +SHOPRO_DEV_BASE_URL = http://127.0.0.1:48080 +# SHOPRO_DEV_BASE_URL = http://47.99.70.12:48080 ### SHOPRO_DEV_BASE_URL = http://yunai.natapp1.cc # 后端接口前缀(一般不建议调整) diff --git a/acdr-ui/src/manifest.json b/acdr-ui/src/manifest.json index f258510d..d2340f5e 100644 --- a/acdr-ui/src/manifest.json +++ b/acdr-ui/src/manifest.json @@ -1,6 +1,6 @@ { "name": "宠屋", - "appid": "H57F2ACE4", + "appid": "__UNI__9D479DC", "description": "", "versionName": "1.0.0", "versionCode": "100", diff --git a/acdr-ui/src/pages/login/phone.vue b/acdr-ui/src/pages/login/phone.vue index 8978786c..92f410f9 100644 --- a/acdr-ui/src/pages/login/phone.vue +++ b/acdr-ui/src/pages/login/phone.vue @@ -38,7 +38,7 @@ import { ref, onMounted, onUnmounted } from 'vue' import { httpGet, httpPost } from '@/utils/http' import { useUserStore } from '@/store/user' import TopBar from '@/components/TopBar.vue' -import { imgUrl } from '@/utils/commUtils' +import { imgUrl, toast, toPath } from "@/utils/commUtils"; const userStore = useUserStore() @@ -50,26 +50,15 @@ let timer = null const sendCode = async () => { if (countdown.value === 0) { if (!phoneNumber.value) { - uni.showToast({ - title: '请输入手机号', - icon: 'none', - }) + toast('请输入手机号') return } - console.log('发送验证码到', phoneNumber.value) const res = await httpGet('/public/getCode', { phone: phoneNumber.value }) - console.log(res) countdown.value = 60 - if (res.code == 200) { - uni.showToast({ - title: res.message, - icon: 'none', - }) + if (res.code === 200) { + toast(res.message) } else { - uni.showToast({ - title: res.message, - icon: 'none', - }) + toast(res.message) } timer = setInterval(() => { countdown.value -= 1 @@ -96,29 +85,24 @@ const login = async () => { return } const res = await httpPost('/public/login', {}, { phone: phoneNumber.value, code: code.value }) - if (res.code == 200) { - uni.showToast({ - title: res.message, - icon: 'none', + if (res.code === 200) { + toast(res.message) + const data = res.data + userStore.setUserInfo({ + id: data.userId , + token: data.accessToken, + expiresTime: data.expiresTime, + refreshToken: data.refreshToken }) - userStore.setUserInfo({ token: res.data.userToken, shopLoginUser: res.data.shopLoginUser }) const userRes = await httpGet('/user/userinfo') - if (userRes.code == 200) { + if (userRes.code === 200) { userStore.setUserInfo(userRes.data) - uni.switchTab({ - url: '/pages/index/index', - }) + toPath('/') } else { - uni.showToast({ - title: userRes.message, - icon: 'none', - }) + toast(userRes.message || '登录失败请重新登录!') } } else { - uni.showToast({ - title: res.message, - icon: 'none', - }) + toast(res.message || '登录失败请重新登录!') } } diff --git a/acdr-ui/src/store/user.js b/acdr-ui/src/store/user.js index c0a2ea2d..86e305b7 100644 --- a/acdr-ui/src/store/user.js +++ b/acdr-ui/src/store/user.js @@ -6,17 +6,16 @@ const initState = { avatar: '', id: null, name: '', - phone: '', - email: '', - typeId: '', + mobile: '', + cardId: '', createTime: '', updateTime: '', token: '', sex: '', - openid: '', // 微信openid,如果不为空就证明用户是用微信登录的 isRealName: false, isPetNursery: false, - shopLoginUser: null, + expiresTime: '', + refreshToken: '', } export const useUserStore = defineStore( diff --git a/acdr-ui/tootls/gif制作脚本.py b/acdr-ui/tootls/gif制作脚本.py new file mode 100644 index 00000000..77e75c4b --- /dev/null +++ b/acdr-ui/tootls/gif制作脚本.py @@ -0,0 +1,45 @@ +import tkinter as tk +from tkinter import filedialog, messagebox +from PIL import Image + +class GIFMakerApp: + def __init__(self, root): + self.root = root + self.root.title("GIF Maker") + + # 选择图片按钮 + self.select_button = tk.Button(root, text="选择图片", command=self.select_images) + self.select_button.pack(pady=10) + + # 保存 GIF 按钮 + self.save_button = tk.Button(root, text="保存 GIF", command=self.save_gif, state=tk.DISABLED) + self.save_button.pack(pady=10) + + self.images = [] # 保存选择的图片 + + def select_images(self): + # 选择多张图片 + image_paths = filedialog.askopenfilenames(title="选择图片", filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp"), ("All files", "*.*")]) + if image_paths: + self.images = [Image.open(image_path) for image_path in image_paths] # 打开所有选择的图片 + messagebox.showinfo("已选择图片", f"已选择 {len(self.images)} 张图片") + self.save_button.config(state=tk.NORMAL) # 启用保存按钮 + + def save_gif(self): + if not self.images: + messagebox.showwarning("警告", "没有选择图片!") + return + + # 设置保存文件名 + save_path = filedialog.asksaveasfilename(defaultextension=".gif", filetypes=[("GIF files", "*.gif")]) + if save_path: + # 保存为GIF,指定每帧的时间间隔 + self.images[0].save(save_path, save_all=True, append_images=self.images[1:], duration=10, loop=0) + messagebox.showinfo("成功", f"GIF 已保存到: {save_path}") + +# 启动 GUI 应用 +if __name__ == "__main__": + root = tk.Tk() + app = GIFMakerApp(root) + root.geometry("300x200") + root.mainloop() diff --git a/acdr-ui/tootls/图片截取位置.py b/acdr-ui/tootls/图片截取位置.py new file mode 100644 index 00000000..29b84114 --- /dev/null +++ b/acdr-ui/tootls/图片截取位置.py @@ -0,0 +1,126 @@ +import tkinter as tk +from tkinter import filedialog, messagebox +from PIL import Image, ImageTk +import os + +class ImageCropApp: + def __init__(self, root): + self.root = root + self.root.title("Multi Image Crop Tool") + + # 选择图片按钮 + self.select_button = tk.Button(root, text="选择图片", command=self.select_images) + self.select_button.pack(pady=10) + + # 画布,用于显示图片 + self.canvas = tk.Canvas(root, cursor="cross") + self.canvas.pack(fill=tk.BOTH, expand=True) + + self.images = [] # 用于保存选择的多张图片路径 + self.image = None # 当前显示的图片 + self.rect_start_x = 0 + self.rect_start_y = 0 + self.rect_end_x = 0 + self.rect_end_y = 0 + self.rect = None + self.tk_image = None + self.save_dir = None # 保存路径 + self.image_display_width = 0 # 显示图片的宽度 + self.image_display_height = 0 # 显示图片的高度 + self.image_original_width = 0 # 图片的原始宽度 + self.image_original_height = 0 # 图片的原始高度 + + # 鼠标事件 + self.canvas.bind("", self.start_selection) + self.canvas.bind("", self.update_selection) + self.canvas.bind("", self.finish_selection) + + def select_images(self): + # 多文件选择 + image_paths = filedialog.askopenfilenames(title="选择多张图片", filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp"), ("All files", "*.*")]) + if image_paths: + self.images = list(image_paths) # 将文件路径保存为列表 + self.load_first_image() + + def load_first_image(self): + # 加载第一张图片并显示在画布上 + if self.images: + self.image = Image.open(self.images[0]) + self.image_original_width, self.image_original_height = self.image.size # 获取原始尺寸 + self.display_image() + + def display_image(self): + # 调整图片大小适应窗口 + self.image.thumbnail((self.root.winfo_width(), self.root.winfo_height())) # 缩放图片 + self.tk_image = ImageTk.PhotoImage(self.image) + + self.image_display_width, self.image_display_height = self.image.size # 显示的宽高 + + self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image) + + def start_selection(self, event): + # 记录起始点 + self.rect_start_x = event.x + self.rect_start_y = event.y + # 创建一个选择框 + self.rect = self.canvas.create_rectangle(self.rect_start_x, self.rect_start_y, self.rect_start_x, self.rect_start_y, outline="red", width=2) + + def update_selection(self, event): + # 更新选择框大小 + self.rect_end_x = event.x + self.rect_end_y = event.y + self.canvas.coords(self.rect, self.rect_start_x, self.rect_start_y, self.rect_end_x, self.rect_end_y) + + def finish_selection(self, event): + self.rect_end_x = event.x + self.rect_end_y = event.y + self.crop_images() + + def crop_images(self): + if self.images: + # 计算图像与显示窗口的比例 + x_ratio = self.image_original_width / self.image_display_width + y_ratio = self.image_original_height / self.image_display_height + + # 获取选择框的坐标,并转换为图片的实际坐标 + left = min(self.rect_start_x, self.rect_end_x) * x_ratio + top = min(self.rect_start_y, self.rect_end_y) * y_ratio + right = max(self.rect_start_x, self.rect_end_x) * x_ratio + bottom = max(self.rect_start_y, self.rect_end_y) * y_ratio + + # 让用户选择保存文件夹,只选择一次 + if self.save_dir is None: + self.save_dir = filedialog.askdirectory(title="选择保存文件夹") + if not self.save_dir: + messagebox.showwarning("警告", "未选择保存文件夹,操作已取消") + return + + for image_path in self.images: + img = Image.open(image_path) + img_original_width, img_original_height = img.size # 获取每张图片的原始大小 + + # 根据比例缩放选择区域并裁剪 + left_scaled = left * (img_original_width / self.image_original_width) + top_scaled = top * (img_original_height / self.image_original_height) + right_scaled = right * (img_original_width / self.image_original_width) + bottom_scaled = bottom * (img_original_height / self.image_original_height) + + cropped_image = img.crop((left_scaled, top_scaled, right_scaled, bottom_scaled)) + + # 自动生成默认文件名 + base_name = os.path.basename(image_path) + default_filename = f"cropped_{base_name}" + + # 保存路径与文件名 + save_path = os.path.join(self.save_dir, default_filename) + cropped_image.save(save_path) + print(f"图片已保存到: {save_path}") + + messagebox.showinfo("成功", "所有图片裁剪完成!") + +# 启动 GUI 应用 +if __name__ == "__main__": + root = tk.Tk() + app = ImageCropApp(root) + root.geometry("800x600") # 设置初始窗口大小 + root.mainloop() diff --git a/acdr-ui/tootls/图片截取单个位置.py b/acdr-ui/tootls/图片截取单个位置.py new file mode 100644 index 00000000..e48dbada --- /dev/null +++ b/acdr-ui/tootls/图片截取单个位置.py @@ -0,0 +1,83 @@ +import tkinter as tk +from tkinter import filedialog, messagebox +from PIL import Image, ImageTk, ImageGrab + +class ImageCropApp: + def __init__(self, root): + self.root = root + self.root.title("Image Crop Tool") + + # 选择图片按钮 + self.select_button = tk.Button(root, text="选择图片", command=self.select_image) + self.select_button.pack(pady=10) + + # 画布,用于显示图片 + self.canvas = tk.Canvas(root, cursor="cross") + self.canvas.pack(fill=tk.BOTH, expand=True) + + self.image = None # 用于保存选择的图片 + self.rect_start_x = 0 + self.rect_start_y = 0 + self.rect_end_x = 0 + self.rect_end_y = 0 + self.rect = None + self.tk_image = None + + # 鼠标事件 + self.canvas.bind("", self.start_selection) + self.canvas.bind("", self.update_selection) + self.canvas.bind("", self.finish_selection) + + def select_image(self): + image_path = filedialog.askopenfilename(title="选择图片", filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp"), ("All files", "*.*")]) + if image_path: + self.image = Image.open(image_path) + self.display_image() + + def display_image(self): + # 调整图片大小适应窗口 + self.image.thumbnail((self.root.winfo_width(), self.root.winfo_height())) + self.tk_image = ImageTk.PhotoImage(self.image) + self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image) + + def start_selection(self, event): + # 记录起始点 + self.rect_start_x = event.x + self.rect_start_y = event.y + # 创建一个选择框 + self.rect = self.canvas.create_rectangle(self.rect_start_x, self.rect_start_y, self.rect_start_x, self.rect_start_y, outline="red", width=2) + + def update_selection(self, event): + # 更新选择框大小 + self.rect_end_x = event.x + self.rect_end_y = event.y + self.canvas.coords(self.rect, self.rect_start_x, self.rect_start_y, self.rect_end_x, self.rect_end_y) + + def finish_selection(self, event): + self.rect_end_x = event.x + self.rect_end_y = event.y + self.crop_image() + + def crop_image(self): + if self.image: + # 获取选择框的坐标 + left = min(self.rect_start_x, self.rect_end_x) + top = min(self.rect_start_y, self.rect_end_y) + right = max(self.rect_start_x, self.rect_end_x) + bottom = max(self.rect_start_y, self.rect_end_y) + + # 根据选择框坐标进行裁剪 + cropped_image = self.image.crop((left, top, right, bottom)) + + # 让用户选择保存路径 + save_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png"), ("All files", "*.*")]) + if save_path: + cropped_image.save(save_path) + messagebox.showinfo("成功", f"图片已保存到: {save_path}") + +# 启动 GUI 应用 +if __name__ == "__main__": + root = tk.Tk() + app = ImageCropApp(root) + root.geometry("800x600") # 设置初始窗口大小 + root.mainloop() diff --git a/acdr-ui/tootls/视频处理工具.py b/acdr-ui/tootls/视频处理工具.py new file mode 100644 index 00000000..aab15bb6 --- /dev/null +++ b/acdr-ui/tootls/视频处理工具.py @@ -0,0 +1,73 @@ +import tkinter as tk +from tkinter import filedialog, messagebox +import cv2 +import os + + +# GUI 界面 +class VideoToFramesApp: + def __init__(self, root): + self.root = root + self.root.title("Video to Frames Converter") + + # 文件选择按钮 + self.select_button = tk.Button( + root, text="选择视频文件", command=self.select_video + ) + self.select_button.pack(pady=10) + + # 选择输出文件夹按钮 + self.select_folder_button = tk.Button( + root, text="选择输出文件夹", command=self.select_output_folder + ) + self.select_folder_button.pack(pady=10) + + # 开始转换按钮 + self.convert_button = tk.Button( + root, text="开始转换", command=self.convert_video + ) + self.convert_button.pack(pady=10) + + self.video_path = None + self.output_folder = None + + def select_video(self): + self.video_path = filedialog.askopenfilename( + title="选择视频文件", + filetypes=(("MP4 files", "*.mp4"), ("All files", "*.*")), + ) + if self.video_path: + messagebox.showinfo("文件已选择", f"已选择视频文件:{self.video_path}") + + def select_output_folder(self): + self.output_folder = filedialog.askdirectory(title="选择输出文件夹") + if self.output_folder: + messagebox.showinfo("文件夹已选择", f"输出文件夹:{self.output_folder}") + + def convert_video(self): + if not self.video_path or not self.output_folder: + messagebox.showwarning("错误", "请先选择视频文件和输出文件夹!") + return + + try: + cap = cv2.VideoCapture(self.video_path) + count = 0 + while True: + ret, frame = cap.read() + if not ret: + break + frame_filename = os.path.join(self.output_folder, f"frame_{count}.jpg") + cv2.imwrite(frame_filename, frame) + count += 1 + + cap.release() + messagebox.showinfo("成功", f"成功提取了 {count} 帧图片") + except Exception as e: + messagebox.showerror("错误", f"发生错误:{e}") + + +# 启动 GUI 应用 +if __name__ == "__main__": + root = tk.Tk() + app = VideoToFramesApp(root) + root.mainloop()