mirror of
https://github.com/KarolChang/jm-expense-vue-ts.git
synced 2024-12-26 03:38:35 +00:00
add include Role
This commit is contained in:
parent
3a335f578a
commit
0d24a3b730
@ -21,7 +21,6 @@ git commit -m 'deploy'
|
||||
|
||||
# if you are deploying to https://<USERNAME>.Github.io/<REPO>
|
||||
# git push -f https://github.com/<USERNAME>/<REPO>.git master:gh-pages
|
||||
git push origin master
|
||||
git push -f https://github.com/KarolChang/jm-expense-vue-ts.git master:gh-pages
|
||||
|
||||
cd -
|
11
package-lock.json
generated
11
package-lock.json
generated
@ -661,6 +661,11 @@
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "2.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
|
||||
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
|
||||
},
|
||||
"@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@ -2687,9 +2692,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"sweetalert2": {
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.3.0.tgz",
|
||||
"integrity": "sha512-C0TFp0VLxgx+PmhJ0mL8qzx+iYjnCLdDbvQHKY6KAGI+xwawMvLkStPgw2LmJl6itaDhR/qLQStPFIbr1VK9Ow=="
|
||||
"version": "11.4.8",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.8.tgz",
|
||||
"integrity": "sha512-BDS/+E8RwaekGSxCPUbPnsRAyQ439gtXkTF/s98vY2l9DaVEOMjGj1FaQSorfGREKsbbxGSP7UXboibL5vgTMA=="
|
||||
},
|
||||
"table": {
|
||||
"version": "5.4.6",
|
||||
|
@ -9,6 +9,7 @@
|
||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.5",
|
||||
"@vueform/multiselect": "^2.3.1",
|
||||
"axios": "^0.24.0",
|
||||
"bootstrap": "^5.1.3",
|
||||
@ -21,7 +22,7 @@
|
||||
"firebase": "^9.6.3",
|
||||
"luxon": "^1.0.0",
|
||||
"pinia": "^2.0.6",
|
||||
"sweetalert2": "^11.3.0",
|
||||
"sweetalert2": "^11.4.8",
|
||||
"vue": "^3.2.29",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-router": "^4.0.0-0",
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import expenseAPI from '@/apis/expense'
|
||||
import { CategoryInput } from '@/models'
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import expenseAPI from '@/apis/expense'
|
||||
import { Category, CategoryInput } from '@/models'
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject, computed, Ref } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import expenseAPI from '@/apis/expense'
|
||||
import { ExpenseInput, Category } from '@/models'
|
||||
import { useStore } from '@/store/index'
|
||||
@ -75,9 +74,12 @@ const btnClick = async () => {
|
||||
if (!item || !amount || !date) {
|
||||
Swal.showValidationMessage('除了[備註],所有資料都是必填!')
|
||||
}
|
||||
console.log('store.currentUser', store.currentUser)
|
||||
console.log('store.currentUser?.id', store.currentUser?.id)
|
||||
if (store.currentUser) {
|
||||
return {
|
||||
input: {
|
||||
UserId: store.currentUser?.id,
|
||||
UserId: store.currentUser.id,
|
||||
CategoryId: Number(categoryId),
|
||||
item,
|
||||
amount,
|
||||
@ -85,9 +87,15 @@ const btnClick = async () => {
|
||||
date
|
||||
} as ExpenseInput
|
||||
}
|
||||
} else {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: '無法取得使用者ID'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
if (formValues) {
|
||||
if (formValues?.input) {
|
||||
createExpense(formValues)
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, Ref } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import expenseAPI from '@/apis/expense'
|
||||
import { Expense, ExpenseInput, Category } from '@/models'
|
||||
import { useStore } from '@/store/index'
|
||||
@ -88,9 +87,10 @@ const btnClick = async () => {
|
||||
if (!item || !amount || !date) {
|
||||
Swal.showValidationMessage('除了[備註],所有資料都是必填!')
|
||||
}
|
||||
if (store.currentUser) {
|
||||
return {
|
||||
input: {
|
||||
UserId: store.currentUser?.id,
|
||||
UserId: store.currentUser.id,
|
||||
CategoryId: Number(categoryId),
|
||||
item,
|
||||
amount,
|
||||
@ -98,9 +98,16 @@ const btnClick = async () => {
|
||||
date
|
||||
} as ExpenseInput
|
||||
}
|
||||
} else {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: '無法取得使用者ID'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
if (formValues) {
|
||||
console.log('formValues', formValues)
|
||||
if (formValues?.input) {
|
||||
editExpense(formValues)
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject, computed } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import userAPI from '@/apis/user'
|
||||
import { PermissionInput, ActionTypePermission } from '@/models'
|
||||
const actions: ActionTypePermission[] = ['查看', '新增', '編輯', '刪除', '停用', '操作']
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject, computed } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import userAPI from '@/apis/user'
|
||||
import { Permission, PermissionInput, ActionTypePermission } from '@/models'
|
||||
const actions: ActionTypePermission[] = ['查看', '新增', '編輯', '刪除', '停用', '操作']
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import recordAPI from '@/apis/record'
|
||||
import { pushMsgToBoth } from '@/utils/lineBotMsg'
|
||||
import { RecordInput } from '@/models'
|
||||
@ -66,6 +65,7 @@ const btnClick = async () => {
|
||||
if (!item || !merchant || !amount || !date) {
|
||||
Swal.showValidationMessage('所有資料都是必填!若紀錄者為空,請登入~')
|
||||
}
|
||||
if (store.currentUser) {
|
||||
return {
|
||||
input: {
|
||||
item,
|
||||
@ -75,9 +75,15 @@ const btnClick = async () => {
|
||||
UserId: store.currentUser?.id
|
||||
} as RecordInput
|
||||
}
|
||||
} else {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: '無法取得使用者ID'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
if (formValues) {
|
||||
if (formValues?.input) {
|
||||
createRecord(formValues)
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import recordAPI from '@/apis/record'
|
||||
import { pushMsgToBoth } from '@/utils/lineBotMsg'
|
||||
import { Record, RecordInput } from '@/models'
|
||||
@ -65,6 +64,7 @@ const btnClick = async () => {
|
||||
if (!item || !merchant || !amount || !date) {
|
||||
Swal.showValidationMessage('所有資料都是必填!若編輯者為空,請登入~')
|
||||
}
|
||||
if (store.currentUser) {
|
||||
return {
|
||||
id: record.id as number,
|
||||
input: {
|
||||
@ -72,12 +72,18 @@ const btnClick = async () => {
|
||||
merchant,
|
||||
amount,
|
||||
date,
|
||||
UserId: store.currentUser?.id
|
||||
UserId: store.currentUser.id
|
||||
} as RecordInput
|
||||
}
|
||||
} else {
|
||||
Toast.fire({
|
||||
icon: 'error',
|
||||
title: '無法取得使用者ID'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
if (formValues) {
|
||||
if (formValues?.input) {
|
||||
editRecord(formValues)
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import userAPI from '@/apis/user'
|
||||
import { RoleInput } from '@/models'
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import Swal from 'sweetalert2'
|
||||
import { Toast, ConfirmBox } from '@/utils/swal'
|
||||
import { Swal, Toast, ConfirmBox } from '@/utils/swal'
|
||||
import userAPI from '@/apis/user'
|
||||
import { Role, RoleInput } from '@/models'
|
||||
|
||||
|
@ -114,6 +114,7 @@ const openUserRP = () => {
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <transition name="slide-right">
|
||||
<UserRP v-show="userRPOpen" />
|
||||
</transition> -->
|
||||
|
@ -1,6 +1,6 @@
|
||||
// import Vue from 'vue'
|
||||
import { createApp } from 'vue'
|
||||
import App from '@/App.vue'
|
||||
import App from '@/views/App.vue'
|
||||
|
||||
function capitalizeFirstLetter(string: string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
|
@ -20,7 +20,7 @@ export const getFirebaseUser = () => {
|
||||
console.log(`[firebase] onAuthStateChanged`)
|
||||
if (user) {
|
||||
console.log('[auth] Get Firebase User', user)
|
||||
store.login(user)
|
||||
await store.login(user)
|
||||
} else {
|
||||
store.logout()
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { initializeApp } from 'firebase/app'
|
||||
import { initializeApp, FirebaseOptions } from 'firebase/app'
|
||||
|
||||
const firebaseConfig = {
|
||||
const firebaseConfig: FirebaseOptions = {
|
||||
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
|
||||
authDomain: import.meta.env.VITE_FIREBASE_AUTO_DOMAIN,
|
||||
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
|
||||
@ -8,7 +8,7 @@ const firebaseConfig = {
|
||||
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
|
||||
appId: import.meta.env.VITE_FIREBASE_APP_ID,
|
||||
measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID
|
||||
}
|
||||
} as FirebaseOptions
|
||||
|
||||
export const initFirebase = () => {
|
||||
initializeApp(firebaseConfig)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import App from './views/App.vue'
|
||||
import router from './router'
|
||||
import { createPinia } from 'pinia'
|
||||
import { getFirebaseUser } from '@/firebase/auth'
|
||||
@ -8,6 +8,7 @@ import { initFirebase } from '@/firebase/config'
|
||||
import Datepicker from 'vue3-date-time-picker'
|
||||
import 'vue3-date-time-picker/dist/main.css'
|
||||
|
||||
import '@popperjs/core'
|
||||
import 'bootstrap'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootswatch/dist/minty/bootstrap.min.css'
|
||||
|
@ -4,7 +4,7 @@ export class Category {
|
||||
id!: number
|
||||
name!: string
|
||||
icon!: string
|
||||
// photoUrl?: string
|
||||
photoUrl!: string | null
|
||||
type!: CategoryType
|
||||
deletedAt!: Date | null
|
||||
createdAt!: Date
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Toast } from '@/utils/swal'
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
||||
import { useStore } from '../store/index'
|
||||
import Default from '@/views/Default.vue'
|
||||
import AppLayout from '@/views/App.vue'
|
||||
|
||||
const root = '/jm-expense-vue-ts'
|
||||
|
||||
@ -73,15 +73,15 @@ export const routes: RouteRecordRaw[] = [
|
||||
show: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: `${root}/tools`,
|
||||
name: 'Tools',
|
||||
component: () => import('../views/Tools.vue'),
|
||||
meta: {
|
||||
pageTitle: '小工具',
|
||||
show: true
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: `${root}/tools`,
|
||||
// name: 'Tools',
|
||||
// component: () => import('../views/Tools.vue'),
|
||||
// meta: {
|
||||
// pageTitle: '小工具',
|
||||
// show: true
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: `${root}/game`,
|
||||
name: 'Game',
|
||||
@ -92,15 +92,15 @@ export const routes: RouteRecordRaw[] = [
|
||||
// auth: ['root', 'admin', 'member']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: `${root}/admin`,
|
||||
name: 'Admin',
|
||||
redirect: { name: 'Admin-Role' },
|
||||
component: Default,
|
||||
meta: {
|
||||
pageTitle: '管理面板',
|
||||
show: true
|
||||
}
|
||||
// {
|
||||
// path: `${root}/admin`,
|
||||
// name: 'Admin',
|
||||
// redirect: { name: 'Admin-Role' },
|
||||
// component: AppLayout,
|
||||
// meta: {
|
||||
// pageTitle: '管理面板',
|
||||
// show: true
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'role',
|
||||
@ -121,45 +121,34 @@ export const routes: RouteRecordRaw[] = [
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
{
|
||||
path: '/admin/role',
|
||||
name: 'Admin-Role',
|
||||
component: () => import('@/views/Role.vue'),
|
||||
meta: {
|
||||
pageTitle: '角色管理',
|
||||
show: true
|
||||
}
|
||||
// children: [
|
||||
// },
|
||||
// {
|
||||
// path: ':id/access',
|
||||
// path: `${root}/admin/role`,
|
||||
// name: 'Admin-Role',
|
||||
// component: () => import('@/views/Role.vue'),
|
||||
// meta: {
|
||||
// pageTitle: '角色管理',
|
||||
// show: true
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: '/admin/role/:id/access',
|
||||
// name: 'Admin-Role-Access',
|
||||
// component: () => import('@/views/Access.vue'),
|
||||
// meta: {
|
||||
// pageTitle: '角色管理 / 設置權限[角色名稱]',
|
||||
// show: false
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: '/admin/permission',
|
||||
// name: 'Admin-Permission',
|
||||
// component: () => import('../views/Permission.vue'),
|
||||
// meta: {
|
||||
// pageTitle: '權限管理',
|
||||
// show: true
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
{
|
||||
path: '/admin/role/:id/access',
|
||||
name: 'Admin-Role-Access',
|
||||
component: () => import('@/views/Access.vue'),
|
||||
meta: {
|
||||
pageTitle: '角色管理 / 設置權限[角色名稱]',
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/admin/permission',
|
||||
name: 'Admin-Permission',
|
||||
component: () => import('../views/Permission.vue'),
|
||||
meta: {
|
||||
pageTitle: '權限管理',
|
||||
show: true
|
||||
}
|
||||
},
|
||||
// },
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
|
@ -43,9 +43,9 @@ export const useStore = defineStore('index', {
|
||||
console.error('error')
|
||||
}
|
||||
},
|
||||
login(user: FirebaseUser) {
|
||||
async login(user: FirebaseUser) {
|
||||
this.firebaseUser = user
|
||||
this.getCurrentUser(user.email!)
|
||||
await this.getCurrentUser(user.email!)
|
||||
},
|
||||
logout() {
|
||||
this.firebaseUser = null
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Swal from 'sweetalert2'
|
||||
import Swal from 'sweetalert2/dist/sweetalert2.js'
|
||||
import 'sweetalert2/dist/sweetalert2.css'
|
||||
|
||||
export const Toast = Swal.mixin({
|
||||
toast: true,
|
||||
@ -11,3 +12,5 @@ export const ConfirmBox = Swal.mixin({
|
||||
showConfirmButton: true,
|
||||
showCancelButton: true
|
||||
})
|
||||
|
||||
export { Swal }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import Navbar from '@/components/Navbar.vue'
|
||||
import { onLoad } from './cocos/config'
|
||||
import { onLoad } from '../cocos/config'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
@ -11,7 +11,6 @@ if (import.meta.env.NODE_ENV === 'production') {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <div> -->
|
||||
<Navbar>
|
||||
<template #main>
|
||||
<router-view v-slot="{ Component }">
|
||||
@ -21,7 +20,6 @@ if (import.meta.env.NODE_ENV === 'production') {
|
||||
</router-view>
|
||||
</template>
|
||||
</Navbar>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;700&display=swap');
|
@ -127,7 +127,7 @@ provide('categoriesByType', categoriesByType)
|
||||
</div>
|
||||
<!-- filter -->
|
||||
<div class="d-flex mb-4" style="width: 100%">
|
||||
<div class="mt-4" style="width: 50px">
|
||||
<div class="mt-4" style="width: 100px">
|
||||
<label for="type" style="float: left; font-size: 0.7em">TYPE</label>
|
||||
<select class="form-select" id="type" aria-label="Default select example" v-model="selectedType">
|
||||
<option selected>ALL</option>
|
||||
|
@ -49,13 +49,13 @@ provide('refetchRoles', fetchRoles)
|
||||
<td>{{ role.name }}</td>
|
||||
<td>{{ role.name_en }}</td>
|
||||
<td>{{ role.deletedAt === null ? 'V' : 'X' }}</td>
|
||||
<td>
|
||||
<!-- <td>
|
||||
<router-link :to="{ name: 'Admin-Role-Access', params: { id: role.id } }">
|
||||
<i class="fa-solid fa-circle-question"></i
|
||||
></router-link>
|
||||
<EditRoleModalButton :role="role" class="ms-2" />
|
||||
<DeleteRoleModalButton :role="role" class="ms-2" />
|
||||
</td>
|
||||
</td> -->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -11,5 +11,8 @@ export default defineConfig({
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src')
|
||||
}
|
||||
},
|
||||
server: {
|
||||
port: 8080
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user