Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
M
mmc-stl-vue2
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Administrator
mmc-stl-vue2
Commits
4b0a5f81
提交
4b0a5f81
authored
5月 19, 2025
作者:
温凯
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(ai): 新增AI配置获取功能并优化AI识别列表展示
上级
688cbd12
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
418 行增加
和
64 行删除
+418
-64
ai.js
src/components/MMCFlightControlCenter/api/modules/ai.js
+39
-15
request.js
src/components/MMCFlightControlCenter/api/request.js
+1
-2
index.vue
...anel/components/controlRight/components/viewLib/index.vue
+100
-21
index.vue
...pplications/components/player/components/aiList/index.vue
+278
-26
没有找到文件。
src/components/MMCFlightControlCenter/api/modules/ai.js
浏览文件 @
4b0a5f81
import
axios
from
"axios"
;
import
axios
from
"axios"
;
import
request
from
"../request"
;
// const gddaiapi = 'https://hawk.mmcuav.cn/gddaiapi';
// const gddaiapi = 'https://hawk.mmcuav.cn/gddaiapi';
export
default
class
AI_API
{
export
default
class
AI_API
{
// 获取当前的ai配置
static
getAiconfig
(
data
)
{
return
request
({
url
:
`/admin-api/system/ai-config/getconfig`
,
method
:
"post"
,
data
,
});
}
// 人脸
// 人脸
static
face
(
data
){
static
face
(
data
)
{
// return axios.post("http://api.user.mmcuav.cn/aidemo/facedetect", data); // 百度的ai
return
axios
.
post
(
return
axios
.
post
(
"https://hawk.mmcuav.cn/faceaiapi/detect/imageface"
,
data
);
"https://hawk.mmcuav.cn/faceaiapi/detect/imageface"
,
data
);
}
}
// 车牌
// 车牌
static
plate
(
data
)
{
static
plate
(
data
)
{
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/e01d1d01-52e2-4883-a5de-0ae268764db0/predict"
,
data
);
// 共达地
return
axios
.
post
(
// return axios.post("https://hawk.mmcuav.cn/plateaiapi/detect/image", data); // 自研
"/gddaiapi/api/inflet/v1/tasks/e01d1d01-52e2-4883-a5de-0ae268764db0/predict"
,
data
);
// 共达地
}
}
// 人流
// 人流
static
crowd
(
data
){
static
crowd
(
data
)
{
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/18493235-4dd0-4f54-ab55-c1856ca7e3a5/predict"
,
data
);
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/18493235-4dd0-4f54-ab55-c1856ca7e3a5/predict"
,
data
);
}
}
// 烟雾
// 烟雾
static
smoke
(
data
){
static
smoke
(
data
)
{
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/fca2eb65-8b99-4109-9f9e-a9f7fd06ac1f/predict"
,
data
);
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/fca2eb65-8b99-4109-9f9e-a9f7fd06ac1f/predict"
,
data
);
}
}
// 漏油识别
// 漏油识别
static
oilLeak
(
data
){
static
oilLeak
(
data
)
{
return
axios
.
post
(
"https://hawk.mmcuav.cn/oilaiapi/detect/image"
,
data
);
return
axios
.
post
(
"https://hawk.mmcuav.cn/oilaiapi/detect/image"
,
data
);
}
}
// 裸土识别
// 裸土识别
static
bareSoil
(
data
){
static
bareSoil
(
data
)
{
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/05a9d657-8339-4575-bced-04b60b74c690/predict"
,
data
);
return
axios
.
post
(
"/gddaiapi/api/inflet/v1/tasks/05a9d657-8339-4575-bced-04b60b74c690/predict"
,
data
);
}
// 其余ai
static
kbtAi
(
data
)
{
return
axios
.
post
(
"https://hawk.mmcuav.cn/detect/image"
,
data
);
}
}
}
}
\ No newline at end of file
src/components/MMCFlightControlCenter/api/request.js
浏览文件 @
4b0a5f81
...
@@ -30,7 +30,6 @@ $axios.interceptors.request.use(
...
@@ -30,7 +30,6 @@ $axios.interceptors.request.use(
config
.
headers
[
"terminal"
]
=
2
;
// 1 为管理后台 2 为前端项目
config
.
headers
[
"terminal"
]
=
2
;
// 1 为管理后台 2 为前端项目
config
.
headers
[
"p-id"
]
=
projectId
;
config
.
headers
[
"p-id"
]
=
projectId
;
console
.
log
(
config
,
store
.
state
,
"token信息验证"
);
console
.
log
(
config
,
store
.
state
,
"token信息验证"
);
return
config
;
return
config
;
},
},
(
error
)
=>
{
(
error
)
=>
{
...
@@ -75,7 +74,7 @@ $axios.interceptors.response.use(
...
@@ -75,7 +74,7 @@ $axios.interceptors.response.use(
isRefreshToken
=
false
;
isRefreshToken
=
false
;
if
(
data
.
code
===
0
)
{
if
(
data
.
code
===
0
)
{
const
token
=
data
.
token
;
const
token
=
data
.
token
;
console
.
log
(
"store"
,
store
);
window
.
$mmc_stl
.
app
.
$store
.
commit
(
window
.
$mmc_stl
.
app
.
$store
.
commit
(
"MMCFlightControlCenter/setState"
,
"MMCFlightControlCenter/setState"
,
{
{
...
...
src/components/MMCFlightControlCenter/components/uavApplications/components/controlPanel/components/controlRight/components/viewLib/index.vue
浏览文件 @
4b0a5f81
...
@@ -17,9 +17,9 @@
...
@@ -17,9 +17,9 @@
>
>
<el-option
<el-option
v-for=
"item in aiTypeList"
v-for=
"item in aiTypeList"
:key=
"item.
i
d"
:key=
"item.
typeI
d"
:label=
"item.
valu
e"
:label=
"item.
titl
e"
:value=
"item.
i
d"
:value=
"item.
typeI
d"
></el-option>
></el-option>
</el-select>
</el-select>
<el-checkbox
<el-checkbox
...
@@ -262,39 +262,118 @@ export default {
...
@@ -262,39 +262,118 @@ export default {
isIndeterminate
:
false
,
isIndeterminate
:
false
,
selectAll
:
false
,
//全选
selectAll
:
false
,
//全选
viewLibTab
:
0
,
// 视图库tab索引, 0: 视图, 1: 机载
viewLibTab
:
0
,
// 视图库tab索引, 0: 视图, 1: 机载
aiType
:
0
,
// 图片类型
aiType
:
1
,
// 图片类型
aiTypeList
:
[
aiTypeList
:
[
// 普通图片或ai图片选项
{
{
id
:
0
,
typeId
:
1
,
value
:
"全部
"
,
title
:
"人车识别
"
,
},
},
{
{
id
:
1
,
typeId
:
2
,
value
:
"人脸
识别"
,
title
:
"烟火
识别"
,
},
},
{
{
id
:
8
,
typeId
:
4
,
// id: 2,
title
:
"行人识别"
,
value
:
"车牌识别"
,
},
},
{
{
id
:
3
,
typeId
:
5
,
value
:
"人流
识别"
,
title
:
"机动车
识别"
,
},
},
{
{
id
:
4
,
typeId
:
6
,
value
:
"烟雾
识别"
,
title
:
"两轮车
识别"
,
},
},
{
{
id
:
5
,
typeId
:
7
,
value
:
"漏油
识别"
,
title
:
"三轮车
识别"
,
},
},
{
{
id
:
6
,
typeId
:
8
,
value
:
"裸土
识别"
,
title
:
"挖掘机
识别"
,
},
},
],
//视图库类型
{
typeId
:
9
,
title
:
"车牌识别"
,
},
{
typeId
:
10
,
title
:
"人脸识别"
,
},
{
typeId
:
11
,
title
:
"口罩识别"
,
},
{
typeId
:
14
,
title
:
"烟雾识别"
,
},
{
typeId
:
15
,
title
:
"火焰识别"
,
},
{
typeId
:
17
,
title
:
"占道经营"
,
},
{
typeId
:
22
,
title
:
"船舶识别"
,
},
{
typeId
:
23
,
title
:
"漏油识别"
,
},
{
typeId
:
24
,
title
:
"头盔识别"
,
},
{
typeId
:
25
,
title
:
"管线识别"
,
},
{
typeId
:
26
,
title
:
"路面裂缝"
,
},
{
typeId
:
27
,
title
:
"顶棚违建"
,
},
{
typeId
:
28
,
title
:
"门牌广告"
,
},
{
typeId
:
29
,
title
:
"井盖识别"
,
},
{
typeId
:
30
,
title
:
"搅拌车识别"
,
},
{
typeId
:
31
,
title
:
"油罐车识别"
,
},
{
typeId
:
32
,
title
:
"渣土车识别"
,
},
{
typeId
:
33
,
title
:
"排气口识别"
,
},
{
typeId
:
34
,
title
:
"人流识别"
,
},
{
title
:
"裸土识别"
,
typeId
:
35
,
},
],
//视图库类型
fileType
:
"图片"
,
//视图文件类型 0:图片;1:视频
fileType
:
"图片"
,
//视图文件类型 0:图片;1:视频
photoList
:
[],
//资源列表对应的对象
photoList
:
[],
//资源列表对应的对象
photoListDate
:
null
,
//某日期的所有资源
photoListDate
:
null
,
//某日期的所有资源
...
...
src/components/MMCFlightControlCenter/components/uavApplications/components/player/components/aiList/index.vue
浏览文件 @
4b0a5f81
...
@@ -5,21 +5,26 @@
...
@@ -5,21 +5,26 @@
<img
src=
"./assets/images/car1.png"
@
click=
"aiVisible = !aiVisible"
/>
<img
src=
"./assets/images/car1.png"
@
click=
"aiVisible = !aiVisible"
/>
<div
class=
"ai-list"
v-show=
"aiVisible"
>
<div
class=
"ai-list"
v-show=
"aiVisible"
>
<el-tooltip
<el-tooltip
v-for=
"(item,index) in aiIdentifyList"
v-for=
"(item,
index) in aiIdentifyList"
:key=
"index"
:key=
"index"
:content=
"item.title"
:content=
"item.title"
placement=
"bottom"
placement=
"bottom"
>
>
<div
class=
"ai-item"
@
click=
"onAiIdentify(item.type)"
>
<div
class=
"ai-item"
@
click=
"onAiIdentify(item.type)"
>
<img
class=
"img_src"
:src=
"item.img"
/>
<img
class=
"img_src"
crossorigin=
"anonymous"
:src=
"item.img"
/>
</div>
</div>
</el-tooltip>
</el-tooltip>
</div>
</div>
</div>
</div>
</el-tooltip>
</el-tooltip>
<el-dialog
:title=
"`$
{aiTitle}结果`" :visible.sync="aiResultShow" append-to-body width="700px">
<el-dialog
<div
style=
"text-align: center;"
>
:title=
"`$
{aiTitle}结果`"
<img
style=
"width: 100%;"
:src=
"aiResultImg"
/>
:visible.sync="aiResultShow"
append-to-body
width="700px"
>
<div
style=
"text-align: center"
>
<img
style=
"width: 100%"
crossorigin=
"anonymous"
:src=
"aiResultImg"
/>
</div>
</div>
</el-dialog>
</el-dialog>
</div>
</div>
...
@@ -46,44 +51,234 @@ export default {
...
@@ -46,44 +51,234 @@ export default {
data
()
{
data
()
{
return
{
return
{
aiVisible
:
false
,
aiVisible
:
false
,
aiIdentifyList
:
[
aiIdentifyList
:
[],
deAiIdentifyList
:
[
{
{
title
:
"人脸识别"
,
type
:
"face"
,
typeId
:
1
,
typeId
:
1
,
img
:
require
(
"./assets/images/人脸识别.svg"
),
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/person_car.png"
,
title
:
"人车识别"
,
},
{
typeId
:
2
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/fire.png"
,
title
:
"烟火识别"
,
},
{
typeId
:
4
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/person.png"
,
title
:
"行人识别"
,
},
{
typeId
:
5
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/car.png"
,
title
:
"机动车识别"
,
},
{
typeId
:
6
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/motor_bicycle.png"
,
title
:
"两轮车识别"
,
},
{
typeId
:
7
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/tricycle.png"
,
title
:
"三轮车识别"
,
},
{
typeId
:
8
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/excavator.png"
,
title
:
"挖掘机识别"
,
},
},
{
{
typeId
:
9
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/plate.png"
,
title
:
"车牌识别"
,
title
:
"车牌识别"
,
type
:
"plate"
,
type
:
"plate"
,
typeId
:
8
,
img
:
require
(
"./assets/images/车牌识别.svg"
),
},
},
{
{
title
:
"人流识别"
,
typeId
:
10
,
type
:
"crowd"
,
typeId
:
3
,
type
:
"face"
,
img
:
require
(
"./assets/images/人流识别.svg"
),
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/face.png"
,
title
:
"人脸识别"
,
},
},
{
{
title
:
"烟雾识别"
,
typeId
:
11
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/mask.png"
,
title
:
"口罩识别"
,
},
{
typeId
:
14
,
type
:
"smoke"
,
type
:
"smoke"
,
typeId
:
7
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/smoke.png"
,
img
:
require
(
"./assets/images/烟雾识别.svg"
)
,
title
:
"烟雾识别"
,
},
},
{
{
title
:
"漏油识别"
,
typeId
:
15
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/fire.png"
,
title
:
"火焰识别"
,
},
{
typeId
:
17
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/zhandao.png"
,
title
:
"占道经营"
,
},
{
type
:
"kbtAi"
,
typeId
:
22
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/boat.png"
,
title
:
"船舶识别"
,
},
{
typeId
:
23
,
type
:
"oilLeak"
,
type
:
"oilLeak"
,
typeId
:
5
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/oilspill.png"
,
img
:
require
(
"./assets/images/漏油识别.svg"
),
title
:
"漏油识别"
,
},
{
typeId
:
24
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/helmet.png"
,
title
:
"头盔识别"
,
},
{
typeId
:
25
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/guanxian.png"
,
title
:
"管线识别"
,
},
{
typeId
:
26
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/lumianliefeng.png"
,
title
:
"路面裂缝"
,
},
{
typeId
:
27
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/dingpeng.png"
,
title
:
"顶棚违建"
,
},
{
typeId
:
28
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/guanggaopai.png"
,
title
:
"门牌广告"
,
},
{
typeId
:
29
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/jinggai.png"
,
title
:
"井盖识别"
,
},
{
typeId
:
30
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/jiaobanche.png"
,
title
:
"搅拌车识别"
,
},
{
typeId
:
31
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/youguanche.png"
,
title
:
"油罐车识别"
,
},
{
typeId
:
32
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/zhatuche.png"
,
title
:
"渣土车识别"
,
},
{
typeId
:
33
,
type
:
"kbtAi"
,
img
:
"https://mmc-crm.oss-cn-shenzhen.aliyuncs.com/prod/tmj-icon/ai/paiwukou.png"
,
title
:
"排气口识别"
,
type
:
"kbtAi"
,
},
{
typeId
:
34
,
img
:
require
(
"./assets/images/人流识别.svg"
),
title
:
"人流识别"
,
type
:
"kbtAi"
,
},
},
{
{
title
:
"裸土识别"
,
title
:
"裸土识别"
,
type
:
"bareSoil"
,
type
:
"bareSoil"
,
typeId
:
6
,
typeId
:
35
,
img
:
require
(
"./assets/images/裸土识别.svg"
),
img
:
require
(
"./assets/images/裸土识别.svg"
),
},
},
],
],
// aiIdentifyList: [
// {
// title: "人脸识别",
// type: "face",
// typeId: 1,
// img: require("./assets/images/人脸识别.svg"),
// },
// {
// title: "车牌识别",
// type: "plate",
// typeId: 8,
// img: require("./assets/images/车牌识别.svg"),
// },
// {
// title: "人流识别",
// type: "crowd",
// typeId: 3,
// img: require("./assets/images/人流识别.svg"),
// },
// {
// title: "烟雾识别",
// type: "smoke",
// typeId: 7,
// img: require("./assets/images/烟雾识别.svg"),
// },
// {
// title: "漏油识别",
// type: "oilLeak",
// typeId: 5,
// img: require("./assets/images/漏油识别.svg"),
// },
// {
// title: "裸土识别",
// type: "bareSoil",
// typeId: 6,
// img: require("./assets/images/裸土识别.svg"),
// },
// ],
aiResultShow
:
false
,
//ai识别结果展示
aiResultShow
:
false
,
//ai识别结果展示
aiTitle
:
""
,
aiTitle
:
""
,
aiResultImg
:
""
,
//ai结果图
aiResultImg
:
""
,
//ai结果图
...
@@ -91,9 +286,43 @@ export default {
...
@@ -91,9 +286,43 @@ export default {
},
},
computed
:
{
computed
:
{
...
mapState
(
"MMCFlightControlCenter"
,
[
"cesiumViewer"
,
"baseUrl"
]),
...
mapState
(
"MMCFlightControlCenter"
,
[
"cesiumViewer"
,
"baseUrl"
]),
...
mapState
(
"MMCFlightControlCenter/uav"
,
[
"uav"
]),
...
mapState
(
"MMCFlightControlCenter/uav"
,
[
"uav"
,
"userInfo"
]),
},
mounted
()
{
this
.
getAiconfig
();
},
},
methods
:
{
methods
:
{
async
getAiconfig
()
{
let
formData
=
new
FormData
();
console
.
log
(
this
.
$store
.
state
.
MMCFlightControlCenter
,
"userInfo"
);
let
{
TenantId
,
projectId
}
=
this
.
$store
.
state
.
MMCFlightControlCenter
;
// formData.append("projectId", projectId);
// formData.append("tenantId", TenantId);
let
res
=
await
AI_API
[
"getAiconfig"
]({
tenantId
:
TenantId
,
projectId
:
projectId
,
});
if
(
res
.
data
.
configInfo
)
{
const
configInfo
=
Object
.
entries
(
res
.
data
.
configInfo
).
map
(
([
key
,
value
])
=>
({
key
,
...
value
,
})
);
let
configInfoData
=
configInfo
.
filter
((
item
)
=>
item
.
status
==
0
);
// 使用 Set 存储数据1中的所有 title,提高查找效率
const
titleSet
=
new
Set
(
configInfoData
.
map
((
item
)
=>
item
.
detectorType
)
);
console
.
log
(
titleSet
,
"titleSet"
);
// 遍历数据2,检查每个 name 是否在 titleSet 中存在
const
matchedData
=
this
.
deAiIdentifyList
.
filter
((
dataItem
)
=>
titleSet
.
has
(
dataItem
.
typeId
)
);
this
.
aiIdentifyList
=
matchedData
;
}
},
/**
/**
* ai识别事件
* ai识别事件
*/
*/
...
@@ -200,7 +429,28 @@ export default {
...
@@ -200,7 +429,28 @@ export default {
}
}
}
}
break
;
break
;
case
"kbtAi"
:
{
let
formData
=
new
FormData
();
formData
.
append
(
"image"
,
blob
,
`下载.jpeg`
);
formData
.
append
(
"iscount"
,
1
);
let
res
=
await
AI_API
[
type
](
formData
);
results
=
res
?.
data
?.
data
?.
data
?.
map
((
item
)
=>
{
return
{
x
:
item
.
bbox
[
0
],
y
:
item
.
bbox
[
1
],
width
:
item
.
bbox
[
2
]
-
item
.
bbox
[
0
],
height
:
item
.
bbox
[
3
]
-
item
.
bbox
[
1
],
label
:
item
.
label_cn
,
prob
:
item
.
bbox
.
conf
,
};
})
||
[];
if
(
results
.
length
>
0
)
{
isSuccess
=
true
;
}
}
break
;
// 共达地通用数据结构
// 共达地通用数据结构
default
:
default
:
{
{
...
@@ -371,11 +621,13 @@ export default {
...
@@ -371,11 +621,13 @@ export default {
position
:
absolute
;
position
:
absolute
;
left
:
-124px
;
left
:
-124px
;
top
:
0
;
top
:
0
;
width
:
1
11
px
;
width
:
1
23
px
;
display
:
flex
;
display
:
flex
;
flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
justify-content
:
space-between
;
justify-content
:
space-between
;
overflow-y
:
auto
;
max-height
:
142px
;
gap
:
4px
;
.ai-item
{
.ai-item
{
cursor
:
pointer
;
cursor
:
pointer
;
width
:
35px
;
width
:
35px
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论