diff --git a/web/src/components/command/ChooseAsset.js b/web/src/components/command/ChooseAsset.js
new file mode 100644
index 0000000..e647bd6
--- /dev/null
+++ b/web/src/components/command/ChooseAsset.js
@@ -0,0 +1,427 @@
+import React, {Component} from 'react';
+
+import {
+ Badge,
+ Button,
+ Col,
+ Divider,
+ Input,
+ Layout,
+ Modal,
+ Row,
+ Select,
+ Space,
+ Table,
+ Tag,
+ Tooltip,
+ Typography
+} from "antd";
+import qs from "qs";
+import request from "../../common/request";
+import {message} from "antd/es";
+
+
+import {PlusOutlined, SyncOutlined, UndoOutlined} from '@ant-design/icons';
+import {PROTOCOL_COLORS} from "../../common/constants";
+import {isEmpty} from "../../utils/utils";
+import dayjs from "dayjs";
+
+const confirm = Modal.confirm;
+const {Search} = Input;
+const {Content} = Layout;
+const {Title, Text} = Typography;
+
+class ChooseAsset extends Component {
+
+ inputRefOfName = React.createRef();
+ inputRefOfIp = React.createRef();
+ changeOwnerFormRef = React.createRef();
+
+ state = {
+ items: [],
+ total: 0,
+ queryParams: {
+ pageIndex: 1,
+ pageSize: 10,
+ protocol: 'ssh'
+ },
+ loading: false,
+ tags: [],
+ model: {},
+ selectedRowKeys: [],
+ selectedRows: [],
+ delBtnLoading: false,
+ changeOwnerModalVisible: false,
+ changeSharerModalVisible: false,
+ changeOwnerConfirmLoading: false,
+ changeSharerConfirmLoading: false,
+ users: [],
+ selected: {},
+ totalSelectedRows: [],
+ };
+
+ checkedAssets = undefined
+
+ async componentDidMount() {
+ this.checkedAssets = this.props.setCheckedAssets;
+ this.loadTableData();
+ let result = await request.get('/tags');
+ if (result['code'] === 1) {
+ this.setState({
+ tags: result['data']
+ })
+ }
+ }
+
+ async loadTableData(queryParams) {
+ this.setState({
+ loading: true
+ });
+
+ queryParams = queryParams || this.state.queryParams;
+
+ // queryParams
+ let paramsStr = qs.stringify(queryParams);
+
+ let data = {
+ items: [],
+ total: 0
+ };
+
+ try {
+ let result = await request.get('/assets/paging?' + paramsStr);
+ if (result['code'] === 1) {
+ data = result['data'];
+ } else {
+ message.error(result['message']);
+ }
+ } catch (e) {
+
+ } finally {
+ let sharer = this.state.sharer;
+ const items = data.items.map(item => {
+ let disabled = false;
+ if (sharer === item['owner']) {
+ disabled = true;
+ }
+ return {...item, 'key': item['id'], 'disabled': disabled}
+ })
+ let totalSelectedRows = this.state.totalSelectedRows;
+ let selectedRowKeys = totalSelectedRows.map(item => item['id']);
+ this.setState({
+ items: items,
+ total: data.total,
+ queryParams: queryParams,
+ loading: false,
+ selectedRowKeys: selectedRowKeys
+ });
+ }
+ }
+
+ handleChangPage = async (pageIndex, pageSize) => {
+ let queryParams = this.state.queryParams;
+ queryParams.pageIndex = pageIndex;
+ queryParams.pageSize = pageSize;
+
+ this.setState({
+ queryParams: queryParams
+ });
+
+ await this.loadTableData(queryParams)
+ };
+
+ handleSearchByName = name => {
+ let query = {
+ ...this.state.queryParams,
+ 'pageIndex': 1,
+ 'pageSize': this.state.queryParams.pageSize,
+ 'name': name,
+ }
+
+ this.loadTableData(query);
+ };
+
+ handleSearchByIp = ip => {
+ let query = {
+ ...this.state.queryParams,
+ 'pageIndex': 1,
+ 'pageSize': this.state.queryParams.pageSize,
+ 'ip': ip,
+ }
+
+ this.loadTableData(query);
+ };
+
+ handleTagsChange = tags => {
+ console.log(tags)
+ // this.setState({
+ // tags: tags
+ // })
+ let query = {
+ ...this.state.queryParams,
+ 'pageIndex': 1,
+ 'pageSize': this.state.queryParams.pageSize,
+ 'tags': tags.join(','),
+ }
+
+ this.loadTableData(query);
+ }
+
+ unSelectRow = async (assetId) => {
+ const selectedRowKeys = this.state.selectedRowKeys.filter(key => key !== assetId);
+ const totalSelectedRows = this.state.totalSelectedRows.filter(item => item['id'] !== assetId);
+ this.setState({
+ selectedRowKeys: selectedRowKeys,
+ totalSelectedRows: totalSelectedRows
+ })
+ }
+
+ render() {
+
+ const columns = [{
+ title: '序号',
+ dataIndex: 'id',
+ key: 'id',
+ render: (id, record, index) => {
+ return index + 1;
+ }
+ }, {
+ title: '资产名称',
+ dataIndex: 'name',
+ key: 'name',
+ render: (name, record) => {
+ let short = name;
+ if (short && short.length > 20) {
+ short = short.substring(0, 20) + " ...";
+ }
+ return (
+