mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 15:53:42 +08:00 
			
		
		
		
	feat: supprt channel priority now & record channel id in log (#484)
* feat: 支持设置渠道优先级 & 日志中显示使用的渠道ID * fix: 设置渠道优先级未更新 ability * chore: update implementation --------- Co-authored-by: Xiangyuan Liu <xiangyuan.liu@ui.com> Co-authored-by: JustSong <songquanpeng@foxmail.com> Co-authored-by: JustSong <39998050+songquanpeng@users.noreply.github.com>
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
			
		||||
import React, { useEffect, useState } from 'react';
 | 
			
		||||
import { Button, Form, Label, Pagination, Popup, Table } from 'semantic-ui-react';
 | 
			
		||||
import {Button, Form, Input, Label, Pagination, Popup, Table} from 'semantic-ui-react';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
import { API, showError, showInfo, showNotice, showSuccess, timestamp2string } from '../helpers';
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +24,7 @@ function renderType(type) {
 | 
			
		||||
    }
 | 
			
		||||
    type2label[0] = { value: 0, text: '未知类型', color: 'grey' };
 | 
			
		||||
  }
 | 
			
		||||
  return <Label basic color={type2label[type].color}>{type2label[type].text}</Label>;
 | 
			
		||||
  return <Label basic color={type2label[type]?.color}>{type2label[type]?.text}</Label>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function renderBalance(type, balance) {
 | 
			
		||||
@@ -96,7 +96,7 @@ const ChannelsTable = () => {
 | 
			
		||||
      });
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const manageChannel = async (id, action, idx) => {
 | 
			
		||||
  const manageChannel = async (id, action, idx, priority) => {
 | 
			
		||||
    let data = { id };
 | 
			
		||||
    let res;
 | 
			
		||||
    switch (action) {
 | 
			
		||||
@@ -111,6 +111,13 @@ const ChannelsTable = () => {
 | 
			
		||||
        data.status = 2;
 | 
			
		||||
        res = await API.put('/api/channel/', data);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'priority':
 | 
			
		||||
        if (priority === '') {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        data.priority = parseInt(priority);
 | 
			
		||||
        res = await API.put('/api/channel/', data);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    const { success, message } = res.data;
 | 
			
		||||
    if (success) {
 | 
			
		||||
@@ -335,6 +342,14 @@ const ChannelsTable = () => {
 | 
			
		||||
            >
 | 
			
		||||
              余额
 | 
			
		||||
            </Table.HeaderCell>
 | 
			
		||||
            <Table.HeaderCell
 | 
			
		||||
                style={{ cursor: 'pointer' }}
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  sortChannel('priority');
 | 
			
		||||
                }}
 | 
			
		||||
            >
 | 
			
		||||
              优先级
 | 
			
		||||
            </Table.HeaderCell>
 | 
			
		||||
            <Table.HeaderCell>操作</Table.HeaderCell>
 | 
			
		||||
          </Table.Row>
 | 
			
		||||
        </Table.Header>
 | 
			
		||||
@@ -373,6 +388,22 @@ const ChannelsTable = () => {
 | 
			
		||||
                      basic
 | 
			
		||||
                    />
 | 
			
		||||
                  </Table.Cell>
 | 
			
		||||
                  <Table.Cell>
 | 
			
		||||
                    <Popup
 | 
			
		||||
                        trigger={<Input type="number"  defaultValue={channel.priority} onBlur={(event) => {
 | 
			
		||||
                          manageChannel(
 | 
			
		||||
                              channel.id,
 | 
			
		||||
                              'priority',
 | 
			
		||||
                              idx,
 | 
			
		||||
                              event.target.value,
 | 
			
		||||
                          );
 | 
			
		||||
                        }}>
 | 
			
		||||
                          <input style={{maxWidth:'60px'}} />
 | 
			
		||||
                        </Input>}
 | 
			
		||||
                        content='渠道选择优先级,越高越优先'
 | 
			
		||||
                        basic
 | 
			
		||||
                    />
 | 
			
		||||
                  </Table.Cell>
 | 
			
		||||
                  <Table.Cell>
 | 
			
		||||
                    <div>
 | 
			
		||||
                      <Button
 | 
			
		||||
@@ -441,7 +472,7 @@ const ChannelsTable = () => {
 | 
			
		||||
 | 
			
		||||
        <Table.Footer>
 | 
			
		||||
          <Table.Row>
 | 
			
		||||
            <Table.HeaderCell colSpan='8'>
 | 
			
		||||
            <Table.HeaderCell colSpan='9'>
 | 
			
		||||
              <Button size='small' as={Link} to='/channel/add' loading={loading}>
 | 
			
		||||
                添加新的渠道
 | 
			
		||||
              </Button>
 | 
			
		||||
 
 | 
			
		||||
@@ -56,9 +56,10 @@ const LogsTable = () => {
 | 
			
		||||
    token_name: '',
 | 
			
		||||
    model_name: '',
 | 
			
		||||
    start_timestamp: timestamp2string(0),
 | 
			
		||||
    end_timestamp: timestamp2string(now.getTime() / 1000 + 3600)
 | 
			
		||||
    end_timestamp: timestamp2string(now.getTime() / 1000 + 3600),
 | 
			
		||||
    channel: ''
 | 
			
		||||
  });
 | 
			
		||||
  const { username, token_name, model_name, start_timestamp, end_timestamp } = inputs;
 | 
			
		||||
  const { username, token_name, model_name, start_timestamp, end_timestamp, channel } = inputs;
 | 
			
		||||
 | 
			
		||||
  const [stat, setStat] = useState({
 | 
			
		||||
    quota: 0,
 | 
			
		||||
@@ -84,7 +85,7 @@ const LogsTable = () => {
 | 
			
		||||
  const getLogStat = async () => {
 | 
			
		||||
    let localStartTimestamp = Date.parse(start_timestamp) / 1000;
 | 
			
		||||
    let localEndTimestamp = Date.parse(end_timestamp) / 1000;
 | 
			
		||||
    let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`);
 | 
			
		||||
    let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`);
 | 
			
		||||
    const { success, message, data } = res.data;
 | 
			
		||||
    if (success) {
 | 
			
		||||
      setStat(data);
 | 
			
		||||
@@ -109,7 +110,7 @@ const LogsTable = () => {
 | 
			
		||||
    let localStartTimestamp = Date.parse(start_timestamp) / 1000;
 | 
			
		||||
    let localEndTimestamp = Date.parse(end_timestamp) / 1000;
 | 
			
		||||
    if (isAdminUser) {
 | 
			
		||||
      url = `/api/log/?p=${startIdx}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
 | 
			
		||||
      url = `/api/log/?p=${startIdx}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
 | 
			
		||||
    } else {
 | 
			
		||||
      url = `/api/log/self/?p=${startIdx}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
 | 
			
		||||
    }
 | 
			
		||||
@@ -205,16 +206,9 @@ const LogsTable = () => {
 | 
			
		||||
        </Header>
 | 
			
		||||
        <Form>
 | 
			
		||||
          <Form.Group>
 | 
			
		||||
            {
 | 
			
		||||
              isAdminUser && (
 | 
			
		||||
                <Form.Input fluid label={'用户名称'} width={2} value={username}
 | 
			
		||||
                            placeholder={'可选值'} name='username'
 | 
			
		||||
                            onChange={handleInputChange} />
 | 
			
		||||
              )
 | 
			
		||||
            }
 | 
			
		||||
            <Form.Input fluid label={'令牌名称'} width={isAdminUser ? 2 : 3} value={token_name}
 | 
			
		||||
            <Form.Input fluid label={'令牌名称'} width={3} value={token_name}
 | 
			
		||||
                        placeholder={'可选值'} name='token_name' onChange={handleInputChange} />
 | 
			
		||||
            <Form.Input fluid label='模型名称' width={isAdminUser ? 2 : 3} value={model_name} placeholder='可选值'
 | 
			
		||||
            <Form.Input fluid label='模型名称' width={3} value={model_name} placeholder='可选值'
 | 
			
		||||
                        name='model_name'
 | 
			
		||||
                        onChange={handleInputChange} />
 | 
			
		||||
            <Form.Input fluid label='起始时间' width={4} value={start_timestamp} type='datetime-local'
 | 
			
		||||
@@ -225,6 +219,19 @@ const LogsTable = () => {
 | 
			
		||||
                        onChange={handleInputChange} />
 | 
			
		||||
            <Form.Button fluid label='操作' width={2} onClick={refresh}>查询</Form.Button>
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          {
 | 
			
		||||
            isAdminUser && <>
 | 
			
		||||
              <Form.Group>
 | 
			
		||||
                <Form.Input fluid label={'渠道 ID'} width={3} value={channel}
 | 
			
		||||
                            placeholder='可选值' name='channel'
 | 
			
		||||
                            onChange={handleInputChange} />
 | 
			
		||||
                <Form.Input fluid label={'用户名称'} width={3} value={username}
 | 
			
		||||
                            placeholder={'可选值'} name='username'
 | 
			
		||||
                            onChange={handleInputChange} />
 | 
			
		||||
 | 
			
		||||
              </Form.Group>
 | 
			
		||||
            </>
 | 
			
		||||
          }
 | 
			
		||||
        </Form>
 | 
			
		||||
        <Table basic compact size='small'>
 | 
			
		||||
          <Table.Header>
 | 
			
		||||
@@ -238,6 +245,17 @@ const LogsTable = () => {
 | 
			
		||||
              >
 | 
			
		||||
                时间
 | 
			
		||||
              </Table.HeaderCell>
 | 
			
		||||
              {
 | 
			
		||||
                isAdminUser && <Table.HeaderCell
 | 
			
		||||
                  style={{ cursor: 'pointer' }}
 | 
			
		||||
                  onClick={() => {
 | 
			
		||||
                    sortLog('channel');
 | 
			
		||||
                  }}
 | 
			
		||||
                  width={1}
 | 
			
		||||
                >
 | 
			
		||||
                  渠道
 | 
			
		||||
                </Table.HeaderCell>
 | 
			
		||||
              }
 | 
			
		||||
              {
 | 
			
		||||
                isAdminUser && <Table.HeaderCell
 | 
			
		||||
                  style={{ cursor: 'pointer' }}
 | 
			
		||||
@@ -299,16 +317,16 @@ const LogsTable = () => {
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  sortLog('quota');
 | 
			
		||||
                }}
 | 
			
		||||
                width={2}
 | 
			
		||||
                width={1}
 | 
			
		||||
              >
 | 
			
		||||
                消耗额度
 | 
			
		||||
                额度
 | 
			
		||||
              </Table.HeaderCell>
 | 
			
		||||
              <Table.HeaderCell
 | 
			
		||||
                style={{ cursor: 'pointer' }}
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  sortLog('content');
 | 
			
		||||
                }}
 | 
			
		||||
                width={isAdminUser ? 4 : 5}
 | 
			
		||||
                width={isAdminUser ? 4 : 6}
 | 
			
		||||
              >
 | 
			
		||||
                详情
 | 
			
		||||
              </Table.HeaderCell>
 | 
			
		||||
@@ -326,6 +344,11 @@ const LogsTable = () => {
 | 
			
		||||
                return (
 | 
			
		||||
                  <Table.Row key={log.id}>
 | 
			
		||||
                    <Table.Cell>{renderTimestamp(log.created_at)}</Table.Cell>
 | 
			
		||||
                    {
 | 
			
		||||
                      isAdminUser && (
 | 
			
		||||
                        <Table.Cell>{log.channel ? <Label basic>{log.channel}</Label> : ''}</Table.Cell>
 | 
			
		||||
                      )
 | 
			
		||||
                    }
 | 
			
		||||
                    {
 | 
			
		||||
                      isAdminUser && (
 | 
			
		||||
                        <Table.Cell>{log.username ? <Label>{log.username}</Label> : ''}</Table.Cell>
 | 
			
		||||
@@ -345,7 +368,7 @@ const LogsTable = () => {
 | 
			
		||||
 | 
			
		||||
          <Table.Footer>
 | 
			
		||||
            <Table.Row>
 | 
			
		||||
              <Table.HeaderCell colSpan={'9'}>
 | 
			
		||||
              <Table.HeaderCell colSpan={'10'}>
 | 
			
		||||
                <Select
 | 
			
		||||
                  placeholder='选择明细分类'
 | 
			
		||||
                  options={LOG_OPTIONS}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user