react-quill 富文本组件编写和应用

  •  index.tsx文件
import React, { useRef, useState } from 'react';
import { Modal, Button } from 'antd';
import RichEditor from './RichEditor';

const AnchorTouchHistory: React.FC = () => {
  const editorRef = useRef<any>(null);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [isEditModalVisible, setIsEditModalVisible] = useState(false);
  const [contentHtml, setContentHtml] = useState('<p>heheda</p>' );

  const openAddModal = () => setIsModalVisible(true);
  const submitContent = () => {
    const content = editorRef.current?.getRichContent();
    console.log(content);
    setIsModalVisible(false);
    editorRef.current?.resetContent();
  };

  const openEditModal = () => setIsEditModalVisible(true);
  const submitEditContent = () => {
    const content = editorRef.current?.getRichContent();
    console.log(content);
    setIsEditModalVisible(false);
    editorRef.current?.resetContent();
  };

  return (
    <div>
      <Button onClick={openAddModal}>打开添加对话框</Button>
      <Modal
        visible={isModalVisible}
        onCancel={() => setIsModalVisible(false)}
        onOk={submitContent}
      >
        <RichEditor ref={editorRef} />
      </Modal>

      <Button onClick={openEditModal}>打开编辑对话框</Button>
      <Modal
        visible={isEditModalVisible}
        onCancel={() => setIsEditModalVisible(false)}
        onOk={submitEditContent}
      >
        <RichEditor ref={editorRef} initialContent={contentHtml} />
      </Modal>
    </div>
  );
};

export default AnchorTouchHistory;
  • RichEditor.tsx
import React, { useState, useEffect, useRef, useMemo, useImperativeHandle, forwardRef } from 'react';
import ReactQuill, { Quill } from 'react-quill';
import 'react-quill/dist/quill.core.css';
import 'react-quill/dist/quill.snow.css';
import 'react-quill/dist/quill.bubble.css';

import { Modal, Input, Upload, Button, Tabs, Alert } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import COS from 'cos-js-sdk-v5';
import ImageResize from 'quill-image-resize-module-react';
import { getTxyCosConf } from '@/services/anchor-touch/history';

Quill.register('modules/imageResize', ImageResize);

import '@/styles/quillEditor.css';

