Compare commits

...

2 Commits

Author SHA1 Message Date
xinadmin fe8c5646d2 前端打包 2026-08-11 10:46:47 +08:00
xinadmin 1b8a0f2d0b 菜单添加标签 2026-08-11 10:46:08 +08:00
11 changed files with 42 additions and 7 deletions
@@ -30,6 +30,7 @@ return new class extends Migration
$table->increments('id');
$table->integer('category_id')->default(0)->comment('所属分类ID');
$table->string('title', 100)->comment('导航标题');
$table->json('tag')->comment('导航标签');
$table->integer('image_id')->comment('导航图标信息');
$table->string('link', 500)->nullable()->default('')->comment('跳转链接');
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0=启用,1=禁用');
@@ -18,6 +18,7 @@ class SysCategoryItemFormRequest extends BaseFormRequest
'title' => 'required|string|max:100',
'image_id' => ['required', 'integer', new Exists(SysFileModel::class, 'id')],
'link' => 'nullable|string|max:500',
'tag' => 'nullable|array',
'status' => 'nullable|integer|in:0,1',
'sort' => 'nullable|integer',
];
@@ -18,6 +18,7 @@ class SysCategoryItemModel extends Model
'status' => 'int',
'sort' => 'int',
'image_id' => 'int',
'tag' => 'array',
];
protected $fillable = [
@@ -25,6 +26,7 @@ class SysCategoryItemModel extends Model
'title',
'image_id',
'link',
'tag',
'status',
'sort',
];
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{i as e}from"./rolldown-runtime-BgaNhQyE.js";import{Dr as t,t as n}from"./jsx-runtime-ADHq9IcL.js";import{o as r,s as i}from"./chunk-KS7C4IRE-CN93VkYO.js";import{t as a}from"./typography-C2UybztD.js";import{t as o}from"./space-BqavXZJj.js";import{t as s}from"./button-CcpWP-mq.js";import{t as c}from"./LeftOutlined-DolIAuof.js";import{t as l}from"./badge-Cim9D6DD.js";import{n as u}from"./LockOutlined-rb6chlKx.js";import{i as d,s as f}from"./XinForm-CH1TH01p.js";import{t as p}from"./image-CBJbXNqF.js";import{t as m}from"./tag-BMkLMUVK.js";import{t as h}from"./useTranslation-DIuTqE8W.js";import{t as g}from"./XinTable-DP0Q6sQS.js";var _=e(t(),1),v=e(u(),1),y=n(),{Title:b}=a;function x(e){return e?typeof e==`string`?e:e.preview_url||e.file_url||``:``}function S(){let{t:e}=h(),t=r(),[n]=i(),a=n.get(`categoryId`),u=n.get(`categoryName`)||``,[S,C]=(0,_.useState)({id:a?parseInt(a):0,name:decodeURIComponent(u)});(0,_.useEffect)(()=>{a&&C({id:parseInt(a),name:decodeURIComponent(u)})},[a,u]);let w=[{title:e(`system.category.item.id`),dataIndex:`id`,hideInForm:!0,width:80,align:`center`},{title:e(`system.category.item.title`),dataIndex:`title`,valueType:`text`,colProps:{span:12},rules:[{required:!0,message:e(`system.category.item.title.required`)}]},{title:e(`system.category.item.image`),dataIndex:`image_id`,valueType:`image`,colProps:{span:24},rules:[{required:!0,message:e(`system.category.item.image.required`)}],hideInSearch:!0,fieldProps:{action:`/system/file/list/upload`,mode:`single`,maxCount:1,changeType:`id`},render:(e,t)=>{let n=x(t.image);return n?(0,y.jsx)(p,{src:n,width:60,height:60,style:{objectFit:`cover`,borderRadius:4}}):`-`}},{title:e(`system.category.item.link`),dataIndex:`link`,valueType:`text`,colProps:{span:12},hideInSearch:!0,fieldProps:{placeholder:e(`system.category.item.link.placeholder`)}},{title:e(`system.category.item.tag`),dataIndex:`tag`,valueType:`select`,colProps:{span:24},hideInSearch:!0,fieldProps:{mode:`tags`,placeholder:e(`system.category.item.tag.placeholder`)},render:e=>{if(!e)return`-`;let t=Array.isArray(e)?e:[e];return t.length===0?`-`:(0,y.jsx)(o,{size:[4,4],wrap:!0,children:t.map(e=>(0,y.jsx)(m,{color:`blue`,children:e},e))})}},{title:e(`system.category.item.status`),dataIndex:`status`,valueType:`select`,colProps:{span:12},initialValue:0,rules:[{required:!0,message:e(`system.category.item.status.required`)}],fieldProps:{options:[{label:e(`system.category.item.status.normal`),value:0},{label:e(`system.category.item.status.disabled`),value:1}]},render:t=>t===0?(0,y.jsx)(l,{status:`success`,text:e(`system.category.item.status.normal`)}):(0,y.jsx)(l,{status:`error`,text:e(`system.category.item.status.disabled`)})},{title:e(`system.category.item.sort`),dataIndex:`sort`,valueType:`digit`,colProps:{span:12},hideInSearch:!0,initialValue:0,fieldProps:{min:0,style:{width:`100%`}}},{title:e(`system.category.item.createdAt`),dataIndex:`created_at`,render:e=>e?(0,v.default)(e).format(`YYYY-MM-DD HH:mm`):`-`,hideInForm:!0,hideInSearch:!0,width:160}];return S.id?(0,y.jsxs)(o,{orientation:`vertical`,style:{width:`100%`},children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(s,{type:`link`,onClick:()=>{t(`/system/category`)},icon:(0,y.jsx)(c,{}),classNames:{root:`p-0 mb-2`},children:e(`system.category.backToList`)}),(0,y.jsx)(b,{level:3,children:(0,y.jsxs)(`span`,{className:`mr-2`,children:[e(`system.category.itemManagement`),` - `,S.name]})})]}),(0,y.jsx)(g,{api:`/system/category/item`,columns:w,rowKey:`id`,accessName:`system.category.item`,formProps:{grid:!0,colProps:{span:12},rowProps:{gutter:[30,0]},layout:`vertical`},modalProps:{width:600},requestParams:e=>({...e,category_id:S.id}),searchShow:!1,handleFinish:async(t,n,r,i)=>(n===`create`?(await d(`/system/category/item`,{...t,tag:t.tag??[],category_id:S.id}),window.$message?.success(e(`system.category.item.createSuccess`))):(await f(`/system/category/item/`+i?.id,{...t,tag:t.tag??[],category_id:S.id}),window.$message?.success(e(`system.category.item.updateSuccess`))),!0)})]}):(0,y.jsx)(`div`,{style:{padding:50,textAlign:`center`},children:(0,y.jsx)(`div`,{style:{marginTop:50,color:`#999`},children:e(`system.category.selectCategoryFirst`)})})}export{S as default};
-1
View File
@@ -1 +0,0 @@
import{i as e}from"./rolldown-runtime-BgaNhQyE.js";import{Dr as t,t as n}from"./jsx-runtime-ADHq9IcL.js";import{o as r,s as i}from"./chunk-KS7C4IRE-CN93VkYO.js";import{t as a}from"./typography-C2UybztD.js";import{t as o}from"./space-BqavXZJj.js";import{t as s}from"./button-CcpWP-mq.js";import{t as c}from"./LeftOutlined-DolIAuof.js";import{t as l}from"./badge-Cim9D6DD.js";import{n as u}from"./LockOutlined-rb6chlKx.js";import{i as d,s as f}from"./XinForm-CH1TH01p.js";import{t as p}from"./image-CBJbXNqF.js";import{t as m}from"./useTranslation-DIuTqE8W.js";import{t as h}from"./XinTable-DP0Q6sQS.js";var g=e(t(),1),_=e(u(),1),v=n(),{Title:y}=a;function b(e){return e?typeof e==`string`?e:e.preview_url||e.file_url||``:``}function x(){let{t:e}=m(),t=r(),[n]=i(),a=n.get(`categoryId`),u=n.get(`categoryName`)||``,[x,S]=(0,g.useState)({id:a?parseInt(a):0,name:decodeURIComponent(u)});(0,g.useEffect)(()=>{a&&S({id:parseInt(a),name:decodeURIComponent(u)})},[a,u]);let C=[{title:e(`system.category.item.id`),dataIndex:`id`,hideInForm:!0,width:80,align:`center`},{title:e(`system.category.item.title`),dataIndex:`title`,valueType:`text`,colProps:{span:12},rules:[{required:!0,message:e(`system.category.item.title.required`)}]},{title:e(`system.category.item.image`),dataIndex:`image_id`,valueType:`image`,colProps:{span:24},rules:[{required:!0,message:e(`system.category.item.image.required`)}],hideInSearch:!0,fieldProps:{action:`/system/file/list/upload`,mode:`single`,maxCount:1,changeType:`id`},render:(e,t)=>{let n=b(t.image);return n?(0,v.jsx)(p,{src:n,width:60,height:60,style:{objectFit:`cover`,borderRadius:4}}):`-`}},{title:e(`system.category.item.link`),dataIndex:`link`,valueType:`text`,colProps:{span:12},hideInSearch:!0,fieldProps:{placeholder:e(`system.category.item.link.placeholder`)}},{title:e(`system.category.item.status`),dataIndex:`status`,valueType:`select`,colProps:{span:12},initialValue:0,rules:[{required:!0,message:e(`system.category.item.status.required`)}],fieldProps:{options:[{label:e(`system.category.item.status.normal`),value:0},{label:e(`system.category.item.status.disabled`),value:1}]},render:t=>t===0?(0,v.jsx)(l,{status:`success`,text:e(`system.category.item.status.normal`)}):(0,v.jsx)(l,{status:`error`,text:e(`system.category.item.status.disabled`)})},{title:e(`system.category.item.sort`),dataIndex:`sort`,valueType:`digit`,colProps:{span:12},hideInSearch:!0,initialValue:0,fieldProps:{min:0,style:{width:`100%`}}},{title:e(`system.category.item.createdAt`),dataIndex:`created_at`,render:e=>e?(0,_.default)(e).format(`YYYY-MM-DD HH:mm`):`-`,hideInForm:!0,hideInSearch:!0,width:160}];return x.id?(0,v.jsxs)(o,{orientation:`vertical`,style:{width:`100%`},children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(s,{type:`link`,onClick:()=>{t(`/system/category`)},icon:(0,v.jsx)(c,{}),classNames:{root:`p-0 mb-2`},children:e(`system.category.backToList`)}),(0,v.jsx)(y,{level:3,children:(0,v.jsxs)(`span`,{className:`mr-2`,children:[e(`system.category.itemManagement`),` - `,x.name]})})]}),(0,v.jsx)(h,{api:`/system/category/item`,columns:C,rowKey:`id`,accessName:`system.category.item`,formProps:{grid:!0,colProps:{span:12},rowProps:{gutter:[30,0]},layout:`vertical`},modalProps:{width:600},requestParams:e=>({...e,category_id:x.id}),searchShow:!1,handleFinish:async(t,n,r,i)=>(n===`create`?(await d(`/system/category/item`,{...t,category_id:x.id}),window.$message?.success(e(`system.category.item.createSuccess`))):(await f(`/system/category/item/`+i?.id,{...t,category_id:x.id}),window.$message?.success(e(`system.category.item.updateSuccess`))),!0)})]}):(0,v.jsx)(`div`,{style:{padding:50,textAlign:`center`},children:(0,v.jsx)(`div`,{style:{marginTop:50,color:`#999`},children:e(`system.category.selectCategoryFirst`)})})}export{x as default};
+1 -1
View File
@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/favicons.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>XinAdmin</title>
<script type="module" crossorigin src="/assets/index-fRsOyCkc.js"></script>
<script type="module" crossorigin src="/assets/index-CmpcUpir.js"></script>
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BgaNhQyE.js">
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-ADHq9IcL.js">
<link rel="modulepreload" crossorigin href="/assets/chunk-KS7C4IRE-CN93VkYO.js">
+2
View File
@@ -11,6 +11,8 @@ export interface ICategoryItem {
image: ISysFileInfo | string;
/** 跳转链接 */
link?: string;
/** 导航标签(字符串数组) */
tag?: string[];
/** 状态:0=启用,1=禁用 */
status: number;
/** 排序 */
+2
View File
@@ -28,6 +28,8 @@ export default {
"system.category.item.image.required": "Item icon is required",
"system.category.item.link": "Redirect Link",
"system.category.item.link.placeholder": "Enter redirect link",
"system.category.item.tag": "Tags",
"system.category.item.tag.placeholder": "Type and press Enter to add a tag",
"system.category.item.status": "Status",
"system.category.item.status.required": "Status is required",
"system.category.item.status.normal": "Active",
+2
View File
@@ -28,6 +28,8 @@ export default {
"system.category.item.image.required": "导航图标不能为空",
"system.category.item.link": "跳转链接",
"system.category.item.link.placeholder": "请输入跳转链接",
"system.category.item.tag": "标签",
"system.category.item.tag.placeholder": "输入后按回车添加标签",
"system.category.item.status": "状态",
"system.category.item.status.required": "状态不能为空",
"system.category.item.status.normal": "启用",
+26 -1
View File
@@ -1,5 +1,5 @@
import XinTable from '@/components/XinTable';
import { Badge, Button, Image, Space, Typography } from 'antd';
import { Badge, Button, Image, Space, Tag, Typography } from 'antd';
import { LeftOutlined } from '@ant-design/icons';
import type { ICategoryItem } from '@/domain/iCategoryItem';
import type { XinTableColumn } from '@/components/XinTable/typings';
@@ -98,6 +98,29 @@ export default function CategoryItemPage() {
placeholder: t('system.category.item.link.placeholder'),
},
},
{
title: t('system.category.item.tag'),
dataIndex: 'tag',
valueType: 'select',
colProps: { span: 24 },
hideInSearch: true,
fieldProps: {
mode: 'tags',
placeholder: t('system.category.item.tag.placeholder'),
},
render: (value: string[] | string | null) => {
if (!value) return '-';
const tags = Array.isArray(value) ? value : [value];
if (tags.length === 0) return '-';
return (
<Space size={[4, 4]} wrap>
{tags.map((tag) => (
<Tag key={tag} color="blue">{tag}</Tag>
))}
</Space>
);
},
},
{
title: t('system.category.item.status'),
dataIndex: 'status',
@@ -188,12 +211,14 @@ export default function CategoryItemPage() {
if (mode === 'create') {
await Create('/system/category/item', {
...values,
tag: values.tag ?? [],
category_id: currentCategory.id,
});
window.$message?.success(t('system.category.item.createSuccess'));
} else {
await Update('/system/category/item/' + defaultValue?.id, {
...values,
tag: values.tag ?? [],
category_id: currentCategory.id,
});
window.$message?.success(t('system.category.item.updateSuccess'));