zbb 1 день назад
Родитель
Сommit
aa51894ee0
8 измененных файлов с 251 добавлено и 52 удалено
  1. 1 1
      .gitignore
  2. 4 2
      main.js
  3. 25 32
      manifest.json
  4. 21 0
      package.json
  5. 9 17
      pages/index/index.vue
  6. 111 0
      store/README.md
  7. 9 0
      store/index.js
  8. 71 0
      store/modules/user.js

+ 1 - 1
.gitignore

@@ -1 +1 @@
-/unpackage/dist/
+unpackage/dist/

+ 4 - 2
main.js

@@ -1,4 +1,3 @@
-
 // #ifndef VUE3
 import Vue from 'vue'
 import App from './App'
@@ -16,10 +15,13 @@ app.$mount()
 // #ifdef VUE3
 import { createSSRApp } from 'vue'
 import App from './App.vue'
+import pinia from './store'
+
 export function createApp() {
   const app = createSSRApp(App)
+  app.use(pinia)
   return {
     app
   }
 }
-// #endif
+// #endif

+ 25 - 32
manifest.json

@@ -64,38 +64,31 @@
             "selectedColor" : "#667eea",
             "backgroundColor" : "#ffffff",
             "borderStyle" : "black",
-            "list" : [
-                {
-                    "pagePath" : "pages/index/index",
-                    "text" : "首页",
-                    "iconPath" : "static/tabbar-home.png",
-                    "selectedIconPath" : "static/tabbar-home-active.png"
-                },
-                {
-                    "pagePath" : "pages/customer/list",
-                    "text" : "客户",
-                    "iconPath" : "static/tabbar-customer.png",
-                    "selectedIconPath" : "static/tabbar-customer-active.png"
-                },
-                {
-                    "pagePath" : "pages/message/list",
-                    "text" : "消息",
-                    "iconPath" : "static/tabbar-message.png",
-                    "selectedIconPath" : "static/tabbar-message-active.png"
-                },
-                {
-                    "pagePath" : "pages/stats/index",
-                    "text" : "统计",
-                    "iconPath" : "static/tabbar-stats.png",
-                    "selectedIconPath" : "static/tabbar-stats-active.png"
-                },
-                {
-                    "pagePath" : "pages/mine/index",
-                    "text" : "我的",
-                    "iconPath" : "static/tabbar-mine.png",
-                    "selectedIconPath" : "static/tabbar-mine-active.png"
-                }
-            ]
+            "list" : [{
+				"pagePath": "pages/index/index",
+				"text": "首页",
+				"iconPath": "static/tabbar/tabbar-home.png",
+				"selectedIconPath": "static/tabbar/tabbar-home-active.png"
+			},
+			{
+				"pagePath": "pages/todos/index",
+				"text": "待办",
+				"iconPath": "static/tabbar/tabbar-todo.png",
+				"selectedIconPath": "static/tabbar/tabbar-todo-active.png"
+			},
+			{
+				"pagePath": "pages/message/index",
+				"text": "消息",
+				"iconPath": "static/tabbar/tabbar-message.png",
+				"selectedIconPath": "static/tabbar/tabbar-message-active.png"
+			},
+			{
+				"pagePath": "pages/mine/index",
+				"text": "我的",
+				"iconPath": "static/tabbar/tabbar-mine.png",
+				"selectedIconPath": "static/tabbar/tabbar-mine-active.png"
+			}
+		]
         }
     },
     "vueVersion" : "3"

+ 21 - 0
package.json

@@ -0,0 +1,21 @@
+{
+  "name": "wechat-crm",
+  "version": "1.0.0",
+  "description": "布尔销销乐 - 微信小程序 CRM 系统",
+  "main": "main.js",
+  "scripts": {
+    "dev:mp-weixin": "uni -p mp-weixin",
+    "build:mp-weixin": "uni build -p mp-weixin"
+  },
+  "dependencies": {
+    "pinia": "^2.1.7",
+    "vue": "^3.4.21"
+  },
+  "devDependencies": {},
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "author": "",
+  "license": "MIT"
+}

+ 9 - 17
pages/index/index.vue

@@ -240,28 +240,20 @@
 <script setup>
 	import NavBar from '@/components/nav-bar/index.vue'
 	import CardPreview from './components/card-preview.vue'
-	import {
-		ref,
-		onMounted
-	} from 'vue'
-	import {
-		getUserInfo,
-		isLogin
-	} from '@/utils/userCache.js'
+	import { ref, onMounted, computed } from 'vue'
+	import { useUserStore } from '@/store/modules/user.js'
+	import { storeToRefs } from 'pinia'
 
-	const userInfo = ref(null)
+	// 使用 Pinia 管理用户状态
+	const userStore = useUserStore()
+	const { userInfo, isLoggedIn } = storeToRefs(userStore)
 
 	onMounted(() => {
-		loadUserInfo()
+		// 从 store 中获取用户信息(已自动从 localStorage 加载)
+		console.log('用户登录状态:', isLoggedIn.value)
+		console.log('用户信息:', userInfo.value)
 	})
 
