PixelAI-admin/src/views/service/apply/index.vue
2024-12-18 14:30:37 +08:00

399 lines
9.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="system-dept-container layout-pd">
<el-card
shadow="hover"
class="filtering-list br-top-no"
v-loading="state.tableData.loading"
element-loading-text="加载中..."
:class="{ 'min-h-360': state.tableData.data.length <= 0 }"
>
<div class="system-dept-search mb15">
应用名称:<el-input size="default" placeholder="请输入应用名称" v-model="state.tableData.param.name"
class="ml10" style="max-width: 180px" clearable></el-input>
<el-button @click="getTableData" size="default" type="primary" class="ml10">
<el-icon>
<ele-Search />
</el-icon>
查询
</el-button>
<el-button @click="reset" size="default" type="primary" class="ml10">
<el-icon>
<ele-RefreshRight />
</el-icon>
重置
</el-button>
<el-button size="default" type="success" class="ml10" @click="addApply">
<el-icon>
<ele-FolderAdd />
</el-icon>
新增应用
</el-button>
</div>
<div v-for="(val, key) in state.filtering" :key="key" ref="dlRefs" class="filtering-list-flex">
<div class="filtering-list-title">{{ val.title }}</div>
<div class="filtering-list-item" :style="{ height: val.isMore ? 'auto' : '50px' }">
<span class="span" :class="v.active ? 'dd-active' : ''" v-for="(v, k) in val.children" :key="k" @click="onSelItem(val, v)">
{{ v.label }}
</span>
<div class="dd-more" v-if="val.isShowMore" @click="val.isMore = !val.isMore">
<span>{{ val.isMore ? '收起' : '展开' }}</span>
<i :class="val.isMore ? 'el-icon-arrow-down' : 'el-icon-arrow-right'"></i>
</div>
</div>
</div>
<div class="flex-warp mt15 mb15" v-if="state.tableData.data.length > 0">
<el-row :gutter="15">
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="4" class="mb15" v-for="(v, k) in state.tableData.data" :key="k" @click="onTableItemClick(v)">
<el-card class="flex-warp-item" shadow="hover" @click="toShowDetail(v)" :title="`¥ ${v.price}钻石`">
<div class="card-item-left">
<img :src="encodeURI(viteUrl + (v.icon||defaultIcon))" :alt="v.name">
</div>
<div class="card-item-right">
<div class="cir-one">{{ v.name }}</div>
<div class="cir-two">{{ v.tips || 'pixel.ai制图功能开始魔法~~' }}</div>
<div class="cir-three">
<el-tag type="info" round>{{ state.filtering[0].children[Number(v.type)+1].label }}</el-tag>
<div>{{ getDate(v.createtime) }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<div v-else class="filtering-no-data">
<div class="no-data-box">
<i class="el-icon-search"></i>
<div class="no-txt">暂无数据</div>
</div>
</div>
<template v-if="state.tableData.data.length > 0">
<div class="bottom-pagination">
<el-pagination
style="text-align: right"
background
@size-change="onHandleSizeChange"
@current-change="onHandleCurrentChange"
:page-sizes="[16, 32, 64]"
:current-page="state.tableData.param.current"
:page-size="state.tableData.param.size"
layout="total, sizes, prev, pager, next, jumper"
:total="state.tableData.total"
>
</el-pagination>
<!-- <div class="bottom-tips">tips右键应用 修改/删除</div> -->
</div>
</template>
</el-card>
<ApplyDialog ref="applyDialogRef" @refresh="getTableData()" />
</div>
</template>
<script setup lang="ts" name="apply">
import { ElMessage } from 'element-plus';
import { applyApi } from '/@/api/service/apply';
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
// 基本路径
const viteUrl = import.meta.env.VITE_API_URL;
console.log('viteUrl:',viteUrl);
// upload/Attachment/20241207/0fb6372ed5cd4fb9be68315301093f57.png
const defaultIcon:string = 'static/pixel/home/default-work.png';
// 引入弹窗
const ApplyDialog = defineAsyncComponent(() => import('/@/views/service/apply/dialog.vue'));
const applyDialogRef = ref();
// 表格数据
const state: any = reactive({
// 导航数据
filtering : [
{
title: '类型',
isMore: false,
isShowMore: false,
id: 0,
children: [
{id: '-1',label: '全部',active: true,},
{id: '0',label: '图生图',active: false,},
{id: '1',label: '文生图',active: false,},
{id: '2',label: '选项+图片',active: false,},
{id: '3',label: '选项+文字',active: false,},
{id: '4',label: '换装',active: false,},
],
},
{
title: '状态',
isMore: false,
isShowMore: false,
id: 1,
children: [
{id: '-1',label: '全部',active: true,},
{id: '0',label: '上架',active: false,},
{id: '1',label: '下架',active: false,}
],
}
],
tableData: {
data: [],
total: 0,
loading: false,
param: {
name: '',
current: 1,
size: 16,
},
},
});
// 引入 api 请求接口
const aplApi = applyApi();
// 过滤当前选中的数据
const onSelItem = (val: FilteringRowType, v: FilteringChilType) => {
val.children.map((v: FilteringChilType) => (v.active = false));
v.active = true;
state.tableData.loading = true;
setTimeout(() => {
state.tableData.loading = false;
}, 500);
};
// 当前列表项点击
const onTableItemClick = (v: FilterListType) => {
};
// 时间格式化
const getDate = (val: string) => {
const date = new Date(val);
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
}
// 重置
const reset = () =>{
state.tableData.param = {
name: '',
current: 1,
size: 16,
}
getTableData();
}
// 获取表格数据
const getTableData = async() => {
try {
state.tableData.loading = true;
let res = await aplApi.getServicesList(state.tableData.param);
if(res?.success){
state.tableData.data = res.data.records;
state.tableData.total = res.data.total;
}else{
ElMessage.error('应用服务获取失败!');
}
} catch (error) {
} finally {
state.tableData.loading = false;
}
};
// 分页改变
const onHandleSizeChange = (val: number) => {
state.tableData.param.size = val;
// getTableData();
};
// 分页改变
const onHandleCurrentChange = (val: number) => {
state.tableData.param.current = val;
// getTableData();
};
// 新增应用
const addApply = () => {
applyDialogRef.value.openDialog('add');
}
// 查看详情-编辑
const toShowDetail = (row: any) => {
applyDialogRef.value.openDialog('edit',row);
// router.push({ path: '/apply/detail', query: { id:id } });
}
onMounted(() => {
getTableData();
})
</script>
<style scoped lang="scss">
.system-dept-container {
display: flex;
min-height: 92vh;
.filtering-list {
flex: 1;
overflow: hidden;
border-bottom: none !important;
.filtering-list-flex {
&:last-of-type {
.filtering-list-item {
border-bottom: none !important;
}
}
.filtering-list-title {
float: left;
width: 64px;
font-weight: 700;
position: relative;
color: #909399;
margin: 15px 0;
&:after {
content: '';
position: absolute;
border: 1px solid #909399;
border-width: 0 1px 1px 0;
width: 4px;
height: 4px;
transform: rotate(-45deg) translateY(-50%);
right: 10px;
top: 50%;
}
}
.filtering-list-item {
border-bottom: 1px dotted var(--next-border-color-light);
margin-left: 64px;
overflow: hidden;
position: relative;
.span {
color: #8d8d91;
font-size: 14px;
float: left;
padding: 0 15px;
margin: 15px 0;
&:hover {
color: var(--el-color-primary);
cursor: pointer;
}
}
.dd-active {
color: var(--el-color-primary);
}
.dd-more {
font-size: 12px;
position: absolute;
right: 0;
top: 16px;
color: #a5a5a5;
&:hover {
cursor: pointer;
color: #8d8d91;
}
}
}
}
}
.br-top-no {
border-top: none;
.flex-warp {
flex: 1;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
margin: 0 -5px;
.el-row {
width: 101%;
}
.flex-warp-item {
padding: 5px;
height: 120px;
border-radius: 12px;
cursor: pointer;
&:hover{
margin-top: -10px;
}
.card-item-left{
width: 80px;
height: 80px;
img{
width: 100%;
height: 100%;
}
margin-right: 14px;
}
.card-item-right{
height: 100%;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
white-space: nowrap;
.cir-one{
font-size: 1.3em;
font-weight: bold;
color: rgba($color: #000000, $alpha: 0.8);
margin-bottom: 0.6em;
text-overflow: ellipsis;
overflow: hidden;
}
.cir-two{
font-size: 1.15em;
color: #8f969c;
margin-bottom: 0.6em;
text-overflow: ellipsis;
overflow: hidden;
}
.cir-three{
display: flex;
align-items: center;
justify-content: space-between;
color: #8f969c;
div{
text-overflow: ellipsis;
overflow: hidden;
}
}
}
}
:deep(.el-card__body) {
flex-direction: row;
align-items: center;
padding-top: 8px;
padding-bottom: 8px;
}
}
:deep(.el-card__body) {
height: 100%;
// width: 100%;
display: flex;
flex-direction: column;
.filtering-no-data {
display: flex;
height: 100%;
.no-data-box {
color: #cccccc;
margin: auto;
i {
font-size: 70px;
}
.no-txt {
font-size: 14px;
text-align: center;
margin-top: 15px;
}
}
}
}
}
.min-h-360 {
// height: 360px;
}
}
.bottom-pagination{
display: flex;
align-items: center;
justify-content: space-between;
.bottom-tips{
margin-right: 10px;
color: #8d8d91;
}
}
</style>