page.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. "use client";
  2. import { useState, type FormEvent } from "react";
  3. import { useRouter } from "next/navigation";
  4. import { apiUrl } from "@/lib/config";
  5. import { Button } from "@/components/ui/button";
  6. import { Input } from "@/components/ui/input";
  7. import { setAgentWSToken } from "@/utils/storage";
  8. export default function AgentLoginPage() {
  9. const [username, setUsername] = useState("");
  10. const [password, setPassword] = useState("");
  11. const [loading, setLoading] = useState(false);
  12. const [error, setError] = useState("");
  13. const router = useRouter();
  14. // 客服登录
  15. async function handleLogin(e: FormEvent<HTMLFormElement>) {
  16. e.preventDefault(); // 阻止默认行为
  17. if (!username || !password) {
  18. setError("用户名和密码不能为空");
  19. return;
  20. }
  21. setLoading(true);
  22. setError("");
  23. try {
  24. const res = await fetch(apiUrl("/login"), {
  25. method: "POST",
  26. headers: { "Content-Type": "application/json" },
  27. body: JSON.stringify({ username, password }),
  28. });
  29. const data = await res.json();
  30. if (res.ok) {
  31. // 登录成功,保存用户信息到 localStorage
  32. localStorage.setItem("agent_user_id", String(data.user_id));
  33. localStorage.setItem("agent_username", data.username);
  34. localStorage.setItem("agent_role", data.role);
  35. localStorage.setItem(
  36. "agent_permissions",
  37. JSON.stringify(Array.isArray(data.permissions) ? data.permissions : [])
  38. );
  39. if (typeof data.ws_token === "string" && typeof data.ws_token_exp === "number") {
  40. setAgentWSToken(data.ws_token, data.ws_token_exp);
  41. }
  42. // 跳转到客服工作台(三栏布局)
  43. router.push("/agent/dashboard");
  44. } else {
  45. // 登录失败,显示错误信息
  46. setError(data.error || data.message || "登录失败");
  47. }
  48. } catch (error) {
  49. console.error("登录失败:", error);
  50. setError("登录失败,请检查网络连接");
  51. } finally {
  52. setLoading(false);
  53. }
  54. }
  55. return (
  56. <div className="flex justify-center items-center min-h-screen bg-background">
  57. <div className="bg-card p-8 rounded-lg border shadow-lg w-full sm:w-96">
  58. <h1 className="text-center text-2xl font-bold mb-2 text-gray-800">
  59. 客服登录
  60. </h1>
  61. <p className="text-center text-sm text-gray-500 mb-6">
  62. 管理员和客服请在此登录
  63. </p>
  64. <form onSubmit={handleLogin}>
  65. <Input
  66. type="text"
  67. placeholder="用户名"
  68. value={username}
  69. onChange={(e) => setUsername(e.target.value)}
  70. className="w-full mb-4"
  71. disabled={loading}
  72. />
  73. <Input
  74. type="password"
  75. placeholder="密码"
  76. value={password}
  77. onChange={(e) => setPassword(e.target.value)}
  78. className="w-full mb-4"
  79. disabled={loading}
  80. />
  81. {error && (
  82. <div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-600 text-sm">
  83. {error}
  84. </div>
  85. )}
  86. <Button
  87. type="submit"
  88. disabled={loading}
  89. variant="default"
  90. size="default"
  91. className="w-full"
  92. >
  93. {loading ? "登录中..." : "登录"}
  94. </Button>
  95. </form>
  96. <div className="mt-4 text-center text-xs text-gray-400">
  97. <p>默认管理员账号:admin / admin123</p>
  98. </div>
  99. </div>
  100. </div>
  101. );
  102. }