Browse Source

feat: 用户名密码登录

feat
xuesinan 4 years ago
parent
commit
95fdeac461
  1. 102
      App.vue
  2. 1
      CHANGELOG.md
  3. 8
      common/styles/theme/default.scss
  4. 5
      common/styles/theme/index.scss
  5. 8
      common/styles/theme/test.scss
  6. 34
      components/Globals/Globals.vue
  7. 13
      components/Theme/Theme.vue
  8. 7
      components/TimeLine/component/Title.vue
  9. 4
      components/Title/components/CreateTask.vue
  10. 7
      hooks/theme/useTheme.js
  11. 1
      hooks/user/useGetToken.js
  12. 1
      package.json
  13. 3
      pages.json
  14. 50
      pages/index/index.vue
  15. 3
      pages/project/project.vue
  16. 9
      plugins/p-deliver/p-deliver.vue
  17. 10
      plugins/p-task-title/p-task-title.vue
  18. 70
      store/index.js

102
App.vue

@ -1,14 +1,26 @@
<script> <script>
import useGetToken from "@/hooks/user/useGetToken"; // import { mapState } from 'vuex';
export default { export default {
// computed: {
// ...mapState(['theme']),
// },
// watch: {
// theme(newTheme) {
// console.log('newTheme: ', newTheme);
// if (!newTheme) return;
// this.loadTheme();
// },
// },
async onLaunch(options) { async onLaunch(options) {
// this.loadTheme();
console.log('onLaunch options: ', options); console.log('onLaunch options: ', options);
this.checkNetwork(); // this.checkNetwork(); //
this.getSystemInfo(); // this.getSystemInfo(); //
this.syncLocalDataToStore(options.query.u); // localStoragestore await this.syncLocalDataToStore(options.query.u); // localStoragestore
const token = await this.getToken();
const token = await useGetToken();
if (!token) { if (!token) {
this.$ui.showToast('获取用户信息失败, 请登录'); this.$ui.showToast('获取用户信息失败, 请登录');
// TODO: // TODO:
@ -19,29 +31,71 @@ export default {
}, },
methods: { methods: {
// loadTheme() {
// const path = this.theme.replace('-', '/');
// import(`./common/styles/${path}.scss`);
// },
async getToken() {
const { token } = this.$store.state.user;
const tokenIsAvailable = this.$store.getters['user/tokenIsAvailable'];
const userId = this.$store.getters['user/userId'];
if (token && tokenIsAvailable) {
// 1.1 storetoken 使storetoken
return token;
} else {
// 2. userIdtoken
if (userId) {
try {
const { token } = await this.$store.dispatch('user/getTokenByUserId', userId);
return token;
} catch (error) {
console.error('error: ', error);
return null;
}
} else {
return null;
}
}
},
/** /**
* 将localStorage里的数据同步到store里 * 将localStorage里的数据同步到store里
* user, token, tokenExpiredTime * user, token, tokenExpiredTime
*/ */
syncLocalDataToStore(urlUserId) { syncLocalDataToStore(urlUserId) {
const localUser = uni.$storage.getStorageSync('user'); return new Promise((resolve, reject) => {
const localToken = uni.$storage.getStorageSync('anyringToken'); try {
const tokenExpiredTime = uni.$storage.getStorageSync('tokenExpiredTime'); const localUser = uni.$storage.getStorageSync('user');
if (!this.$store.state.user.user && localUser) { const localToken = uni.$storage.getStorageSync('anyringToken');
// user const tokenExpiredTime = uni.$storage.getStorageSync('tokenExpiredTime');
const user = JSON.parse(localUser); if (!this.$store.state.user.user) {
if (!urlUserId || user.id === urlUserId) { if (localUser) {
this.$store.commit('user/setUser', user); // user
} else { const user = JSON.parse(localUser);
this.$store.commit('user/setUser', { id: urlUserId }); if (!urlUserId || user.id === urlUserId) {
this.$store.commit('user/setUser', user);
} else {
this.$store.commit('user/setUser', { id: urlUserId });
}
} else {
this.$store.commit('user/setUser', { id: urlUserId });
}
}
if (this.$store.state.user.token && localToken) {
// token
this.$store.commit('user/setToken', localToken);
}
if (this.$store.state.user.tokenExpiredTime && tokenExpiredTime) {
// tokenExpiredTime
this.$store.commit('user/setTokenExpiredTime', +tokenExpiredTime);
}
resolve();
} catch (error) {
reject(error);
} }
} });
if (this.$store.state.user.token && localToken) { // token
this.$store.commit('user/setToken', localToken);
}
if (this.$store.state.user.tokenExpiredTime && tokenExpiredTime) { // tokenExpiredTime
this.$store.commit('user/setTokenExpiredTime', +tokenExpiredTime);
}
}, },
// store // store
@ -93,7 +147,8 @@ export default {
*/ */
async noPhone(phone) { async noPhone(phone) {
if (!phone) { if (!phone) {
uni.navigateTo({ title: '/pages/phone-bind/phone-bind' }); // TODO:
// uni.navigateTo({ url: '/pages/phone-bind/phone-bind' });
} }
}, },
}, },
@ -102,10 +157,11 @@ export default {
<style lang="scss"> <style lang="scss">
/*每个页面公共css */ /*每个页面公共css */
@import "@/uni_modules/vk-uview-ui/index.scss"; @import '@/uni_modules/vk-uview-ui/index.scss';
@import '@/common/styles/iconfont.scss'; @import '@/common/styles/iconfont.scss';
@import '@/common/styles/app.scss'; @import '@/common/styles/app.scss';
@import '@/common/styles/tailwind.scss'; @import '@/common/styles/tailwind.scss';
@import '@/common/styles/theme/index.scss';
page { page {
height: 100%; height: 100%;

1
CHANGELOG.md

@ -12,6 +12,7 @@
- | 添加 timeline | [72dad2b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/72dad2b) - | 添加 timeline | [72dad2b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/72dad2b)
- | 项目操作面板 | [3beb05e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3beb05e) - | 项目操作面板 | [3beb05e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3beb05e)
- | 项目列表 | [a52e6d5](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a52e6d5) - | 项目列表 | [a52e6d5](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a52e6d5)
- | 账户名密码登录 | [ebf456e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/ebf456e)
- | app.vue | [970cf9a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/970cf9a) - | app.vue | [970cf9a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/970cf9a)
- | first commit | [8dc26de](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8dc26de) - | first commit | [8dc26de](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8dc26de)
- | vue3 | [12ed2ad](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/12ed2ad) - | vue3 | [12ed2ad](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/12ed2ad)

8
common/styles/theme/default.scss

@ -0,0 +1,8 @@
// 默认主题文件
.theme-default {
background-color: #333;
.u-card {
font-size: 24px !important;
color: #0f0;
}
}

5
common/styles/theme/index.scss

@ -0,0 +1,5 @@
// 整合所有主题
// 默认主题
@import './default.scss';
@import './test.scss';

8
common/styles/theme/test.scss

@ -0,0 +1,8 @@
// TODO: 测试用的scss主题样式
.theme-test {
background-color: #fff;
.u-card {
font-size: 24px !important;
background-color: #ff0 !important;
}
}

34
components/Globals/Globals.vue

@ -1,5 +1,5 @@
<template> <template>
<view class="m-2" v-show="globals && globals.length"> <theme class="m-2" >
<u-card <u-card
@click="openCard" @click="openCard"
:show-foot="false" :show-foot="false"
@ -7,14 +7,16 @@
:style="{ 'max-height': globalsHeight + 'px' }" :style="{ 'max-height': globalsHeight + 'px' }"
border-radius="25" border-radius="25"
margin="0" margin="0"
class="global-container"
> >
<view slot="body"> <template v-slot:body>
<scroll-view :scrollY="true" :style="{ 'max-height': globalsHeight - 30 + 'px' }"> <scroll-view :scrollY="true" :style="{ 'max-height': globalsHeight - 30 + 'px' }">
<skeleton :banner="false" :loading="!globals.length" :row="4" animate class="u-line-2 skeleton"></skeleton> <skeleton :banner="false" :loading="!globals.length" :row="3" animate class="u-line-2 skeleton"></skeleton>
<view class="grid gap-2"> <view class="grid gap-2">
<block v-for="item in globals" :key="item.id"> <view v-for="item in globals" :key="item.id">
<template v-if="item.plugins"> <template v-if="item.plugins && item.plugins.length">
<block v-for="(pluginArr, i) in item.plugins" :key="i"> <view v-for="(pluginArr, i) in item.plugins" :key="i">
<template class="p-0 u-col-between" v-if="pluginArr.length"> <template class="p-0 u-col-between" v-if="pluginArr.length">
<Plugin <Plugin
:class="[`row-span-${plugin.row}`, `col-span-${plugin.col}`]" :class="[`row-span-${plugin.row}`, `col-span-${plugin.col}`]"
@ -27,14 +29,19 @@
v-for="plugin in pluginArr" v-for="plugin in pluginArr"
/> />
</template> </template>
</block> </view>
</template> </template>
</block>
<!-- 任务名插件 -->
<p-task-title :task="item" v-else />
<!-- 交付物插件 -->
<p-deliver></p-deliver>
</view>
</view> </view>
</scroll-view> </scroll-view>
</view> </template>
</u-card> </u-card>
</view> </theme>
</template> </template>
<script setup> <script setup>
@ -42,11 +49,12 @@ import { computed } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import Skeleton from '@/components/Skeleton/Skeleton.vue'; import Skeleton from '@/components/Skeleton/Skeleton.vue';
const sysHeight = uni.getSystemInfoSync().screenHeight; //
const globalsHeight = Math.floor(((sysHeight - 44 - 30 - 10) / 5) * 4); //
const store = useStore(); const store = useStore();
const isShrink = computed(() => store.state.task.isShrink); const isShrink = computed(() => store.state.task.isShrink); //
const sysHeight = uni.getSystemInfoSync().screenHeight;
const globals = computed(() => store.getters['task/globals']); const globals = computed(() => store.getters['task/globals']);
const globalsHeight = computed(() => [((sysHeight.value - 44 - 30 - 10) / 5) * 4]); console.log('globals: ', globals.value);
// //
function openCard() { function openCard() {

13
components/Theme/Theme.vue

@ -0,0 +1,13 @@
<template>
<view :class="[theme]">
<slot></slot>
</view>
</template>
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const theme = computed(() => store.state.theme);
</script>

7
components/TimeLine/component/Title.vue

@ -1,7 +0,0 @@
<!--
* @Author: aBin
* @email: binbin0314@126.com
* @Date: 2021-07-19 15:40:02
* @LastEditors: aBin
* @LastEditTime: 2021-07-19 15:40:03
-->

4
components/Title/components/CreateTask.vue

@ -55,7 +55,7 @@
:key="roleIndex" :key="roleIndex"
@click="change(roleIndex)" @click="change(roleIndex)"
> >
<view v-model="role.id">{{ role.name }}</view> <view>{{ role.name }}</view>
<u-icon v-if="role.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon> <u-icon v-if="role.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon>
</div> </div>
</view> </view>
@ -107,7 +107,7 @@
:key="Index" :key="Index"
@click="choose(Index)" @click="choose(Index)"
> >
<view v-model="checkoutOption.value">{{ checkoutOption.name }}</view> <view>{{ checkoutOption.name }}</view>
<u-icon v-if="checkoutOption.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon> <u-icon v-if="checkoutOption.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon>
</div> </div>
</view> </view>

7
hooks/theme/useTheme.js

@ -0,0 +1,7 @@
import { computed } from 'vue';
import { useStore } from 'vuex';
export default function useTheme() {
const store = useStore();
const theme = computed(() => store.state.theme);
return theme;
}

1
hooks/user/useGetToken.js

@ -16,6 +16,7 @@ export default async function useGetToken() {
const token = computed(() => store.state.user.token); const token = computed(() => store.state.user.token);
const tokenIsAvailable = computed(() => store.getters['user/tokenIsAvailable']); // token是否可用 const tokenIsAvailable = computed(() => store.getters['user/tokenIsAvailable']); // token是否可用
const userId = computed(() => store.getters['user/userId']); const userId = computed(() => store.getters['user/userId']);
debugger;
if (token.value && tokenIsAvailable.value) { if (token.value && tokenIsAvailable.value) {
// 1.1 store里有token 且没过期直接:使用store的token // 1.1 store里有token 且没过期直接:使用store的token
return token.value; return token.value;

1
package.json

@ -53,6 +53,7 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"cz": "npm run log && git add . && git cz", "cz": "npm run log && git add . && git cz",
"fix": "eslint --fix",
"log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0" "log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0"
}, },
"author": "", "author": "",

3
pages.json

@ -31,7 +31,8 @@
"autoscan": true, "autoscan": true,
"custom": { "custom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue", "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
"^p-(.*)": "@/plugins/p-$1/p-$1.vue" "^p-(.*)": "@/plugins/p-$1/p-$1.vue",
"theme": "@/components/Theme/Theme.vue"
} }
} }
} }

50
pages/index/index.vue

@ -107,29 +107,29 @@ function onMove(event) {
</script> </script>
<style> <style>
.content { .content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.logo { .logo {
height: 200rpx; height: 200rpx;
width: 200rpx; width: 200rpx;
margin-top: 200rpx; margin-top: 200rpx;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-bottom: 50rpx; margin-bottom: 50rpx;
} }
.text-area { .text-area {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.title { .title {
font-size: 36rpx; font-size: 36rpx;
color: #8f8f94; color: #8f8f94;
} }
</style> </style>

3
pages/project/project.vue

@ -13,6 +13,9 @@
<!-- 定期任务面板 --> <!-- 定期任务面板 -->
<!-- <TimeLine @getTasks="getTasks" class="flex-1 overflow-hidden" ref="timeLine" /> --> <!-- <TimeLine @getTasks="getTasks" class="flex-1 overflow-hidden" ref="timeLine" /> -->
<TimeLine class="flex-1 overflow-hidden" ref="timeLine" /> <TimeLine class="flex-1 overflow-hidden" ref="timeLine" />
<!-- TODO: DEBUG: -->
<u-button @click="$store.commit('setTheme', 'theme-test')">测试切换主题</u-button>
</view> </view>
</view> </view>
</template> </template>

9
plugins/p-deliver/p-deliver.vue

@ -0,0 +1,9 @@
<template>
<view class="deliver-container">p-deliver</view>
</template>
<script setup>
</script>
<style lang="scss"></style>

10
plugins/p-task-title/p-task-title.vue

@ -0,0 +1,10 @@
<template>
<!-- 任务名插件 -->
<theme>
<view>{{ task.name }}</view>
</theme>
</template>
<script setup>
defineProps({ task: { type: Object, default: () => {} } });
</script>

70
store/index.js

@ -1,48 +1,58 @@
import { createStore } from 'vuex'; import { createStore } from 'vuex';
import user from './user/index.js';
import socket from './socket/index.js';
import project from './project/index.js'; import project from './project/index.js';
import role from './role/index.js'; import role from './role/index.js';
import socket from './socket/index.js';
import task from './task/index.js'; import task from './task/index.js';
import user from './user/index.js';
// 不属于具体模块的 应用级的 store内容 // 不属于具体模块的 应用级的 store内容
const state = { const state = {
networkConnected: true, // 网络是否连接 theme: 'theme-default',
forceUseStorage: true, // 强制启用storage networkConnected: true, // 网络是否连接
systemInfo: null, // 系统设备信息 forceUseStorage: true, // 强制启用storage
systemInfo: null, // 系统设备信息
}; };
const getters = { const getters = {
// 是否启用本地存储 // 是否启用本地存储
// 设置了强制启用本地存储 或者 没有网络连接的时候 // 设置了强制启用本地存储 或者 没有网络连接的时候
useStorage({ networkConnected, forceUseStorage }) { useStorage({ networkConnected, forceUseStorage }) {
return forceUseStorage || !networkConnected; return forceUseStorage || !networkConnected;
}, },
}; };
const mutations = { const mutations = {
/** /**
* 设置网络是否连接的变量 * 设置网络是否连接的变量
* @param {*} state * @param {*} state
* @param {boolean} networkConnected * @param {boolean} networkConnected
*/ */
setNetworkConnected(state, networkConnected) { setNetworkConnected(state, networkConnected) {
state.networkConnected = networkConnected; state.networkConnected = networkConnected;
}, },
/**
* 设置系统信息的数据
* @param {object} state
* @param {object | null} data 获取到的数据
*/
setSystemInfo(state, data) {
state.systemInfo = data;
},
/** /**
* 设置系统信息的数据 * 设置主题
* @param {object} state * @param {object} state
* @param {object | null} data 获取到的数据 * @param {string} theme 主题名称 默认theme-default
*/ */
setSystemInfo(state, data) { setTheme(state, theme) {
state.systemInfo = data; state.theme = theme || 'theme-default';
}, },
}; };
export default createStore({ export default createStore({
state, state,
getters, getters,
mutations, mutations,
modules: {user, socket, project, role, task} modules: { user, socket, project, role, task },
}); });

Loading…
Cancel
Save