@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>demo</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>404 找不到页面</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class=" border-top-wide border-primary d-flex flex-column">
|
||||
|
||||
<div class="page page-center">
|
||||
<div class="container-tight py-4">
|
||||
<div class="empty">
|
||||
<div class="empty-header">404</div>
|
||||
<p class="empty-title">抱歉,当前页面出错了!</p>
|
||||
<p class="empty-subtitle text-secondary">
|
||||
找不到资源
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<a href="/" class="btn btn-primary">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/arrow-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M5 12l14 0" />
|
||||
<path d="M5 12l6 6" />
|
||||
<path d="M5 12l6 -6" />
|
||||
</svg>
|
||||
返回主页
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>500 服务器错误</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class=" border-top-wide border-primary d-flex flex-column">
|
||||
|
||||
<div class="page page-center">
|
||||
<div class="container-tight py-4">
|
||||
<div class="empty">
|
||||
<div class="empty-header">500</div>
|
||||
<p class="empty-title">抱歉,服务器出错了!</p>
|
||||
<p class="empty-subtitle text-secondary">
|
||||
服务器内部错误!
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<a href="/" class="btn btn-primary">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/arrow-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M5 12l14 0" />
|
||||
<path d="M5 12l6 6" />
|
||||
<path d="M5 12l6 -6" />
|
||||
</svg>
|
||||
返回主页
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
<footer class="footer footer-transparent d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="row text-center align-items-center flex-row-reverse">
|
||||
<div class="col-lg-auto ms-lg-auto">
|
||||
<ul class="list-inline list-inline-dots mb-0">
|
||||
<li class="list-inline-item"><a href="https://git.lmve.net/kevin/gin_saas/-/blob/main/readme.md?ref_type=heads" target="_blank"
|
||||
class="link-secondary" rel="noopener">文档</a></li>
|
||||
<li class="list-inline-item"><a href="https://git.lmve.net/kevin/gin_saas/-/blob/main/LICENSE?ref_type=heads" target="_blank" class="link-secondary">开源协议</a>
|
||||
</li>
|
||||
<li class="list-inline-item"><a href="https://git.lmve.net/kevin/gin_saas" target="_blank"
|
||||
class="link-secondary" rel="noopener">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-orange" width="24" height="24"
|
||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-gitlab">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M21 14l-9 7l-9 -7l3 -11l3 7h6l3 -7z" />
|
||||
</svg>
|
||||
源码</a></li>
|
||||
<li class="list-inline-item">
|
||||
<a href="https://wnfed.com" target="_blank" class="link-secondary" rel="noopener">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/heart -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-pink icon-filled icon-inline" width="24"
|
||||
height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M19.5 12.572l-7.5 7.428l-7.5 -7.428a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" />
|
||||
</svg>
|
||||
博客
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
|
||||
<ul class="list-inline list-inline-dots mb-0">
|
||||
<li class="list-inline-item">
|
||||
Copyright © 2025
|
||||
<a href="https://lmve.net" target="_blank" class="link-secondary">Lmve.NET</a>.
|
||||
All rights reserved.
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<a href="https://git.lmve.net/kevin/gin_saas/-/commits/main" target="_blank" class="link-secondary" rel="noopener">
|
||||
v0.0.1
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- CSS files -->
|
||||
<link href="/dist/css/tabler.min.css?1692870487" rel="stylesheet" />
|
||||
<link href="/dist/css/tabler-flags.min.css?1692870487" rel="stylesheet" />
|
||||
<link href="/dist/css/tabler-payments.min.css?1692870487" rel="stylesheet" />
|
||||
<link href="/dist/css/tabler-vendors.min.css?1692870487" rel="stylesheet" />
|
||||
<link href="/dist/css/demo.min.css?1692870487" rel="stylesheet" />
|
||||
<style>
|
||||
@import url('https://rsms.me/inter/inter.css');
|
||||
|
||||
:root {
|
||||
--tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
font-feature-settings: "cv03", "cv04", "cv11";
|
||||
}
|
||||
</style>
|
||||
<!-- Libs JS -->
|
||||
<!-- <script src="/dist/libs/apexcharts/dist/apexcharts.min.js?1692870487" defer></script>
|
||||
<script src="/dist/libs/jsvectormap/dist/js/jsvectormap.min.js?1692870487" defer></script>
|
||||
<script src="/dist/libs/jsvectormap/dist/maps/world.js?1692870487" defer></script>
|
||||
<script src="/dist/libs/jsvectormap/dist/maps/world-merc.js?1692870487" defer></script> -->
|
||||
<!-- Tabler Core -->
|
||||
<script src="/dist/js/tabler.min.js?1692870487" defer></script>
|
||||
<script src="/dist/js/demo.min.js?1692870487" defer></script>
|
||||
<script src="/dist/js/demo-theme.min.js?1692870487"></script>
|
||||
<script src="/dist/js/my_js_func.js"></script>
|
||||
<script src="/dist/js/axios.min.js"></script>
|
||||
<script src="/dist/js/jquery-3.7.1.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<!-- 已登录header -->
|
||||
<header class="navbar navbar-expand-md d-print-none">
|
||||
<div class="container-xl">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu"
|
||||
aria-controls="navbar-menu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
|
||||
<a href="/">
|
||||
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image">
|
||||
</a>
|
||||
</h1>
|
||||
<div class="navbar-nav flex-row order-md-last">
|
||||
|
||||
<div class="d-none d-md-flex">
|
||||
<a href="?theme=dark" class="nav-link px-0 hide-theme-dark" title="Enable dark mode" data-bs-toggle="tooltip"
|
||||
data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/moon -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="?theme=light" class="nav-link px-0 hide-theme-light" title="Enable light mode" data-bs-toggle="tooltip"
|
||||
data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/sun -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
|
||||
<path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" />
|
||||
</svg>
|
||||
</a>
|
||||
<div class="nav-item dropdown d-none d-md-flex me-3">
|
||||
<a href="#" class="nav-link px-0" data-bs-toggle="dropdown" tabindex="-1" aria-label="Show notifications">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/bell -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6" />
|
||||
<path d="M9 17v1a3 3 0 0 0 6 0v-1" />
|
||||
</svg>
|
||||
<!-- <span class="badge bg-red"></span> -->
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-arrow dropdown-menu-end dropdown-menu-card">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">最新消息</h3>
|
||||
</div>
|
||||
<div class="list-group list-group-flush list-group-hoverable">
|
||||
<div class="list-group-item">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto"><span class="status-dot status-dot-animated bg-green d-block"></span></div>
|
||||
<div class="col text-truncate">
|
||||
<a class="text-body d-block">测试消息</a>
|
||||
<div class="d-block text-secondary text-truncate mt-n1">
|
||||
这是一条测试用的占位消息
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a class="list-group-item-actions">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/star -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-muted" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-item dropdown">
|
||||
<a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu">
|
||||
<span class="avatar avatar-sm" style="background-image: url({{.user_info.AvatarPath}})"></span>
|
||||
<div class="d-none d-xl-block ps-2">
|
||||
<div>{{.user_info.Username}}</div>
|
||||
<div class="mt-1 small text-secondary">{{.user_info.FirstName}}</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
|
||||
<!-- <a href="#" class="dropdown-item">Status</a> -->
|
||||
<a href="./profile" class="dropdown-item">个人资料</a>
|
||||
<!-- <a href="#" class="dropdown-item">Feedback</a> -->
|
||||
<a href="/setting-my" class="dropdown-item">设置</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" onclick="logout()" class="dropdown-item">登出</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
function logout() {
|
||||
console.log("logout");
|
||||
const url = '/api/v1/user/logout';
|
||||
const sumt_data = {
|
||||
cookie: "",
|
||||
};
|
||||
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
//console.log('提交成功:', response.data); // 正确打印服务器数据
|
||||
//跳转到主页
|
||||
if (response.data.err_code == 0) {
|
||||
location.href = '/'
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!-- 未登录状态header -->
|
||||
<header class="navbar navbar-expand-md d-print-none">
|
||||
<div class="container-xl">
|
||||
<h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
|
||||
<a href="/">
|
||||
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image">
|
||||
</a>
|
||||
</h1>
|
||||
<div class="navbar-nav flex-row order-md-last">
|
||||
<!-- 深色模式按钮 -->
|
||||
<div class="d-none d-md-flex">
|
||||
<a href="?theme=dark" class="nav-link px-0 hide-theme-dark" title="Enable dark mode"
|
||||
data-bs-toggle="tooltip" data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/moon -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="?theme=light" class="nav-link px-0 hide-theme-light" title="Enable light mode"
|
||||
data-bs-toggle="tooltip" data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/sun -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
|
||||
<path
|
||||
d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<!-- 深色模式按钮 -->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,86 @@
|
||||
<header class="navbar-expand-md">
|
||||
<div class="collapse navbar-collapse" id="navbar-menu">
|
||||
<div class="navbar">
|
||||
<div class="container-xl">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">
|
||||
<span
|
||||
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M5 12l-2 0l9 -9l9 9l-2 0"></path>
|
||||
<path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path>
|
||||
<path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="nav-link-title">
|
||||
主页
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/warehouses">
|
||||
<span
|
||||
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-building-warehouse">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M3 21v-13l9 -4l9 4v13"></path>
|
||||
<path d="M13 13h4v8h-10v-6h6"></path>
|
||||
<path d="M13 21v-9a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v3"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="nav-link-title">
|
||||
仓库
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/workorders">
|
||||
<span
|
||||
class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-file-description">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
|
||||
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
|
||||
<path d="M9 17h6" />
|
||||
<path d="M9 13h6" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="nav-link-title">
|
||||
工单
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="my-2 my-md-0 flex-grow-1 flex-md-grow-0 order-first order-md-last">
|
||||
|
||||
<div class="input-icon">
|
||||
<span class="input-icon-addon">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/search -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path>
|
||||
<path d="M21 21l-6 -6"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" value="" class="form-control" placeholder="全站搜索"
|
||||
aria-label="Search in website">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,62 @@
|
||||
<!-- 未登录状态header -->
|
||||
<header class="navbar navbar-expand-md d-print-none">
|
||||
<div class="container-xl">
|
||||
<h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
|
||||
<a href="/">
|
||||
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image">
|
||||
</a>
|
||||
</h1>
|
||||
<div class="navbar-nav flex-row order-md-last">
|
||||
<!-- 深色模式按钮 -->
|
||||
<div class="d-none d-md-flex">
|
||||
<a href="?theme=dark" class="nav-link px-0 hide-theme-dark" title="Enable dark mode"
|
||||
data-bs-toggle="tooltip" data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/moon -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="?theme=light" class="nav-link px-0 hide-theme-light" title="Enable light mode"
|
||||
data-bs-toggle="tooltip" data-bs-placement="bottom">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/sun -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
|
||||
<path
|
||||
d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<!-- 深色模式按钮 -->
|
||||
|
||||
<div class="nav-item btn-list">
|
||||
<a href="/sign-in" class="btn" rel="noreferrer">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/heart -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon text-blue" width="24" height="24"
|
||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-password-user">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 17v4" />
|
||||
<path d="M10 20l4 -2" />
|
||||
<path d="M10 18l4 2" />
|
||||
<path d="M5 17v4" />
|
||||
<path d="M3 20l4 -2" />
|
||||
<path d="M3 18l4 2" />
|
||||
<path d="M19 17v4" />
|
||||
<path d="M17 20l4 -2" />
|
||||
<path d="M17 18l4 2" />
|
||||
<path d="M9 6a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
<path d="M7 14a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2" />
|
||||
</svg>
|
||||
登录/注册
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>主页</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>添加新仓库</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{template "header-logined.html" .}}
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,630 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>设置-个人设置</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
<!-- Navbar -->
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
<header class="navbar-expand-md">
|
||||
|
||||
</header>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<!-- Page header -->
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<h2 class="page-title">
|
||||
设置
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page body -->
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="card">
|
||||
<div class="row g-0">
|
||||
|
||||
<div class="col-12 col-md-3 border-end">
|
||||
<div class="card-body">
|
||||
<h4 class="subheader">账号设置</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center active">信息设置</a>
|
||||
<a href="/setting-security"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center">安全设置</a>
|
||||
</div>
|
||||
<h4 class="subheader mt-4">外部设置</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-9 d-flex flex-column">
|
||||
<div class="card-body">
|
||||
<h2 class="mb-4">信息设置</h2>
|
||||
<!-- <h3 class="card-title">Profile Details</h3> -->
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto"><span id="myAvatar" class="avatar avatar-xl"
|
||||
style="background-image: url({{.user_info.AvatarPath}})"></span>
|
||||
</div>
|
||||
<div class="col-auto"><a href="#" class="btn" onclick="avatar_toolt.show()">
|
||||
更改头像
|
||||
</a></div>
|
||||
<!-- <div class="col-auto"><a href="#" class="btn btn-ghost-danger">
|
||||
删除头像
|
||||
</a></div> -->
|
||||
</div>
|
||||
<!-- <h3 class="card-title mt-4">Business Profile</h3> -->
|
||||
<div class="row g-3">
|
||||
<div class="col-md">
|
||||
<div class="form-label">名字</div>
|
||||
<input id="username" type="text" class="form-control" value="{{.user_info.Username}}" maxlength="30">
|
||||
</div>
|
||||
|
||||
<div class="col-md">
|
||||
<div class="form-label">备注</div>
|
||||
<input id="first_name" type="text" class="form-control" value="{{.user_info.FirstName}}" maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">生日</label>
|
||||
<div class="row g-2">
|
||||
<div class="col-5">
|
||||
<input type="text" class="form-control" id="birthday-picker" placeholder="选择生日"
|
||||
value="{{.user_info.Birthdate}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-footer bg-transparent mt-auto">
|
||||
<div class="btn-list justify-content-end">
|
||||
|
||||
<a href="#" onclick="updata_user_info()" class="btn btn-primary">
|
||||
提交
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<div class="modal modal-blur fade" id="avata_toolt" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="container">
|
||||
<h1>头像裁剪工具</h1>
|
||||
|
||||
<div class="flex-wrapper">
|
||||
<!-- 左侧裁剪区 -->
|
||||
<div class="crop-section">
|
||||
<div id="image-wrapper">
|
||||
<img id="cropper-image"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
|
||||
</div>
|
||||
<!-- 上传进度 -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar"></div>
|
||||
</div>
|
||||
|
||||
<!-- 消息提示 -->
|
||||
<div id="message" class="alert"></div>
|
||||
|
||||
<div class="preview-stats">
|
||||
<!-- <p>当前缩放: <span id="zoomValue">100%</span></p> -->
|
||||
<p>图片尺寸: <span id="imageSize">0 x 0</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧预览区 -->
|
||||
<div class="preview-section">
|
||||
<h3>实时预览</h3>
|
||||
<div class="preview-box">
|
||||
<img id="preview-img"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
|
||||
</div>
|
||||
|
||||
<!-- 控制按钮 -->
|
||||
<div class="controls">
|
||||
<label class="btn btn-primary">
|
||||
📁 选择图片
|
||||
<input type="file" id="fileInput" accept="image/*">
|
||||
</label>
|
||||
<button class="btn btn-secondary " onclick="rotateImage(-90)">↩️ 左旋</button>
|
||||
<button class="btn btn-success " id="uploadBtn">✂️ 裁剪头像</button>
|
||||
|
||||
<button class="btn btn-danger " style="margin-top: 150px;" onclick="avatar_toolt.hide()">❌ 取消</button>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
/* 主容器 */
|
||||
.litepicker {
|
||||
--color-primary: #4f46e5;
|
||||
/* 主题色(选中日期/按钮) */
|
||||
--color-primary-light: #e0e7ff;
|
||||
--color-text: #1f2937;
|
||||
/* 文本颜色 */
|
||||
--color-text-light: #6b7280;
|
||||
--font-family: 'Inter', sans-serif;
|
||||
/* 自定义字体 */
|
||||
}
|
||||
|
||||
/* 日期单元格悬停效果 */
|
||||
.litepicker .container__days .day-item:hover {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.litepicker {
|
||||
border-radius: 8px;
|
||||
/* 整体圆角 */
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.litepicker .container__months {
|
||||
gap: 24px;
|
||||
/* 月份之间的间距 */
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.litepicker {
|
||||
width: 100% !important;
|
||||
/* 全屏宽度 */
|
||||
}
|
||||
|
||||
.litepicker .container__months {
|
||||
flex-direction: column;
|
||||
/* 垂直排列 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 头像裁剪器样式*/
|
||||
|
||||
.container {
|
||||
width: 95%; /* 改为百分比宽度 */
|
||||
margin: 20px auto; /* 增加上下边距 */
|
||||
max-width: 1200px; /* 保留最大宽度 */
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
|
||||
}
|
||||
|
||||
.flex-wrapper {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
margin-top: 20px;
|
||||
flex-wrap: wrap; /* 添加换行支持 */
|
||||
}
|
||||
|
||||
/* 裁剪区域 */
|
||||
.crop-section {
|
||||
flex: 1 1 60%; /* 弹性布局基础宽度 */
|
||||
min-width: 300px; /* 降低最小宽度 */
|
||||
height: auto; /* 移除固定高度 */
|
||||
min-height: 400px; /* 设置最小高度 */
|
||||
}
|
||||
|
||||
#image-wrapper {
|
||||
width: 100%;
|
||||
height: 60vh; /* 改用视窗单位 */
|
||||
max-height: 600px; /* 设置最大高度 */
|
||||
background: #f8f9fa;
|
||||
border: 2px dashed #ddd;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* 预览区域自适应 */
|
||||
.preview-section {
|
||||
flex: 1 1 35%; /* 弹性布局基础宽度 */
|
||||
min-width: 250px; /* 设置合理最小宽度 */
|
||||
}
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 15px; /* 减少内边距 */
|
||||
}
|
||||
|
||||
.flex-wrapper {
|
||||
flex-direction: column; /* 垂直排列 */
|
||||
}
|
||||
|
||||
.crop-section,
|
||||
.preview-section {
|
||||
width: 100% !important; /* 强制全宽 */
|
||||
min-width: unset; /* 移除最小宽度 */
|
||||
}
|
||||
|
||||
#image-wrapper {
|
||||
height: 50vh; /* 调整移动端高度 */
|
||||
}
|
||||
|
||||
.preview-box {
|
||||
width: 120px; /* 缩小预览区域 */
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
flex-direction: column; /* 垂直排列按钮 */
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#cropper-image {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
/* 控制区域 */
|
||||
.controls {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 预览区域 */
|
||||
.preview-section {
|
||||
flex: 1;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.preview-box {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
/* border-radius: 50%; */
|
||||
border: 3px solid var(--primary-color);
|
||||
overflow: hidden;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
|
||||
#preview-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 上传进度 */
|
||||
.progress-container {
|
||||
height: 8px;
|
||||
background: #eee;
|
||||
border-radius: 4px;
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background: var(--primary-color);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* 消息提示 */
|
||||
.alert {
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-top: 20px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #dff0d8;
|
||||
color: #3c763d;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: #f2dede;
|
||||
color: var(--error-color);
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- lib -->
|
||||
|
||||
<!-- 依赖库 -->
|
||||
<!-- 引入 Litepicker 核心 CSS 和 JS -->
|
||||
|
||||
<script src="/dist/libs/litepicker/dist/js/litepicker.js"></script>
|
||||
|
||||
<script src="/dist/libs/cropper/cropper.min.js"></script>
|
||||
|
||||
<link href="/dist/libs/cropper/cropper.min.css" rel="stylesheet">
|
||||
|
||||
<!-- libs -->
|
||||
<script src="/dist/libs/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
const avatar_dom = document.getElementById('myAvatar');
|
||||
function get_user_avatar() {
|
||||
|
||||
const bgImage = avatar_dom.style.backgroundImage;
|
||||
// 方法 2:字符串分割
|
||||
const currentUrl = bgImage.split('url("')[1]?.split('")')[0];
|
||||
return currentUrl;
|
||||
}
|
||||
|
||||
function set_user_avatar(str) {
|
||||
avatar_dom.style.backgroundImage = 'url("' + str + '")';
|
||||
}
|
||||
|
||||
//头像裁剪工具
|
||||
const avatar_toolt = new bootstrap.Modal('#avata_toolt');
|
||||
|
||||
const birthdayPicker = new Litepicker({
|
||||
element: document.getElementById('birthday-picker'),
|
||||
lang: 'zh-cn', // 设置为中文
|
||||
firstDay: 0, // 周日为首日
|
||||
format: 'YYYY-MM-DD', // 日期格式
|
||||
maxDate: new Date(), // 最大日期为今天
|
||||
dropdowns: {
|
||||
minYear: 1900, // 最小可选年份
|
||||
maxYear: new Date().getFullYear(), // 最大为当前年份
|
||||
months: true, // 显示月份下拉
|
||||
years: true // 显示年份下拉
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//头像裁剪区
|
||||
let cropper;
|
||||
const image = document.getElementById('cropper-image');
|
||||
const message = document.getElementById('message');
|
||||
let currentScale = 1;
|
||||
|
||||
// 初始化Cropper
|
||||
function initCropper(imageSrc) {
|
||||
if (cropper) {
|
||||
cropper.destroy();
|
||||
}
|
||||
|
||||
image.src = imageSrc;
|
||||
cropper = new Cropper(image, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 2,
|
||||
autoCropArea: 0.8,
|
||||
zoomable: true,
|
||||
zoomOnWheel: true,
|
||||
zoomOnTouch: true,
|
||||
wheelZoomRatio: 0.1,
|
||||
//minCanvasWidth: 400,
|
||||
//minCanvasHeight: 400,
|
||||
crop: updatePreview,
|
||||
ready() {
|
||||
updateImageInfo();
|
||||
document.querySelector('.progress-container').style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 旋转控制
|
||||
function rotateImage(degrees) {
|
||||
if (cropper) {
|
||||
cropper.rotateTo(cropper.getData().rotate + degrees);
|
||||
updatePreview();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新预览
|
||||
function updatePreview() {
|
||||
const canvas = cropper.getCroppedCanvas({
|
||||
width: 250,
|
||||
height: 250,
|
||||
imageSmoothingQuality: 'high'
|
||||
});
|
||||
|
||||
if (canvas) {
|
||||
canvas.toBlob(blob => {
|
||||
const previewUrl = URL.createObjectURL(blob);
|
||||
document.getElementById('preview-img').src = previewUrl;
|
||||
// 清理旧URL
|
||||
setTimeout(() => URL.revokeObjectURL(previewUrl), 1000);
|
||||
}, 'image/jpeg', 0.85);
|
||||
updateImageInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新图片信息
|
||||
function updateImageInfo() {
|
||||
if (cropper) {
|
||||
const data = cropper.getData();
|
||||
// document.getElementById('zoomValue').textContent =
|
||||
// `${Math.round(currentScale * 100)}%`;
|
||||
document.getElementById('imageSize').textContent =
|
||||
`${Math.round(data.width)} x ${Math.round(data.height)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 文件选择事件
|
||||
document.getElementById('fileInput').addEventListener('change', function (e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (!file.type.startsWith('image/')) {
|
||||
showMessage('⚠️ 请选择有效的图片文件', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
initCropper(reader.result);
|
||||
currentScale = 1;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
// 上传功能
|
||||
document.getElementById('uploadBtn').addEventListener('click', async () => {
|
||||
const progressBar = document.querySelector('.progress-bar');
|
||||
const progressContainer = document.querySelector('.progress-container');
|
||||
|
||||
try {
|
||||
if (!cropper) {
|
||||
showMessage('⚠️ 请先选择并裁剪图片', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
progressContainer.style.display = 'block';
|
||||
const canvas = cropper.getCroppedCanvas({
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
imageSmoothingQuality: 'high'
|
||||
});
|
||||
|
||||
const blob = await new Promise(resolve =>
|
||||
canvas.toBlob(resolve, 'image/jpeg', 0.9)
|
||||
);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', blob, `avatar_${Date.now()}.jpg`);
|
||||
formData.append('meta', JSON.stringify({
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
scale: currentScale.toFixed(2)
|
||||
}));
|
||||
|
||||
const response = await fetch('/api/v1/file/avatar', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error(`服务器错误: ${response.status}`);
|
||||
|
||||
const result = await response.json();
|
||||
if (result.err_code == 0) {
|
||||
showMessage(`✅ 上传成功!`, 'success');
|
||||
set_user_avatar(result.data.path);
|
||||
console.log(get_user_avatar());
|
||||
avatar_toolt.hide();
|
||||
} else {
|
||||
showMessage(`❌ 上传失败: ${result.err_msg}`, 'error');
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('上传错误:', error);
|
||||
showMessage(`❌ 上传失败: ${error.message}`, 'error');
|
||||
} finally {
|
||||
progressBar.style.width = '0%';
|
||||
progressContainer.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// 消息提示
|
||||
function showMessage(text, type = 'success') {
|
||||
message.className = `alert alert-${type}`;
|
||||
message.textContent = text;
|
||||
message.style.display = 'block';
|
||||
setTimeout(() => message.style.display = 'none', 5000);
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (cropper) cropper.destroy();
|
||||
document.querySelectorAll('img').forEach(img => {
|
||||
if (img.src.startsWith('blob:')) URL.revokeObjectURL(img.src);
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化默认图片
|
||||
//initCropper('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');
|
||||
|
||||
//更新用户资料
|
||||
function updata_user_info(){
|
||||
const url = '/api/v1/user/updata_info';
|
||||
const sumt_data = {
|
||||
avatar:get_user_avatar(),
|
||||
username:document.getElementById("username").value,
|
||||
first_name:document.getElementById("first_name").value,
|
||||
birthday:document.getElementById("birthday-picker").value,
|
||||
|
||||
|
||||
};
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
//console.log(response)
|
||||
if(response.data.err_code==0){
|
||||
location.reload()
|
||||
}else{
|
||||
console.log(response.data)
|
||||
}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,303 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>设置-安全设置</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
<!-- Navbar -->
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
<header class="navbar-expand-md">
|
||||
|
||||
</header>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<!-- Page header -->
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<h2 class="page-title">
|
||||
设置
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page body -->
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="card">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 col-md-3 border-end">
|
||||
<div class="card-body">
|
||||
<h4 class="subheader">账号设置</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
<a href="/setting-my"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center ">信息设置</a>
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center active">安全设置</a>
|
||||
</div>
|
||||
<h4 class="subheader mt-4">外部设置</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-9 d-flex flex-column">
|
||||
<div class="card-body">
|
||||
|
||||
<h2 class="mb-4">安全设置</h2>
|
||||
|
||||
|
||||
<h3 class="card-title mt-4">安全邮箱</h3>
|
||||
<p class="card-subtitle">用于找回账号密码,该联系方式不会公开显示给其他人。</p>
|
||||
<div>
|
||||
<div class="row g-2">
|
||||
<div class="col-auto">
|
||||
<input id="mail" type="email" class="form-control w-auto " value="{{.user.Email}}"
|
||||
maxlength="64">
|
||||
<div id="email_input_err" class="invalid-feedback">不能为空</div>
|
||||
<div class="valid-feedback">修改成功</div>
|
||||
</div>
|
||||
<div class="col-auto"><a href="#" class="btn" onclick="change_email()">
|
||||
修改邮箱
|
||||
</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="card-title mt-4">登录密码</h3>
|
||||
<p class="card-subtitle">修改密码后需要重新登录</p>
|
||||
<div class="col-auto">
|
||||
<input id="pass_old" type="password" class="form-control w-auto mt-1" placeholder="旧密码"
|
||||
autocomplete="off">
|
||||
<div id="pass_old_err" class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<input id="pass_new" type="password" class="form-control w-auto mt-1" placeholder="新密码"
|
||||
autocomplete="off">
|
||||
<div class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<input id="pass_cmf" type="password" class="form-control w-auto mt-1 mb-1" placeholder="确认密码"
|
||||
autocomplete="off">
|
||||
<div id="pass_cmf_err" class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
|
||||
<a id="show_pass" class="link-secondary " title="显示密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a id="show_pass_no" class="link-secondary d-none" title="隐藏密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye-off">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||
<path
|
||||
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" />
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<a href="#" class="btn" onclick="change_pass()">
|
||||
修改密码
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
const dom_mail = document.getElementById("mail")
|
||||
const dom_pass_old = document.getElementById("pass_old")
|
||||
const dom_pass_new = document.getElementById("pass_new")
|
||||
const dom_pass_cmf = document.getElementById("pass_cmf")
|
||||
var show_password_dom = document.getElementById('show_pass');
|
||||
var show_password_no_dom = document.getElementById('show_pass_no');
|
||||
|
||||
show_password_dom.addEventListener('click', function () {
|
||||
|
||||
dom_pass_old.type = "text";
|
||||
dom_pass_new.type = "text";
|
||||
dom_pass_cmf.type = "text";
|
||||
show_password_dom.classList.add("d-none")
|
||||
show_password_no_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
show_password_no_dom.addEventListener('click', function () {
|
||||
|
||||
dom_pass_old.type = "password";
|
||||
dom_pass_new.type = "password";
|
||||
dom_pass_cmf.type = "password";
|
||||
show_password_no_dom.classList.add("d-none")
|
||||
show_password_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
|
||||
dom_mail.addEventListener('input', function () {
|
||||
if (dom_mail.value != "") {
|
||||
dom_mail.classList.remove("is-invalid");
|
||||
dom_mail.classList.remove("is-valid");
|
||||
}
|
||||
})
|
||||
|
||||
dom_pass_old.addEventListener('input', function () {
|
||||
if (dom_pass_old.value != "") {
|
||||
dom_pass_old.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
dom_pass_new.addEventListener('input', function () {
|
||||
if (dom_pass_new.value != "") {
|
||||
dom_pass_new.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
dom_pass_cmf.addEventListener('input', function () {
|
||||
if (dom_pass_cmf.value != "") {
|
||||
dom_pass_cmf.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
function change_email() {
|
||||
if (dom_mail.value != "") {
|
||||
if (isValidEmail(dom_mail.value)) {
|
||||
const url = '/api/v1/user/change_email';
|
||||
const sumt_data = {
|
||||
new_email: dom_mail.value
|
||||
};
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.data.err_code == 0) {
|
||||
dom_mail.classList.add("is-valid");
|
||||
} else {
|
||||
console.log(response.data)
|
||||
}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
//console.log(sumt_data);
|
||||
} else {
|
||||
dom_mail.classList.add("is-invalid");
|
||||
dom_mail.placeholder = "不是邮箱";
|
||||
document.getElementById("email_input_err").innerHTML = "不是邮箱";
|
||||
}
|
||||
} else {
|
||||
dom_mail.classList.add("is-invalid");
|
||||
}
|
||||
}
|
||||
|
||||
function change_pass() {
|
||||
var valid = true
|
||||
|
||||
if (dom_pass_old.value == "") {
|
||||
valid = false
|
||||
dom_pass_old.classList.add("is-invalid")
|
||||
}
|
||||
if (dom_pass_new.value == "") {
|
||||
valid = false
|
||||
dom_pass_new.classList.add("is-invalid")
|
||||
}
|
||||
if (dom_pass_cmf.value == "") {
|
||||
valid = false
|
||||
dom_pass_cmf.classList.add("is-invalid")
|
||||
} else {
|
||||
if (dom_pass_cmf.value != dom_pass_new.value) {
|
||||
valid = false
|
||||
dom_pass_cmf.classList.add("is-invalid")
|
||||
document.getElementById("pass_cmf_err").innerHTML = "密码不一致";
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
const url = '/api/v1/user/change_pass';
|
||||
const sumt_data = {
|
||||
pass_old: dom_pass_old.value,
|
||||
pass_new: dom_pass_new.value,
|
||||
};
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.data.err_code == 0) {
|
||||
location.href = '/sign-in'
|
||||
} else if (response.data.err_code == 3) {
|
||||
dom_pass_old.classList.add("is-invalid")
|
||||
document.getElementById("pass_old_err").innerHTML = "密码不正确";
|
||||
} else {
|
||||
console.log(response.data)
|
||||
}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,197 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>登录</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class=" d-flex flex-column">
|
||||
<div class="page page-center">
|
||||
{{template "header-min.html" .}}
|
||||
<div class="container container-normal py-4">
|
||||
<div class="row align-items-center g-4">
|
||||
<div class="col-lg">
|
||||
<div class="container-tight">
|
||||
<div class="text-center mb-4">
|
||||
<a href="." class="navbar-brand navbar-brand-autodark"><img src="/static/logo.svg" height="36"
|
||||
alt=""></a>
|
||||
</div>
|
||||
<div class="card card-md">
|
||||
<div class="card-body">
|
||||
<h2 class="h2 text-center mb-4">登录你的账号</h2>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">用户名</label>
|
||||
<input id="username" type="text" class="form-control" placeholder="输入你的用户名" autocomplete="off"
|
||||
maxlength="25">
|
||||
<div class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">
|
||||
密码
|
||||
</label>
|
||||
<div class="input-group input-group-flat">
|
||||
<input id="password" type="password" class="form-control" placeholder="输入你的密码" autocomplete="off">
|
||||
|
||||
<span class="input-group-text">
|
||||
<a id="show_pass" class="link-secondary " title="显示密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a id="show_pass_no" class="link-secondary d-none" title="隐藏密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye-off">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||
<path
|
||||
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" />
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
<div id="pass_err" class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-check">
|
||||
<input id="keep_login" type="checkbox" class="form-check-input" />
|
||||
<span class="form-check-label">保持登录</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-footer">
|
||||
<button onclick="sign_in()" class="btn btn-primary w-100">登录</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="text-center text-secondary mt-3">
|
||||
还没账号?
|
||||
<a href="/sign-up/" tabindex="-1">点击注册</a>
|
||||
<span class="form-label-description">
|
||||
<a href="./forgot-password.html">忘记密码?</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg d-none d-lg-block">
|
||||
<img src="/static/illustrations/undraw_secure_login_pdn4.svg" height="300" class="d-block mx-auto" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
<!-- Libs JS -->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var username_dom = document.getElementById('username');
|
||||
var password_dom = document.getElementById('password');
|
||||
var keep_login_dom = document.getElementById('keep_login');
|
||||
var show_password_dom = document.getElementById('show_pass');
|
||||
var show_password_no_dom = document.getElementById('show_pass_no');
|
||||
show_password_dom.addEventListener('click', function () {
|
||||
|
||||
password_dom.type = "text";
|
||||
show_password_dom.classList.add("d-none")
|
||||
show_password_no_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
show_password_no_dom.addEventListener('click', function () {
|
||||
|
||||
password_dom.type = "password";
|
||||
show_password_no_dom.classList.add("d-none")
|
||||
show_password_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
username_dom.addEventListener('input', function () {
|
||||
if (username_dom.value != "") {
|
||||
username_dom.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
password_dom.addEventListener('input', function () {
|
||||
if (password_dom.value != "") {
|
||||
password_dom.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
function sign_in() {
|
||||
var from_data_check = true;
|
||||
if (username_dom.value == "") {
|
||||
username_dom.classList.add("is-invalid");
|
||||
username_dom.placeholder = "不能为空";
|
||||
from_data_check = false;
|
||||
} else {
|
||||
username_dom.classList.remove("is-invalid");
|
||||
}
|
||||
if (password_dom.value == "") {
|
||||
password_dom.classList.add("is-invalid");
|
||||
password_dom.placeholder = "不能为空";
|
||||
from_data_check = false;
|
||||
} else {
|
||||
password_dom.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
if (from_data_check) {
|
||||
const url = '/api/v1/user/login';
|
||||
const sumt_data = {
|
||||
username: username_dom.value,
|
||||
userpass: password_dom.value,
|
||||
keep_login: keep_login_dom.checked
|
||||
};
|
||||
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
console.log('提交成功:', response.data); // 正确打印服务器数据
|
||||
//跳转到主页
|
||||
if (response.data.err_code == 0) {
|
||||
location.href = '/'
|
||||
} else {
|
||||
password_dom.classList.add("is-invalid");
|
||||
document.getElementById("pass_err").innerHTML = "账号或密码错误";
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,254 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>新用户注册</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class=" d-flex flex-column">
|
||||
|
||||
<div class="page page-center">
|
||||
|
||||
{{template "header-min.html" .}}
|
||||
|
||||
<div class="container container-tight py-4">
|
||||
<div class="text-center mb-4">
|
||||
<a href="." class="navbar-brand navbar-brand-autodark">
|
||||
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image">
|
||||
</a>
|
||||
</div>
|
||||
<div class="card card-md" action="" method="" autocomplete="off" novalidate>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-center mb-4">创建新用户</h2>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">用户名</label>
|
||||
<input id="username" type="text" class="form-control" placeholder="输入用户名" maxlength="25">
|
||||
<div id="name_input_err" class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">邮箱地址</label>
|
||||
<input id="email" type="email" class="form-control" placeholder="输入电子邮箱" maxlength="64">
|
||||
<div id="email_input_err" class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">密码</label>
|
||||
<div class="input-group input-group-flat">
|
||||
<input id="password" type="password" class="form-control" placeholder="输入密码" autocomplete="off">
|
||||
<span class="input-group-text">
|
||||
|
||||
<a id="show_pass" class="link-secondary " title="显示密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a id="show_pass_no" class="link-secondary d-none" title="隐藏密码"
|
||||
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-eye-off">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||
<path
|
||||
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" />
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
</span>
|
||||
<div class="invalid-feedback">不能为空</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="mb-3">
|
||||
<label class="form-check">
|
||||
<input type="checkbox" class="form-check-input"/>
|
||||
<span class="form-check-label">Agree the <a href="./terms-of-service.html" tabindex="-1">terms and policy</a>.</span>
|
||||
</label>
|
||||
</div> -->
|
||||
<div class="form-footer">
|
||||
<button id="sumtbutton" class="btn btn-primary w-100">创建</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center text-secondary mt-3">
|
||||
已有账号? <a href="/sign-in/" tabindex="-1">点击登录</a>
|
||||
</div>
|
||||
</div>
|
||||
{{template "footer.html"}}
|
||||
</div>
|
||||
<!-- Libs JS -->
|
||||
<div class="modal modal-blur fade" id="modal-success" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<div class="modal-status bg-success"></div>
|
||||
<div class="modal-body text-center py-4">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/circle-check -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon mb-2 text-green icon-lg" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
||||
<path d="M9 12l2 2l4 -4" />
|
||||
</svg>
|
||||
<h3>用户注册成功</h3>
|
||||
<div class="text-secondary">你已成功注册,请前往邮箱激活账号。或者 立即登录</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="w-100">
|
||||
<div class="row">
|
||||
<div class="col"><a onclick="location.href = '/'" class="btn w-100" data-bs-dismiss="modal">
|
||||
返回主页
|
||||
</a></div>
|
||||
<div class="col"><a onclick="location.href = '/sign-in'" class="btn btn-success w-100"
|
||||
data-bs-dismiss="modal">
|
||||
立即登录
|
||||
</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
//console.log("test");
|
||||
function sup() {
|
||||
|
||||
}
|
||||
|
||||
var username_dom = document.getElementById('username');
|
||||
var email_dom = document.getElementById('email');
|
||||
var password_dom = document.getElementById('password');
|
||||
var show_password_dom = document.getElementById('show_pass');
|
||||
var show_password_no_dom = document.getElementById('show_pass_no');
|
||||
|
||||
username_dom.addEventListener('input', function () {
|
||||
if (username_dom.value != "") {
|
||||
username_dom.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
email_dom.addEventListener('input', function () {
|
||||
if (email_dom.value != "") {
|
||||
email_dom.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
password_dom.addEventListener('input', function () {
|
||||
if (password_dom.value != "") {
|
||||
password_dom.classList.remove("is-invalid");
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
show_password_dom.addEventListener('click', function () {
|
||||
|
||||
password_dom.type = "text";
|
||||
show_password_dom.classList.add("d-none")
|
||||
show_password_no_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
show_password_no_dom.addEventListener('click', function () {
|
||||
|
||||
password_dom.type = "password";
|
||||
show_password_no_dom.classList.add("d-none")
|
||||
show_password_dom.classList.remove("d-none");
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
document.getElementById('sumtbutton').addEventListener('click', function () {
|
||||
//console.log('按钮被点击了!');
|
||||
var from_data_check = true;
|
||||
|
||||
if (username_dom.value == "") {
|
||||
username_dom.classList.add("is-invalid");
|
||||
username_dom.placeholder = "不能为空";
|
||||
from_data_check = false;
|
||||
} else {
|
||||
username_dom.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
if (email_dom.value == "") {
|
||||
email_dom.classList.add("is-invalid");
|
||||
email_dom.placeholder = "不能为空";
|
||||
document.getElementById("email_input_err").innerHTML = "不能为空";
|
||||
from_data_check = false;
|
||||
} else if (!isValidEmail(email_dom.value)) {
|
||||
email_dom.classList.add("is-invalid");
|
||||
email_dom.placeholder = "不是邮箱";
|
||||
document.getElementById("email_input_err").innerHTML = "不是邮箱";
|
||||
from_data_check = false;
|
||||
} else {
|
||||
email_dom.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
if (password_dom.value == "") {
|
||||
password_dom.classList.add("is-invalid");
|
||||
password_dom.placeholder = "不能为空";
|
||||
from_data_check = false;
|
||||
} else {
|
||||
password_dom.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
if (from_data_check) {
|
||||
//console.log("ok");
|
||||
const url = '/api/v1/user/add';
|
||||
const sumt_data = {
|
||||
username: username_dom.value,
|
||||
useremail: email_dom.value,
|
||||
userpass: password_dom.value
|
||||
};
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
console.log('提交成功:', response.data); // 正确打印服务器数据
|
||||
if (response.data.err_code == 1) {
|
||||
username_dom.classList.add("is-invalid");
|
||||
document.getElementById("name_input_err").innerHTML = "用户名已存在";
|
||||
} else if (response.data.err_code == 0) {
|
||||
const myModal = new bootstrap.Modal('#modal-success');
|
||||
myModal.show();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
//console.log(sumt_data);
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,372 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>头像裁剪上传系统 - 完整版</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2196F3;
|
||||
--error-color: #f44336;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
background: #f5f5f5;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.flex-wrapper {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* 裁剪区域 */
|
||||
.crop-section {
|
||||
flex: 2;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
#image-wrapper {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background: #f8f9fa;
|
||||
border: 2px dashed #ddd;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cropper-image {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
/* 控制区域 */
|
||||
.controls {
|
||||
margin-top: 20px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 预览区域 */
|
||||
.preview-section {
|
||||
flex: 1;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.preview-box {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid var(--primary-color);
|
||||
overflow: hidden;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
|
||||
#preview-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.btn {
|
||||
padding: 12px 20px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #1976D2;
|
||||
}
|
||||
|
||||
.btn-zoom {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
/* 上传进度 */
|
||||
.progress-container {
|
||||
height: 8px;
|
||||
background: #eee;
|
||||
border-radius: 4px;
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background: var(--primary-color);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* 消息提示 */
|
||||
.alert {
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-top: 20px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #dff0d8;
|
||||
color: #3c763d;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: #f2dede;
|
||||
color: var(--error-color);
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>专业头像裁剪系统</h1>
|
||||
|
||||
<div class="flex-wrapper">
|
||||
<!-- 左侧裁剪区 -->
|
||||
<div class="crop-section">
|
||||
<div id="image-wrapper">
|
||||
<img id="cropper-image"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
|
||||
</div>
|
||||
|
||||
<!-- 控制按钮 -->
|
||||
<div class="controls">
|
||||
<label class="btn btn-primary">
|
||||
📁 选择图片
|
||||
<input type="file" id="fileInput" accept="image/*">
|
||||
</label>
|
||||
<button class="btn btn-primary" id="uploadBtn">🚀 上传头像</button>
|
||||
<button class="btn btn-primary" id="resetBtn">🔄 重置</button>
|
||||
<button class="btn btn-zoom" onclick="zoomControl(0.2)">➕ 放大</button>
|
||||
<button class="btn btn-zoom" onclick="zoomControl(-0.2)">➖ 缩小</button>
|
||||
<button class="btn btn-primary" onclick="rotateImage(-90)">↩️ 左旋</button>
|
||||
</div>
|
||||
|
||||
<!-- 上传进度 -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar"></div>
|
||||
</div>
|
||||
|
||||
<!-- 消息提示 -->
|
||||
<div id="message" class="alert"></div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧预览区 -->
|
||||
<div class="preview-section">
|
||||
<h3>实时预览 (250x250px)</h3>
|
||||
<div class="preview-box">
|
||||
<img id="preview-img"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
|
||||
</div>
|
||||
<div class="preview-stats">
|
||||
<p>当前缩放: <span id="zoomValue">100%</span></p>
|
||||
<p>图片尺寸: <span id="imageSize">0 x 0</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 依赖库 -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
|
||||
|
||||
<script>
|
||||
let cropper;
|
||||
const image = document.getElementById('cropper-image');
|
||||
const message = document.getElementById('message');
|
||||
let currentScale = 1;
|
||||
|
||||
// 初始化Cropper
|
||||
function initCropper(imageSrc) {
|
||||
if (cropper) {
|
||||
cropper.destroy();
|
||||
}
|
||||
|
||||
image.src = imageSrc;
|
||||
cropper = new Cropper(image, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 2,
|
||||
autoCropArea: 0.8,
|
||||
zoomable: true,
|
||||
zoomOnWheel: true,
|
||||
zoomOnTouch: true,
|
||||
wheelZoomRatio: 0.1,
|
||||
minCanvasWidth: 400,
|
||||
minCanvasHeight: 400,
|
||||
crop: updatePreview,
|
||||
ready() {
|
||||
updateImageInfo();
|
||||
document.querySelector('.progress-container').style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 缩放控制
|
||||
function zoomControl(ratio) {
|
||||
if (!cropper) return;
|
||||
|
||||
currentScale = Math.min(Math.max(0.5, currentScale + ratio), 3);
|
||||
cropper.zoomTo(currentScale);
|
||||
updateImageInfo();
|
||||
}
|
||||
|
||||
// 旋转控制
|
||||
function rotateImage(degrees) {
|
||||
if (cropper) {
|
||||
cropper.rotateTo(cropper.getData().rotate + degrees);
|
||||
updatePreview();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新预览
|
||||
function updatePreview() {
|
||||
const canvas = cropper.getCroppedCanvas({
|
||||
width: 250,
|
||||
height: 250,
|
||||
imageSmoothingQuality: 'high'
|
||||
});
|
||||
|
||||
if (canvas) {
|
||||
canvas.toBlob(blob => {
|
||||
const previewUrl = URL.createObjectURL(blob);
|
||||
document.getElementById('preview-img').src = previewUrl;
|
||||
// 清理旧URL
|
||||
setTimeout(() => URL.revokeObjectURL(previewUrl), 1000);
|
||||
}, 'image/jpeg', 0.85);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新图片信息
|
||||
function updateImageInfo() {
|
||||
if (cropper) {
|
||||
const data = cropper.getData();
|
||||
document.getElementById('zoomValue').textContent =
|
||||
`${Math.round(currentScale * 100)}%`;
|
||||
document.getElementById('imageSize').textContent =
|
||||
`${Math.round(data.width)} x ${Math.round(data.height)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 文件选择事件
|
||||
document.getElementById('fileInput').addEventListener('change', function (e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (!file.type.startsWith('image/')) {
|
||||
showMessage('⚠️ 请选择有效的图片文件', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
initCropper(reader.result);
|
||||
currentScale = 1;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
// 上传功能
|
||||
document.getElementById('uploadBtn').addEventListener('click', async () => {
|
||||
const progressBar = document.querySelector('.progress-bar');
|
||||
const progressContainer = document.querySelector('.progress-container');
|
||||
|
||||
try {
|
||||
if (!cropper) {
|
||||
showMessage('⚠️ 请先选择并裁剪图片', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
progressContainer.style.display = 'block';
|
||||
const canvas = cropper.getCroppedCanvas({
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
imageSmoothingQuality: 'high'
|
||||
});
|
||||
|
||||
const blob = await new Promise(resolve =>
|
||||
canvas.toBlob(resolve, 'image/jpeg', 0.9)
|
||||
);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', blob, `avatar_${Date.now()}.jpg`);
|
||||
formData.append('meta', JSON.stringify({
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
scale: currentScale.toFixed(2)
|
||||
}));
|
||||
|
||||
const response = await fetch('/api/v1/file/upload', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error(`服务器错误: ${response.status}`);
|
||||
|
||||
const result = await response.json();
|
||||
showMessage(`✅ 上传成功!路径: ${result.path}`, 'success');
|
||||
|
||||
} catch (error) {
|
||||
console.error('上传错误:', error);
|
||||
showMessage(`❌ 上传失败: ${error.message}`, 'error');
|
||||
} finally {
|
||||
progressBar.style.width = '0%';
|
||||
progressContainer.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// 消息提示
|
||||
function showMessage(text, type = 'success') {
|
||||
message.className = `alert alert-${type}`;
|
||||
message.textContent = text;
|
||||
message.style.display = 'block';
|
||||
setTimeout(() => message.style.display = 'none', 5000);
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (cropper) cropper.destroy();
|
||||
document.querySelectorAll('img').forEach(img => {
|
||||
if (img.src.startsWith('blob:')) URL.revokeObjectURL(img.src);
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化默认图片
|
||||
initCropper('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,268 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>仓库</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
|
||||
<div class="page-wrapper">
|
||||
<!-- Page header -->
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<h2 class="page-title">
|
||||
所有仓库
|
||||
</h2>
|
||||
<div class="text-secondary mt-1">第{{.this_page}}页-共{{.total_pages}}页</div>
|
||||
</div>
|
||||
<!-- Page title actions -->
|
||||
<div class="col-auto ms-auto d-print-none">
|
||||
<div class="d-flex">
|
||||
<input type="search" class="form-control d-inline-block w-9 me-3" placeholder="搜索仓库">
|
||||
<a href="#" class="btn btn-primary" onclick="new_warehouses_windows_dom.show()">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 5l0 14"></path>
|
||||
<path d="M5 12l14 0"></path>
|
||||
</svg>
|
||||
创建新仓库
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page body -->
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="row row-cards">
|
||||
|
||||
{{range .Warehouses}}
|
||||
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body p-4 text-center">
|
||||
<span class="avatar avatar-xl mb-3 rounded">仓库{{.ID}}</span>
|
||||
<h3 class="m-0 mb-1"><a href="/warehouse/{{.ID}}">{{.Name}}</a></h3>
|
||||
<div class="text-secondary">{{.Info}}</div>
|
||||
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="card-btn">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-box">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3l8 4.5l0 9l-8 4.5l-8 -4.5l0 -9l8 -4.5" />
|
||||
<path d="M12 12l8 -4.5" />
|
||||
<path d="M12 12l0 9" />
|
||||
<path d="M12 12l-8 -4.5" />
|
||||
</svg>
|
||||
{{.UsedCapacity}}
|
||||
</div>
|
||||
<a href="/warehouse/{{.ID}}" class="card-btn"><!-- Download SVG icon from http://tabler-icons.io/i/phone -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="icon icon-tabler icons-tabler-outline icon-tabler-binoculars">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M7 16m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M17 16m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
|
||||
<path d="M16.346 9.17l-.729 -1.261c-.16 -.248 -1.056 -.203 -1.117 .091l-.177 1.38" />
|
||||
<path
|
||||
d="M19.761 14.813l-2.84 -5.133c-.189 -.31 -.592 -.68 -1.421 -.68c-.828 0 -1.5 .448 -1.5 1v6" />
|
||||
<path d="M7.654 9.17l.729 -1.261c.16 -.249 1.056 -.203 1.117 .091l.177 1.38" />
|
||||
<path d="M4.239 14.813l2.84 -5.133c.189 -.31 .592 -.68 1.421 -.68c.828 0 1.5 .448 1.5 1v6" />
|
||||
<rect width="4" height="2" x="10" y="12" />
|
||||
</svg>
|
||||
查看</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex mt-4">
|
||||
<ul class="pagination ms-auto">
|
||||
<li class="page-item {{if .disabled_prev_page}}disabled{{end}}">
|
||||
<a class="page-link" href="{{.prev_page}}">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M15 6l-6 6l6 6"></path>
|
||||
</svg>
|
||||
上一页
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
{{range .page_range}}
|
||||
<li class="page-item {{.active}}"><a class="page-link" href="{{.page_href}} ">{{.page}} </a></li>
|
||||
{{end}}
|
||||
|
||||
<li class="page-item {{if .disabled_next_page}}disabled{{end}}">
|
||||
<a class="page-link" href="{{.next_page}}">
|
||||
下一页 <!-- Download SVG icon from http://tabler-icons.io/i/chevron-right -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M9 6l6 6l-6 6"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<!-- 弹出内容 -->
|
||||
<div class="modal modal-blur fade" id="new_warehouses_windows" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">创建新仓库</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row mb-3 align-items-end">
|
||||
<div class="col-auto">
|
||||
<a href="#" class="avatar avatar-upload rounded">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 5l0 14" />
|
||||
<path d="M5 12l14 0" />
|
||||
</svg>
|
||||
<span class="avatar-upload-text">添加图片</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">仓库名*</label>
|
||||
<input type="text" class="form-control" id="wh_name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label">仓库说明</label>
|
||||
<textarea class="form-control" id="wh_info"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn me-auto" data-bs-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-primary" onclick="creat_ware_houses_post()">创建</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- libs -->
|
||||
<script src="/dist/libs/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
<script>
|
||||
//新建仓库窗口
|
||||
const new_warehouses_windows_dom = new bootstrap.Modal('#new_warehouses_windows');
|
||||
|
||||
function creat_ware_houses_post() {
|
||||
|
||||
var data_chack = false;
|
||||
//检测数据合法性
|
||||
if ($("#wh_name").val() == "") {
|
||||
//console.log("no");
|
||||
data_chack = false;
|
||||
} else {
|
||||
data_chack = true;
|
||||
}
|
||||
|
||||
//数据合法,推送
|
||||
if (data_chack) {
|
||||
const url = '/api/v1/warehouses_api/create';
|
||||
const sumt_data = {
|
||||
warehouses_name: $("#wh_name").val(),
|
||||
warehouses_info: $("#wh_info").val()
|
||||
|
||||
};
|
||||
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
console.log('提交成功:', response.data); // 正确打印服务器数据
|
||||
//跳转到主页
|
||||
if (response.data.err_code == 0) {
|
||||
new_warehouses_windows_dom.hide();
|
||||
location.reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,295 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>仓库-{{.warehouse_id}}</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">物件清单</h3>
|
||||
</div>
|
||||
<div class="card-body border-bottom py-3">
|
||||
<div class="d-flex">
|
||||
<div class="text-secondary">
|
||||
显示
|
||||
<div class="mx-2 d-inline-block">
|
||||
<input type="text" class="form-control form-control-sm" value="8" size="3"
|
||||
aria-label="Invoices count">
|
||||
</div>
|
||||
个物件
|
||||
</div>
|
||||
<div class="ms-auto text-secondary d-flex">
|
||||
<input type="search" class="form-control d-inline-block w-9 me-3" placeholder="搜索物件">
|
||||
<a href="#" class="btn btn-primary" onclick="new_warehouses_item_windows_dom.show()">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 5l0 14"></path>
|
||||
<path d="M5 12l14 0"></path>
|
||||
</svg>
|
||||
添加物件
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table card-table table-vcenter text-nowrap datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-1"><input class="form-check-input m-0 align-middle" type="checkbox"
|
||||
aria-label="Select all invoices"></th>
|
||||
<th class="w-1">ID. <!-- Download SVG icon from http://tabler-icons.io/i/chevron-up -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick" width="24"
|
||||
height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
|
||||
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 15l6 -6l6 6"></path>
|
||||
</svg>
|
||||
</th>
|
||||
<th>型号</th>
|
||||
<th>序列号</th>
|
||||
<th>归属</th>
|
||||
<th>工单</th>
|
||||
<th>最后状态</th>
|
||||
<th>更新时间</th>
|
||||
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{{range .items}}
|
||||
<tr>
|
||||
<td><input class="form-check-input m-0 align-middle" type="checkbox"
|
||||
aria-label="Select invoice"></td>
|
||||
<td><span class="text-secondary">{{.ID}}</span></td>
|
||||
<td><a href="invoice.html" class="text-reset" tabindex="-1">{{.Name}}</a></td>
|
||||
<td>
|
||||
{{.SerialNumber}}
|
||||
</td>
|
||||
<td>
|
||||
{{.Destiny}}
|
||||
</td>
|
||||
<td>2</td>
|
||||
<td>
|
||||
<span class="badge {{.Color}} me-1"></span> {{.Status}}
|
||||
</td>
|
||||
<td>
|
||||
{{.UpdatedAt}}
|
||||
</td>
|
||||
|
||||
<td class="text-end">
|
||||
<button class="btn ">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer d-flex align-items-center">
|
||||
<p class="m-0 text-secondary">Showing <span>1</span> to <span>8</span> of <span>16</span> entries
|
||||
</p>
|
||||
<ul class="pagination m-0 ms-auto">
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M15 6l-6 6l6 6"></path>
|
||||
</svg>
|
||||
prev
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item"><a class="page-link" href="#">1</a></li>
|
||||
<li class="page-item active"><a class="page-link" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">4</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">5</a></li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="#">
|
||||
next <!-- Download SVG icon from http://tabler-icons.io/i/chevron-right -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M9 6l6 6l-6 6"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
<!-- 弹出内容 -->
|
||||
<div class="modal modal-blur fade" id="new_warehouses_item_windows" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">添加物件</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row mb-3 align-items-end">
|
||||
<div class="col-auto">
|
||||
<a href="#" class="avatar avatar-upload rounded">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 5l0 14" />
|
||||
<path d="M5 12l14 0" />
|
||||
</svg>
|
||||
<span class="avatar-upload-text">添加图片</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">物件名*</label>
|
||||
<input type="text" class="form-control" maxlength="128" id="item_name" />
|
||||
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">序列号</label>
|
||||
<input type="text" class="form-control" maxlength="100" id="item_sn" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">物件说明</label>
|
||||
<textarea class="form-control" id="item_info"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-end">
|
||||
<div class="col">
|
||||
<label class="form-label">物件归属</label>
|
||||
<input type="text" class="form-control" maxlength="100" id="item_who" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">物件数量</label>
|
||||
<input type="number" class="form-control" id="item_int" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">物件价值</label>
|
||||
<input type="number" step="0.01" class="form-control" id="item_consts" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn me-auto" data-bs-dismiss="modal"
|
||||
onclick="new_warehouses_item_windows_dom.hide()">取消</button>
|
||||
<button type="button" class="btn btn-primary" onclick="add_item()">创建</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- libs -->
|
||||
<script src="/dist/libs/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var items;
|
||||
|
||||
function add_item() {
|
||||
var data_chack = true;
|
||||
//检测数据合法性
|
||||
if ($("#item_name").val() == "") {
|
||||
//console.log("no");
|
||||
data_chack = false;
|
||||
$("#item_name").addClass("is-invalid")
|
||||
}
|
||||
|
||||
if (data_chack) {
|
||||
const url = '/api/v1/warehouses_api/add_item';
|
||||
const sumt_data = {
|
||||
warehouse_id: parseInt("{{.warehouse_id}}", 10),
|
||||
item_name: $("#item_name").val(),
|
||||
item_sn: $("#item_sn").val(),
|
||||
item_info: $("#item_info").val(),
|
||||
item_who: $("#item_who").val(),
|
||||
item_int: parseInt($("#item_int").val(), 10),
|
||||
item_consts: parseFloat($("#item_consts").val()),
|
||||
|
||||
};
|
||||
|
||||
try {
|
||||
const response = axios.post(url, sumt_data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
console.log('提交成功:', response.data); // 正确打印服务器数据
|
||||
|
||||
if (response.data.err_code == 0) {
|
||||
new_warehouses_item_windows_dom.hide();
|
||||
location.reload();
|
||||
}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// 服务器返回了错误状态码(如 4xx, 5xx)
|
||||
console.error('服务器错误:', error.response.data);
|
||||
} else {
|
||||
console.error('请求未完成:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//新建仓库窗口
|
||||
const new_warehouses_item_windows_dom = new bootstrap.Modal('#new_warehouses_item_windows');
|
||||
//输入的时候清除输入框的异常状态
|
||||
$("#item_name").on('input', function () {
|
||||
$("#item_name").removeClass("is-invalid")
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,152 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
* Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
|
||||
* @version 1.0.0-beta20
|
||||
* @link https://tabler.io
|
||||
* Copyright 2018-2023 The Tabler Authors
|
||||
* Copyright 2018-2023 codecalm.net Paweł Kuna
|
||||
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>工单列表</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page">
|
||||
|
||||
{{if .is_login}}
|
||||
{{template "header-logined.html" .}}
|
||||
{{else}}
|
||||
{{template "header-no-login.html"}}
|
||||
{{end}}
|
||||
|
||||
{{template "header-navigation.html"}}
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">工单列表</h3>
|
||||
</div>
|
||||
<div class="card-body border-bottom py-3">
|
||||
<div class="d-flex">
|
||||
<div class="text-secondary">
|
||||
显示
|
||||
<div class="mx-2 d-inline-block">
|
||||
<input type="text" class="form-control form-control-sm" value="8" size="3"
|
||||
aria-label="Invoices count">
|
||||
</div>
|
||||
个工单
|
||||
</div>
|
||||
<div class="ms-auto text-secondary d-flex">
|
||||
<input type="search" class="form-control d-inline-block w-9 me-3" placeholder="搜索工单">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table card-table table-vcenter text-nowrap datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-1"><input class="form-check-input m-0 align-middle" type="checkbox"
|
||||
aria-label="Select all invoices"></th>
|
||||
<th class="w-1">ID. <!-- Download SVG icon from http://tabler-icons.io/i/chevron-up -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick" width="24"
|
||||
height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
|
||||
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 15l6 -6l6 6"></path>
|
||||
</svg>
|
||||
</th>
|
||||
<th>标题</th>
|
||||
<th>简报</th>
|
||||
<th>归属</th>
|
||||
<th>评论</th>
|
||||
<th>最后状态</th>
|
||||
<th>更新时间</th>
|
||||
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{{range .items}}
|
||||
<tr>
|
||||
<td><input class="form-check-input m-0 align-middle" type="checkbox"
|
||||
aria-label="Select invoice"></td>
|
||||
<td><span class="text-secondary">{{.ID}}</span></td>
|
||||
<td><a href="invoice.html" class="text-reset" tabindex="-1">{{.Name}}</a></td>
|
||||
<td>
|
||||
{{.SerialNumber}}
|
||||
</td>
|
||||
<td>
|
||||
{{.Destiny}}
|
||||
</td>
|
||||
<td>2</td>
|
||||
<td>
|
||||
<span class="badge {{.Color}} me-1"></span> {{.Status}}
|
||||
</td>
|
||||
<td>
|
||||
{{.UpdatedAt}}
|
||||
</td>
|
||||
|
||||
<td class="text-end">
|
||||
<button class="btn ">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer d-flex align-items-center">
|
||||
<p class="m-0 text-secondary">Showing <span>1</span> to <span>8</span> of <span>16</span> entries
|
||||
</p>
|
||||
<ul class="pagination m-0 ms-auto">
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M15 6l-6 6l6 6"></path>
|
||||
</svg>
|
||||
prev
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item"><a class="page-link" href="#">1</a></li>
|
||||
<li class="page-item active"><a class="page-link" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">4</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">5</a></li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="#">
|
||||
next <!-- Download SVG icon from http://tabler-icons.io/i/chevron-right -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M9 6l6 6l-6 6"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "footer.html"}}
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user