mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
refactor: enhance parameter handling and improve code clarity
- Updated GetListParams to set a default sort option for better query handling. - Enhanced PostSpiderRunParams to include a default mode and improved error handling for missing spider. - Added parameters field to ChatMessageContent for more flexible message content management. - Refactored getNodeIds method to simplify mode handling and removed unnecessary error checks. - Improved ChatMessageAction component to display parameters and response sections more effectively, enhancing user experience.
This commit is contained in:
@@ -63,7 +63,7 @@ type BaseController[T any] struct {
|
||||
|
||||
type GetListParams struct {
|
||||
Filter string `query:"filter" description:"Filter query"`
|
||||
Sort string `query:"sort" description:"Sort options"`
|
||||
Sort string `query:"sort" default:"-_id" description:"Sort options"`
|
||||
Page int `query:"page" default:"1" description:"Page number" minimum:"1"`
|
||||
Size int `query:"size" default:"10" description:"Page size" minimum:"1"`
|
||||
All bool `query:"all" default:"false" description:"Whether to get all items"`
|
||||
|
||||
@@ -674,7 +674,7 @@ func PostSpiderExport(c *gin.Context, _ *PostSpiderExportParams) (err error) {
|
||||
|
||||
type PostSpiderRunParams struct {
|
||||
Id string `path:"id" description:"Spider ID" format:"objectid" pattern:"^[0-9a-fA-F]{24}$"`
|
||||
Mode string `json:"mode" description:"Run mode" enum:"random,all,selected-nodes"`
|
||||
Mode string `json:"mode" description:"Run mode: random,all,selected-nodes" default:"random" enum:"random,all,selected-nodes"`
|
||||
NodeIds []string `json:"node_ids" description:"Node IDs, used in selected-nodes mode"`
|
||||
Cmd string `json:"cmd" description:"Command"`
|
||||
Param string `json:"param" description:"Parameters"`
|
||||
@@ -688,6 +688,12 @@ func PostSpiderRun(c *gin.Context, params *PostSpiderRunParams) (response *Respo
|
||||
return GetErrorResponse[[]primitive.ObjectID](errors.BadRequestf("invalid id format"))
|
||||
}
|
||||
|
||||
// get spider
|
||||
s, err := service.NewModelService[models.Spider]().GetById(id)
|
||||
if err != nil {
|
||||
return GetErrorResponse[[]primitive.ObjectID](errors.NotFoundf("spider not found"))
|
||||
}
|
||||
|
||||
// options
|
||||
var nodeIds []primitive.ObjectID
|
||||
if len(params.NodeIds) > 0 {
|
||||
@@ -714,6 +720,18 @@ func PostSpiderRun(c *gin.Context, params *PostSpiderRunParams) (response *Respo
|
||||
ScheduleId: scheduleId,
|
||||
Priority: params.Priority,
|
||||
}
|
||||
if opts.Mode == "" {
|
||||
opts.Mode = s.Mode
|
||||
}
|
||||
if opts.Cmd == "" {
|
||||
opts.Cmd = s.Cmd
|
||||
}
|
||||
if opts.Param == "" {
|
||||
opts.Param = s.Param
|
||||
}
|
||||
if opts.Priority == 0 {
|
||||
opts.Priority = s.Priority
|
||||
}
|
||||
|
||||
// user
|
||||
if u := GetUserFromContext(c); u != nil {
|
||||
|
||||
@@ -29,6 +29,7 @@ type ChatMessageContent struct {
|
||||
BaseModel `bson:",inline"`
|
||||
MessageId primitive.ObjectID `json:"message_id" bson:"message_id" description:"Message ID"`
|
||||
Key string `json:"key" bson:"key" description:"Message content key"`
|
||||
Parameters map[string]interface{} `json:"parameters" bson:"parameters" description:"Message content parameters"`
|
||||
Content string `json:"content" bson:"content" description:"Message content"`
|
||||
Type string `json:"type" bson:"type" description:"Message type (text/action)"`
|
||||
Action string `json:"action,omitempty" bson:"action,omitempty" description:"Action name"`
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/crawlab-team/crawlab/core/constants"
|
||||
"github.com/crawlab-team/crawlab/core/interfaces"
|
||||
"github.com/crawlab-team/crawlab/core/models/models"
|
||||
@@ -82,7 +81,8 @@ func (svc *Service) scheduleTasks(s *models.Spider, opts *interfaces.SpiderRunOp
|
||||
}
|
||||
|
||||
func (svc *Service) getNodeIds(opts *interfaces.SpiderRunOptions) (nodeIds []primitive.ObjectID, err error) {
|
||||
if opts.Mode == constants.RunTypeAllNodes {
|
||||
switch opts.Mode {
|
||||
case constants.RunTypeAllNodes:
|
||||
query := bson.M{
|
||||
"active": true,
|
||||
"enabled": true,
|
||||
@@ -95,12 +95,10 @@ func (svc *Service) getNodeIds(opts *interfaces.SpiderRunOptions) (nodeIds []pri
|
||||
for _, node := range nodes {
|
||||
nodeIds = append(nodeIds, node.Id)
|
||||
}
|
||||
} else if opts.Mode == constants.RunTypeSelectedNodes {
|
||||
case constants.RunTypeSelectedNodes:
|
||||
nodeIds = opts.NodeIds
|
||||
} else if opts.Mode == constants.RunTypeRandom {
|
||||
default:
|
||||
nodeIds = []primitive.ObjectID{primitive.NilObjectID}
|
||||
} else {
|
||||
return nil, errors.New("invalid run mode")
|
||||
}
|
||||
return nodeIds, nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import markdownit from 'markdown-it';
|
||||
import hljs from 'highlight.js';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import 'highlight.js/styles/github.css';
|
||||
import ClChatMessageAction from '@/components/ui/chat/ChatMessageAction.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -69,9 +70,9 @@ const filteredContents = computed<ChatMessageContent[]>(() => {
|
||||
// Compute token usage display
|
||||
const hasTokenUsage = computed(() => {
|
||||
const { message } = props;
|
||||
return message.usage &&
|
||||
(message.usage.total_tokens ||
|
||||
message.usage.prompt_tokens ||
|
||||
return message.usage &&
|
||||
(message.usage.total_tokens ||
|
||||
message.usage.prompt_tokens ||
|
||||
message.usage.completion_tokens);
|
||||
});
|
||||
|
||||
@@ -98,6 +99,7 @@ defineOptions({ name: 'ClChatMessage' });
|
||||
v-if="content.type === 'action'"
|
||||
:action="content.action!"
|
||||
:action-status="content.action_status!"
|
||||
:parameters="content.parameters"
|
||||
:content="content.content"
|
||||
/>
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ import JsonEditorVue from 'json-editor-vue';
|
||||
const props = defineProps<{
|
||||
action: string;
|
||||
actionStatus: ChatMessageActionStatus;
|
||||
parameters?: Record<string, any>;
|
||||
content?: string;
|
||||
}>();
|
||||
|
||||
const isExpanded = ref(false);
|
||||
const isFullScreen = ref(false);
|
||||
const isParamsExpanded = ref(true);
|
||||
const isResponseExpanded = ref(true);
|
||||
|
||||
const actionStatusIcon = computed<Icon>(() => {
|
||||
switch (props.actionStatus) {
|
||||
@@ -33,8 +36,16 @@ const parsedContent = computed<Record<string, any> | Record<string, any>[] | nul
|
||||
}
|
||||
});
|
||||
|
||||
const hasParameters = computed(() => {
|
||||
return props.parameters && Object.keys(props.parameters).length > 0;
|
||||
});
|
||||
|
||||
const isJsonContent = computed(() => {
|
||||
return parsedContent.value !== null;
|
||||
return parsedContent.value !== null || hasParameters.value;
|
||||
});
|
||||
|
||||
const hasContent = computed(() => {
|
||||
return props.content || hasParameters.value;
|
||||
});
|
||||
|
||||
defineOptions({ name: 'ClChatMessageAction' });
|
||||
@@ -69,7 +80,7 @@ defineOptions({ name: 'ClChatMessageAction' });
|
||||
@click.stop="isFullScreen = true"
|
||||
/>
|
||||
<cl-icon
|
||||
v-if="content"
|
||||
v-if="hasContent"
|
||||
class="action-button"
|
||||
:icon="['fas', isExpanded ? 'chevron-up' : 'chevron-down']"
|
||||
@click.stop="isExpanded = !isExpanded"
|
||||
@@ -77,23 +88,53 @@ defineOptions({ name: 'ClChatMessageAction' });
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="content"
|
||||
v-if="hasContent"
|
||||
class="action-content"
|
||||
:class="{ expanded: isExpanded }"
|
||||
>
|
||||
<el-scrollbar max-height="500px">
|
||||
<template v-if="isJsonContent">
|
||||
<div class="json-content">
|
||||
<!-- Parameters Section -->
|
||||
<div v-if="hasParameters" class="content-section">
|
||||
<div class="section-header" @click="isParamsExpanded = !isParamsExpanded">
|
||||
<span class="section-title">Parameters</span>
|
||||
<cl-icon
|
||||
class="action-button"
|
||||
:icon="['fas', isParamsExpanded ? 'chevron-up' : 'chevron-down']"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="isParamsExpanded" class="json-content">
|
||||
<json-editor-vue
|
||||
v-model="parsedContent"
|
||||
:model-value="parameters"
|
||||
expanded-on-start
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ content }}
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Response Section -->
|
||||
<div v-if="content" class="content-section">
|
||||
<div class="section-header" @click="isResponseExpanded = !isResponseExpanded">
|
||||
<span class="section-title">Response</span>
|
||||
<cl-icon
|
||||
class="action-button"
|
||||
:icon="['fas', isResponseExpanded ? 'chevron-up' : 'chevron-down']"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="isResponseExpanded">
|
||||
<template v-if="parsedContent">
|
||||
<div class="json-content">
|
||||
<json-editor-vue
|
||||
:model-value="parsedContent"
|
||||
expanded-on-start
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="text-content">{{ content }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
@@ -107,11 +148,50 @@ defineOptions({ name: 'ClChatMessageAction' });
|
||||
fullscreen
|
||||
append-to-body
|
||||
>
|
||||
<json-editor-vue
|
||||
v-model="parsedContent"
|
||||
expanded-on-start
|
||||
read-only
|
||||
/>
|
||||
<div class="fullscreen-content">
|
||||
<!-- Parameters Section -->
|
||||
<div v-if="hasParameters" class="content-section">
|
||||
<div class="section-header" @click="isParamsExpanded = !isParamsExpanded">
|
||||
<span class="section-title">Parameters</span>
|
||||
<cl-icon
|
||||
class="action-button"
|
||||
:icon="['fas', isParamsExpanded ? 'chevron-up' : 'chevron-down']"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="isParamsExpanded" class="json-content">
|
||||
<json-editor-vue
|
||||
:model-value="parameters"
|
||||
expanded-on-start
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Response Section -->
|
||||
<div v-if="content" class="content-section">
|
||||
<div class="section-header" @click="isResponseExpanded = !isResponseExpanded">
|
||||
<span class="section-title">Response</span>
|
||||
<cl-icon
|
||||
class="action-button"
|
||||
:icon="['fas', isResponseExpanded ? 'chevron-up' : 'chevron-down']"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="isResponseExpanded">
|
||||
<template v-if="parsedContent">
|
||||
<div class="json-content">
|
||||
<json-editor-vue
|
||||
:model-value="parsedContent"
|
||||
expanded-on-start
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="text-content">{{ content }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -221,8 +301,36 @@ defineOptions({ name: 'ClChatMessageAction' });
|
||||
transition: max-height 0.3s ease-in;
|
||||
}
|
||||
|
||||
.content-section {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.content-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px 0 0;
|
||||
margin-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.json-content {
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.text-content {
|
||||
padding: 8px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.action-content :deep(.jse-main) {
|
||||
@@ -246,10 +354,22 @@ defineOptions({ name: 'ClChatMessageAction' });
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.fullscreen-content {
|
||||
height: calc(100vh - 80px);
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.fullscreen-content .content-section {
|
||||
background: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.el-dialog.is-fullscreen .jse-main {
|
||||
height: calc(100vh - 80px) !important;
|
||||
background: var(--el-bg-color);
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
@@ -56,6 +56,7 @@ export declare global {
|
||||
interface ChatMessageContent extends BaseModel {
|
||||
message_id?: string;
|
||||
key?: string;
|
||||
parameters?: Record<string, any>;
|
||||
content?: string;
|
||||
type: ChatMessageContentType;
|
||||
action?: string;
|
||||
@@ -114,6 +115,7 @@ export declare global {
|
||||
conversation_title?: string;
|
||||
message_id?: string;
|
||||
key?: string;
|
||||
parameters?: Record<string, any>;
|
||||
content?: string;
|
||||
type: 'text' | 'action'; // Message type
|
||||
action_id?: string;
|
||||
|
||||
@@ -49,7 +49,7 @@ const actions = {
|
||||
page,
|
||||
size,
|
||||
conditions: JSON.stringify(state.tableListFilter),
|
||||
sort: JSON.stringify(state.tableListSort),
|
||||
// sort: JSON.stringify(state.tableListSort),
|
||||
} as ListRequestParams);
|
||||
commit('setNodeMetricsMap', res.data);
|
||||
return res;
|
||||
|
||||
@@ -103,7 +103,7 @@ const actions = {
|
||||
const payload = {
|
||||
...state.tablePagination,
|
||||
conditions: JSON.stringify(state.tableListFilter),
|
||||
sort: JSON.stringify(state.tableListSort),
|
||||
// sort: JSON.stringify(state.tableListSort),
|
||||
stats: true,
|
||||
};
|
||||
const res = await getList(`/spiders`, payload);
|
||||
|
||||
@@ -38,7 +38,6 @@ const actions = {
|
||||
if (!setting.value) {
|
||||
setting.value = {};
|
||||
}
|
||||
console.debug(setting)
|
||||
commit('setSetting', { key, value: setting });
|
||||
},
|
||||
saveSetting: async (
|
||||
|
||||
@@ -86,7 +86,7 @@ const actions = {
|
||||
const payload = {
|
||||
...state.tablePagination,
|
||||
conditions: JSON.stringify(state.tableListFilter),
|
||||
sort: JSON.stringify(state.tableListSort),
|
||||
// sort: JSON.stringify(state.tableListSort),
|
||||
stats: true,
|
||||
};
|
||||
const res = await getList(`/tasks`, payload);
|
||||
|
||||
@@ -316,6 +316,7 @@ export const getDefaultStoreActions = <T = any>(
|
||||
state,
|
||||
commit,
|
||||
}: StoreActionContext<BaseStoreState<T>>) => {
|
||||
console.debug('getList');
|
||||
const { page, size } = state.tablePagination;
|
||||
try {
|
||||
commit('setTableLoading', true);
|
||||
|
||||
Reference in New Issue
Block a user