const RichEditor = forwardRef(({ initialContent = '' }, ref) => {
  const [value, setValue] = useState(initialContent);
  const [isCosReady, setIsCosReady] = useState(false);
  const quillRef = useRef<any>(null);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [isLinkModalVisible, setIsLinkModalVisible] = useState(false);
  const [bucket, setBucket] = useState('');
  const [region, setRegion] = useState('');
  const [cos, setCos] = useState<COS | null>(null);
  const [width, setWidth] = useState('');
  const [height, setHeight] = useState('');
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [currentFile, setCurrentFile] = useState<File | null>(null);
  const [originalWidth, setOriginalWidth] = useState<number | null>(null);
  const [originalHeight, setOriginalHeight] = useState<number | null>(null);
  const [imageUrl, setImageUrl] = useState('');
  const [uploadMode, setUploadMode] = useState<'local' | 'url'>('local');
  const [linkUrl, setLinkUrl] = useState('');
  const [linkText, setLinkText] = useState('');
  const [urlError, setUrlError] = useState('');

  useImperativeHandle(ref, () => ({
    getRichContent: () => value,
    resetContent: () => setValue(initialContent)
  }));

  useEffect(() => {
    const fetchCosConfig = async () => {
      try {
        const response = await getTxyCosConf();
        setBucket(response.data.bucket);
        setRegion(response.data.region);
        const cosInstance = new COS({
          SecretId: response.data.secretid,
          SecretKey: response.data.secretkey,
        });
        setCos(cosInstance);
        setIsCosReady(true);
      } catch (error) {
        console.error('获取 COS 配置失败:', error);
      }
    };

    fetchCosConfig();
  }, []);

  const showImageUploadModal = () => {
    setIsModalVisible(true);
  };

  const showLinkModal = () => {
    setIsLinkModalVisible(true);
  };

  const handleLinkOk = () => {
    if (!linkUrl.startsWith('http://') && !linkUrl.startsWith('https://')) {
      setUrlError('链接地址格式不正确,请输入有效的链接地址。');
      return;
    }

    const editor = quillRef.current?.getEditor();
    const range = editor?.getSelection()?.index || 0;

    editor?.insertText(range, linkText, 'link', linkUrl);
    editor?.setSelection(range + linkText.length);
    handleLinkCancel();
  };

  const handleLinkCancel = () => {
    setIsLinkModalVisible(false);
    setLinkUrl('');
    setLinkText('');
    setUrlError('');
  };

  const handleOk = () => {
    if (uploadMode === 'local') {
      if (!currentFile || !cos) {
        handleCancel();
        return;
      }

      const uniqueFileName = `${Date.now()}_${currentFile.name}`;

      cos.uploadFile(
        {
          Bucket: bucket,
          Region: region,
          Key: uniqueFileName,
          Body: currentFile,
          SliceSize: 1024 * 1024,
        },
        (err, data) => {
          if (err) {
            console.error('上传失败:', err);
          } else {
            const imageUrl = `https://${data.Location}`;
            insertImageToEditor(imageUrl);
          }
        }
      );
    } else {
      insertImageToEditor(imageUrl);
    }
  };

  const insertImageToEditor = (imageUrl: string) => {
    const editor = quillRef.current?.getEditor();
    const range = editor?.getSelection()?.index || 0;

    editor?.insertEmbed(range, 'image', imageUrl);
    editor?.formatText(range, 1, {
      width: width ? width : undefined,
      height: height ? height : undefined,
    });
    editor?.setSelection(range + 1);
    handleCancel();
    console.log('图片的链接为: ', imageUrl);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
    setPreviewUrl(null);
    setCurrentFile(null);
    setWidth('');
    setHeight('');
    setImageUrl('');
  };

  const beforeUpload = (file: File) => {
    if (!file.type.startsWith('image/')) {
      console.error('不是有效的图像文件');
      return false;
    }

    const reader = new FileReader();
    reader.onload = (e) => {
      const preview = e.target?.result as string;
      setPreviewUrl(preview);
      setCurrentFile(file);

      const img = new Image();
      img.onload = () => {
        console.log('Image loaded:', img.naturalWidth, img.naturalHeight);
        setOriginalWidth(img.naturalWidth);
        setOriginalHeight(img.naturalHeight);
        setWidth(img.naturalWidth.toString());
        setHeight(img.naturalHeight.toString());
      };
      img.onerror = (error) => {
        console.error('图像加载失败:', error);
      };
      img.src = preview;
    };

    reader.onerror = (error) => {
      console.error('文件读取失败:', error);
    };

    reader.readAsDataURL(file);
    return false;
  };

  const handleWidthBlur = () => {
    const widthValue = parseFloat(width);
    if (isNaN(widthValue)) {
      console.error('Invalid width: ', width);
      return;
    }
    if (originalWidth && originalHeight && widthValue > 0) {
      const calculatedHeight = (widthValue / originalWidth) * originalHeight;
      setHeight(calculatedHeight.toFixed(0).toString());
    }
  };

  const handleHeightBlur = () => {
    const heightValue = parseFloat(height);
    if (originalWidth && originalHeight && heightValue > 0) {
      const calculatedWidth = (heightValue / originalHeight) * originalWidth;
      setWidth(calculatedWidth.toFixed(0).toString());
    }
  };

  const handleLinkUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const url = e.target.value;
    setLinkUrl(url);

    if (url.startsWith('http://') || url.startsWith('https://')) {
      setUrlError('');
    } else if (url) {
      setUrlError('链接地址格式不正确,请输入有效的链接地址。');
    }
  };

  const sizes = [false, '14px', '16px', '18px', '20px', '22px', '26px', '28px', '30px'];
  const Size = Quill.import('formats/size');
  Size.whitelist = sizes;

  const fonts = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif'];
  const Font = Quill.import('formats/font');
  Font.whitelist = fonts;
  Quill.register(Font, true);

  const modules = useMemo(() => ({
    toolbar: {
      container: [
        ['bold', 'italic', 'underline'],
        [{ size: sizes }],
        [{ header: [1, 2, 3, 4, 5, false] }],
        [{ color: [] }, { background: [] }],
        ['link', 'image', 'clean']
      ],
      handlers: {
        image: showImageUploadModal,
        link: showLinkModal,
      },
    },
    imageResize: {
      modules: ['DisplaySize'],
      handleStyles: {
        backgroundColor: 'transparent',
        border: 'none',
      },
      resizeWidth: false,
    },
  }), [cos]);

  const formats = [
    'font',
    'header',
    'size',
    'bold',
    'italic',
    'underline',
    'strike',
    'list',
    'bullet',
    'link',
    'image',
    'width',
    'height',
    'color', // include color format
    'background', // include background color format
  ];

  if (!isCosReady) {
    return <div>加载中...</div>;
  }

  return (
    <>
      <ReactQuill
        ref={quillRef}
        value={value}
        onChange={setValue}
        modules={modules}
        formats={formats}
      />
      {/* Modes for Image and Link Modals */}
      <Modal
        title="插入图片"
        visible={isModalVisible}
        onCancel={handleCancel}
        footer={null}
      >
        <Tabs defaultActiveKey="local" onChange={setUploadMode}>
          <Tabs.TabPane tab="本地图片" key="local">
            <Upload beforeUpload={beforeUpload} showUploadList={false}>
              <Button icon={<UploadOutlined />}>选择图片</Button>
            </Upload>
            {previewUrl && (
              <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: 10, width: 150, height: 150, overflow: 'hidden', border: '1px solid #e8e8e8' }}>
                <img src={previewUrl} alt="预览" style={{ width: 150, maxHeight: '100%' }} />
              </div>
            )}
          </Tabs.TabPane>
          <Tabs.TabPane tab="链接图片" key="url">
            <Input placeholder="图片链接" value={imageUrl} onChange={(e) => setImageUrl(e.target.value)} onBlur={() => {
              const img = new Image();
              img.onload = () => {
                setOriginalWidth(img.naturalWidth);
                setOriginalHeight(img.naturalHeight);
                setWidth(img.naturalWidth.toString());
                setHeight(img.naturalHeight.toString());
                setPreviewUrl(imageUrl);
              };
              img.onerror = (error) => {
                console.error('图像加载失败:', error);
                setPreviewUrl(null);
              };
              img.src = imageUrl;
            }} />
            {previewUrl && (
              <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: 10, width: 150, height: 150, overflow: 'hidden', border: '1px solid #e8e8e8' }}>
                <img src={previewUrl} alt="预览" style={{ width: 150, maxHeight: '100%' }} />
              </div>
            )}
          </Tabs.TabPane>
        </Tabs>
        <Input placeholder="设置宽度" value={width} onChange={(e) => setWidth(e.target.value)} onBlur={handleWidthBlur} style={{ marginTop: 10 }} />
        <Input placeholder="设置高度" value={height} onChange={(e) => setHeight(e.target.value)} onBlur={handleHeightBlur} style={{ marginTop: 10 }} />
        <div style={{ marginTop: 10, textAlign: 'right' }}>
          <Button type="primary" onClick={handleOk} disabled={uploadMode === 'local' ? !currentFile : !imageUrl}>确认</Button>
          <Button onClick={handleCancel} style={{ marginLeft: 10 }}>取消</Button>
        </div>
      </Modal>

      <Modal title="添加链接" visible={isLinkModalVisible} onCancel={handleLinkCancel} onOk={handleLinkOk}>
        {urlError && <Alert message={urlError} type="error" />}
        <Input placeholder="链接地址" value={linkUrl} onChange={handleLinkUrlChange} style={{ marginBottom: 10 }} />
        <Input placeholder="备注" value={linkText} onChange={(e) => setLinkText(e.target.value)} />
      </Modal>
    </>
  );
});

