diff --git a/index.html b/index.html
index a5e4796..6143dde 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,34 @@
-
-
-
-
+
+
+
+
营养与健康数据管理处理平台
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 5816078..8bcdec5 100644
--- a/package.json
+++ b/package.json
@@ -9,9 +9,11 @@
"preview": "vite preview"
},
"dependencies": {
- "@handsontable/vue3": "^14.0.0",
+ "dayjs": "^1.11.10",
+ "pinia": "^2.1.7",
"view-ui-plus": "^1.3.15",
- "vue": "^3.4.0"
+ "vue": "^3.4.0",
+ "vue-router": "4"
},
"devDependencies": {
"@types/node": "^20.10.5",
diff --git a/src/App.vue b/src/App.vue
index 1f722fd..26b676a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,69 +1,32 @@
@@ -74,6 +37,12 @@ const onMenuSelect = (name: string) => {
box-sizing: border-box;
}
+.hideLoading {
+ background: rgba(255, 255, 255, 0);
+ pointer-events: none;
+ opacity: 0;
+}
+
.app-header {
display: flex;
align-items: center;
@@ -114,5 +83,5 @@ body {
will-change: filter;
transition: filter 300ms;
}
-
+./service/api/user.ts
diff --git a/src/components/data-fields/index.vue b/src/components/data-fields/index.vue
index b8f95e9..790ac71 100644
--- a/src/components/data-fields/index.vue
+++ b/src/components/data-fields/index.vue
@@ -77,9 +77,12 @@ const onInputPaste = (e: ClipboardEvent, pIndex: number, fIndex: number) => {
//border-bottom: solid 1px #eee;
&:hover {
- .item:not(.item-header) {
- background: #fafafa;
- }
+ // .item:not(.item-header) {
+ // background: #fafafa;
+ // }
+ }
+ &:focus-within{
+ background-color: #fcf2e0;
}
}
@@ -112,9 +115,12 @@ const onInputPaste = (e: ClipboardEvent, pIndex: number, fIndex: number) => {
//transform: translateX(-1px) translateY(-1px);
&:focus {
- box-shadow: 0 0 5px rgba(87, 116, 189, 0.5) inset;
+ // box-shadow: 0 0 5px rgba(87, 116, 189, 0.5) inset;
//box-shadow: 0 0 1px rgb(0, 0, 0) inset;
- //outline: solid 1px rgb(87, 116, 189);
+ outline: solid 2px rgb(87, 116, 189);
+ position: relative;
+ left:0px;
+ background-color: #fff;
//border-color: #ccc;
//background: rgba(87,87,189,0.15);
}
diff --git a/src/components/login/index.vue b/src/components/login/index.vue
index 0ce83e7..17126e3 100644
--- a/src/components/login/index.vue
+++ b/src/components/login/index.vue
@@ -1,22 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/errors.ts b/src/core/errors.ts
new file mode 100644
index 0000000..ec783e7
--- /dev/null
+++ b/src/core/errors.ts
@@ -0,0 +1,8 @@
+export class BizError extends Error {
+ code: number;
+
+ constructor(code: number, message: string='') {
+ super(message);
+ this.code = code;
+ }
+}
diff --git a/src/core/sleep.ts b/src/core/sleep.ts
new file mode 100644
index 0000000..93b2081
--- /dev/null
+++ b/src/core/sleep.ts
@@ -0,0 +1,5 @@
+export function sleep(time: number) {
+ return new Promise((resolve) => {
+ setTimeout(resolve, time);
+ })
+}
diff --git a/src/main.ts b/src/main.ts
index eff85ba..cdafc3e 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,9 +1,11 @@
import { createApp } from 'vue'
-// import ViewUIPlus from 'view-ui-plus'
import 'view-ui-plus/dist/styles/viewuiplus.css'
-import './style.css'
+import { createPinia } from 'pinia'
import App from './App.vue'
+import router from './router'
+import './style.css'
createApp(App)
- // .use(ViewUIPlus)
+ .use(createPinia())
+ .use(router)
.mount('#app')
diff --git a/src/pages/Layout.vue b/src/pages/Layout.vue
new file mode 100644
index 0000000..ef97949
--- /dev/null
+++ b/src/pages/Layout.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/src/pages/datas.vue b/src/pages/datas.vue
new file mode 100644
index 0000000..b77a46c
--- /dev/null
+++ b/src/pages/datas.vue
@@ -0,0 +1,3 @@
+
+ result
+
\ No newline at end of file
diff --git a/src/pages/result.vue b/src/pages/result.vue
new file mode 100644
index 0000000..1e86ff5
--- /dev/null
+++ b/src/pages/result.vue
@@ -0,0 +1,3 @@
+
+ 输出计算
+
\ No newline at end of file
diff --git a/src/pages/user.vue b/src/pages/user.vue
new file mode 100644
index 0000000..d6c0588
--- /dev/null
+++ b/src/pages/user.vue
@@ -0,0 +1,3 @@
+
+ user
+
\ No newline at end of file
diff --git a/src/router.ts b/src/router.ts
new file mode 100644
index 0000000..0ad75c4
--- /dev/null
+++ b/src/router.ts
@@ -0,0 +1,69 @@
+import {onMounted, onUnmounted, ref} from "vue";
+import {createRouter, createWebHashHistory, RouteRecordRaw} from "vue-router";
+
+function getHash() {
+ const hash = window.location.hash
+ return hash.length > 0 ? hash.slice(1) : '';
+}
+
+export const useHash = () => {
+ const hash = ref(getHash())
+
+ const onHashChange = () => {
+ hash.value = getHash()
+ }
+ onMounted(() => {
+ window.addEventListener('hashchange', onHashChange, false)
+ })
+ onUnmounted(() => {
+ window.removeEventListener('hashchange', onHashChange, false)
+ })
+ return hash
+}
+
+export const routes:RouteRecordRaw[] = [
+ {
+ path: '',
+ name: 'home',
+ meta: {
+ title: '输出计算'
+ },
+ component: () => import('./pages/result.vue')
+ },
+ {
+ path: 'data',
+ name: 'data',
+ meta: {
+ title: '数据管理'
+ },
+ component: () => import('./pages/datas.vue')
+ },
+ {
+ path: 'user',
+ name: 'user',
+ component: () => import('./pages/user.vue'),
+ meta: {
+ role: 'root',
+ title: '用户管理'
+ }
+ }
+]
+
+export const router = createRouter({
+ routes: [
+ // 路由配置
+ {
+ path: '/',
+ component: () => import('./pages/Layout.vue'),
+ children: routes
+ },
+ // {
+ // path: '/login',
+ // name: 'login',
+ // component: () => import('./pages/login.vue')
+ // }
+ ],
+ history: createWebHashHistory()
+})
+
+export default router
diff --git a/src/service/api/user.ts b/src/service/api/user.ts
new file mode 100644
index 0000000..e9adac3
--- /dev/null
+++ b/src/service/api/user.ts
@@ -0,0 +1,29 @@
+import {BizError} from "../../core/errors.ts";
+
+export type LoginModel = {
+ account: string;
+ password: string;
+}
+
+const fakeUser: UserInfo = {
+ account: "admin",
+ nickname: "管理员",
+ password: "",
+ role: 'root',
+ uid: 1
+}
+
+export async function LoginService(params: LoginModel) {
+ if (params.account == 'admin' && params.password == 'admin') {
+ const loginInfo = Date.now().toString(16);
+ return {
+ userinfo: fakeUser,
+ token: loginInfo
+ };
+ }
+ throw new BizError(1001, '用户名或密码错误');
+}
+
+export async function GetLoginInfo() {
+ return fakeUser;
+}
diff --git a/src/service/router.ts b/src/service/router.ts
deleted file mode 100644
index 8ad3b21..0000000
--- a/src/service/router.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import {onMounted, onUnmounted, ref} from "vue";
-
-function getHash() {
- const hash = window.location.hash
- return hash.length > 0 ? hash.slice(1) : '';
-}
-
-export const useHash = () => {
- const hash = ref(getHash())
-
- const onHashChange = () => {
- hash.value = getHash()
- }
- onMounted(() => {
- window.addEventListener('hashchange', onHashChange, false)
- })
- onUnmounted(() => {
- window.removeEventListener('hashchange', onHashChange, false)
- })
- return hash
-}
-
diff --git a/src/service/user-store.ts b/src/service/user-store.ts
new file mode 100644
index 0000000..838c4b3
--- /dev/null
+++ b/src/service/user-store.ts
@@ -0,0 +1,63 @@
+import {defineStore} from "pinia"
+import {onMounted, ref} from "vue"
+import {GetLoginInfo, LoginService} from "./api/user";
+import {BizError} from "../core/errors.ts";
+import router from "../router.ts";
+import {sleep} from "../core/sleep.ts";
+
+type LoginParam = {
+ account: string;
+ password: string;
+}
+
+export const LOGIN_SESSION_KEY = 'x-yy-js-data-user';
+
+export const useUserStore = defineStore('counter', () => {
+ const userInfo = ref()
+ const userInit = ref(false)
+
+ // 登录
+ const login = async (data: LoginParam) => {
+ await sleep(1000);
+ const info = await LoginService(data);
+ userInfo.value = info.userinfo;
+ localStorage.setItem(LOGIN_SESSION_KEY, info.token)
+ }
+
+ // 登出
+ const logout = async () => {
+ localStorage.removeItem(LOGIN_SESSION_KEY)
+ userInfo.value = undefined;
+ }
+ // 更新用户信息
+ const updateUserInfo = async (info: UserInfo) => {
+ userInfo.value = info
+ }
+ // 获取用户信息
+ const getUserInfo = async () => {
+ const token = localStorage.getItem(LOGIN_SESSION_KEY);
+ if (!token) {
+ throw new BizError(401)
+ }
+ userInfo.value = await GetLoginInfo();
+ }
+ onMounted(() => {
+ getUserInfo().catch((e: BizError) => {
+ if (e.code == 401) {
+ router.replace(`/login?redirect=${router.currentRoute.value.path}`).then(() => console.log('401 show login'))
+ }
+ }).finally(() => {
+ console.log('onMounted inited')
+ userInit.value = true
+ })
+ })
+
+ return {
+ userInfo,
+ userInit,
+ login,
+ logout,
+ updateUserInfo,
+ getUserInfo
+ }
+})
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 11f02fe..cefc0fa 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1 +1,16 @@
///
+
+type int = number;
+type double = number;
+type bool = boolean;
+type AccountRole = 'root' | 'admin' | 'user';
+type UserInfo = {
+ uid: number;
+ nickname: string;
+ account: string;
+ password: string;
+ avatar?: string;
+ lastUpdate?:string;
+ createTime?: string;
+ role: AccountRole;
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index b5014df..31e530b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -117,11 +117,6 @@
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
-"@handsontable/vue3@^14.0.0":
- version "14.0.0"
- resolved "https://registry.npmmirror.com/@handsontable/vue3/-/vue3-14.0.0.tgz#7c62091cc3393cb556771d9678cced4622095f1c"
- integrity sha512-4/XuCxXw+8d3fHB3/v0zbb9PYgyjJfU6Tol+dsxRHk0L8FGUFCM8WIDFn3DCb5PHtE2peQBIUl/HvnsCpPpEMg==
-
"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
@@ -203,6 +198,11 @@
"@vue/compiler-dom" "3.4.0"
"@vue/shared" "3.4.0"
+"@vue/devtools-api@^6.5.0":
+ version "6.5.1"
+ resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.1.tgz#7f71f31e40973eeee65b9a64382b13593fdbd697"
+ integrity sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==
+
"@vue/language-core@1.8.27":
version "1.8.27"
resolved "https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.27.tgz"
@@ -332,6 +332,11 @@ dayjs@^1.11.0:
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
+dayjs@^1.11.10:
+ version "1.11.10"
+ resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
+ integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
+
de-indent@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz"
@@ -511,6 +516,14 @@ picomatch@^2.0.4, picomatch@^2.2.1:
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+pinia@^2.1.7:
+ version "2.1.7"
+ resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
+ integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
+ dependencies:
+ "@vue/devtools-api" "^6.5.0"
+ vue-demi ">=0.14.5"
+
popper.js@^1.14.6:
version "1.16.1"
resolved "https://registry.npmmirror.com/popper.js/-/popper.js-1.16.1.tgz"
@@ -622,6 +635,18 @@ vite@^4.3.2:
optionalDependencies:
fsevents "~2.3.2"
+vue-demi@>=0.14.5:
+ version "0.14.6"
+ resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
+ integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
+
+vue-router@4:
+ version "4.2.5"
+ resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a"
+ integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==
+ dependencies:
+ "@vue/devtools-api" "^6.5.0"
+
vue-template-compiler@^2.7.14:
version "2.7.16"
resolved "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz"