feat: 添加文章相关页面

master
luoer 2023-09-21 09:49:40 +08:00
parent d76ead755b
commit 3ab73274d9
10 changed files with 445 additions and 147 deletions

View File

@ -0,0 +1,77 @@
name: 自动部署
on:
push:
branches:
- master
paths-ignore:
- .gitignore
- README.md
- .vscode/**
tags:
- v*
env:
docker_host: ${{ secrets.DOCKER_REGISTRY }}
docker_user: ${{ secrets.DOCKER_USERNAME }}
docker_pass: ${{ secrets.DOCKER_PASSWORD }}
docker_name: ${{ secrets.DOCKER_REGISTRY }}/${{ gitea.repository }}
deploy_host: ${{ secrets.DEPLOY_HOSTNAME }}
deploy_port: ${{ secrets.DEPLOY_PORT }}
deploy_user: ${{ secrets.DEPLOY_USERNAME }}
deploy_pass: ${{ secrets.DEPLOY_PASSWORD }}
deploy_name: demo_web
jobs:
build:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: 检出代码
id: checkout
uses: https://gitea.com/actions/checkout@v3
- name: 设置环境
uses: https://gitea.com/actions/setup-node@v2
- name: 安装依赖
run: |
npm install --registry https://registry.npmmirror.com/
- name: 构建产物
run: npm run build
- name: 打印目录
run: ls ./dist
- name: 构建镜像
run: |
docker build -t ${{ env.docker_name }}:latest .
- name: 登陆镜像
run: |
docker login -u "${{ env.docker_user }}" -p "${{ env.docker_pass }}" ${{ env.docker_host }}
- name: 推送镜像
shell: bash
run: |
docker push ${{ env.docker_name }}:latest
- name: 标记镜像
if: gitea.ref_type == 'tag'
run: |
echo "当前推送版本:${{ gitea.ref_name }}"
docker tag ${{ env.docker_name }}:latest ${{ env.docker_name }}:${{ gitea.ref_name }}
docker push ${{ env.docker_name }}:${{ gitea.ref_name }}
- name: 更新服务
uses: http://git.dev.juetan.cn/mirror/ssh-action@v1.0.0
with:
host: ${{ env.deploy_host }}
port: ${{ env.deploy_port }}
username: ${{ env.deploy_user }}
password: ${{ env.deploy_pass }}
script: |
docker service ls | grep -q ${{ env.deploy_name }} || exit 0
docker service update --image ${{ env.docker_name }}:latest ${{ env.deploy_name }}

View File

@ -19,6 +19,8 @@ interface UseColumnRenderOptions {
rowIndex: number;
}
export type ColumnRender = (options: UseColumnRenderOptions) => any;
export interface TableColumnButton {
/**
*

View File

@ -36,6 +36,7 @@ export default defineComponent({
) : (
<a-menu-item key={route.path} v-slots={{ icon }} onClick={() => this.goto(route)}>
{route.title}
{ false && <span class="text-xs text-slate-400 ml-2">({route.sort})</span>}
</a-menu-item>
);

View File

@ -0,0 +1,89 @@
<template>
<BreadPage>
<Table v-bind="table"></Table>
</BreadPage>
</template>
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/libs/dayjs";
import { Tag } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {
return api.log.getLoginLogs({ ...model, ...paging });
},
columns: [
{
title: "登陆账号",
dataIndex: "nickname",
width: 140,
},
{
title: "操作描述",
dataIndex: "description",
render: ({ record: { status, description } }) => {
return (
<span>
<Tag color={status === null || status ? "green" : "red"} class="mr-2">
{ status === null || status ? "成功" : "失败" }
</Tag>
{description}
</span>
);
},
},
{
title: "登陆地址",
dataIndex: "ip",
width: 200,
render: ({ record }) => `${record.addr || "未知"}(${record.ip})`,
},
{
title: "操作系统",
dataIndex: "os",
width: 160,
},
{
title: "浏览器",
dataIndex: "browser",
width: 160,
},
{
title: "登陆时间",
dataIndex: "createdAt",
width: 120,
render: ({ record }) => dayjs(record.createdAt).fromNow(),
},
],
search: {
items: [
{
field: "nickname",
label: "登陆账号",
type: "input",
required: false,
nodeProps: {
placeholder: '请输入登陆账号',
},
itemProps: {
hideLabel: true,
}
},
],
},
});
</script>
<style scoped></style>
<route lang="json">
{
"meta": {
"sort": 10300,
"title": "分类管理",
"icon": "icon-park-outline-category-management"
}
}
</route>

View File

@ -0,0 +1,89 @@
<template>
<BreadPage>
<Table v-bind="table"></Table>
</BreadPage>
</template>
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/libs/dayjs";
import { Tag } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {
return api.log.getLoginLogs({ ...model, ...paging });
},
columns: [
{
title: "登陆账号",
dataIndex: "nickname",
width: 140,
},
{
title: "操作描述",
dataIndex: "description",
render: ({ record: { status, description } }) => {
return (
<span>
<Tag color={status === null || status ? "green" : "red"} class="mr-2">
{ status === null || status ? "成功" : "失败" }
</Tag>
{description}
</span>
);
},
},
{
title: "登陆地址",
dataIndex: "ip",
width: 200,
render: ({ record }) => `${record.addr || "未知"}(${record.ip})`,
},
{
title: "操作系统",
dataIndex: "os",
width: 160,
},
{
title: "浏览器",
dataIndex: "browser",
width: 160,
},
{
title: "登陆时间",
dataIndex: "createdAt",
width: 120,
render: ({ record }) => dayjs(record.createdAt).fromNow(),
},
],
search: {
items: [
{
field: "nickname",
label: "登陆账号",
type: "input",
required: false,
nodeProps: {
placeholder: '请输入登陆账号',
},
itemProps: {
hideLabel: true,
}
},
],
},
});
</script>
<style scoped></style>
<route lang="json">
{
"meta": {
"sort": 10304,
"title": "评论管理",
"icon": "icon-park-outline-comments"
}
}
</route>

View File

@ -0,0 +1,89 @@
<template>
<BreadPage>
<Table v-bind="table"></Table>
</BreadPage>
</template>
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/libs/dayjs";
import { Tag } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {
return api.log.getLoginLogs({ ...model, ...paging });
},
columns: [
{
title: "登陆账号",
dataIndex: "nickname",
width: 140,
},
{
title: "操作描述",
dataIndex: "description",
render: ({ record: { status, description } }) => {
return (
<span>
<Tag color={status === null || status ? "green" : "red"} class="mr-2">
{ status === null || status ? "成功" : "失败" }
</Tag>
{description}
</span>
);
},
},
{
title: "登陆地址",
dataIndex: "ip",
width: 200,
render: ({ record }) => `${record.addr || "未知"}(${record.ip})`,
},
{
title: "操作系统",
dataIndex: "os",
width: 160,
},
{
title: "浏览器",
dataIndex: "browser",
width: 160,
},
{
title: "登陆时间",
dataIndex: "createdAt",
width: 120,
render: ({ record }) => dayjs(record.createdAt).fromNow(),
},
],
search: {
items: [
{
field: "nickname",
label: "登陆账号",
type: "input",
required: false,
nodeProps: {
placeholder: '请输入登陆账号',
},
itemProps: {
hideLabel: true,
}
},
],
},
});
</script>
<style scoped></style>
<route lang="json">
{
"meta": {
"sort": 10304,
"title": "素材管理",
"icon": "icon-park-outline-movie-board"
}
}
</route>

View File

@ -63,8 +63,8 @@
{
"meta": {
"sort": 10300,
"title": "新增文章",
"icon": "icon-park-outline-edit"
"title": "文章管理",
"icon": "icon-park-outline-editor"
}
}
</route>

View File

@ -1,146 +1,5 @@
<template>
<BreadPage>
<Table v-bind="table"></Table>
</BreadPage>
</template>
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/libs";
import { Avatar, Button } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {
return api.user.getUsers({ ...model, ...paging });
},
columns: [
{
type: "index",
},
{
title: "用户昵称",
dataIndex: "username",
width: 200,
render: ({ record }) => (
<div class="flex items-center">
<Avatar size={32}>
<img src={record.avatar} alt="" />
</Avatar>
<span class="ml-2 flex-1 flex flex-col overflow-hidden">
<span>{record.nickname}</span>
<span class="text-gray-400 text-xs truncate">账号{record.username}</span>
</span>
</div>
),
},
{
title: "用户描述",
dataIndex: "description",
},
{
title: "用户邮箱",
dataIndex: "email",
},
{
title: "创建时间",
dataIndex: "createdAt",
width: 200,
render: ({ record }) => dayjs(record.createdAt).format(),
},
{
title: "操作",
type: "button",
width: 148,
buttons: [
{
type: "modify",
text: "修改",
},
{
type: "delete",
text: "删除",
onClick: async ({ record }) => {
return api.user.delUser(record.id, { toast: true });
},
},
],
},
],
search: {
items: [
{
extend: "nickname",
required: false,
},
],
},
create: {
title: "新建用户",
trigger: () => (
<Button type="primary">
{{
icon: () => <i class="icon-park-outline-people-plus-one" />,
default: () => "添加",
}}
</Button>
),
modalProps: {
width: 772,
maskClosable: false,
},
formProps: {
layout: "vertical",
class: "!grid grid-cols-2 gap-x-3",
},
items: [
{
field: "username",
label: "登录账号",
type: "input",
required: true,
},
{
field: "nickname",
label: "用户昵称",
type: "input",
},
{
field: "description",
label: "个人描述",
type: "input",
},
{
field: "password",
label: "密码",
type: "password",
},
{
label: "头像",
field: "avatar",
type: "select",
},
{
field: "[startTime,endTime]",
label: "日期范围",
type: "dateRange",
nodeProps: {},
},
],
submit: ({ model }) => {
return api.user.addUser(model);
},
},
modify: {
extend: true,
title: "修改用户",
submit: ({ model }) => {
return api.user.updateUser(model.id, model);
},
},
});
</script>
<template><div></div></template>
<script setup lang="tsx"></script>
<style scoped></style>
<route lang="json">

View File

@ -0,0 +1,89 @@
<template>
<BreadPage>
<Table v-bind="table"></Table>
</BreadPage>
</template>
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/libs/dayjs";
import { Tag } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {
return api.log.getLoginLogs({ ...model, ...paging });
},
columns: [
{
title: "登陆账号",
dataIndex: "nickname",
width: 140,
},
{
title: "操作描述",
dataIndex: "description",
render: ({ record: { status, description } }) => {
return (
<span>
<Tag color={status === null || status ? "green" : "red"} class="mr-2">
{ status === null || status ? "成功" : "失败" }
</Tag>
{description}
</span>
);
},
},
{
title: "登陆地址",
dataIndex: "ip",
width: 200,
render: ({ record }) => `${record.addr || "未知"}(${record.ip})`,
},
{
title: "操作系统",
dataIndex: "os",
width: 160,
},
{
title: "浏览器",
dataIndex: "browser",
width: 160,
},
{
title: "登陆时间",
dataIndex: "createdAt",
width: 120,
render: ({ record }) => dayjs(record.createdAt).fromNow(),
},
],
search: {
items: [
{
field: "nickname",
label: "登陆账号",
type: "input",
required: false,
nodeProps: {
placeholder: '请输入登陆账号',
},
itemProps: {
hideLabel: true,
}
},
],
},
});
</script>
<style scoped></style>
<route lang="json">
{
"meta": {
"sort": 10304,
"title": "操作日志",
"icon": "icon-park-outline-doc-detail"
}
}
</route>

View File

@ -44,7 +44,7 @@ const table = useTable({
{record.nickname}
</span>
<span class="text-gray-400 text-xs truncate">
{record.username}
ID: {record.username}
</span>
</span>
</div>
@ -68,12 +68,15 @@ const table = useTable({
{
title: "操作",
type: "button",
width: 110,
width: 180,
buttons: [
{
type: "modify",
text: "修改",
},
{
text: '设置密码',
},
{
type: "delete",
text: "删除",