export default RichEditor;
  • quillEditor.css
/* 字体风格 */
/* 处理下拉字体选择器中选项的文本溢出并显示省略号 */
.ql-snow .ql-picker.ql-font .ql-picker-label::before {
  width: 88px; /* 设置下拉选项宽度,可以根据需要调整 */
  white-space: nowrap; /* 不换行显示 */
  overflow: hidden; /* 隐藏溢出部分 */
  text-overflow: ellipsis; /* 使用省略号显示溢出文本 */
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimSun"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimSun"]::before {
  content: "宋体";
  font-family: "SimSun";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimHei"]::before {
  content: "黑体";
  font-family: "SimHei";
}

.ql-snow
.ql-picker.ql-font
.ql-picker-label[data-value="Microsoft-YaHei"]::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-item[data-value="Microsoft-YaHei"]::before {
  content: "微软雅黑";
  font-family: "Microsoft YaHei";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="KaiTi"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="KaiTi"]::before {
  content: "楷体";
  font-family: "KaiTi";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="FangSong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="FangSong"]::before {
  content: "仿宋";
  font-family: "FangSong";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Arial"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Arial"]::before {
  content: "Arial";
  font-family: "Arial";
}

.ql-snow
.ql-picker.ql-font
.ql-picker-label[data-value="Times-New-Roman"]::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-item[data-value="Times-New-Roman"]::before {
  content: "Times New Roman";
  font-family: "Times New Roman";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="sans-serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="sans-serif"]::before {
  content: "sans-serif";
  font-family: "sans-serif";
}

