feat: 增加密码管理模块

This commit is contained in:
2025-06-11 23:43:40 +08:00
parent 38efe4483d
commit b5dd5703a5
15 changed files with 460 additions and 108 deletions

View File

@@ -0,0 +1,76 @@
<template>
<div class="password-card card-item">
<el-avatar class="avatar-info">{{ passwordItem.title.charAt(0) }}</el-avatar>
<div class="title-info">
<span>{{ passwordItem.title }}</span>
<span>{{ passwordItem.username }}</span>
</div>
<div class="button-info">
<el-button type="primary" :icon="Edit" circle
@click="editClick"/>
<el-button type="danger" :icon="DeleteFilled" circle
@click="deleteClick()" />
</div>
</div>
</template>
<script setup lang="ts">
import { Edit, DeleteFilled } from '@element-plus/icons-vue'
import { usePasswordStore } from '@/store/password.ts'
import { defineProps, onMounted, PropType } from 'vue'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { useRouter } from 'vue-router'
import { IPassword } from '@/types/password.ts'
const passwordStore = usePasswordStore()
const router = useRouter()
const props = defineProps({
passwordItem: {
required: true,
type: Object as PropType<IPassword>
}
})
onMounted(() => {
})
const editClick = async () => {
const id = props.passwordItem?.id
passwordStore.passwordApiType = 'UPDATE'
passwordStore.currentPassword = props.passwordItem as IPassword
await router.push({ name: 'MobileHomePasswordDetailId', params: { id } })
}
const deleteClick = () => {
passwordStore.passwordApiType = 'DELETE'
commonElMessageBox(`请确认是否删除该密码记录: ${props.passwordItem?.title}?`).then(() => {
passwordStore.handlePasswordApi(props.passwordItem as IPassword)
})
}
</script>
<style lang="scss">
.password-card {
padding: 10px;
display: grid;
grid-template-columns: 40px 1fr 80px;
align-items: center;
gap: 10px;
.avatar-info {
background-color: var(--el-color-primary);
}
.title-info {
display: flex;
flex-direction: column;
gap: 5px;
}
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<div class="mobile-common-query card-item">
<div class="query-item">
<span>分类</span>
<el-segmented v-model="passwordStore.queryInfo.category"
:options="queryCategoryList"
@change="passwordStore.queryPasswordList()"/>
</div>
<div class="query-item">
<span>所属人</span>
<el-segmented v-model="passwordStore.queryInfo.owner"
:options="queryOrderList"
@change="passwordStore.queryPasswordList()"/>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { usePasswordStore } from '@/store/password.ts'
import { ICategory } from '@/types'
const passwordStore = usePasswordStore()
const queryCategoryList = ref([] as ICategory[])
onMounted(async () => {
await passwordStore.queryPasswordCategory()
initCategoryList()
})
const queryOrderList = [
{
label: '哥哥',
value: '哥哥'
}, {
label: '宝宝',
value: '宝宝'
}
]
const initCategoryList = () => {
queryCategoryList.value = []
queryCategoryList.value.push({
label: '全部',
value: ''
})
passwordStore.categoryList.forEach((item) => {
queryCategoryList.value.push({
label: item,
value: item
})
})
}
</script>

View File

@@ -1,52 +0,0 @@
<template>
<div class="mobile-common-query card-item">
<div class="query-item">
<span>分类</span>
<el-segmented v-model="productStore.queryInfo.category"
:options="queryCategoryList"
@change="productStore.queryProductList()"/>
</div>
<div class="query-item">
<span>排序</span>
<el-segmented v-model="productStore.queryInfo.order"
:options="queryOrderList"
@change="productStore.queryProductList()"/>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useProductStore } from '@/store/product.ts'
const productStore = useProductStore()
const queryCategoryList = ref([])
onMounted(async () => {
await productStore.queryProductCategory()
queryCategoryList.value = []
queryCategoryList.value.push({
label: '全部',
value: ''
})
productStore.categoryList.forEach((item) => {
queryCategoryList.value.push({
label: item,
value: item
})
})
})
const queryOrderList = [
{
label: '购买日期',
value: 'date'
}, {
label: '日均价格',
value: 'price'
}
]
</script>

View File

@@ -67,10 +67,8 @@
import { Edit, DeleteFilled } from '@element-plus/icons-vue'
import { useProductStore } from '@/store/product.ts'
import { defineProps, onMounted, PropType } from 'vue'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { IProduct } from '@/types/product.ts'
import { isMobile } from 'vue3-common/utils/layoutUtil'
import { useRouter } from 'vue-router'
import { serviceFileRootPath } from '@/utils'
@@ -92,16 +90,8 @@ const editClick = async () => {
const id = props.productItem?.id
productStore.productApiType = 'UPDATE'
if (isMobile()) {
productStore.currentProduct = props.productItem as IProduct
await router.push({ name: 'MobileHomeProductDetailId', params: { id } })
} else {
productStore.productDialog = {
title: '编辑物品',
visible: true,
data: deepCopyObject(props.productItem)
}
}
productStore.currentProduct = props.productItem as IProduct
await router.push({ name: 'MobileHomeProductDetailId', params: { id } })
}
const deleteClick = () => {

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="isMobile()" class="mobile-common-query card-item">
<div class="mobile-common-query card-item">
<div class="query-item">
<span>分类</span>
<el-segmented v-model="productStore.queryInfo.category"
@@ -14,37 +14,11 @@
@change="productStore.queryProductList()"/>
</div>
</div>
<div v-else class="common-query">
<el-select v-model="productStore.queryInfo.category"
placeholder="请选择类别" clearable
@change="productStore.queryProductList()"
style="width: 120px">
<el-option
v-for="(item, index) in productStore.categoryList"
:key="index" :label="item" :value="item"
/>
</el-select>
<el-select v-model="productStore.queryInfo.order"
placeholder="请选择排序" clearable
@change="productStore.queryProductList()"
style="width: 120px">
<el-option
v-for="(item, index) in queryOrderList"
:key="index" :label="item.label" :value="item.value"
/>
</el-select>
<el-button :icon="Refresh" circle @click="refreshClick"/>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useProductStore } from '@/store/product.ts'
import { Refresh } from '@element-plus/icons-vue'
import { isMobile } from 'vue3-common/utils/layoutUtil'
import { ICategory } from '@/types'
const productStore = useProductStore()
@@ -79,12 +53,4 @@ const initCategoryList = () => {
})
})
}
const refreshClick = async () => {
productStore.queryInfo = {
category: '',
order: ''
}
await productStore.queryProductList()
}
</script>