-	const loadUserInfo = () => {
-		const info = getUserInfo()
-		if (info) {
-			userInfo.value = info
-		}
-	}
-
 	const makeCall = () => {
 		uni.makePhoneCall({
 			phoneNumber: '4000000000'

+ 111 - 0
store/README.md

@@ -0,0 +1,111 @@
+# Pinia 状态管理使用说明
+
+## 目录结构
+
+```
+store/
+├── index.js              # Pinia 实例
+├── README.md             # 使用说明
+└── modules/              # 状态模块
+    ├── user.js           # 用户状态
+    └── ...               # 其他模块
+```
+
+## 使用方式
+
+### 1. 在组件中使用
+
+```vue
+<script setup>
+import { useUserStore } from '@/store/modules/user.js'
+import { storeToRefs } from 'pinia'
+
+// 方式一:直接使用(推荐用于修改数据)
+const userStore = useUserStore()
+
+// 方式二:使用 storeToRefs(推荐用于读取,保持响应式)
+const { token, userInfo, isLoggedIn } = storeToRefs(userStore)
+
+// 调用方法
+userStore.loginSuccess({ token: 'xxx', userInfo: {...} })
+userStore.logout()
+</script>
+```
+
+### 2. 在 JS 文件中使用
+
+```javascript
+import { useUserStore } from '@/store/modules/user.js'
+import { createPinia } from 'pinia'
+
+// 注意:在非组件中使用时,需要确保 pinia 已初始化
+const userStore = useUserStore()
+```
+
+## 内置模块
+
+### user.js - 用户状态
+
+**状态:**
+- `token` - 登录令牌
+- `userInfo` - 用户信息对象
+
+**计算属性:**
+- `isLoggedIn` - 是否已登录
+- `userName` - 用户名
+- `userAvatar` - 用户头像
+
+**方法:**
+- `setToken(token)` - 设置 token
+- `setUserInfo(info)` - 设置用户信息
+- `loginSuccess(data)` - 登录成功处理
+- `logout()` - 退出登录
+- `updateUserInfo(info)` - 更新用户信息
+
+## 创建新模块
+
+在 `store/modules/` 目录下创建新文件:
+
+```javascript
+// store/modules/todo.js
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useTodoStore = defineStore('todo', () => {
+  // 状态
+  const list = ref([])
+  
+  // 方法
+  const addTodo = (item) => {
+    list.value.push(item)
+  }
+  
+  return {
+    list,
+    addTodo
+  }
+})
+```
+
+## 注意事项
+
+1. **数据持久化**:当前使用 `uni.setStorageSync` 手动持久化重要数据
+2. **小程序兼容性**:Pinia 已兼容微信小程序
+3. **响应式**:所有状态都是响应式的,组件会自动更新
+
+## 迁移指南
+
+从 `utils/userCache.js` 迁移到 Pinia:
+
+**之前:**
+```javascript
+import { getUserInfo, isLogin } from '@/utils/userCache.js'
+const info = getUserInfo()
+```
+
+**现在:**
+```javascript
+import { useUserStore } from '@/store/modules/user.js'
+const userStore = useUserStore()
+const info = userStore.userInfo
+```

+ 9 - 0
store/index.js

@@ -0,0 +1,9 @@
+/**
+ * Pinia 状态管理入口
+ */
+import { createPinia } from 'pinia'
+
+// 创建 pinia 实例
+const pinia = createPinia()
+
+export default pinia

+ 71 - 0
store/modules/user.js

@@ -0,0 +1,71 @@
+/**
+ * 用户状态管理
+ */
+import { defineStore } from 'pinia'
+import { ref, computed } from 'vue'
+
+export const useUserStore = defineStore('user', () => {
+	// 状态
+	const token = ref(uni.getStorageSync('token') || '')
+	const userInfo = ref(uni.getStorageSync('userInfo') || null)
+
+	// 计算属性
+	const isLoggedIn = computed(() => !!token.value)
+	const userName = computed(() => userInfo.value?.name || '')
+	const userAvatar = computed(() => userInfo.value?.avatar || '')
+
+	// 设置 token
+	const setToken = (newToken) => {
+		token.value = newToken
+		uni.setStorageSync('token', newToken)
+	}
+
+	// 设置用户信息
+	const setUserInfo = (info) => {
+		userInfo.value = info
+		uni.setStorageSync('userInfo', info)
+	}
+
+	// 登录成功
+	const loginSuccess = (data) => {
+		if (data.token) {
+			setToken(data.token)
+		}
+		if (data.userInfo) {
+			setUserInfo(data.userInfo)
+		}
+	}
+
+	// 退出登录
+	const logout = () => {
+		token.value = ''
+		userInfo.value = null
+		uni.removeStorageSync('token')
+		uni.removeStorageSync('userInfo')
+	}
+
+	// 更新用户信息
+	const updateUserInfo = (info) => {
+		userInfo.value = {
+			...userInfo.value,
+			...info
+		}
+		uni.setStorageSync('userInfo', userInfo.value)
+	}
+
+	return {
+		// 状态
+		token,
+		userInfo,
+		// 计算属性
+		isLoggedIn,
+		userName,
+		userAvatar,
+		// 方法
+		setToken,
+		setUserInfo,
+		loginSuccess,
+		logout,
+		updateUserInfo
+	}
+})