.ql-font-SimSun { font-family: "SimSun"; }
.ql-font-SimHei { font-family: "SimHei"; }
.ql-font-Microsoft-YaHei { font-family: "Microsoft YaHei"; }
.ql-font-KaiTi { font-family: "KaiTi"; }
.ql-font-FangSong { font-family: "FangSong"; }
.ql-font-Arial { font-family: "Arial"; }
.ql-font-Times-New-Roman { font-family: "Times New Roman"; }
.ql-font-sans-serif { font-family: "sans-serif"; }

/* 字体大小 */
.ql-snow .ql-picker.ql-size .ql-picker-label::before { content: "字体大小"; }
.ql-snow .ql-picker.ql-size .ql-picker-item::before { content: "常规"; }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before{
  content: "14px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before{
  content: "16px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before{
  content: "18px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before{
  content: "20px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="22px"]::before{
  content: "22px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="26px"]::before{
  content: "26px";
  font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before {
  content: "30px";
  font-size: 14px;
}

.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
  content: "14px";
  font-size: 14px;
}

.ql-size-14px { font-size: 14px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
  content: "16px";
  font-size: 16px;
}

.ql-size-16px { font-size: 16px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
  content: "18px";
  font-size: 18px;
}

.ql-size-18px { font-size: 18px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
  content: "20px";
  font-size: 20px;
}

.ql-size-20px { font-size: 20px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="22px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="22px"]::before {
  content: "22px";
  font-size: 22px;
}

.ql-size-22px { font-size: 22px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="26px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="26px"]::before {
  content: "26px";
  font-size: 26px;
}

.ql-size-26px { font-size: 26px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]::before {
  content: "28px";
  font-size: 28px;
}

.ql-size-28px { font-size: 28px; }

/* .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before, */
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="30px"]::before {
  content: "30px";
  font-size: 30px;
}

.ql-size-30px { font-size: 30px; }

/* 段落大小 */
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "常规";
}

/* .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, */
.ql-snow .ql-picker.ql-header .ql-picker-label::before {
  content: "标题大小";
}

/* 默认设置 */
.ql-snow .ql-editor { font-size: 14px; }
/* 查看样式 */
.view-editor .ql-toolbar { display: none; }
.view-editor .ql-container.ql-snow { border: 0; }
.view-editor .ql-container.ql-snow .ql-editor { padding: 0; }
/* 编辑样式 */
.edit-editor .ql-toolbar { display: block; }
.edit-editor .ql-container.ql-snow {
  border: 1px solid #ccc;
  min-height: inherit;
}

  • golang后端接口,获取
    TxyCosConf:
      SecretId: 'xxxxx'
      SecretKey: 'xxxxx'
      Bucket: 'xxxxx'
      Region: 'xxxx'
