Compare commits
3 Commits
261f2490ec
...
d2b8bc2f8e
| Author | SHA1 | Date |
|---|---|---|
|
|
d2b8bc2f8e | |
|
|
e5c6b080a8 | |
|
|
7148e464be |
2
.env
2
.env
|
|
@ -24,7 +24,7 @@ VITE_PORT = 3020
|
||||||
# 代理前缀
|
# 代理前缀
|
||||||
VITE_PROXY_PREFIX = /api,/upload
|
VITE_PROXY_PREFIX = /api,/upload
|
||||||
# 代理地址
|
# 代理地址
|
||||||
VITE_PROXY = https://appnify.app.juetan.cn/
|
VITE_PROXY = http://127.0.0.1:3030/
|
||||||
# API文档 说明:需返回符合 OPENAPI 规范的json内容
|
# API文档 说明:需返回符合 OPENAPI 规范的json内容
|
||||||
VITE_OPENAPI = http://127.0.0.1:3030/openapi.json
|
VITE_OPENAPI = http://127.0.0.1:3030/openapi.json
|
||||||
# 文件后缀 说明:设为dev时会优先加载index.dev.vue文件,否则回退至index.vue文件
|
# 文件后缀 说明:设为dev时会优先加载index.dev.vue文件,否则回退至index.vue文件
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
import { AnForm, AnFormInstance, AnFormProps } from '../components/Form';
|
import { AnForm, AnFormInstance, AnFormProps } from '../components/Form';
|
||||||
import { FormItem, useItems } from './useItems';
|
import { FormItem, useItems } from './useItems';
|
||||||
|
|
||||||
|
|
@ -17,7 +18,8 @@ export type FormUseOptions = Partial<Omit<AnFormProps, 'items'>> & {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useFormProps(options: FormUseOptions): Required<AnFormProps> {
|
export function useFormProps(options: FormUseOptions): Required<AnFormProps> {
|
||||||
const { model = {}, items: _items = [], submit = () => null, formProps = {} } = options;
|
const { model: _model = {}, items: _items = [], submit = () => null, formProps = {} } = options;
|
||||||
|
const model = merge({ id: undefined }, _model);
|
||||||
const items = useItems(_items ?? [], model);
|
const items = useItems(_items ?? [], model);
|
||||||
return {
|
return {
|
||||||
model,
|
model,
|
||||||
|
|
|
||||||
|
|
@ -12,27 +12,28 @@ import { listToTree } from '@/utils/listToTree';
|
||||||
const { component: CategoryTable } = useTable({
|
const { component: CategoryTable } = useTable({
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '分类名称',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
width: 240,
|
|
||||||
render: ({ record }) => (
|
render: ({ record }) => (
|
||||||
<div class="flex flex-col overflow-hidden">
|
<div class="flex flex-col overflow-hidden">
|
||||||
<span>{record.title}</span>
|
<span>
|
||||||
<span class="text-gray-400 text-xs truncate">#{record.slug}</span>
|
{record.title}
|
||||||
|
<span class="text-gray-400 text-xs truncate ml-2">@{record.slug}</span>
|
||||||
|
</span>
|
||||||
|
<div class="text-gray-400 text-xs truncate mt-0.5">{record.description}</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '描述',
|
|
||||||
dataIndex: 'description',
|
|
||||||
},
|
|
||||||
useCreateColumn(),
|
useCreateColumn(),
|
||||||
useUpdateColumn(),
|
useUpdateColumn(),
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 120,
|
width: 180,
|
||||||
buttons: [
|
buttons: [
|
||||||
|
{
|
||||||
|
text: '文章列表',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'modify',
|
type: 'modify',
|
||||||
text: '修改',
|
text: '修改',
|
||||||
|
|
@ -67,15 +68,18 @@ const { component: CategoryTable } = useTable({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
field: 'title',
|
field: 'title',
|
||||||
label: '分类名称',
|
label: '名称',
|
||||||
setter: 'input',
|
setter: 'input',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'slug',
|
field: 'slug',
|
||||||
label: '分类别名',
|
label: '别名',
|
||||||
setter: 'input',
|
setter: 'input',
|
||||||
required: true,
|
required: true,
|
||||||
|
setterProps: {
|
||||||
|
placeholder: '只包含字母、小数和连字符'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'description',
|
field: 'description',
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { FileCategory, api } from '@/api';
|
import { FileCategory, api } from '@/api';
|
||||||
import { useCreateColumn, useTable, useTableDelete, useUpdateColumn } from '@/components/AnTable';
|
import { useCreateColumn, useTable, useTableDelete, useUpdateColumn } from '@/components/AnTable';
|
||||||
import { getIcon } from './components/util';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import numeral from 'numeral';
|
import numeral from 'numeral';
|
||||||
import AnGroup from './components/AnGroup.vue';
|
import AnGroup from './components/AnGroup.vue';
|
||||||
import AnUpload from './components/AnUpload.vue';
|
import AnUpload from './components/AnUpload.vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { getIcon } from './components/util';
|
||||||
|
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const current = ref<FileCategory>();
|
const current = ref<FileCategory>();
|
||||||
|
|
@ -80,8 +80,8 @@ const {
|
||||||
>
|
>
|
||||||
{record.name}
|
{record.name}
|
||||||
</span>
|
</span>
|
||||||
<span class="hidden group-hover:inline text-xs text-gray-400 ml-0" title="复制地址" onClick={() => copyLink(record)}>
|
<span class="inline-block w-5 text-xs text-gray-400 ml-0" title="复制地址" onClick={() => copyLink(record)}>
|
||||||
<i class=" icon-park-outline-copy hover:text-gray-700 cursor-pointer"></i>
|
<i class="hidden! group-hover:inline-block! icon-park-outline-copy hover:text-gray-700 cursor-pointer"></i>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<div class="h-5 inline-flex items-center text-xs text-gray-400 space-x-4">
|
<div class="h-5 inline-flex items-center text-xs text-gray-400 space-x-4">
|
||||||
|
|
|
||||||
|
|
@ -35,34 +35,24 @@ const { component: LoginLogTable } = useTable({
|
||||||
return api.log.getLoginLogs(model);
|
return api.log.getLoginLogs(model);
|
||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{
|
|
||||||
title: '登陆账号',
|
|
||||||
dataIndex: 'nickname',
|
|
||||||
width: 140,
|
|
||||||
render({ record }) {
|
|
||||||
return (
|
|
||||||
<div class="overflow-hidden">
|
|
||||||
<i class="icon-park-outline-user mr-2"></i>
|
|
||||||
<span>{record.nickname}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '操作描述',
|
title: '操作描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
render: ({ record: { status, description } }) => {
|
render: ({ record }) => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<div class="flex items-center gap-2">
|
||||||
<span
|
<span
|
||||||
class={
|
class={
|
||||||
status === null || status
|
record.status === null || record.status
|
||||||
? 'text-base text-green-500 icon-park-outline-check-one mr-2'
|
? 'text-base text-green-500 icon-park-outline-check-one mr-2'
|
||||||
: 'text-base text-red-500 icon-park-outline-close-one mr-2'
|
: 'text-base text-red-500 icon-park-outline-close-one mr-2'
|
||||||
}
|
}
|
||||||
></span>
|
></span>
|
||||||
{description}
|
<div>
|
||||||
</span>
|
<div>{record.nickname}</div>
|
||||||
|
<div class="text-xs text-gray-400">{record.description}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,6 @@ const [menuTable, menu] = useAniTable({
|
||||||
type: "button",
|
type: "button",
|
||||||
width: 200,
|
width: 200,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
|
||||||
type: "modify",
|
|
||||||
text: "修改",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: "新增子项",
|
text: "新增子项",
|
||||||
disabled: ({ record }) => record.type === MenuType.BUTTON,
|
disabled: ({ record }) => record.type === MenuType.BUTTON,
|
||||||
|
|
@ -83,6 +79,10 @@ const [menuTable, menu] = useAniTable({
|
||||||
console.log(record);
|
console.log(record);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "modify",
|
||||||
|
text: "修改",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: "删除",
|
text: "删除",
|
||||||
type: "delete",
|
type: "delete",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const { component: UserTable } = useTable({
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full text-gray-400 space-x-4 text-xs">
|
<div class="w-full text-gray-400 space-x-4 text-xs">
|
||||||
<span>
|
<span>
|
||||||
<i class="icon-park-outline-mail mr-1 align-[-3px]"></i>
|
<i class="icon-park-outline-mail mr-1 align-[-4px]"></i>
|
||||||
contact@juetan.cn
|
contact@juetan.cn
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ declare module '@vue/runtime-core' {
|
||||||
ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb']
|
ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb']
|
||||||
ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem']
|
ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem']
|
||||||
AButton: typeof import('@arco-design/web-vue')['Button']
|
AButton: typeof import('@arco-design/web-vue')['Button']
|
||||||
ACard: typeof import('@arco-design/web-vue')['Card']
|
|
||||||
ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
|
ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
|
||||||
ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
|
ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
|
||||||
AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
|
AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
|
||||||
|
|
@ -26,7 +25,6 @@ declare module '@vue/runtime-core' {
|
||||||
AEmpty: typeof import('@arco-design/web-vue')['Empty']
|
AEmpty: typeof import('@arco-design/web-vue')['Empty']
|
||||||
AForm: typeof import('@arco-design/web-vue')['Form']
|
AForm: typeof import('@arco-design/web-vue')['Form']
|
||||||
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
|
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
|
||||||
AImage: typeof import('@arco-design/web-vue')['Image']
|
|
||||||
AImagePreview: typeof import('@arco-design/web-vue')['ImagePreview']
|
AImagePreview: typeof import('@arco-design/web-vue')['ImagePreview']
|
||||||
AInput: typeof import('@arco-design/web-vue')['Input']
|
AInput: typeof import('@arco-design/web-vue')['Input']
|
||||||
AInputNumber: typeof import('@arco-design/web-vue')['InputNumber']
|
AInputNumber: typeof import('@arco-design/web-vue')['InputNumber']
|
||||||
|
|
@ -37,15 +35,11 @@ declare module '@vue/runtime-core' {
|
||||||
ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
|
ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
|
||||||
ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
|
ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
|
||||||
ALink: typeof import('@arco-design/web-vue')['Link']
|
ALink: typeof import('@arco-design/web-vue')['Link']
|
||||||
AList: typeof import('@arco-design/web-vue')['List']
|
|
||||||
AListItem: typeof import('@arco-design/web-vue')['ListItem']
|
|
||||||
AListItemMeta: typeof import('@arco-design/web-vue')['ListItemMeta']
|
|
||||||
AMenu: typeof import('@arco-design/web-vue')['Menu']
|
AMenu: typeof import('@arco-design/web-vue')['Menu']
|
||||||
AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
|
AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
|
||||||
AModal: typeof import('@arco-design/web-vue')['Modal']
|
AModal: typeof import('@arco-design/web-vue')['Modal']
|
||||||
AnEmpty: typeof import('./../components/AnEmpty/AnEmpty.vue')['default']
|
AnEmpty: typeof import('./../components/AnEmpty/AnEmpty.vue')['default']
|
||||||
AnForbidden: typeof import('./../components/AnForbidden/AnForbidden.vue')['default']
|
AnForbidden: typeof import('./../components/AnForbidden/AnForbidden.vue')['default']
|
||||||
AnForbiden: typeof import('./../components/AnForbidden/AnForbiden.vue')['default']
|
|
||||||
AnToast: typeof import('./../components/AnToast/AnToast.vue')['default']
|
AnToast: typeof import('./../components/AnToast/AnToast.vue')['default']
|
||||||
APagination: typeof import('@arco-design/web-vue')['Pagination']
|
APagination: typeof import('@arco-design/web-vue')['Pagination']
|
||||||
APopover: typeof import('@arco-design/web-vue')['Popover']
|
APopover: typeof import('@arco-design/web-vue')['Popover']
|
||||||
|
|
@ -62,7 +56,6 @@ declare module '@vue/runtime-core' {
|
||||||
ATag: typeof import('@arco-design/web-vue')['Tag']
|
ATag: typeof import('@arco-design/web-vue')['Tag']
|
||||||
ATextarea: typeof import('@arco-design/web-vue')['Textarea']
|
ATextarea: typeof import('@arco-design/web-vue')['Textarea']
|
||||||
ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
|
ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
|
||||||
ATree: typeof import('@arco-design/web-vue')['Tree']
|
|
||||||
AUpload: typeof import('@arco-design/web-vue')['Upload']
|
AUpload: typeof import('@arco-design/web-vue')['Upload']
|
||||||
BaseOption: typeof import('./../components/editor/components/BaseOption.vue')['default']
|
BaseOption: typeof import('./../components/editor/components/BaseOption.vue')['default']
|
||||||
BreadCrumb: typeof import('./../components/breadcrumb/bread-crumb.vue')['default']
|
BreadCrumb: typeof import('./../components/breadcrumb/bread-crumb.vue')['default']
|
||||||
|
|
@ -77,7 +70,6 @@ declare module '@vue/runtime-core' {
|
||||||
InputTexter: typeof import('./../components/editor/components/InputTexter.vue')['default']
|
InputTexter: typeof import('./../components/editor/components/InputTexter.vue')['default']
|
||||||
Marquee: typeof import('./../components/editor/blocks/text/marquee.vue')['default']
|
Marquee: typeof import('./../components/editor/blocks/text/marquee.vue')['default']
|
||||||
Option: typeof import('./../components/editor/blocks/date/option.vue')['default']
|
Option: typeof import('./../components/editor/blocks/date/option.vue')['default']
|
||||||
Page403: typeof import('./../components/AnForbiden/page-403.vue')['default']
|
|
||||||
PanelHeader: typeof import('./../components/editor/components/PanelHeader.vue')['default']
|
PanelHeader: typeof import('./../components/editor/components/PanelHeader.vue')['default']
|
||||||
PanelLeft: typeof import('./../components/editor/components/PanelLeft.vue')['default']
|
PanelLeft: typeof import('./../components/editor/components/PanelLeft.vue')['default']
|
||||||
PanelMain: typeof import('./../components/editor/components/PanelMain.vue')['default']
|
PanelMain: typeof import('./../components/editor/components/PanelMain.vue')['default']
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue