commit d171a5b73bf3d54be20c63d641027f976984da24
Author: Zones <765289303@qq.com>
Date: Tue Jun 9 19:29:04 2026 +0800
init
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2370852
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+unpackage/
+.hbuilderx/
+.DS_Store
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..7fef9a1
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,27 @@
+
+
+
diff --git a/api/auth.js b/api/auth.js
new file mode 100644
index 0000000..e3c852f
--- /dev/null
+++ b/api/auth.js
@@ -0,0 +1,7 @@
+import {
+ get,
+ post
+} from '@/utils/request.js'
+
+
+export const reqLogin = (data) => post('user/postLoginOn', data)
\ No newline at end of file
diff --git a/api/user.js b/api/user.js
new file mode 100644
index 0000000..6771950
--- /dev/null
+++ b/api/user.js
@@ -0,0 +1,8 @@
+import { get, post} from "@/utils/request.js"
+
+
+/**
+ * 根据用户获取项目列表
+ * @param userId {string} 用户的ID
+ */
+export const reqProjectByUserId = (userId)=>get(`Project/getProjectsByUserId?userId=${userId}`)
diff --git a/assets/css/components.scss b/assets/css/components.scss
new file mode 100644
index 0000000..0e7239c
--- /dev/null
+++ b/assets/css/components.scss
@@ -0,0 +1,47 @@
+.project-select{
+ height: 100%;
+ width: 100%;
+ &-btns{
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ height: 80rpx;
+ padding: 0 30rpx;
+ border-bottom: 1px solid var(--u-border-color);
+ >button{
+ margin: 0;
+ padding: 0 40rpx !important;
+ }
+ }
+ &-filter{
+ height: 120rpx;
+ padding: 20rpx 30rpx 0;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ }
+ &-inner{
+ padding-bottom: 20rpx;
+ height: calc(100% - 210rpx);
+ overflow: hidden;
+ border-top: 1px solid var(--u-border-color);
+ &-wrap{
+ >.li{
+ padding: 20rpx 30rpx;
+ background-color: var(--u-bg-gray-light);
+ }
+ >.li:nth-of-type(2n){
+ background-color: var(--u-bg-white);
+ }
+ >.li.active{
+ background-color: var(--u-type-primary-dark);
+ color: var(--u-white-color);
+ }
+ >.li:hover{
+ background-color: var(--u-type-primary-dark);
+ color: var(--u-white-color);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/css/page.scss b/assets/css/page.scss
new file mode 100644
index 0000000..843b307
--- /dev/null
+++ b/assets/css/page.scss
@@ -0,0 +1,148 @@
+.wrap {}
+
+// 登录
+.login {
+ width: 100vw;
+ height: 100vh;
+ background-color: $u-bg-white;
+
+ .sys-name {
+ font-size: 48rpx;
+ font-weight: 700;
+ color: #333333;
+ position: absolute;
+ top: 300rpx;
+ width: 100%;
+ text-align: center;
+ }
+
+ .login-form {
+ position: absolute;
+ bottom: 240rpx;
+ right: 60rpx;
+ left: 60rpx;
+ }
+}
+
+// 首页
+.home {
+ .u-border-bottom:after {
+ border: none;
+ }
+
+ .slot-wrap {
+ padding: 20rpx;
+ width: 220rpx;
+
+ .u-input__input {
+ color: #ffffff;
+ }
+ }
+
+ &-icons {
+ height: 160rpx;
+ width: 100%;
+ background-color: $u-type-primary;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+ padding: 0 20rpx;
+ }
+
+ &-icon {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ >text {
+ margin-top: 6rpx;
+ color: #ffffff;
+ }
+ }
+
+ &-icon+&-icon {
+ margin-left: 60rpx;
+ }
+
+ &-hj {
+ margin: 20rpx;
+ background: #fff;
+ border-radius: 16rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
+ overflow: hidden;
+
+ .hj-title {
+ font-size: 28rpx;
+ font-weight: 600;
+ color: #333;
+ padding: 24rpx 32rpx;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .hj-content {
+ padding: 24rpx 32rpx;
+
+ .hj-row {
+ display: flex;
+ justify-content: space-between;
+
+ &:not(:last-child) {
+ margin-bottom: 24rpx;
+ }
+ }
+
+ .hj-cell {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 16rpx 0;
+ border-radius: 8rpx;
+
+ &:not(:last-child) {
+ border-right: 1px solid #f0f0f0;
+ padding-right: 24rpx;
+ }
+ }
+
+ .hj-label {
+ font-size: 24rpx;
+ color: #666;
+ margin-bottom: 12rpx;
+ }
+
+ .hj-value {
+ font-size: 28rpx;
+ font-weight: 500;
+ color: #333;
+
+ &.hj-sub {
+ font-size: 22rpx;
+ color: #999;
+ }
+ }
+ }
+
+ .hj-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 24rpx 32rpx;
+ background: linear-gradient(90deg, #f8f9fa 0%, #fff 100%);
+ border-top: 1px solid #f0f0f0;
+
+ .hj-footer-label {
+ font-size: 26rpx;
+ color: #666;
+ }
+
+ .hj-footer-value {
+ font-size: 36rpx;
+ font-weight: 700;
+ color: $u-type-primary;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/icon/nbd-icon.css b/assets/icon/nbd-icon.css
new file mode 100644
index 0000000..681d5ae
--- /dev/null
+++ b/assets/icon/nbd-icon.css
@@ -0,0 +1,22 @@
+@font-face {
+ font-family: "nbd-icon"; /* Project id 5193086 */
+ src: url('//at.alicdn.com/t/c/font_5193086_zgg3m1cv22e.woff2?t=1781003671405') format('woff2'),
+ url('//at.alicdn.com/t/c/font_5193086_zgg3m1cv22e.woff?t=1781003671405') format('woff'),
+ url('//at.alicdn.com/t/c/font_5193086_zgg3m1cv22e.ttf?t=1781003671405') format('truetype');
+}
+
+.nbd-icon {
+ font-family: "nbd-icon" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.nbd-icon-daiban:before {
+ content: "\e612";
+}
+
+.nbd-icon-saoyisao:before {
+ content: "\e891";
+}
diff --git a/components/nbd-select-project.vue b/components/nbd-select-project.vue
new file mode 100644
index 0000000..62e7048
--- /dev/null
+++ b/components/nbd-select-project.vue
@@ -0,0 +1,94 @@
+
+
+
+
+ 取消
+
+ 确定
+
+
+
+
+
+
+ {{item[props.labelKey]}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..b5d330d
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..15b1540
--- /dev/null
+++ b/main.js
@@ -0,0 +1,28 @@
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import {
+ createSSRApp
+} from 'vue'
+import uViewPro from 'uview-pro'
+import { setupStore } from '@/store'
+export function createApp() {
+ const app = createSSRApp(App)
+ app.use(uViewPro)
+ setupStore(app)
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..ac8ee13
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,72 @@
+{
+ "name" : "SHJ_APP",
+ "appid" : "__UNI__48399D1",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "",
+ "setting" : {
+ "urlCheck" : false
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3"
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..276425b
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,377 @@
+{
+ "name": "SHJ_APP",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "crypto-js": "^4.2.0",
+ "pinia": "^2.3.1",
+ "uview-pro": "^0.6.2"
+ }
+ },
+ "node_modules/.pnpm/uview-pro@0.6.2/node_modules/uview-pro": {
+ "version": "0.6.2",
+ "license": "MIT",
+ "engines": {
+ "HBuilderX": "^4.07",
+ "uni-app": "^4.07",
+ "uni-app-x": ""
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
+ "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.29.7"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
+ "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.35.tgz",
+ "integrity": "sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/parser": "^7.29.3",
+ "@vue/shared": "3.5.35",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.35.tgz",
+ "integrity": "sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/compiler-core": "3.5.35",
+ "@vue/shared": "3.5.35"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.35.tgz",
+ "integrity": "sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/parser": "^7.29.3",
+ "@vue/compiler-core": "3.5.35",
+ "@vue/compiler-dom": "3.5.35",
+ "@vue/compiler-ssr": "3.5.35",
+ "@vue/shared": "3.5.35",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.15",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.35.tgz",
+ "integrity": "sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.35",
+ "@vue/shared": "3.5.35"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.35.tgz",
+ "integrity": "sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/shared": "3.5.35"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.35.tgz",
+ "integrity": "sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/reactivity": "3.5.35",
+ "@vue/shared": "3.5.35"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.35.tgz",
+ "integrity": "sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/reactivity": "3.5.35",
+ "@vue/runtime-core": "3.5.35",
+ "@vue/shared": "3.5.35",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.35.tgz",
+ "integrity": "sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.35",
+ "@vue/shared": "3.5.35"
+ },
+ "peerDependencies": {
+ "vue": "3.5.35"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.35.tgz",
+ "integrity": "sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/crypto-js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
+ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/pinia": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
+ "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.3",
+ "vue-demi": "^0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.4.4",
+ "vue": "^2.7.0 || ^3.5.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "nanoid": "^3.3.12",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/uview-pro": {
+ "resolved": "node_modules/.pnpm/uview-pro@0.6.2/node_modules/uview-pro",
+ "link": true
+ },
+ "node_modules/vue": {
+ "version": "3.5.35",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.35.tgz",
+ "integrity": "sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.35",
+ "@vue/compiler-sfc": "3.5.35",
+ "@vue/runtime-dom": "3.5.35",
+ "@vue/server-renderer": "3.5.35",
+ "@vue/shared": "3.5.35"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..85caf40
--- /dev/null
+++ b/package.json
@@ -0,0 +1,7 @@
+{
+ "dependencies": {
+ "pinia": "^2.3.1",
+ "pinia-plugin-persist-uni": "^1.3.2",
+ "uview-pro": "^0.6.2"
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..e1fa50f
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,32 @@
+{
+ "easycom": {
+ "autoscan": true,
+ "custom": {
+ "^u-(.*)": "uview-pro/components/u-$1/u-$1.vue",
+ "^nbd-(.*)": "@/components/nbd-$1.vue"
+ }
+ },
+ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+ {
+ "path": "pages/login/index",
+ "style": {
+ "navigationBarTitleText": "登录",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationBarTitleText": "首页",
+ "navigationStyle": "custom"
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "施工管理",
+ "navigationBarBackgroundColor": "#2979ff",
+ "backgroundColor": "#2979ff"
+ },
+ "uniIdRouter": {}
+}
\ No newline at end of file
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..a9c98b6
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+ 扫一扫
+
+
+
+ 待办
+
+
+
+ 项目管道实时预制率
+
+
+
+ 工厂焊接一次合格率
+ 99.5%
+
+
+ 现场焊接一次合格率
+ 0%
+
+
+
+
+ 工厂预制进度
+ 49229.500/286639.000 DIN
+
+
+ 现场焊接进度
+ 5906.500/84951.000 DIN
+
+
+
+
+ 工厂焊工功效
+ 252 DIN/天
+
+
+ 现场焊接功效
+ 95 DIN/天
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/login/index.vue b/pages/login/index.vue
new file mode 100644
index 0000000..2fec4ab
--- /dev/null
+++ b/pages/login/index.vue
@@ -0,0 +1,33 @@
+
+
+
+ 施工管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..43ed97a
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,282 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ pinia:
+ specifier: ^2.3.1
+ version: 2.3.1(vue@3.5.35)
+ pinia-plugin-persist-uni:
+ specifier: ^1.3.2
+ version: 1.3.2(pinia@2.3.1(vue@3.5.35))(vue@3.5.35)
+ uview-pro:
+ specifier: ^0.6.2
+ version: 0.6.2
+
+packages:
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.7':
+ resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.7':
+ resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+ engines: {node: '>=6.9.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@vue/compiler-core@3.5.35':
+ resolution: {integrity: sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==}
+
+ '@vue/compiler-dom@3.5.35':
+ resolution: {integrity: sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==}
+
+ '@vue/compiler-sfc@3.5.35':
+ resolution: {integrity: sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==}
+
+ '@vue/compiler-ssr@3.5.35':
+ resolution: {integrity: sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==}
+
+ '@vue/devtools-api@6.6.4':
+ resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
+
+ '@vue/reactivity@3.5.35':
+ resolution: {integrity: sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==}
+
+ '@vue/runtime-core@3.5.35':
+ resolution: {integrity: sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==}
+
+ '@vue/runtime-dom@3.5.35':
+ resolution: {integrity: sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==}
+
+ '@vue/server-renderer@3.5.35':
+ resolution: {integrity: sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==}
+ peerDependencies:
+ vue: 3.5.35
+
+ '@vue/shared@3.5.35':
+ resolution: {integrity: sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ nanoid@3.3.12:
+ resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ pinia-plugin-persist-uni@1.3.2:
+ resolution: {integrity: sha512-Z47MWlAI3dnm9xENwodYyT6B3TMDuwFK7MHHymwQyrTchuhG2Yu26w7bYlIap7df0fCwNCmAo0n7n1RK3Ute+w==}
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0
+ pinia: '>2.0.0'
+ vue: ^2.0.0 || >=3.0.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ pinia@2.3.1:
+ resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==}
+ peerDependencies:
+ typescript: '>=4.4.4'
+ vue: ^2.7.0 || ^3.5.11
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ postcss@8.5.15:
+ resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ uview-pro@0.6.2:
+ resolution: {integrity: sha512-I9veDKJKwnN3ZAuFG7pK+CiCh3tqWv1z+7jQ9/H8iIHTAF5Dk6C67yqN3YtDtPzFQ5dnhvW6L3RIWPrXfNpAIA==}
+ engines: {HBuilderX: ^4.07, uni-app: ^4.07, uni-app-x: ''}
+
+ vue-demi@0.12.5:
+ resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue@3.5.35:
+ resolution: {integrity: sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+snapshots:
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/parser@7.29.7':
+ dependencies:
+ '@babel/types': 7.29.7
+
+ '@babel/types@7.29.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@vue/compiler-core@3.5.35':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/shared': 3.5.35
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.35':
+ dependencies:
+ '@vue/compiler-core': 3.5.35
+ '@vue/shared': 3.5.35
+
+ '@vue/compiler-sfc@3.5.35':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/compiler-core': 3.5.35
+ '@vue/compiler-dom': 3.5.35
+ '@vue/compiler-ssr': 3.5.35
+ '@vue/shared': 3.5.35
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.15
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.35':
+ dependencies:
+ '@vue/compiler-dom': 3.5.35
+ '@vue/shared': 3.5.35
+
+ '@vue/devtools-api@6.6.4': {}
+
+ '@vue/reactivity@3.5.35':
+ dependencies:
+ '@vue/shared': 3.5.35
+
+ '@vue/runtime-core@3.5.35':
+ dependencies:
+ '@vue/reactivity': 3.5.35
+ '@vue/shared': 3.5.35
+
+ '@vue/runtime-dom@3.5.35':
+ dependencies:
+ '@vue/reactivity': 3.5.35
+ '@vue/runtime-core': 3.5.35
+ '@vue/shared': 3.5.35
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.35(vue@3.5.35)':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.35
+ '@vue/shared': 3.5.35
+ vue: 3.5.35
+
+ '@vue/shared@3.5.35': {}
+
+ csstype@3.2.3: {}
+
+ entities@7.0.1: {}
+
+ estree-walker@2.0.2: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ nanoid@3.3.12: {}
+
+ picocolors@1.1.1: {}
+
+ pinia-plugin-persist-uni@1.3.2(pinia@2.3.1(vue@3.5.35))(vue@3.5.35):
+ dependencies:
+ pinia: 2.3.1(vue@3.5.35)
+ vue: 3.5.35
+ vue-demi: 0.12.5(vue@3.5.35)
+
+ pinia@2.3.1(vue@3.5.35):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.35
+ vue-demi: 0.14.10(vue@3.5.35)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ postcss@8.5.15:
+ dependencies:
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ source-map-js@1.2.1: {}
+
+ uview-pro@0.6.2: {}
+
+ vue-demi@0.12.5(vue@3.5.35):
+ dependencies:
+ vue: 3.5.35
+
+ vue-demi@0.14.10(vue@3.5.35):
+ dependencies:
+ vue: 3.5.35
+
+ vue@3.5.35:
+ dependencies:
+ '@vue/compiler-dom': 3.5.35
+ '@vue/compiler-sfc': 3.5.35
+ '@vue/runtime-dom': 3.5.35
+ '@vue/server-renderer': 3.5.35(vue@3.5.35)
+ '@vue/shared': 3.5.35
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..b5771e2
Binary files /dev/null and b/static/logo.png differ
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 0000000..6eb7d4e
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,11 @@
+import { createPinia } from 'pinia'
+import piniaPersist from "pinia-plugin-persist-uni"
+const pinia = createPinia()
+
+pinia.use(piniaPersist)
+export function setupStore(app) {
+ app.use(pinia)
+}
+
+export * from './modules/user'
+export default pinia
diff --git a/store/modules/user.js b/store/modules/user.js
new file mode 100644
index 0000000..2a29055
--- /dev/null
+++ b/store/modules/user.js
@@ -0,0 +1,92 @@
+import {
+ defineStore
+} from 'pinia'
+import {
+ ref
+} from 'vue'
+import {
+ reqLogin
+} from '@/api/auth.js'
+
+export const useUserStore = defineStore('user', () => {
+ const token = ref("")
+ const userInfo = ref(null)
+ const loginForm = ref({
+ account: 'hfnbd',
+ password: '1111',
+ Telephone: '',
+ })
+
+ const projectList = ref([])
+ const currentProject = ref(null)
+
+
+ /**
+ * 登出
+ */
+ const logout = () => {
+ token.value = ""
+ userInfo.value = null
+ loginForm.value = {
+ account: '',
+ password: '',
+ Telephone: '',
+ }
+ currentProject.value = null
+ }
+
+ /**
+ * 登录请求
+ */
+ const fetchLogin = async () => {
+ try {
+ let res = await reqLogin(loginForm.value)
+ userInfo.value = res.data
+ token.value = res.data?.PersonId
+ currentProject.value = {
+ ProjectId: res.data?.LoginProjectId,
+ ProjectName: res.data?.LoginProjectName
+ }
+ setTimeout(() => {
+ uni.reLaunch({
+ url: '/pages/index/index'
+ })
+ }, 900)
+ } catch (err) {
+
+ }
+ }
+
+ /**
+ * 获取用户的项目列表
+ */
+ const setProjectList = (list) => {
+ console.log(list)
+ projectList.value = list
+ }
+ /**
+ * 选择当前的项目
+ */
+ const setCurrentProject = (item) => {
+ currentProject.value = item ? { ...item } : null
+ console.log(11111111, currentProject.value)
+ }
+ return {
+ token,
+ userInfo,
+ loginForm,
+ fetchLogin,
+ projectList,
+ currentProject,
+ setProjectList,
+ setCurrentProject
+ }
+}, {
+ persist: {
+ enabled: true, // 开启持久化
+ strategies: [{
+ key: 'user', // 自定义存储键
+ paths: ['loginForm', 'userInfo', 'token', 'currentProject'], // 仅持久化token字段
+ }]
+ },
+})
\ No newline at end of file
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..5fec4f3
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,13 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => {
+ if (!res) return resolve(res)
+ return res[0] ? reject(res[0]) : resolve(res[1])
+ });
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..03d2193
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,77 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+@import 'uview-pro/theme.scss';
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
diff --git a/utils/request.js b/utils/request.js
new file mode 100644
index 0000000..75ee5eb
--- /dev/null
+++ b/utils/request.js
@@ -0,0 +1,147 @@
+import { useUserStore } from '@/store'
+
+// TODO: 替换为实际的 API 地址
+export const baseUrl = ' https://lygcgs.com.cn:8078/shjapi/api/'
+
+// ===== 防止重复请求 =====
+const pendingRequests = new Map()
+
+/**
+ * 生成请求唯一标识
+ */
+function getRequestKey(config) {
+ const { url = '', method = 'GET', data = {} } = config
+ const paramStr = JSON.stringify(data)
+ return `${method}:${url}:${paramStr}`
+}
+
+/**
+ * 检查是否为重复请求
+ */
+function checkDuplicate(config) {
+ const key = getRequestKey(config)
+ if (pendingRequests.has(key)) {
+ const meta = config.meta || {}
+ if (meta.toast !== false) {
+ uni.showToast({ title: '请求过于频繁,请稍后再试', icon: 'none' })
+ }
+ return new Error('duplicate request')
+ }
+ pendingRequests.set(key, true)
+ return null
+}
+
+/**
+ * 移除请求标识
+ */
+function removePending(config) {
+ const key = getRequestKey(config)
+ pendingRequests.delete(key)
+}
+// ========================
+
+// uview-pro 全局请求配置
+export const httpRequestConfig = {
+ baseUrl,
+ header: {
+ 'content-type': 'application/json'
+ },
+ meta: {
+ originalData: true,
+ toast: true,
+ loading: true
+ }
+}
+
+// 全局请求/响应拦截器
+export const httpInterceptor = {
+ request: (config) => {
+ // 检查重复请求
+ const dupError = checkDuplicate(config)
+ if (dupError) throw dupError
+
+ const meta = config.meta || {}
+ if (meta.loading) {
+ uni.showLoading({ title: '加载中...', mask: true })
+ }
+ const userStore = useUserStore()
+ if (userStore.token) {
+ config.header.token = userStore.token
+ }
+ return config
+ },
+ response: (response) => {
+ const meta = response.config?.meta || {}
+ if (meta.loading) {
+ uni.hideLoading()
+ }
+
+ // 请求完成,移除标识
+ removePending(response.config)
+
+ // 根据业务处理错误、例如登录失效等处理接口返回错误码
+ if (response.data.code !== 1) {
+ if (meta.toast) {
+ uni.showToast({
+ title: response.data.message || '请求失败',
+ icon: 'none'
+ })
+ }
+ // 401 登录失效,跳转登录页
+ if (response.data.code === 401) {
+ const userStore = useUserStore()
+ userStore.logout()
+ uni.reLaunch({ url: '/pages/login/index' })
+ }
+ throw new Error(response.data.message || '请求失败')
+ }
+ uni.showToast({
+ title: response.data.message || '请求成功',
+ icon: 'none'
+ })
+ return response.data
+ }
+}
+
+/**
+ * 便捷请求方法(基于 uni.request 封装)
+ * 也可用 uni.$http.get / uni.$http.post(uview-pro)
+ */
+export function request(options) {
+ return new Promise((resolve, reject) => {
+ // 运行请求拦截器
+ const config = { ...httpRequestConfig, ...options }
+ const finalConfig = httpInterceptor.request({
+ ...config,
+ header: { ...httpRequestConfig.header, ...options.header }
+ })
+
+ uni.request({
+ ...finalConfig,
+ url: `${finalConfig.baseUrl}${finalConfig.url}`,
+ success: (res) => {
+ try {
+ const data = httpInterceptor.response({ data: res.data, config: finalConfig })
+ resolve(data)
+ } catch (err) {
+ reject(err)
+ }
+ },
+ fail: (err) => {
+ removePending(finalConfig) // 网络失败也要清理标识
+ uni.showToast({ title: '网络连接失败', icon: 'none' })
+ reject(err)
+ }
+ })
+ })
+}
+
+// GET 快捷方法
+export function get(url, params = {}) {
+ return request({ url, method: 'GET', data: params })
+}
+
+// POST 快捷方法
+export function post(url, data = {}) {
+ return request({ url, method: 'POST', data })
+}