import {request} from "@@/plugin-request/request";
export function getTxyCosConf() {
  return request('/api/v1/xxxx/getTxyCosConf', {
    method: 'get',
  })
    .then(response => {
      return response;
    })
    .catch(error => {
      console.error('Error get data:', error);
      throw error;
    });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/951160.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习】多目标融合算法(二):底部共享多任务模型(Shared-Bottom Multi-task Model)

目录 一、引言 1.1 往期回顾 1.2 本期概要 二、Shared-Bottom Multi-task Model&#xff08;SBMM&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 三、总结 一、引言 在朴素的深度学习ctr预估模型中&#xff08;如DNN&#xff09;&#xff0c;通常以一个行…

探秘MetaGPT:革新软件开发的多智能体框架(22/30)

一、MetaGPT 引发的 AI 变革浪潮 近年来&#xff0c;人工智能大模型领域取得了令人瞩目的进展&#xff0c;GPT-3、GPT-4、PaLM 等模型展现出了惊人的自然语言处理能力&#xff0c;仿佛为 AI 世界打开了一扇通往无限可能的大门。它们能够生成流畅的文本、回答复杂的问题、进行创…

LabVIEW软件Bug的定义与修改

在LabVIEW软件开发过程中&#xff0c;bug&#xff08;程序错误或缺陷&#xff09;指的是程序中导致不符合预期行为的任何问题。Bug可能是由于编码错误、逻辑漏洞、硬件兼容性问题、系统资源限制等因素引起的。它可能会导致程序崩溃、功能无法正常执行或输出结果不符合预期。理解…

高性能网络模式:Reactor 和 Proactor

Reactor Reactor 采用I/O多路复用监听事件&#xff0c;收到事件后&#xff0c;根据事件类型分配给某个进程/线程。 实际应用中用到的模型&#xff1a; 单 Reactor 单进程 单 Reactor 多线程 优点&#xff1a;能充分利用多核CPU性能。 缺点&#xff1a;存在多线程竞争共享资源…

扩散模型论文概述(三):Stability AI系列工作【学习笔记】

视频链接&#xff1a;扩散模型论文概述&#xff08;三&#xff09;&#xff1a;Stability AI系列工作_哔哩哔哩_bilibili 本期视频讲的是Stability AI在图像生成的工作。 同样&#xff0c;第一张图片是神作&#xff0c;总结的太好了&#xff01; 介绍Stable Diffusion之前&…

大数据技术-Hadoop(四)Yarn的介绍与使用

目录 一、Yarn 基本结构 1、Yarn基本结构 2、Yarn的工作机制 二、Yarn常用的命令 三、调度器 1、Capacity Scheduler&#xff08;容量调度器&#xff09; 1.1、特点 1.2、配置 1.2.1、yarn-site.xml 1.2.2、capacity-scheduler.xml 1.3、重启yarn、刷新队列 测试 向hi…

玩转大语言模型——ollama导入huggingface下载的模型

ollama导入huggingface模型 前言gguf模型查找相关模型下载模型 导入Ollama配置参数文件导入模型查看导入情况 safetensfors模型下载模型下载llama.cpp配置环境并转换 前言 ollama在大语言模型的应用中十分的方便&#xff0c;但是也存在一定的问题&#xff0c;比如不能使用自己…

apollo内置eureka dashboard授权登录

要确保访问Eureka Server时要求输入账户和密码&#xff0c;需要确保以下几点&#xff1a; 确保 eurekaSecurityEnabled 配置为 true&#xff1a;这个配置项控制是否启用Eureka的安全认证。如果它被设置为 false&#xff0c;即使配置了用户名和密码&#xff0c;也不会启用安全认…

【Dify】Dify自定义模型设置 | 对接DMXAPI使用打折 Openai GPT 或 Claude3.5系列模型方法详解

一、Dify & DMXAPI 1、Dify DIFY&#xff08;Do It For You&#xff09;是一种自动化工具或服务&#xff0c;旨在帮助用户简化操作&#xff0c;减少繁琐的手动操作&#xff0c;提升工作效率。通过DIFY&#xff0c;用户能够快速完成任务、获取所需数据&#xff0c;并且可以…

【深度学习】布匹寻边:抓边误差小于3px【附完整链接】

布匹寻边 项目简介 布匹寻边是指布料裁剪过程中&#xff0c;通过AI寻边技术自动识别布匹的边缘&#xff0c;将检测到的边缘信息输出&#xff0c;确保裁剪的准确性&#xff0c;减少浪费&#xff0c;并提高生产效率。 项目需求 将打满针眼的布匹边缘裁剪掉&#xff0c;且误差小…

http range 下载大文件分片

摘自&#xff1a;https://www.jianshu.com/p/32c16103715a 上传分片下载也能分 HTTP 协议范围请求允许服务器只发送 HTTP 消息的一部分到客户端。范围请求在传送大的媒体文件&#xff0c;或者与文件下载的断点续传功能搭配使用时非常有用。 检测服务器端是否支持范围请求 假…

解决WordPress出现Fatal error: Uncaught TypeError: ftp_nlist()致命问题

错误背景 WordPress版本&#xff1a;wordpress-6.6.2-zh_CN WooCommerce版本&#xff1a;woocommerce.9.5.1 WordPress在安装了WooCommerce插件后&#xff0c;安装的过程中没有问题&#xff0c;在安装完成后提示&#xff1a; 此站点遇到了致命错误&#xff0c;请查看您站点管理…

用户使用LLM模型都在干什么?

Anthropic 对用户与 Claude 3.5 Sonnet 的大量匿名对话展开分析&#xff0c;主要发现及相关情况如下&#xff1a; 使用用途分布 软件开发主导&#xff1a;在各类使用场景中&#xff0c;软件开发占比最高&#xff0c;其中编码占 Claude 对话的 15% - 25%&#xff0c;网页和移动应…

【巨实用】Git客户端基本操作

本文主要分享Git的一些基本常规操作&#xff0c;手把手教你如何配置~ ● 一个文件夹中初始化Git git init ● 为了方便以后提交代码需要对git进行配置&#xff08;第一次使用或者需求变更的时候&#xff09;&#xff0c;告诉git未来是谁在提交代码 git config --global user.na…

腾讯云AI代码助手编程挑战赛:自动生成漂亮的网页

在当今数字化时代&#xff0c;网页设计和开发已经成为一项至关重要的技能。在当今时代&#xff0c;借助AI的力量&#xff0c;这部分工作变得简单。本文借助腾讯云AI代码助手——“自动生成需要的网页”。本文将详细介绍如何利用AI代码助手生成网页素材&#xff0c;帮助你轻松打…

多台PC共用同一套鼠标键盘

当环境中有多个桌面 pc 需要操作的时候&#xff0c;在 多台 pc 之间切换会造成很多的不方便 可以通过远程进行连接&#xff0c;但是有一个更好的方案是让多台机器之间共用同一套键盘鼠标 常用的解决方案 synergy 和 sharemouse&#xff0c;通过移动光标在不同的 pc 间切换 s…

UOS系统mysql服务安装

UOS系统mysql服务安装 背景 1、安装环境&#xff1a;kvm虚拟机2、运行环境&#xff1a;uos server-1060e3、架构&#xff1a;x864、安装mysql版本&#xff1a;mysql-5.71、安装准备 # Mysql官网 https://downloads.mysql.com/archives/community/ # 下载安装包 wget -i -c …

Binlog实现MySQL主从同步

主从复制原理 ● Master 数据库只要发生变化&#xff0c;立马记录到Binary log 日志文件中 ● Slave数据库启动一个I/O thread连接Master数据库&#xff0c;请求Master变化的二进制日志 ● Slave I/O获取到的二进制日志&#xff0c;保存到自己的Relay log 日志文件中。 ● Sla…

matlab离线安装硬件支持包

MATLAB 硬件支持包离线安装 本文章提供matlab硬件支持包离线安装教程&#xff0c;因为我的matlab安装的某种原因&#xff08;破解&#xff09;&#xff0c;不支持硬件支持包的安装&#xff0c;相信也有很多相同情况的朋友&#xff0c;所以记录一下我是如何离线安装的&#xff…

C#进阶-在Ubuntu上部署ASP.NET Core Web API应用

随着云计算和容器化技术的普及&#xff0c;Linux 服务器已成为部署 Web 应用程序的主流平台之一。ASP.NET Core 作为一个跨平台、高性能的框架&#xff0c;非常适合在 Linux 环境中运行。本篇博客将详细介绍如何在 Linux 服务器上部署 ASP.NET Core Web API 应用&#xff0c;包…