diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..76028a3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "package"] + path = package + url = git@git.wm-app.xyz:Zverse/ai-plugin-fe-basic.git diff --git a/index.html b/index.html index f94d3a3..735fc42 100644 --- a/index.html +++ b/index.html @@ -21,6 +21,6 @@
- + diff --git a/package b/package new file mode 160000 index 0000000..3b85508 --- /dev/null +++ b/package @@ -0,0 +1 @@ +Subproject commit 3b855086ecb55a0c54b45b4688adb11913e1e234 diff --git a/package.json b/package.json index 870599f..7f4825b 100644 --- a/package.json +++ b/package.json @@ -58,5 +58,6 @@ "typescript": "^5.2.2", "vite": "^5.0.8", "vite-plugin-make-offline": "^1.0.0" - } + }, + "packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72" } diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index c44a725..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import {ConfigProvider} from 'antd'; -import zhCN from 'antd/locale/zh_CN'; -import './assets/App.less' -import AppRoutes from "./routes"; -import {Suspense, useEffect} from "react"; -import {useUserinfoStore} from "./service/userinfoStore.ts"; -import {useBridge} from "@/core/bridge.ts"; -import {ApplicationInfo} from "@/core/config.ts"; - - -function App() { - const {initialized, init} = useUserinfoStore() - const {getAppInfo} = useBridge() - - const initAppData = async () => { - document.body.oncontextmenu = () => false; - console.log(`APP-BUILD-AT: ${ApplicationInfo.buildVersion}`,ApplicationInfo) - try{ - const info = await getAppInfo() - console.log(`start GetAppVersion`,info) - ApplicationInfo.platformVersion = info.version; - ApplicationInfo.platform = info.platform; - ApplicationInfo.environment = info.environment; - ApplicationInfo.deviceId = info.deviceId; - }catch (e){ - console.log(`start GetAppVersion error`,e) - } - const logged = await init(); - console.log('init user data finished!logged =>', logged) - } - useEffect(() => {initAppData().catch(e=>console.log(e));}, []); - - return ( - -
- - {initialized && } - -
-
- ) -} - -export default App diff --git a/src/assets/App.less b/src/assets/App.less deleted file mode 100644 index 6cf1b4c..0000000 --- a/src/assets/App.less +++ /dev/null @@ -1,337 +0,0 @@ -.test-age { - max-width: 90%; - margin: auto; - height: 100vh; - overflow: hidden; - width: 400px; - - .box-container { - border: solid 3px var(--primary-color); - height: 600px; - overflow: hidden; - } - - .row-item { - line-height: 50px; - text-align: center; - border-bottom: solid 1px #eee; - - &:hover { - background-color: #fafafa; - } - - &:last-child { - border-bottom: none; - } - - &.active-item { - background-color: #efefef; - } - } -} - -.proofread-panel-container { - .proofread-item { - border-radius: 4px; - margin-bottom: 10px; - padding: 18px 24px; - cursor: pointer; - transition: height 0.2s; - margin-left: 0; - position: relative; - background-color: #efefef; - display: flex; - align-items: center; - justify-content: space-between; - - &.processed { - background-color: #fff; - outline: solid 1px #f5f5f5; - } - - &:before { - content: ' '; - background: var(--proofread-color,#fd6643 ); - position: absolute; - left: 0px; - top: 0px; - bottom: 0px; - width: 4px; - border-radius: 4px 0 0 4px; - } - .description { - overflow: hidden; - line-height: 20px; - font-size: 12px; - //display: grid; - //grid-template-rows: 0fr; - //transition: grid-template-rows ease 1s; - height: 0; - interpolate-size: allow-keywords; - transition: height ease 0.5s; - } - .item-description{ - word-break: break-all; - margin-top: 10px; - span{ - display: inline; - } - } - .description-item-container{ - overflow: hidden; - } - - &.select { - //box-shadow: 0 0 8px rgba(0, 0, 0, 0.3); - box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05), 0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12); - - margin-bottom: 20px; - background-color: #fff; - border-color: #efefef; - - outline: 1px solid #efefef; - - .description { - //display: block; - //grid-template-rows: 1fr; - height: auto; - } - } - } - - &.v3 { - - - .proofread-item { - display: block; - } - - .processed-wrapper { - font-size: 13px; - - .state-accept { - color: var(--primary-process-color, #aaaaaa); - margin-top: 4px; - white-space: nowrap; - margin-left: 2px; - } - } - - .action { - - .btn, .more-action { - margin-top: 10px; - white-space: nowrap; - width: auto; - display: inline-block; - padding: 0 10px; - height: 26px; - line-height: 26px; - color: white; - border: solid 1px var(--primary-color); - background-color: var(--primary-color); - &:hover { - background-color: #fff !important; - color: var(--primary-color) !important; - } - } - } - } -} - -.state-filter-tab { - margin-top: 10px; - padding-right: var(--type-width); - - .tab-wrapper { - display: flex; - justify-content: center; - } - - .tab-item { - border-bottom: none; - height: 40px; - line-height: 38px; - width: 90px; - text-align: center; - border-radius: 4px 4px 0 0; - margin-right: 7px; - cursor: pointer; - position: relative; - font-size: 16px; - &:after{ - content: ' '; - position: absolute; - left: 0; - right: 0; - bottom: 1px; - background: rgba(0,0,0,0); - height: 4px; - border-radius: 10px; - } - - &.active { - font-weight: bold; - color: var(--primary-color); - &:after{ - background: var(--primary-color); - } - } - - &:hover { - background-color: #fff; - border-color: #d9d9d9; - } - .tab-item-count{ - font-size: 14px; - } - } -} - -.proofread-loading-wrapper { - position: fixed; - z-index: 999; - background: center bottom no-repeat #f5f5f5; - background-size: contain; - font-size: 16px; - min-height: 40px; - - .display-control-btn{ - position: absolute; - right: 10px; - top:10px; - background: #ffffff; - border-radius: 4px; - padding: 3px 4px 3px 3px; - display: flex; - transform: rotate(180deg); - cursor: pointer; - border: solid 1px #fff; - &:hover{ - border-color: var(--primary-color); - } - svg{ - transform: translateY(1px); - } - &.hide{ - transform: rotate(0); - } - } - &.full-screen { - inset: 0; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - } - - &.bottom { - left: 10px; - right: 70px; - bottom: 10px; - border-radius: 4px; - font-size: 14px; - font-weight: 600; - background: linear-gradient(90.87deg, rgba(236, 220, 188, 0.9) 26.04%, rgba(240, 219, 178, 0.7) 60.98%, rgba(249, 235, 207, 0.7) 99.6%); - padding: 0 20px; - - .progress-bar-container { - width: 100%; - border: solid 1px rgba(214, 170, 105, 0.6); - } - - .progress-bar { - border-radius: 4px 0 0 4px; - background: rgba(214, 170, 105, 0.6); - } - } - - .progress-container { - margin: 15px 0; - - p { - margin-top: 10px; - color: #000; - } - } - - .progress-value { - margin-bottom: 5px; - } - - .progress-bar-container { - --bg-bar: no-repeat linear-gradient(rgba(202, 161, 101, 1) 0 0); - --bg: linear-gradient(90.87deg, #ECDCBC 26.04%, #F0DBB2 60.98%, #F9EBCF 99.6%); - border-radius: 4px; - overflow: hidden; - width: 200px; - background: var(--bg); - } - - .progress-bar { - height: 6px; - width: 0; - background: var(--bg-bar); - transition: width 0.1s; - border-radius: 4px; - - &.loading { - position: relative; - overflow: hidden; - background: none; - width: 100%; - - &:before, &:after { - content: ' '; - width: auto; - display: block; - background: var(--bg-bar); - border-radius: 4px; - left: 0; - bottom: 0; - top: 0; - position: absolute; - transition: transform 0.2s linear; - transform-origin: left; - animation: progress-bar-loading 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; - } - - &:after { - animation: progress-bar-loading-1 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.1s infinite; - } - } - } - - .waiting-tips { - margin: 20px 0; - color: rgba(89, 89, 89, 1); - } - - .ant-btn { - padding: 0; - margin: 0; - - span { - text-decoration: underline; - color: #000; - } - } -} - -.list-container { - padding: 10px; - .list-item { - cursor: pointer; - padding: 10px 20px; - border-radius: 4px; - - &:hover { - background-color: #efefef; - } - - &.active { - color: #fff; - background-color: #c9a063; - } - } -} \ No newline at end of file diff --git a/src/assets/icons/history.svg b/src/assets/icons/history.svg deleted file mode 100644 index 7df0dee..0000000 --- a/src/assets/icons/history.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/assets/icons/logo.svg b/src/assets/icons/logo.svg deleted file mode 100644 index 28fb4c6..0000000 --- a/src/assets/icons/logo.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/assets/icons/logo_no_text.svg b/src/assets/icons/logo_no_text.svg deleted file mode 100644 index a39dcd0..0000000 --- a/src/assets/icons/logo_no_text.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/assets/icons/save.svg b/src/assets/icons/save.svg deleted file mode 100644 index ae85978..0000000 --- a/src/assets/icons/save.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/icons/view.svg b/src/assets/icons/view.svg deleted file mode 100644 index 63ccd40..0000000 --- a/src/assets/icons/view.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/index.less b/src/assets/index.less deleted file mode 100644 index b32effc..0000000 --- a/src/assets/index.less +++ /dev/null @@ -1,174 +0,0 @@ -:root { - scroll-behavior: smooth; - font-family: -apple-system,pingfang, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - --bar-height: 50px; - user-select: none; - overflow: hidden; - //scrollbar-gutter: stable; - - --primary-golden-color: rgba(214, 170, 105, 1); - --primary-color: #D6AA69; - --primary-disabled-color: #D9D9D9; - --primary-process-color: #aaaaaa; - - --action-btn-radius: 2px; -} - -::-webkit-scrollbar { - width: 3px; -} - -::-webkit-scrollbar-thumb { - background: #999; - height: 10px; - border-radius: 5px; - - &:hover { - background: #666; - cursor: pointer; - } -} - -::-webkit-scrollbar-track { - background: #f0f0f0; - border-radius: 5px; -} -.container-overflow-auto{ - overflow: auto; - scrollbar-gutter: stable; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - background: #fff; - min-height: 100vh; -} -.full-width{ - width: 100%; -} -.fz-small{ - font-size: 14px; -} -.text-tip{ - color: #999; -} -.text-link{ - cursor: pointer; - color: #000; - text-decoration: underline; -} -.text-link-blue{ - cursor: pointer; - color: #558CB7 !important; -} -.pointer{ - cursor: pointer; -} -.relative { - - position: relative; -} - - -.ml-2 { - margin-left: 2px; -} -.d-flex { - display: flex; -} -.space-between{ - justify-content: space-between; -} -.text-center { - text-align: center; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-justify { - text-align: justify; -} - -.align-start { - .d-flex; - user-select: text; - align-items: start; -} -.justify-between { - justify-content: space-between; -} -.justify-center { - justify-content: center; -} - -.align-end { - .d-flex; - align-items: end; -} - -.align-center,.item-center { - .d-flex; - align-items: center; -} - -.flex-1 { - flex: 1; -} -.ai-proofread-top { - margin-block-start: calc(var(--bar-height) + 10px); -} -.btn-golden.ant-btn-primary{ - box-shadow: none; - background: linear-gradient(270deg, #CAA266 0%, #E9C57E 100%); - &:not(:disabled):not(.ant-btn-disabled):hover{ - background: linear-gradient(270deg, #CAA266 0%, #CAA266 100%); - } -} -.text-blank-space{ - min-width: 12px; - white-space: pre-wrap; - display: inline !important; - //&:after{ - // content: ' '; - //} -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } -} -@media (prefers-color-scheme: dark) { - :root { - color: #213547; - background-color: #ffffff; - } -} diff --git a/src/components/Dot.tsx b/src/components/Dot.tsx deleted file mode 100644 index 3aedc70..0000000 --- a/src/components/Dot.tsx +++ /dev/null @@ -1,33 +0,0 @@ -// material-ui -import {CSSObject} from '@mui/material/styles'; -import {Box} from '@mui/material'; - -// project import - -interface Props { - color?: string; - bgColor?: string; - size?: number; - variant?: string; - sx?: CSSObject; -} - -const Dot = ({size, variant, sx, bgColor,color}: Props) => { - const main = '#f00' - return ( - - ); -}; - -export default Dot; diff --git a/src/components/app/title-bar.less b/src/components/app/title-bar.less deleted file mode 100644 index f22dfe3..0000000 --- a/src/components/app/title-bar.less +++ /dev/null @@ -1,28 +0,0 @@ -.win-app-title-bar{ - user-select: none; -} -.app-title-bar{ - display: flex; - align-items: center; - justify-content: space-between; - height: var(--bar-height); - background-color: #eee; - overflow: hidden; - position: fixed; - left:0;right:0;top:0; - padding: 0 10px 0 20px; - z-index: 9999; - //box-shadow: 0 0 5px rgba(0,0,0,0.7); - // - &.show-bar-border{ - border-bottom: solid 1px rgba(181, 181, 181, 0.5); - } - .app-close-btn{ - &:hover{ - background-color: rgba(0,0,0,0.05) !important; - } - } -} -.app-title-bar-placeholder{ - height: var(--bar-height); -} \ No newline at end of file diff --git a/src/components/app/title-bar.tsx b/src/components/app/title-bar.tsx deleted file mode 100644 index 89332c3..0000000 --- a/src/components/app/title-bar.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from "react"; -import {createPortal} from "react-dom" -import {Button} from "antd"; -import {CloseOutlined} from "@ant-design/icons"; -import './title-bar.less' - -export type AppTitleBarProps = { - title?: React.ReactNode; - bordered?: boolean; - backgroundColor?: string; - closeSize?: string | number; - className?:string; - onClose?:()=>void; -} -export const AppTitleBar: React.FC = ({title,className,onClose, backgroundColor, closeSize = 16, bordered = true}) => { - const onMouseDown = (evt: React.MouseEvent) => { - chrome.webview.hostObjects.sync.event.MouseDownDrag(); - evt.preventDefault(); - // evt.stopPropagation(); - } - return createPortal(( -
{ - e.stopPropagation(); - e.preventDefault(); - }}> -
-
{title}
- -
-
-
- ), document.querySelector('#app_ext')!) -} \ No newline at end of file diff --git a/src/components/messages/Modal.tsx b/src/components/messages/Modal.tsx deleted file mode 100644 index 9dbf313..0000000 --- a/src/components/messages/Modal.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import {Button, Checkbox, Input, Modal, Space, message, App} from "antd"; -import React, {useState} from "react"; -import {useSetState} from "ahooks"; - -export type ModalOptions = { - content?: React.ReactNode, - title?: React.ReactNode, -} - -message.config({ - prefixCls:'ai-proofread' -}) - -export const showModal = (opt: ModalOptions) => { - Modal.confirm({ - title: opt.title, - content: opt.content, - onOk() { - console.log('OK'); - }, - onCancel() { - console.log('Cancel'); - }, - }) -} - -export function useAlert() { - const {modal} = App.useApp() - return { - show(content: React.ReactNode, width = 300, afterClose?: () => void,title?:string) { - modal.info({ - content, - title, - className: 'aui-alert', - icon: null, - width, - onOk: afterClose - }); - } - } -} - -export function useLoading() { - const {message} = App.useApp() - const key = Math.random().toString(16).substring(2); - return { - show(content = 'loading...') { - message.open({ - type: 'loading', - content, - duration: 0, - key - }).then() - }, - close() { - message.destroy(key) - } - } -} - - -export function showToast(content: string, type?: 'success' | 'info' | 'warning' | 'error',duration?:number) { - - message.open({ - type, - content, - className: 'aui-toast', - duration, - }).then(); -} - -type ConfirmOptions = { - content?: string; - onYes?: (hideNextNotice?: boolean) => void; - onNo?: () => void; - yesText?: string; - noText?: string; - title?: string; - showNextAsk?: boolean; -} - -export function useConfirm() { - const [opts, setOpts] = useState({}) - const [open, setOpen] = useState(false) - const [checked, setChecked] = useState(false) - const confirmHolder = ( - { - setOpen(false); - opts.onNo?.() - }} - rootClassName="aui-custom-modal" - footer={
-
- {opts.showNextAsk && { - setChecked(e.target.checked) - }}>不再提醒} -
- - - - -
} - > -
- {opts.content} -
-
- ) - return { - confirmHolder, - showConfirm: (opts: ConfirmOptions) => { - setOpts(opts) - setOpen(true) - } - } -} - -type PromptOptions = { - title?: string; - defaultValue?: string; - placeholder?: string; - required?: boolean; - onOK?: (value: string) => void; -} - -export function usePrompt() { - const [opt, setOpt] = useSetState({}) - const [open, setOpen] = useState(false) - const [value, setValue] = useState('') - - const promptHolder = ( - { - setOpen(false) - }} - onOk={() => { - setOpen(false); - opt.onOK?.(value) - }} - > - setValue(e.currentTarget.value)} - placeholder={opt.placeholder || '请输入'} - /> - - ) - return { - promptHolder, - show(option: PromptOptions) { - setOpt(option) - setValue(option.defaultValue || '') - setOpen(true) - // return new Promise((resolve) => { - // options.resolve = resolve - // }) - } - } -} diff --git a/src/components/pagination/index.tsx b/src/components/pagination/index.tsx deleted file mode 100644 index ce623f1..0000000 --- a/src/components/pagination/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; -import {Button, Empty, Pagination as AntPage} from "antd" -import {TPaginationResult} from "@/service/types/base.ts"; - -type TPagination = { - param?: TPaginationResult; - className?: string; - defaultCurrent?: number; - onPageChange?: (page: number) => void; - emptyText?: string | null; - onEmptyReLoadClick?: () => void; - emptyReLoadText?: string; -} -export const Pagination: React.FC = (props) => { - return props.param && props.param.total > 0 ? ( - - ) : (props.emptyText === null ? null : ({props.onEmptyReLoadClick && - })) -} diff --git a/src/components/popover/dropdown-menu.tsx b/src/components/popover/dropdown-menu.tsx deleted file mode 100644 index 6f207b2..0000000 --- a/src/components/popover/dropdown-menu.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React from "react"; -import {Dropdown, Popover} from "antd"; -import {cx} from "@emotion/css"; -import {CheckOutlined} from "@ant-design/icons"; - - -export type PopoverMenuItems = { - type?: 'divider' | 'title' | string; - label?: string; - render?: React.ReactNode; - icon?: React.ReactNode; - key?: string; - checked?: boolean; -} -export type PopoverMenuProps = { - items: PopoverMenuItems[] - open?: boolean; - theme?: 'dark' | 'light'; - children?: React.ReactNode; - onItemClick?: (item: PopoverMenuItems) => void; - itemClassName?: string; - showCheckBox?: boolean; -} - -export const PopoverMenu: React.FC = (props) => { - return ( - {props.items && props.items.map((it, index) => ( - it.type == 'divider' ?
:
{ - props.onItemClick && it.type != 'title' && props.onItemClick(it) - }} - > - {props.showCheckBox && {it.checked && }} -
- {it.icon} - {it.render || it.label} -
-
- ))} - }> - {props.children} -
) -} - -export type DropDownMenuItem = { - disabled?: boolean; - danger?: boolean; - icon?: React.ReactNode; - title?: string; - type?: 'divider' | 'title' | string; - label?: string; - key?: string; - theme?: 'dark' | 'light'; - children?: DropDownMenuItem[]; - onClick?: () => void; -} -export type DropdownMenuProps = { - items: DropDownMenuItem[] - open?: boolean; - theme?: 'dark' | 'light'; - children?: React.ReactNode; - onItemClick?: (item: DropDownMenuItem) => void; - inToolbar?:boolean; - className?:string; - itemClassName?: string; - placement?: "topLeft" | "topCenter" | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight" | "top" | "bottom"; - selectable?: boolean; - selectedKey?: string; -} -// 通用popover下拉菜单 -export const DropdownMenu: React.FC = (props) => { - const onClick = ({key}: { key: string }) => { - const item = props.items.find(it => it.key == key); - if (!item) { - return; - } - if (!item.onClick) { - props.onItemClick?.(item) - } - } - return ( - {props.children} - ) -} diff --git a/src/components/test/index.tsx b/src/components/test/index.tsx deleted file mode 100644 index 71661da..0000000 --- a/src/components/test/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import {useSetState} from "ahooks"; -import {useNavigate} from "react-router-dom"; -import {useDemoStore} from "../../core/use-demo-store.ts"; -import {Alert, Button, Space} from "antd"; - -export function Test(){ - const [state, setState] = useSetState({ - warning: false - }) - const navigate = useNavigate(); - const {view} = useDemoStore() - const startProofread = () => { - setState({warning: true}) - } - return <> -

Home

- - - - - {state.warning &&
- setState({warning: false})}/> -
} -
- {JSON.stringify(view)} -
- -} \ No newline at end of file diff --git a/src/core/bridge.ts b/src/core/bridge.ts deleted file mode 100644 index 93325bd..0000000 --- a/src/core/bridge.ts +++ /dev/null @@ -1,69 +0,0 @@ -import {DependencyList, useEffect} from "react"; - -type NoticeDataType = { - action: string; - data?: any; -} - -// type HostBridge = { -// showDialog: (message: string) => void; -// loginSuccess: (userinfo: string|Account) => void; -// noticeOtherWeb: (data: string, target: string | null) => Promise; -// getAllText: () => Promise; -// } - -export const bridge: HostBridge = chrome.webview?.hostObjects.bridge; - -export const useBridge = () => { - return { - bridge, - showView: (url:string, width:number, height:number, dialog:boolean)=>{ - url = `${location.origin}${url}` - bridge.ShowWebView(url,Math.ceil(width * window.devicePixelRatio),Math.ceil(height * window.devicePixelRatio),dialog); - }, - getAppInfo: async () => { - const res = await bridge.GetAppVersion() - if(/^\d+(\.\d+){1,2}$/.test(res)){ - return { - version: res, - platform: 'wps', - environment: 'Windows', - deviceId:'' - } - } - return JSON.parse(res) as AppPluginInfo - }, - noticeOtherWeb: (params: string | NoticeDataType, target: string | null = null) => { - if (typeof params == "object") { - params = JSON.stringify(params) - } - return bridge.noticeOtherWeb(params, target) - } - } -}; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-expect-error -window.bridge_ext = { - bridge, - markSentence: (content:string) => { - bridge.MarkSentence(content,0).then((res)=>{ - console.log('标记成功',res) - }) - } -} - -export function useBridgeMessageListener(listener: (params: WebMessage) => void,deps?: DependencyList) { - const onBridgeMessage = (e: MessageEvent) => { - listener(e.data); - } - - useEffect(() => { - // 添加消息事件监听 - chrome.webview?.addEventListener('message', onBridgeMessage) - return () => { - // 移除消息事件 - chrome.webview?.removeEventListener('message', onBridgeMessage) - } - }, deps || []) -} \ No newline at end of file diff --git a/src/core/cache.ts b/src/core/cache.ts deleted file mode 100644 index dae6a29..0000000 --- a/src/core/cache.ts +++ /dev/null @@ -1,54 +0,0 @@ -// 数据 主要是保存当前文档id -import {AppUpgradeInfo} from "@/service/types/settings.ts"; - -export const CACHE_DATA: { - wordCount: number; - state: 'ready' | 'proofreading' | 'finish'; - proofreadMode?: 'full' | 'exact' | string; - DocumentID: number; - correctId: number; - selectId: number; - selectStatus: 1 | 2 | 3; - timer: number | null | undefined | object | object; - progress_timer: number | null | undefined | object | object; - progress_count: number; - userinfo?: Account; - upgradeInfo: AppUpgradeInfo; - clearTimer: () => void; - clearProgressTimer: () => void; - currentSentenceList: V3.ProofreadSentence[]; - originData: { - [key: number]: V3.OriginDataInfo - } -} = { - state: 'ready', - DocumentID: 0, - wordCount: 0, - correctId: 1, - selectId: -1, - selectStatus: 1, - userinfo: undefined, - upgradeInfo: {}, - timer: null, - progress_timer: null, - progress_count: 0, - currentSentenceList: [], - originData: {}, - clearProgressTimer: () => { - console.log('clearProgressTimer') - if (CACHE_DATA.progress_timer) { - clearInterval(Number(CACHE_DATA.progress_timer)) - } - CACHE_DATA.progress_timer = 0; - CACHE_DATA.progress_count = 0; - }, - clearTimer: () => { - if (CACHE_DATA.timer) { - clearTimeout(Number(CACHE_DATA.timer)) - CACHE_DATA.timer = null; - } - } -} - - -export const SentenceListCache: V3.ProofreadSentence[] = []; \ No newline at end of file diff --git a/src/core/config.ts b/src/core/config.ts deleted file mode 100644 index 7a6f1fc..0000000 --- a/src/core/config.ts +++ /dev/null @@ -1,23 +0,0 @@ -export const ApplicationInfo = { - version: AppVersion.version, - buildVersion: AppVersion.buildVersion, - platform: AppVersion.platform, - platformVersion: AppVersion.platformVersion, - environment: 'Dev', - deviceId: '' -} - -export const ProofreadModelConfig:{ - [key:string]:{ - name:string;id:string - } -} = { - exact: { - name:'优先查准', - id:'xt-20250305183041-correct' - }, - full:{ - name:'优先查全', - id:'xt-20250305183041-allround' - } -} \ No newline at end of file diff --git a/src/core/device-id.ts b/src/core/device-id.ts deleted file mode 100644 index 90e3037..0000000 --- a/src/core/device-id.ts +++ /dev/null @@ -1,87 +0,0 @@ -// 缓存设备id -import FingerprintJS from "@fingerprintjs/fingerprintjs"; -import md5 from "crypto-js/md5" - -const CACHE = { - deviceId: localStorage.getItem('ai_office_device_id') -} - -function getCanvasFingerprint() { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - if (!ctx) { - return md5(navigator.userAgent).toString(); - } - canvas.width = 2000 - canvas.height = 200 - canvas.style.display = 'inline' - ctx.rect(0, 0, 10, 10) - ctx.rect(2, 2, 6, 6) - //result.canvasWinding = ((ctx.isPointInPath(5, 5, 'evenodd') === false) ? 'yes' : 'no'); - - ctx.textBaseline = 'alphabetic' - ctx.fillStyle = '#f60' - ctx.fillRect(125, 1, 62, 20) - ctx.fillStyle = '#069' - ctx.font = '11pt Arial' - ctx.fillText('Cwm fjordbank glyphs vext quiz, \ud83d\ude03', 2, 15) - ctx.fillStyle = 'rgba(102, 204, 0, 0.2)' - ctx.font = '18pt Arial' - ctx.fillText('Cwm fjordbank glyphs vext quiz, \ud83d\ude03', 4, 45) - ctx.globalCompositeOperation = 'multiply' - ctx.fillStyle = 'rgb(255,0,255)' - ctx.beginPath() - ctx.arc(50, 50, 50, 0, Math.PI * 2, true) - ctx.closePath() - ctx.fill() - ctx.fillStyle = 'rgb(0,255,255)' - ctx.beginPath() - ctx.arc(100, 50, 50, 0, Math.PI * 2, true) - ctx.closePath() - ctx.fill() - ctx.fillStyle = 'rgb(255,255,0)' - ctx.beginPath() - ctx.arc(75, 100, 50, 0, Math.PI * 2, true) - ctx.closePath() - ctx.fill() - ctx.fillStyle = 'rgb(255,0,255)' - ctx.arc(75, 75, 75, 0, Math.PI * 2, true) - ctx.arc(75, 75, 25, 0, Math.PI * 2, true) - ctx.fill('evenodd') - return md5(canvas.toDataURL()).toString().replace( - /^(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})$/i, - '$1-$2-$3-$4-$5' - ) -} - -const DEVICE_ID_KEY = 'ai_office_device_id' - -function saveDeviceId(deviceId: string){ - CACHE.deviceId = deviceId - localStorage.setItem(DEVICE_ID_KEY, CACHE.deviceId) -} -function calcDeviceId() { - if (!CACHE.deviceId) { - const deviceId = localStorage.getItem(DEVICE_ID_KEY) - if(deviceId){ - CACHE.deviceId = deviceId - return - } - // 如果缓存中没有设备id则获取指纹作为设备id - FingerprintJS.load().then(ret => { - ret.get().then((ret) => { - saveDeviceId(ret.visitorId) - }) - }) - } -} - -// 计算设备id -calcDeviceId(); -export function getDeviceId() { - if(!CACHE.deviceId){ - CACHE.deviceId = getCanvasFingerprint() - saveDeviceId(CACHE.deviceId) - } - return CACHE.deviceId; -} \ No newline at end of file diff --git a/src/core/proofread-queue.ts b/src/core/proofread-queue.ts deleted file mode 100644 index a575c09..0000000 --- a/src/core/proofread-queue.ts +++ /dev/null @@ -1,127 +0,0 @@ -import {bridge} from "@/core/bridge.ts"; -import {CACHE_DATA} from "@/core/cache.ts"; -import GovInfo = V3.GovInfo; - -/** - * 队列信息 - */ -const QUEUE_INFO: { - state: 'initial' | 'pause' | 'marking' | 'ended'; - list: V3.ProofreadSentence[]; - govExtra: { - [key:string]: GovInfo[] - }, - confusionNotice: { - [key:string]: string - }; - correctId: number[]; - index: number; -} = { - state: 'initial', - govExtra: {}, - confusionNotice: {}, - list: [], - correctId: [], - index: 0, -} - -/** - * 初始化队列信息 - */ -export function init() { - QUEUE_INFO.list = []; - QUEUE_INFO.govExtra = {}; - QUEUE_INFO.confusionNotice = {}; - QUEUE_INFO.correctId = []; - QUEUE_INFO.index = 0; - QUEUE_INFO.state = 'initial'; - return QUEUE_INFO; -} - -/** - * 获取队列信息 - */ -export function getQueue() { - return QUEUE_INFO; -} - -export function getQueueItem(count: number) { - const list: V3.ProofreadSentence[] = []; - for (let i = 0; i < count; i++) { - if (QUEUE_INFO.index >= QUEUE_INFO.list.length) { - break; - } - list.push(QUEUE_INFO.list[QUEUE_INFO.index]) - QUEUE_INFO.index++; - } - return list; -} - -// 获取当前处理句子 -export function getCurrent() { - return QUEUE_INFO.list[QUEUE_INFO.index]; -} - -export function pause() { - QUEUE_INFO.state = 'pause'; -} - -export function resume() { - if (QUEUE_INFO.state !== 'pause') return; - QUEUE_INFO.state = 'marking'; - processCurrentSentence(); -} - -export function end() { - QUEUE_INFO.state = 'ended'; - QUEUE_INFO.index = QUEUE_INFO.list.length; -} - -// 处理当前队列的句子 -export function processCurrentSentence() { - if (QUEUE_INFO.state !== 'marking') return; - if (QUEUE_INFO.index >= QUEUE_INFO.list.length) { - QUEUE_INFO.state = 'ended' - return; - } - // 每次取5个句子进行标记 - const list = getQueueItem(5) - // 提交句子到word进行标记 - try { - // console.log('mark sentence ===> ', list) - bridge.MarkSentence(JSON.stringify(list), CACHE_DATA.DocumentID) - .then(() => { - processCurrentSentence() - }) - .catch(e => { - console.log(e) - processCurrentSentence() - }) - } catch (e) { - console.log('MarkSentence==>', e) - } - - // const sentence = getCurrent(); - // setTimeout(() => { - // console.log('sentence', sentence.insert) - // }, 800) -} - -/** - * 添加到队列 - * @param sentence - */ -export function push(sentence: V3.ProofreadSentence) { - // 判断数据是否重复 - // 添加到队列中 - QUEUE_INFO.list.push(sentence); - // 判断状态是未开始 - if (QUEUE_INFO.state === 'marking') { - return; - } - - // 状态改为标记中 - QUEUE_INFO.state = 'marking'; - // 处理当前句子 - processCurrentSentence() -} diff --git a/src/core/proofread-util.ts b/src/core/proofread-util.ts deleted file mode 100644 index a1789c5..0000000 --- a/src/core/proofread-util.ts +++ /dev/null @@ -1,174 +0,0 @@ -import {bridge} from "@/core/bridge.ts"; -import {V3Enums} from "@/types/v3/enums.ts"; -import {base64Decode} from "@/core/string-utils.ts"; -import {getQueue} from "@/core/proofread-queue.ts"; -import {CACHE_DATA} from "@/core/cache.ts"; - -function findIndexByParagraphAndSentenceNum(searchItem: V3.ProofreadSentence, originList: V3.ProofreadSentence[]) { - const index = originList.findIndex(item => { - // 如果paragraph_num 大于 searchItem.paragraph_num,或者 paragraph_num 相同,sentence_offset 大于 searchItem.sentence_offset,则返回true - return item.paragraph_num > searchItem.paragraph_num || ( - item.paragraph_num === searchItem.paragraph_num && item.sentence_offset! > searchItem.sentence_offset! - ) - }) - // console.log(JSON.stringify(searchItem), index) - return index -} - -export function parseProofreadSentence(sentence: V3.ProofreadSentence) { - // 过滤纯空格删除 - sentence.diffs = sentence.diffs.filter(it=>{ - if(it.tag != 'd') return true; - return it.origin.trim().length > 0; - }); - sentence.diffs.forEach(it => { - if(it.color) return; - const data = V3Enums.ProofreadType[it.type] as V3.ProofreadTypeConfig - if(!it.addition && data){ - it.addition = data.name - } - if(it.type == "incorrect_expression"){ - it.tag = ''; - }else if(it.type == 'blacklist_mask'){ - it.type = 'blacklist'; - it.tag = '' - }else if(it.type == 'blacklist_replace'){ - it.type = 'blacklist'; - it.tag = 'r' - } - it.color = data?.color || '#D6AA69'; //#80D6AA69 #fd6643 - if(data && ['incorrect_expression'].includes(it.type)){ - it.typeName = data.name - } - // - // it.id = CACHE_DATA.correctId ++ ; - }) -} - -/** - * 将proofreadSentence插入到originList中 - * @param sentence - */ -export function buildProofreadSentenceList(sentenceList: V3.ProofreadSentence[], originList: V3.ProofreadSentence[]) { - // 1. 对sentence中的diffs数组根据start进行排序 - // const diffs = sentence.diffs - // .sort((a, b) => a.start - b.start) - // .map(it=>({ - // ...it, - // sentence_offset: sentence.sentence_offset, - // paragraph_num: sentence.paragraph_num - // })) - const queue = getQueue(); - sentenceList.forEach(sentence=>{ - if(!sentence.paragraph_offset){ - const ext = JSON.parse(base64Decode(sentence.ext)) as V3.SentenceExt; - const origin = CACHE_DATA.originData[ext.index] - if(!origin){ - return; - } - // 还原原始段落 - sentence.paragraph_num = origin.paragraph_num; - sentence.paragraph_offset = origin.paragraph_num; - sentence.sentence_offset = sentence.sentence_num; - } - // 判断originList中是否存在相同的offset - const oldItem = originList.find(item => - item.paragraph_num === sentence.paragraph_num - && item.sentence_num === sentence.sentence_num - ); - if (oldItem){ - // 如果新数据和老数据不一致 则新增 - if(oldItem.diffs.length != sentence.diffs.length){ - // 比对差异 并将不存在的数据添加到老的diffs中 - const oldDiffs = oldItem.diffs.map(it=>it.id); - // const newDiffs = sentence.diffs.filter(newItem=>{ - // return !oldItem.diffs.some(oldItem=>oldItem.id === newItem.id) - // }) - sentence.diffs.forEach(it=>{ - // 判断是否已经存在, 并且添加到correctId中 - if(oldDiffs.includes(it.id) || queue.correctId.includes(it.id)) return; - oldItem.diffs.push(it) - queue.correctId.push(it.id) - }) - } - return; - } - // 重新赋值 - sentence.diffs = sentence.diffs.filter(it=>{ - if(it.index.length == 0){ - it.index = '-1' - } - // 判断是否已经存在, 并且添加到correctId中 - if(queue.correctId.includes(it.id)) return false; - queue.correctId.push(it.id) - return true - }); - - sentence.diffs.sort((a, b) => a.start - b.start).forEach(it=>{ - if(typeof(it.addition) == "undefined") it.addition = ''; - }) - // 2. 根据sentence的offset,计算出当前结果在originList中所处的位置 - const index = findIndexByParagraphAndSentenceNum(sentence, originList) - // 3. 根据找到的位置, 将diffs插入到originList中 - //如果index为-1,则说明sentence在originList的最后面,直接插入即可 - if (index === -1) { - originList.push(sentence) - // return [...originList, sentence] - } else { - originList.splice(index, 0, sentence) - } - }) - originList.forEach(sentence=>{ - // 过滤纯粹的空格删除 - sentence.diffs = sentence.diffs.filter(it=> { - if( it.tag == 'd' && (!it.origin || it.origin.trim().length == 0)) return false; - return true; - }) - }) - return originList;//[...originList.slice(0, index), sentence, ...originList.slice(index)] - -} - - -export function parseV3ProofreadResult(sentences: V3.ProofreadSentence[], disabled: number[] = []) { - const list: V3.ProofreadCorrect[] = []; - - const count: { - [key: string]: number - } = { - total: 0 - }; - - try { - // 遍历内容 - sentences.forEach((s) => { - s.diffs.forEach(it => { - if (disabled.includes(it.id)) return; - list.push(it) - if (!count[it.type]) count[it.type] = 0; - count['total']++; - count[it.type]++; - }) - }) - } catch (e) { - console.log('parseV3ProofreadResult=>', e) - } - - return { - list, - count: count as V3.ProofreadCount - } -} - -export async function saveProofreadCache(cache: V3.CacheData,silent: boolean) { - return await bridge.SaveCache(CACHE_DATA.DocumentID, btoa(encodeURIComponent(JSON.stringify(cache))), silent); -} - -export async function loadProofreadCache() { - const res = await bridge.LoadCache(); - const data = JSON.parse(res) as BridgeResult - if (data.code != 0) { - throw new Error(data.message) - } - return JSON.parse(decodeURIComponent(atob(data.data))) as V3.CacheData -} \ No newline at end of file diff --git a/src/core/string-utils.ts b/src/core/string-utils.ts deleted file mode 100644 index 019fe58..0000000 --- a/src/core/string-utils.ts +++ /dev/null @@ -1,62 +0,0 @@ -// import Base64 from 'crypto-js/enc-base64'; -// import Utf8Encode from 'crypto-js/enc-utf8' - -/** - * 判断是否为不可打印字符 - * @param char - */ -export function isInvisibleChar(char: string) { - return char.charCodeAt(0) < 32 || char.charCodeAt(0) == 127; -} - -/** - * 记录并去除掉字符串中不可见字符的位置及对应的字符,然后返回过滤后的字符串及对应不可见字符及位置 - * @param str - */ -export function getAndRemoveInvisibleChars(str: string) { - const invisibleChars: { pos: number, char: string }[] = []; - let newStr = ''; - // let lastPos = 0; - for (let i = 0; i < str.length; i++) { - const char = str[i]; - if (isInvisibleChar(char)) { - invisibleChars.push({pos: i, char}); - } else { - newStr += char;//str.substring(lastPos,i); - // lastPos = i + 1; - } - } - return {newStr, invisibleChars}; -} - -/** - * 判断内容是否为空或空行 - * @param content - */ -export function isBlankOrInvisibleContent(content: string) { - ///^[\x20-\x7E\x7F-\x9F]+$/.test(content) - return !content || content.trim().length === 0 || /^[\x00-\x1F\x7F-\x9F]+$/.test(content); -} - -const FootnoteRegExp = /^\[footnoteRef:\d+\]|\[endnoteRef:\d+\]$/ - -// 判断内容是否时脚注 -export function isFootnote(content: string) { - return FootnoteRegExp.test(content); - //return content.startsWith('[^') && content.endsWith(']'); -} - -/** - * base64编码 - * @param str - */ -export const base64Encode = (data: string) => btoa(encodeURI(data));//Base64.stringify(Utf8Encode.parse(data)).toString(); - -/** - * base64解码 - * @param str - */ -export const base64Decode = (content: string) => decodeURI(atob(content));//Utf8Encode.stringify(Base64.parse(content)); - - -export const stringIsEmpty = (str: string|null|undefined) => !str || str.length === 0; \ No newline at end of file diff --git a/src/core/use-demo-store.ts b/src/core/use-demo-store.ts deleted file mode 100644 index b8bcd76..0000000 --- a/src/core/use-demo-store.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {create} from "zustand"; - -export type ModalStoreType = { - open: boolean; - show: () => void; - hide: () => void; -} -type CommonStoreKeys = 'login' - -type CommonStoreType = { - view: { - [key in CommonStoreKeys]: boolean; - }; - showView: (key: CommonStoreKeys) => void; - hideView: (key: CommonStoreKeys) => void; -} - -export const useDemoStore = create((set, _, _state) => ({ - view: { - login: false - }, - showView: (key: CommonStoreKeys) => { - const view = _state.getState().view; - view[key] = true - set({view}) - }, - hideView: (key: CommonStoreKeys) => { - const view = _state.getState().view; - view[key] = false - set({view}) - } -})) diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..07bba22 --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,23 @@ +import ReactDOM from "react-dom/client"; + +import createApp from "../package/package/index.tsx" + +const HelloWorld = ()=>

Hello world

+console.log(createApp) +const App = createApp([ + { + path: "hello-world", + element: + }, + { + path: "hello-2", + element: + }, + { + path: "hello-3", + element: + } +]) + + +ReactDOM.createRoot(document.getElementById('root')!).render(App) \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx deleted file mode 100644 index d40a255..0000000 --- a/src/main.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import ReactDOM from 'react-dom/client' -import './assets/index.less' -import App from './App.tsx' - -ReactDOM.createRoot(document.getElementById('root')!).render() diff --git a/src/pages/detection/components/ellipsi-paragraph.tsx b/src/pages/detection/components/ellipsi-paragraph.tsx deleted file mode 100644 index e3622d3..0000000 --- a/src/pages/detection/components/ellipsi-paragraph.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, {useEffect, useRef, useState,} from "react"; -import styles from "./style.module.less"; -import markdownit from "markdown-it"; - - -type EllipsisParagraphProps = { - content: string; - className?: string; -} -const md = markdownit() -export default function EllipsisParagraph({content,className}: EllipsisParagraphProps) { - const contentRef = useRef(null); - const [expanded, setExpanded] = useState(false); - const [state, setState] = useState({ - expandVisible: false, - }) - - useEffect(() => { - if (contentRef.current) { - const height = contentRef.current.getBoundingClientRect().height, - scrollHeight = contentRef.current.scrollHeight; - if (scrollHeight > height) { - setState({expandVisible: true,}) - } - } - }, [contentRef]) - - - return (
-
- {state.expandVisible &&
- setExpanded(!expanded)}>{expanded ? '收起' : '展开'} -
} -
) -} \ No newline at end of file diff --git a/src/pages/detection/components/generating.tsx b/src/pages/detection/components/generating.tsx deleted file mode 100644 index 8d08087..0000000 --- a/src/pages/detection/components/generating.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import {Divider, Space} from "antd"; -import React from "react"; - -import styles from "./style.module.less"; -import {DetectionType} from "./types.ts"; -import {cutSummary} from "@/utils/strings.ts"; - -export default function GenerateResult({type,summary,location}:{ - type: DetectionType; - summary?: string; - location?: string; - onGenerated: () => void; -}){ - - return (
- - {(type == DetectionType.All || type == DetectionType.AllError) ? '全文检测' : '段落检测'} - {type == DetectionType.Paragraph && <> - - “{location?`${location}:`:''}{cutSummary(summary)}” - } - - -
-
- 结果生成中... -
-
-
) -} \ No newline at end of file diff --git a/src/pages/detection/components/style.module.less b/src/pages/detection/components/style.module.less deleted file mode 100644 index 835e521..0000000 --- a/src/pages/detection/components/style.module.less +++ /dev/null @@ -1,100 +0,0 @@ -.header { -} - -.page { - background-color: #f5f5f5; - min-height: 100vh; - padding: 0 20px; -} - -.contentContainer { -} - -.noData { - text-align: center; - height: calc(100vh - 100px); - display: flex; - align-items: center; - justify-content: center; -} - -.summaryText { - font-size: 14px; -} - -.listContainer { - max-height: calc(100vh - 80px); - padding-right: 5px; - margin-right: -5px; - overflow: auto; - margin-top: -4px; -} - -.listItem { - padding: 15px 15px; - margin: 15px 0; - background-color: #fff; - border-radius: 3px; - - &:first-child { - margin-top: 5px; - } - - &:last-child { - margin-bottom: 0; - } -} - -.detectionResultContainer { - text-align: justify; - position: relative; -} -.detectionResult{ - line-height: 20px; - height: 60px; - font-size: 14px; - overflow: hidden; - user-select: text; - p,h1,h2,h3,h4,h5,h6,ul,ol,li{ - margin: 0; - font-size: 14px; - } - h1{ - font-size: 16px; - margin-top: 20px; - &:first-child{ - margin-top: 0; - } - } - h2{ - margin-top: 20px; - &:first-child{ - margin-top: 0; - } - } -} -.resultError{ - color: rgba(255, 0, 0, 1); -} - -.contentExpand { - margin-top: 5px; - display: block; - text-align: right; - color: rgba(214, 170, 105, 1); - span{ - cursor: pointer; - font-size: 14px; - } -} - -.expandedBtn { - position: absolute; - right: 0; -} - -.generating { - color: rgba(68, 52, 255, 1); - min-height: 100px; - user-select: none !important; -} \ No newline at end of file diff --git a/src/pages/detection/components/types.ts b/src/pages/detection/components/types.ts deleted file mode 100644 index 9d241b0..0000000 --- a/src/pages/detection/components/types.ts +++ /dev/null @@ -1,7 +0,0 @@ - -export enum DetectionType { - All = 1, - Paragraph = 2, - AllError = 3, - ParagraphError = 4 -} diff --git a/src/pages/detection/sense.tsx b/src/pages/detection/sense.tsx deleted file mode 100644 index f9f362a..0000000 --- a/src/pages/detection/sense.tsx +++ /dev/null @@ -1,238 +0,0 @@ -import {Divider, Empty, Space} from "antd"; -import React, {useEffect, useState} from "react"; - -import {AppTitleBar} from "@/components/app/title-bar.tsx"; -import styles from './components/style.module.less' -import {DetectionType} from "./components/types.ts"; -import EllipsisParagraph from "./components/ellipsi-paragraph.tsx"; -import GenerateResult from "./components/generating.tsx"; -import {useBridge, useBridgeMessageListener} from "@/core/bridge.ts"; -import { getDetectionResult, parseDetectionResult, sendContentToDetection } from '@/service/api/detection.ts'; -import {cutSummary} from "@/utils/strings.ts"; -import {sleep} from "@/utils/sleep.ts"; - -const runCache = { - first: true -} -// 检测状态 -enum DetectionResultStatus { - // 状态需要继续请求(未完成) - Pending = 101, - // result为json格式字符串需要转换成DetectionResult[] - Success = 200, - // 成功状态,未检测到常识性错误 - Correct = 201, - // 400+ 异常 - Error = 400 -} - -type IState = { - generating: boolean; - generateType: DetectionType; - generateSummary: string; - location: string; -} -export default function CommonsenseDetection() { - const detectionApi = chrome.webview.hostObjects.detection; - const {bridge} = useBridge() - const [state, setState] = useState({ - generating: false, - generateType: DetectionType.All, - generateSummary: '', - location: '' - }) - const [detectionHistory, setHistory] = useState([]); - - function saveHistory(prev:IState,result:string,type:DetectionType){ - const item:Detection.DetectionInfo = { - id: detectionHistory.length + 1, - result_content:result, - summary: prev.generateSummary, - location: prev.location, - type, - } - // 重置检测状态 - detectionApi.SetCheckingData(false, '', prev.generateType == DetectionType.All ? '' : prev.generateSummary, '') - //存储结果 - setHistory((list) => [...list, item]) - detectionApi.SetHistory(JSON.stringify(item)); - return {...prev,generating: false, } - } - - - - // 获取检测结果 - const getCheckResult = (key: string,type:number) => { - getDetectionResult(key,type).then((ret) => { - if (ret.status == DetectionResultStatus.Pending) { - // 没有结果 - setTimeout(() => { - getCheckResult(key,type) - }, 5000); - return; - }else { - const result = ret.status == DetectionResultStatus.Success ? parseDetectionResult(ret) : ret.result; - setState(prev => saveHistory(prev,result,prev.generateType)) - } - }).catch(e=>{ - setState(prev => saveHistory(prev,e.message || '常识检测服务异常,请稍后重试',prev.generateType == DetectionType.All ?DetectionType.AllError:DetectionType.ParagraphError)) - }) - } - /** - * 判断是否已经存在检测任务 - */ - const checkExistsTask = async () => { - const ret = JSON.parse(await detectionApi.GetCheckStatus()) as Detection.CheckResult; - if (ret.isChecking) { - const generateType = ret.checkingSummary && ret.checkingSummary.length > 0?DetectionType.Paragraph : DetectionType.All - setState(prev => ({ - ...prev, - generating: true, - generateSummary: ret.checkingSummary, - location: ret.checkingLocation, - generateType, - })) - // 使用缓存的key进行获取检测结果 - getCheckResult(ret.checkingKey!,generateType) - return true; - } - return false - } - const startCheck = async (content: string, type: DetectionType, location = '') => { - if(runCache.first) { - runCache.first = false - await sleep(0.2) - } - const exists = await checkExistsTask(); - if (exists) { - return; - } - setState(() => ({ - generating: true, - generateType: type, - generateSummary: content, - location - })) - try { - const ret = await sendContentToDetection(content,type) - // 存储检测数据 - detectionApi.SetCheckingData(true, ret.assistantKey, type == DetectionType.All ? '' : content,location) - // 获取检测结果 ai段落校对,后端这边采用分段异步请求了组装 等2s后再获取 - setTimeout(()=>getCheckResult(ret.assistantKey,type),2000) - - } catch (e) { - bridge.ShowMessage('常识检测失败,请稍后重试',3500,false) - setState(prev => ({ - ...prev, - generating: false, - })) - } - } - - const scrollToBottom = () => { - const scroller = document.querySelector('.list-container') - // 判断是否为null - if (!scroller) { - return; - } - // 自动滚动到底部 - scroller.scrollTo({ - behavior: 'smooth', - top: scroller.scrollHeight + scroller.getBoundingClientRect().height - }) - } - useEffect(() => { - requestAnimationFrame(scrollToBottom) - }, [state.generating,detectionHistory]) - - // 全文检测 - const checkAll = () => { - bridge.GetDocumentAllText().then(async (result) => { - await startCheck(result, DetectionType.All) - }) - } - // 选中段落检测 - const checkRange = (start: number, end: number) => { - if (start == end || start > end) { - return false; - } - bridge.GetTextByRange(start, end).then(async (result) => { - try { - const ret = JSON.parse(result) as { text: string; line: number; page: number; }; - await startCheck(ret.text, DetectionType.Paragraph, `第${ret.page}页第${ret.line}行`) - } catch (e) { - return false; - } - }) - } - - /** - * 监听消息 - */ - useBridgeMessageListener(({Message, Data}) => { - const data = Data ? JSON.parse(Data) : {} - if (Message == 'detect-all') { - checkAll() - } else if (Message == 'detect-range') { - checkRange(data.start, data.end) - } else { - runCache.first = false - - scrollToBottom() - // document.querySelector('.list-container')?.scrollTo({ - // behavior: 'smooth', top: 0 - // }) - } - }); - - useEffect(() => { - // 通知初始化完成 - detectionApi.WebInitializationCompleted(); - // 获取当前历史 - detectionApi.GetHistory().then((result) => { - setHistory(JSON.parse(result)) - }) - // 初始化已经存在任务的状态 - checkExistsTask().then() - }, []) - - return (<> - detectionApi.Close()} - /> -
-
-
- {!state.generating && detectionHistory.length == 0 &&
- -
} - {detectionHistory.map((item, idx) => { - return (
- - {(item.type == DetectionType.All || item.type == DetectionType.AllError) ? '全文检测' : '段落检测'} - {(item.type == DetectionType.Paragraph || item.type == DetectionType.ParagraphError) && <> - - “{item.location?`${item.location}:`:''}{cutSummary(item.summary)}” - } - - -
-
- -
-
-
) - })} - {state.generating && { - setState(prev => ({...prev, generating: false})) - }}/>} -
-
-
- ); -} \ No newline at end of file diff --git a/src/pages/home-deprecated/components/editor.less b/src/pages/home-deprecated/components/editor.less deleted file mode 100644 index 0ddb13a..0000000 --- a/src/pages/home-deprecated/components/editor.less +++ /dev/null @@ -1,297 +0,0 @@ - -.proofread-container { - .proofread-items, .types { - box-sizing: border-box; - } - - .proofread-items { - display: flex; - flex-direction: column; - padding-bottom: 15px; - max-width: calc(100% - 60px); - } - - .operation-button { - padding: 10px 0; - } - - .btn-accept { - background-color: rgba(0, 0, 0, 0); - color:var(--selected-color); - border-color: var(--selected-color); - &:hover{ - background-color: #e7eaf0; - } - } - .btn-cancel{ - --btn-background-color: #c9c9c9; - &:hover{ - --btn-background-color: #a2a2a2; - } - } - - .btn-rollback { - border-color: var(--border-color); - background-color: transparent; - } -} - - -.proofread-list { - - - .description { - height: 0; - overflow: hidden; - font-size: 12px; - transition: all 0.5s; - } - - span { - display: inline-block; - } - - .item:last-child + .selected-line{ - display: none; - } - - .info{ - max-width: 100%; - flex: 1; - } - - .origin,.replaced { - max-width: 80%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - padding: 2px 4px; - //height: 30px; - } - .origin { - color:#000; - } - .replaced { - background-color: var(--primary-color, #558CB7); - color: #fff; - border-radius: 3px; - } - .select{ - .replaced { - - } - .origin,.replaced { - white-space: normal; - //max-width: 100px; - } - } - .proofread-replace-item-replace{ - .origin,.replaced { - max-width: 50%; - } - } - .proofread-replace-item-delete, - .proofread-replace-item-insert{ - .origin { - //max-width: 180px; - } - &.select{ - .origin,.replaced { - white-space: inherit; - //max-width: 160px; - } - } - } - - .action-text { - color: var(--primary-color); - margin-left:20px; - font-weight: bold; - min-width: 40px; - white-space: nowrap; - } - - .arrow { - margin: 0 10px; - } -} - -// 右侧面板 -.panel-right-state-wrapper { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - color: #979797; - - .desc { - margin: 5px 0 20px; - } - - .proofread-state-perfect { - .desc { - font-size: 18px; - margin-top: 10px; - } - } - .proofread-state-analyzing{ - font-size: 18px; - color: #000; - .remain{ - font-weight: bold; - } - .remain-time{ - margin-top: 10px; - } - .value{ - color: #FA674A; - font-size: 20px; - } - .unit{ - font-size: 14px; - margin-left: 3px; - } - .control{ - color: #979797; - margin-top: 30px; - line-height: 26px; - - .small{ - font-size: 14px; - } - } - .back-to-document{ - margin-top: 30px; - } - } -} - -// tihuan -.text-replace-item { - position: relative; - cursor: pointer; - padding: 5px 0; - &:before{ - content:' '; - display: none; - position: absolute; - left:-1px; - right:-1px; - bottom: -5px; - top:-5px; - background-color: rgba(253, 102, 67, 0.4); - } - &.replace-type-replace{ - padding-bottom: 7px; - --background-image:url(./../../assets/editor/replace.svg); - background-image:var(--background-image); - background-size: 12px 5px; - background-repeat: repeat-x; - background-position:0 26px; - &:after{ - //content:'\2000\2000\2000\2000'; - //display: block; - //position: absolute; - //left:0;right:0; - //bottom: -7px; - //height: 5px; - //background-image:linear-gradient(135deg, transparent 40%, var(--current-color,#f00), transparent 60%), - //linear-gradient(45deg, transparent 40%, var(--current-color,#f00), transparent 60%); - //background-size: 10px 10px; - //background-repeat: repeat-x; - //background-position: 0 0rem; - } - } - &.text-replace-none{ - text-decoration:none; - border-bottom:none; - color: inherit; - cursor: inherit; - } - &.processed-accept{ - --current-color:var(--primary-color) !important; - &.replace-type-replace{ - --background-image:url(./../../assets/editor/replace-accept.svg); - background-image: var(--background-image); - } - } - &.processed-ignore{ - border-color:#c9c9c9 !important; - --current-color:#c9c9c9 !important; - &.replace-type-replace{ - --background-image:url(./../../assets/editor/replace-ignore.svg); - background-image: var(--background-image); - } - } - &.replace-type-insert{ - --background-image:url(./../../assets/editor/insert.svg); - min-width: 15px; - background-size: 16px 30px; - background-repeat: repeat-x; - background-position: 0 1px; - - &:not(.processed){ - background-image: var(--background-image); - color: transparent; - &::selection{ - color: transparent; - text-decoration-color: #fff; - } - } - &.processed-ignore{ - display: none; - } - } - - &.selection { - //background-color: rgba(253, 102, 67, 0.4); - background-image: var(--background-image),linear-gradient(to bottom,rgba(253, 102, 67, .4),rgba(253, 102, 67, .4)) !important; - background-size: 12px 5px,100% 28px; - background-position:0 26px,0 0; - &.replace-type-delete,&.replace-type-insert.processed{ - background-image: linear-gradient(to bottom,rgba(253, 102, 67, .4),rgba(253, 102, 67, .4)) !important; - background-size: 100% 28px; - background-position: 0 0; - } - &.replace-type-insert:not(.processed){ - background-size: 16px 30px,100% 28px; - background-position:0 1px,0 0; - } - - } - &.replace-type-delete{ - text-decoration: line-through; - text-decoration-color: var(--current-color,#f00); - text-decoration-thickness: 2px; - border-bottom:none; - &.processed-ignore{ - border-color:gray !important; - --current-color: gray !important; - //text-decoration:none; - } - } - - &.processed { - &.processed-ignore{ - //text-decoration:none; - //border-bottom:none; - } - &.processed-delete:not(.processed-delete-init) { - &:before { - //content: attr(data-replace-text); - text-decoration: line-through; - } - } - } -} - - -.text-replace-item.processed-delete,.replace-type-insert.processed-ignore{ - width: 4px; - max-width: 4px; - min-width: 4px; - display: inline-block !important; - height: 30px; - vertical-align: middle; -} \ No newline at end of file diff --git a/src/pages/home-deprecated/components/home-proofread.less b/src/pages/home-deprecated/components/home-proofread.less deleted file mode 100644 index ea2e8c2..0000000 --- a/src/pages/home-deprecated/components/home-proofread.less +++ /dev/null @@ -1,777 +0,0 @@ -.view-size-notice { - position: fixed; - //inset-inline: 0; - //inset-block-start: 0; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - background-color: rgba(255, 255, 255, 0.2); - padding: 10px; - line-height: 30px; - z-index: 9999; - text-align: center; - font-weight: bold; - font-size: 14px; - backdrop-filter: blur(2px); -} - -@keyframes progress-bar-animation { - 0% { - background-position: -150% 0, -150% 0 - } - 100% { - background-position: 250% 0, 250% 0 - } -} - -.proofread-notice-wrapper { - position: fixed; - inset: 0; - z-index: 999; - //url(./images/loading.svg) - background: center bottom no-repeat #f5f5f5; - background-size: contain; - text-align: center; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - - .error-notice { - p { - margin: 0; - color: rgba(140, 140, 140, 1); - font-size: 12px; - } - - .error-title { - color: #000; - font-size: 20px; - font-weight: bold; - } - } - - .buttons { - button { - width: 260px; - } - } -} - -.proofread-panel { - --btn-size: 40px; - --padding-right: 0px; - --padding-left: 0px; - --padding: 10px; - --type-width: 60px; - --header-height: 53px; - font-size: 14px; - - .panel-controls { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: calc(var(--padding-left) - var(--padding-right)); - background: #fafafa; - z-index: 1; - } - - .panel-btn-visible { - border-radius: 5px 0 0 5px; - width: 28px; - height: 40px; - background-color: var(--primary-color, #36cfc9); - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - color: #fff; - position: absolute; - top: 53px; - right: 0; - - svg { - transform: rotate(-180deg) translateX(-3px); - } - - &:hover { - box-shadow: 0 0 1px rgba(0, 0, 0, 0.1); - background-color: #009688; - } - } - - &.open { - - .panel-btn-visible svg { - transform: rotate(0deg); - } - } - - .proofread-count-tag { - border-radius: 8px; - line-height: 1; - padding: 2px 10px; - } - - .proofread-panel-tab-wrapper { - background-color: #fff; - margin: 0 var(--padding-right) 0 var(--padding-left); - } - - .ant-tabs-nav, .ant-tabs-nav-list { - width: 100%; - } - - .ant-tabs-tab { - flex: 1; - justify-content: center; - } - - .proofread-panel-tab { - width: 100%; - display: flex; - align-items: center; - - .tab-item { - flex: 1; - font-size: 14px; - color: #262626; - - &.Mui-selected { - color: #262626; - } - - // - } - } - - // - .proofread-status { - background-color: #fff; - border-radius: 0 0 4px 4px; - margin: 0 var(--padding-right) 20px var(--padding-left); - } - - .btn-all { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - height: 32px; - border: 1px solid #D9D9D9; - box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.016); - border-radius: 4px; - - &:hover { - border-color: #999; - } - } - - .btn-accept-all { - color: rgba(54, 207, 201, 1); - } - - .btn-ignore-all { - color: rgba(140, 140, 140, 1); - } -} - -.panel-header { - position: sticky; - top: 0; - background: #fff; - z-index: 10; - padding: 10px; - border-bottom: solid 1px rgba(217, 217, 217, 1); - - .btn-start-proofread { - display: flex; - align-items: center; - justify-content: center; - width: 150px; - border: none !important; - background: linear-gradient(to right, #E9C57E 0%, #CAA266 100%); - - &:hover { - background: linear-gradient(to right, #CAA266 0%, #CAA266 100%) !important; - } - } - - .text-tip { - color: #333; - } - - .count-value { - color: #E9C57E; - } -} -.header-logo{ - svg{ - height: 46px; - width: 120px; - } -} -.proofread-list-wrapper { - margin-right: var(--type-width); - &.has-result{ - } -} -.proofread-list{ - padding: 0 var(--padding); - margin-top: 13px; - margin-right: 5px; - height: calc(100vh - var(--header-height) - 64px); - bottom: 10px; - overflow: auto; - &::-webkit-scrollbar { - width: 5px; - } - &::-webkit-scrollbar-thumb { - background: #fff; - } - &::-webkit-scrollbar-track { - background: #fff; - } - - // hover时 显示滚动条 - &:hover{ - &::-webkit-scrollbar-thumb { - background: #999; - } - &::-webkit-scrollbar-track { - background: #f0f0f0; - } - } - - - //.selected-line{ - // border-bottom:solid 1px transparent; - // margin: 10px 0; - //} -} -.operation-buttons { - position: sticky; - z-index: 10; - background: #fff; - top: calc(var(--header-height) - 1px); - button.ant-btn-default{ - &.btn-operation-batch{ - border-color: var(--primary-color,rgba(76, 182, 125, 1)); - color: var(--primary-color,rgba(76, 182, 125, 1)); - &:not(:disabled):hover{ - background-color: var(--primary-color,rgba(76, 182, 125, 1)); - color: #fff; - } - &:disabled{ - background-color: #f4f4f4; - border-color: #D9D9D9; - } - } - &.btn-ignore-all{ - border-color: #D9D9D9; - } - } -} -.test-item{ - background-color:#99ffff; - height:50px; - margin:10px auto; - justify-content: center; - align-items: center; - display: flex; - border-radius: 4px; - &:hover,&.active{ - background-color: #83d9d9; - } -} - -.proofread-item-wrapper { - --border-size: 2px; - --timeline-width: 14px; - --proofread-font-size: 16px; - --content-font-size: 12px; - --padding-size: 10px; - cursor: default; - padding: var(--border-size); - overflow: hidden; - margin-top: 15px; - margin-right: calc(var(--padding-right) - 10px); - margin-left: var(--padding-left); - border-radius: 4px; - background-image: linear-gradient(91.26deg, #fff, #fff); - transition: 0.5s; - outline: solid 1px transparent; - - .d-flex { - display: flex; - } - - .align-center { - align-items: center; - } - - &:first-child { - margin-top: 0; - } - - .content-container { - padding: 10px; - background: #fff; - border-radius: 4px; - } - - &:hover { - outline: solid 1px #ccc; - } - - .proofread-content { - display: none; - color: #666; - font-size: var(--content-font-size); - margin-top: 10px; - } - - .description-item { - display: flex; - background-color: #f6f5f6; - padding: 5px 6px; - border-radius: 3px; - text-align: justify; - width: 100%; - margin-bottom: 5px; - line-height: 20px; - align-items: flex-start; - - ::-webkit-scrollbar { - width: 3px; - } - - .error_sort { - color: #f00; - } - - .content { - flex: 1; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - height: 20px; - padding-right: 5px; - transition: all 0.5s; - - a { - color: var(--primary-color); - text-decoration: underline; - } - } - - .content-text { - display: none; - - span { - display: inline; - } - } - - .selection { - background-color: #fabeb0; - } - - .arrow-icon { - transform: rotate(-90deg); - } - - .desc-item { - display: flex; - background-color: #f6f5f6; - padding: 5px 6px; - border-radius: 3px; - text-align: justify; - width: 100%; - margin-bottom: 5px; - line-height: 20px; - align-items: flex-start; - } - - &.open { - .content { - white-space: normal; - height: 100%; - overflow: auto; - max-height: 120px; - } - - .content-text { - display: block; - max-height: 100px; - overflow: auto; - padding-right: 5px; - } - - .arrow-icon { - transform: rotate(0deg); - } - } - } - - &.active { - outline: solid 1px transparent; - border-color: transparent; - margin-left: 0px; - background-image: linear-gradient(91.26deg, #5E98FE -28.63%, #3DC3FF 13.62%, #FED700 51%, #B80BA7 94.06%, #CE5884 133.87%); - - .proofread-content { - display: block; - } - - .proofread-info { - .replaced, .origin { - white-space: normal; - } - } - } - - &.proofread-item-model { - outline: solid 1px transparent; - border-color: transparent; - background-image: linear-gradient(91.26deg, #5E98FE -28.63%, #3DC3FF 13.62%, #FED700 51%, #B80BA7 94.06%, #CE5884 133.87%); - } - - .proofread-item-container { - display: flex; - overflow-x: hidden; - max-width: 100%; - border-bottom: 1px solid #F0F0F0; - padding: var(--padding-size) 0; - } - - // - .proofread-item { - position: relative; - padding: 0 var(--padding-size); - font-size: var(--proofread-font-size); - inset-inline-start: 10px; - - &:last-child { - .proofread-item-dot:before { - display: none; - } - - .proofread-item-container { - border-bottom: none; - } - } - } - - .proofread-info { - position: relative; - margin-inline-end: 0; - margin-block-start: 0; - margin-block-end: 0; - line-height: 1.2; - flex: 1; - min-width: 0; - - .proofread-text { - display: flex; - align-items: center; - - &.has-tag { - align-items: flex-start; - } - } - - .proofread-tag { - font-size: 16px; - font-weight: 400; - line-height: 19px; - text-align: center; - color: var(--item-type-color, #f00); - margin-inline-start: 10px; - margin-block-start: -1px; - white-space: nowrap; - } - - .text { - width: 100%; - } - } - - .proofread-item-dot { - width: var(--timeline-width); - position: absolute; - top: 13px; - bottom: -20px; - left: -10px; - - &:before { - content: ""; - display: block; - position: absolute; - inset-block-start: 10px; - inset-inline-start: 6px; - height: calc(100% - 10px); - border-inline-start: 1px solid rgba(255, 133, 192, 1); - } - - .dot { - width: var(--timeline-width); - height: var(--timeline-width); - border-radius: 50%; - background: var(--item-type-color, #36cfc9); - position: absolute; - border: solid 3px #fff; - left: 0; - } - - } - - .actions { - margin-inline-start: 10px; - white-space: nowrap; - } - - &:hover, &.active { - .proofread-action { - visibility: visible; - } - } - - .proofread-action { - visibility: hidden; - display: flex; - --btn-size: 20px; - - &.processed { - visibility: visible; - } - - .process-state-container { - - } - - .process-state-actions { - - } - - button { - width: var(--btn-size); - height: var(--btn-size); - outline: none; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - line-height: 1; - padding: 0; - color: #999; - cursor: pointer; - background: none; - border: solid 1px transparent; - border-radius: 4px; - - &:not[disabled]:hover { - color: #36CFC9; - border-color: #36CFC9; - } - } - - .btn-accept { - color: #36CFC9; - border-color: #36CFC9; - } - - .btn-review { - color: #9747FF; - border-color: #9747FF; - } - - .btn-ignore { - color: #fff; - background-color: #D9D9D9; - border-color: #D9D9D9; - - &:not[disabled]:hover { - color: #fff; - background-color: #ccc; - border-color: #999; - } - } - - .btn-add-to-lexicon { - color: #D9D9D9; - border-color: #D9D9D9; - } - - .btn-more { - font-size: 10px; - color: rgba(182, 182, 182, 1); - background-color: rgba(245, 245, 245, 1); - border-color: rgba(245, 245, 245, 1); - } - - // 已处理状态 - .process-state { - display: flex; - font-size: 12px; - align-items: center; - background-color: #f0f0f0; - border-radius: 3px; - padding: 0 4px; - height: var(--btn-size); - } - - .state-accept { - color: var(--primary-color-main, #08979C); - } - - .state-ignore { - color: #C9C9C9; - } - - .ml-2 { - margin-left: 2px; - } - - .rollback { - border-radius: 4px; - padding: 2px 4px; - - &:hover { - background-color: var(--background-hover-color); - } - } - } - -} - -.types { - background: #f0f0f0; - position: fixed; - right: 0; - bottom: 0; - top: var(--header-height); - width: var(--type-width); - - .item { - text-align: center; - padding: 10px 0; - cursor: pointer; - .count{ - color: var(--primary-color); - font-weight: bold; - font-size: 16px; - } - &.active { - background: #fff; - box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.1); - } - } -} - -.proofread-item{ - .action { - margin-left: 10px; - .btn { - background: #fff; - outline: none; - width: 20px; - height: 20px; - border: solid 1px var(--primary-color); - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; - color: var(--primary-color); - cursor: pointer; - box-sizing: border-box; - - &:disabled{ - background-color: var(--primary-disabled-color); - border: solid 1px var(--primary-disabled-color); - color:#fff; - } - - &:not(:disabled):hover { - background-color: var(--primary-color); - color: #fff; - } - } - .btn-odd{ - background-color: var(--primary-color); - color: #fff; - &:hover { - background-color: #fff; - color: var(--primary-color); - } - } - .btn-review{ - .icon-type{ - transform: translateY(0.5px); - } - } - .btn-accept { - } - - .btn-ignore { - } - - .more-action { - box-sizing: border-box; - width: 20px; - height: 20px; - border-radius: 4px; - border: solid 1px var(--primary-color); - background-color: var(--primary-color); - color: #fff; - text-align: center; - - &:hover { - background-color: #fff; - color: var(--primary-color); - } - } - - .btn-add-to-lexicon { - } - - .processed-wrapper { - font-size: 12px; - } - - .state-accept { - color: var(--primary-process-color,#aaaaaa); - margin-right: 12px; - } - .state-review{ - //color: #3FD4CF; - } - - .state-ignore { - color: #C9C9C9; - margin-right: 12px; - } - - .rollback { - border-radius: 4px; - padding: 2px 4px; - - &:hover { - background-color: var(--background-hover-color); - } - } - } -} -.ant-popover.black-bg{ - //--antd-arrow-background-color: var(--primary-color); - .ant-popover-inner{ - transform: translateY(1px); - // background-color: var(--primary-color); - padding: 5px 10px; - // .ant-popover-inner-content{ - // color: #fff; - // } - } -} \ No newline at end of file diff --git a/src/pages/home-deprecated/components/icons.tsx b/src/pages/home-deprecated/components/icons.tsx deleted file mode 100644 index 5e3fe1d..0000000 --- a/src/pages/home-deprecated/components/icons.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import React, {CSSProperties} from "react"; -import Icon from "@ant-design/icons"; -import {cx} from "@emotion/css"; - -type SvgIconProps = { - size?: number; - className?: string; - style?: CSSProperties; - onClick?: (e: React.MouseEvent) => void; - component: React.ComponentType -} - -export const SvgIcon: React.FC = (props) => { - const styles: CSSProperties = props.style || {} - if (props.size) { - styles.fontSize = props.size + 'px'; - } - - return (); -} - -export const IconClose = () => ( - // width="28" height="40" - - - - -) -export const IconOpen = () => ( - - - -) -export const IconArrowRight = () => ( - - - -) -export const IconDotMore = () => ( - - - - - -) -export const IconArrowDown = () => ( - - - -) - -export const IconAccept = () => ( - - - -) -export const IconIgnore = () => ( - - - -) -export const IconReviewOutlined = () => ( - - - - - -) - -export const IconReview = () => ( - - - -) - -export const IconPlus = () => ( - - - - - - -) -export const IconRollback = () => ( - - - -) -export const IconRollbackOld = () => ( - - - - -) - -export const IconDotMore2 = ()=>( - - - - -) -export const IconStartProofread = () => ( - - - -) \ No newline at end of file diff --git a/src/pages/home-deprecated/components/images/loading.svg b/src/pages/home-deprecated/components/images/loading.svg deleted file mode 100644 index 3bb898a..0000000 --- a/src/pages/home-deprecated/components/images/loading.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/pages/home-deprecated/components/images/logo.tsx b/src/pages/home-deprecated/components/images/logo.tsx deleted file mode 100644 index 2e0137c..0000000 --- a/src/pages/home-deprecated/components/images/logo.tsx +++ /dev/null @@ -1,45 +0,0 @@ -export const IconLogo = () => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) \ No newline at end of file diff --git a/src/pages/home-deprecated/components/images/notice.tsx b/src/pages/home-deprecated/components/images/notice.tsx deleted file mode 100644 index 822880a..0000000 --- a/src/pages/home-deprecated/components/images/notice.tsx +++ /dev/null @@ -1,391 +0,0 @@ -export const ErrorNotice = ()=>( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) \ No newline at end of file diff --git a/src/pages/home-deprecated/components/index.tsx b/src/pages/home-deprecated/components/index.tsx deleted file mode 100644 index dbcdf77..0000000 --- a/src/pages/home-deprecated/components/index.tsx +++ /dev/null @@ -1,366 +0,0 @@ -import React, {useEffect, useMemo, useState} from "react"; -import Icon from "@ant-design/icons"; -import {useSetState} from "ahooks"; -import {Button, Flex, Space, Typography} from "antd"; - -import {IProofreadTypeData, ProofreadTypeData} from "@/types/proofread.ts"; -import { - ProofreadStateEnum, ProofreadTypeEnum, - TCorrectData, - TCorrectedContent, - TDocumentContentDetail -} from "@/service/types/document.ts"; -import {showToast} from "@/components/messages/Modal.tsx"; - -import {IconRollback, IconStartProofread} from "./icons.tsx"; -import {ActionKey, ProofreadItem} from "./proofread-item.tsx"; -import {parseProofreadResult} from "./parse-proofread-result.ts"; -import './editor.less' -import {IconLogo} from "./images/logo.tsx"; - - -type ProofreadPanelProps = { - document?: TDocumentContentDetail; - proofreadLoading?: boolean - onUpdateProofreadItem: (item: TCorrectedContent) => void; - onSelectProofreadItem: (item: TCorrectedContent | null) => void; - activeProofreadItemId?: number; - disabledProofreadItemList:number[]; - onStartProofread: () => Promise | void; - selectedProofreadItemId?: number; - userinfo?: Account; -} - -const ProofreadPanel: React.FC = (props) => { - const {userinfo} = props - const [state, setState] = useSetState<{ - // 当前选中分类 - currentType: IProofreadTypeData | null; - // 默认是否展开panel - open: boolean; - adoptAll?: boolean; - ignoreAll?: boolean; - listMaxCount: number; - activeIndex: number; - }>({ - currentType: null, - open: true, - adoptAll: false, - ignoreAll: false, - activeIndex: -1, - listMaxCount: 100000, - }) - - - const [proofreadResult, setProofreadResult] = useState() - const [histories, setHistories] = useState([]) - - useEffect(() => { - handleTypeChange(null) - if (props.proofreadLoading) { - //setProofreadList({all: [], processed: []}) - } else { - if (props.document) { - const result = parseProofreadResult(props.document,props.disabledProofreadItemList) - setProofreadResult({ - abnormalCount: result.abnormalCount, - list: result.resultList - }) - setHistories([]) - } - } - }, [props.document, props.proofreadLoading,props.disabledProofreadItemList]) - - // 当前状态校对列表 - const currentProofreadList = useMemo(() => { - const list = proofreadResult?.list || []; - if (!state.currentType) return list; - return list.filter(s => Array.isArray(state.currentType?.id) ? state.currentType?.id.includes(s.type) : s.type == state.currentType?.id) - }, [proofreadResult, state.currentType]) - - // useEffect(() => { - // if (props.document && bridge) { - // bridge.clearAllProofreadMark() - // currentProofreadList.forEach(it => { - // bridge.addBookmark(JSON.stringify(it)) - // }) - // } - // }, [currentProofreadList]) - - // 撤销操作 - const redoAction = async () => { - if (!props.document) return; - if (histories.length == 0) return; - const currentList = histories.pop(); - setHistories(histories); - if (!currentList || currentList.length == 0) return; - currentList.forEach(id => { - // 状态调整为未处理 - const item = proofreadResult?.list?.find(s => s.id == id) - if (item) { - item.isAccept = ProofreadStateEnum.Default - props.onUpdateProofreadItem(item) - } - }) - setProofreadResult({ - abnormalCount: proofreadResult!.abnormalCount, - list: proofreadResult!.list - }) - } - - /** - * 获取全部/类似校对项 - * @param isAccept - * @param p 如果不传入则获取该状态对应类型所有校对项 - */ - const getSameProofreadItems = (isAccept?: boolean, p?: TCorrectedContent) => { - const list = currentProofreadList.filter(s => { - if (isAccept && s.type == ProofreadTypeEnum.sensitive) return false; - return s.isAccept == ProofreadStateEnum.Default; - }) - // 获取当前类型下所有 - return p ? list.filter(s => { - return s.origin == p.origin && s.text == p.text && ( - isAccept ? s.tag : true - ); - }) : ( - isAccept ? list.filter(s => s.tag) : [...list] - ) - } - - const addToHistory = (items: TCorrectedContent[]) => { - setHistories([ - ...histories, - items.map(s => s.id) - ]) - setProofreadResult(proofreadResult) - } - - // 批量处理 - const batchProcess = (status: ProofreadStateEnum, proofread?: TCorrectedContent) => { - const list = getSameProofreadItems(status == ProofreadStateEnum.Accept, proofread); - if (list.length > 0) { - // 设置 状态 - list.map(s => { - s.isAccept = status; - props.onUpdateProofreadItem(s); - return s; - }) - addToHistory(list) - } - } - - // 处理全部 - const handleProcessAll = (action: ActionKey) => { - return () => { - if (!props.document) return; - batchProcess(action == 'acceptAll' ? ProofreadStateEnum.Accept : ProofreadStateEnum.Ignore) - } - } - - - // 让当前选中的 item 居中 - const centerItem = (activeIndex: number) => { - setState({activeIndex}) - // 将提示显示在视图中间 - const div = document.querySelector(`div.proofread-index-${activeIndex}`) - if (div) { - div.scrollIntoView({ - behavior: 'smooth', - block: 'center' - }) - } - // - props.onSelectProofreadItem(currentProofreadList[activeIndex]); - } - useEffect(() => { - if (props.selectedProofreadItemId) { - const index = currentProofreadList.findIndex(s => s.id == props.selectedProofreadItemId) - if (index >= 0) { - centerItem(index) - } - } - }, [props.selectedProofreadItemId]) - // 处理校对项 - const handleItemAction = async (key: ActionKey, item: TCorrectedContent, index: number) => { - try { - if (key == 'click') { - if (item) { - setState({activeIndex: index}) - } - centerItem(index) - return; - } else if (key == 'addToLexicon') { - // 添加到词库 - showToast('添加词库成功', "success") - } else { - if (key == 'ignoreAll' || key == 'acceptAll') { // 同类型处理 - batchProcess(key == 'acceptAll' ? ProofreadStateEnum.Accept : ProofreadStateEnum.Ignore, item) - } else { - if (key == 'ignore') { // 忽略 - item.isAccept = ProofreadStateEnum.Ignore; - } else if (key == 'accept') { // 采纳 - item.isAccept = ProofreadStateEnum.Accept; - } else if (key == 'review') { // 复核 - item.isAccept = ProofreadStateEnum.Review; - } - props.onUpdateProofreadItem(item) - addToHistory([item]) - } - } - } catch (e) { // 处理错误了 - console.log('process item action error:', (e as Error).message) - } - } - - - const handleTypeChange = (currentType: IProofreadTypeData | null) => { - setState({ - currentType, - activeIndex: -1, - }) - window.scrollTo({ - top: 0, - behavior: 'smooth' - }) - } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const movePrevOrNextProofreadItem = (action: 'prev' | 'next') => { - const maxCount = currentProofreadList.length; - if (maxCount == 0) return; - let newId = state.activeIndex; - if (action == 'next') { - if (state.activeIndex >= maxCount - 1) { - return; - } - newId += 1; - } else { // 向上滚 - if (state.activeIndex <= 0) return; - newId -= 1; - } - centerItem(newId) - } - // const handleUpAndDownEvent = (e: KeyboardEvent) => { - // const key = e.key.toLowerCase(); - // if (key == 'arrowup' || key == 'arrowdown') { - // movePrevOrNextProofreadItem(key == 'arrowup' ? 'prev' : 'next') - // } else if (key == 'arrowleft' || key == 'arrowright') { - // // movePrevOrNextProofreadItem(key == 'arrowleft' ? 'accept' : 'ignore') - // } - // } - // const processScroll = (e: WheelEvent) => { - // const {deltaY} = e; - // movePrevOrNextProofreadItem(deltaY > 0 ? 'next' : 'prev') - // } - - // const {run: onMousewheel} = useDebounceFn((e) => processScroll(e), {wait: 20,}) - // useEffect(() => { - // 绑定键盘事件 - // document.documentElement.addEventListener('keyup', handleUpAndDownEvent, false) - // 绑定滚动事件 - // document.documentElement.addEventListener('wheel', onMousewheel, false) - // return () => { - // document.documentElement.removeEventListener('wheel', onMousewheel, false) - // // document.documentElement.removeEventListener('keyup', handleUpAndDownEvent, false) - // } - // }, []); - const currentProofreadTotal = useMemo(() => { - return proofreadResult?.abnormalCount.total && proofreadResult?.abnormalCount.total > 0 ? proofreadResult?.abnormalCount.total : 0 - }, [proofreadResult]) - - // const {bridge} = useBridge(); - // const processGetContent = () => { - // const t = Date.now() - // // - // bridge.getDocumentData().then(ret => { - // console.log(ret, Date.now() - t); - // // bridge.getTotalParagraphNumber().then((total) => { - // // console.log(total, Date.now() - t) - // // // bridge.getParagraphTextByRange(1535, 1544).then((ret) => { - // // // console.log(ret, Date.now() - t); - // // // }) - // // - // // }) - // }) - // } - - - return (
- -
- {proofreadResult && currentProofreadTotal > 0 ? - - : } -
- - 建议修改 {currentProofreadTotal} 项 - 待审核 - {proofreadResult?.list.filter(s => s.isAccept == ProofreadStateEnum.Default)?.length || 0} 项 - -
-
-
- - - - - - - -
-
- {currentProofreadList.map((it, index) => ( - index >= state.listMaxCount ? null : handleItemAction(key, it, index)} - key={it.id} - previewMode={false} - /> - ))} -
-
-
-
-
-
handleTypeChange(null)} - className={`item ${!state.currentType ? 'active' : ''}`}> -
{currentProofreadTotal}
-
全部
-
- {ProofreadTypeData.map((currentType, activeType) => ( - // 只显示有错误的项 - proofreadResult?.abnormalCount[currentType.key] ? -
handleTypeChange(currentType)} - className={`item ${state.currentType?.key == currentType.key ? 'active' : ''}`}> -
{proofreadResult?.abnormalCount[currentType.key] || 0}
-
{currentType.text}
-
: null - ))} -
-
-
-
) -} -export default ProofreadPanel; \ No newline at end of file diff --git a/src/pages/home-deprecated/components/panel-right-state.tsx b/src/pages/home-deprecated/components/panel-right-state.tsx deleted file mode 100644 index cfa26aa..0000000 --- a/src/pages/home-deprecated/components/panel-right-state.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import {Button} from "antd"; -import IdleImage from "./../images/icon-idle.png" -import PerfectImg from "./../images/icon-perfect.png" - -export type TProofreadState = 'idle' | 'processing' | 'perfect' | 'edit' | 'analyzing' -type PanelRightStateProp = { - state: TProofreadState; - proofreadEndTime?: number; - onBack?:()=>void; -} - -// 状态配置 -const StateConfig: { - [key in TProofreadState]: {image: string, text: string} | null -} = { - 'idle': {image: IdleImage, text: '在左侧输入内容开始校验'}, - 'processing': {image: IdleImage, text: '正在校验中'}, - 'edit': {image: IdleImage, text: '正在编辑中'}, - 'perfect': null, - 'analyzing': null, -} - -const StateElement = ({state}: PanelRightStateProp) => { - return (
-
- {state} -
-
专业校验工具
-
全面检查语义、语法、敏感词、标点符号等问题
-
{StateConfig[state]?.text}
-
) -} - -const Perfect = () => (
-
- perfect -
-
非常完美
-
) - -const Analyzing = (props:PanelRightStateProp) => (
-
- {props.proofreadEndTime === -2 ?
排队校对中...
:<> -
预计还有
-
- {Math.round(props.proofreadEndTime! / 1000)} - -
- } -
-
-
- 校对时间太长? -
返回文稿同样可查看进度
-
-
-
- -
-
) - -const PanelElement = ({state,onBack,proofreadEndTime}: PanelRightStateProp)=>{ - if(state === 'perfect') return ; - if(state === 'analyzing') return ; - return ; -} - -export const PanelRightState: React.FC = (props) => ( -
- -
-) diff --git a/src/pages/home-deprecated/components/parse-proofread-result.ts b/src/pages/home-deprecated/components/parse-proofread-result.ts deleted file mode 100644 index cd977c4..0000000 --- a/src/pages/home-deprecated/components/parse-proofread-result.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - ProofreadTypeEnum, - TCorrectedContent, - TDocumentContentDetail, TProofreadCountResult, -} from "@/service/types/document.ts"; -import {ProofreadTypeData, ProofreadTypeKeys} from "@/types/proofread.ts"; -import {int} from "@/service/types/base.ts"; - -function getTypeData(type: ProofreadTypeEnum) { - return ProofreadTypeData.find(s => Array.isArray(s.id) ? s.id.includes(type) : s.id == type) -} - - -export function buildProofreadResult(document: TDocumentContentDetail) { - let offset = 0; - let paragraph_offset = 1; - document.correctedSet.forEach((item) => { - item.offset = offset;//Math.ceil(item.offset) + offset; - offset += item.insert_len; - item.diffs?.forEach(it => { - // it.start += item.offset + 1 - // it.end += item.offset + 1 - it.typeData = getTypeData(it.type) - it.color = '#80D6AA69';//it.typeData?.color; - }) - if (item.insert?.length > 1 && (item.insert.startsWith("\f") || item.insert.startsWith("\n"))) { - paragraph_offset++; - } - // 当前是第几段 - item.paragraph_offset = paragraph_offset; - // item.paragraph_num = paragraph_offset; - if (item.insert.endsWith("\n") || item.insert.endsWith("\f")) { - paragraph_offset++; - } - }) -} - -// 解析并处理校对结果 -export function parseProofreadResult(document: TDocumentContentDetail, disabled: number[] = []) { - const parseData = []; - const resultList: TCorrectedContent[] = []; - - const abnormalCount: { - [key: string]: int - } = { - total: 0 - }; - - // 遍历内容 - document.correctedSet.forEach((item) => { - item.diffs?.forEach(it => { - // it.start += item.offset + 1 - // it.end += item.offset + 1 - // it.typeData = getTypeData(it.type) - // it.color = it.typeData?.color; - if (disabled.includes(it.id)) return; - resultList.push(it) - const type = ProofreadTypeKeys[it.type]; - if (!abnormalCount[type]) abnormalCount[type] = 0; - abnormalCount['total']++; - abnormalCount[type]++; - }) - }) - - return { - parseData, - resultList, - abnormalCount: abnormalCount as TProofreadCountResult - } -} diff --git a/src/pages/home-deprecated/components/proofread-item.tsx b/src/pages/home-deprecated/components/proofread-item.tsx deleted file mode 100644 index d36748d..0000000 --- a/src/pages/home-deprecated/components/proofread-item.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import React, {useMemo} from "react"; -import {RightOutlined} from "@ant-design/icons"; -import {Popover, Space} from "antd"; -import {css} from "@emotion/css"; -import {DropdownMenu} from "@/components/popover/dropdown-menu"; -import { - ProofreadStateEnum, - ProofreadTypeEnum, - TCorrectedContent, -} from "@/service/types/document"; -import {showToast} from "@/components/messages/Modal.tsx"; -import {whitelist} from "@/service/api/lexicon.ts"; -import {useSetState} from "ahooks"; -import { - IconAccept, - IconDotMore2, - IconIgnore, - IconPlus, - IconReview, - SvgIcon -} from "./icons.tsx"; - - -export type ActionKey = 'click' | 'accept' | 'acceptAll' | 'ignore' | 'ignoreAll' | 'addToLexicon' | 'review' | 'redo' -type ProofreadItemProps = { - selected?: boolean; - className?: string | undefined; - previewMode?: boolean; - last?: boolean; - onAction: (key: ActionKey) => void - it: TCorrectedContent - index?: number; -} - -const ActionToolTip = (props: {open?:boolean; text: string; children: React.ReactNode }) => ( - {props.children}) - -function getDescription(it: TCorrectedContent) { - // 获取类型数据 - // const typeData = getTypeData(it.type)!; - - const str = [`【${it.typeData?.text}】`] - if (it.typeData?.type === 'black' || it.type == ProofreadTypeEnum.sensitive) { - str.push('请复核',it.tag == 'r' && !/^[*]+$/.test(it.text) ?`,将选用"${it.text}"`:'') - } else if (it.tag == 'r') { - str.push(`建议选用"${it.text}"`) - } else { - str.push('建议' + (it.tag == 'd' ? '删除' : '新增')) - } - return str.join(''); - // return typeData?.text ? typeData?.text + ',' : ''}{props.it.tag == 'r' ? `选用"${props.it.text}"` : ( - // it.tag == 'd' ? '删除' : '新增' -} - -export const ProofreadItem: React.FC = (props) => { - - const requireReview = useMemo(() => { - // 敏感词或者要拦截的黑名单 - return props.it.type == ProofreadTypeEnum.sensitive || props.it.type == ProofreadTypeEnum.blackWordBlock || ( - props.it.type == ProofreadTypeEnum.blackWord - && props.it.tag == 'r' - && /^[*]+$/.test(props.it.text) - ); - }, [props.it]) - - // 当前类别颜色 - const colorStyle = css`--proofread-color: ${props.it.typeData?.color || '#000000'}` - const [state, setState] = useSetState({ - addToLexiconVisible: true - }) - - // 添加到词库 - const handleAddToLexicon = () => { - whitelist.create({ - word: props.it.origin - }).then(() => { - showToast('加入白名单成功', 'success'); - // 隐藏添加按钮 - setState({ - addToLexiconVisible: false - }) - }).catch((e) => { - console.log(e); - showToast('加入白名单失败', 'warning') - }) - } - // const handleUndo = async () => { - // showToast('撤销成功') - // } - const AddToLexiconButton = ({disabled}:{disabled:boolean}) => { - const AddButton = ; - return (props.selected && state.addToLexiconVisible && props.it.type != ProofreadTypeEnum.blackWord) ? - disabled ? AddButton : ( - {AddButton} - ) : null - } - return (<> -
props.onAction('click')} - className={`proofread-item ${props.it.isAccept == ProofreadStateEnum.Default?'':'processed'} proofread-action-${props.it.action} proofread-item-${props.it.id} ${props.className} ${colorStyle} item ${props.selected ? 'select' : ''}`}> -
-
- { - props.it.tag == 'i' ? props.it.text : ( - props.it.origin == ' ' ? '空格' : props.it.origin - ) - } - { - props.it.type == ProofreadTypeEnum.blackWord ? - 黑名单 : (props.it.typeData?.type == 'sensitive' ? - 敏感词 : (props.it.tag == 'r' - ? <> - - {props.it.text} - - : {props.it.tag == 'd' ? '删除' : '新增'})) - - } -
-
- {getDescription(props.it)} -
-
- {!props.previewMode &&
- {props.selected && (props.it.isAccept == ProofreadStateEnum.Default) && - {!requireReview && - - } - {requireReview && - - } - - - - - props.onAction('acceptAll')}, - {type: 'divider'}, - {key: 'accept', label: '忽略全部相同结果', onClick: () => props.onAction('ignoreAll')}, - ] : [{key: 'accept', label: '忽略全部相同结果', onClick: () => props.onAction('ignoreAll')}]} - > -
-
-
} - {props.it.isAccept != ProofreadStateEnum.Default && -
- {props.it.isAccept == ProofreadStateEnum.Accept &&
- - 已采纳 -
} - {props.it.isAccept == ProofreadStateEnum.Review && -
- - 已复核 -
} - {props.it.isAccept == ProofreadStateEnum.Ignore &&
- - 已忽略 -
} -
} -
} -
- {props.selected && !props.last &&
} - ) -} diff --git a/src/pages/home-deprecated/components/tools.ts b/src/pages/home-deprecated/components/tools.ts deleted file mode 100644 index a233bf8..0000000 --- a/src/pages/home-deprecated/components/tools.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {IDocumentCorrect, IDocumentDetail, IDocumentProofread} from "@/types/document"; -import {IProofreadResult, ProofreadTypeEnum} from "./types.ts"; - -type Range = { - start:number; - end:number; -} -export function inRange(a:Range,b:Range){ - if(a.start == b.start && a.end == b.end) return true; - // check a in b - if( - a.start >= b.start && - a.start <= b.end && - a.end >= b.start && - a.end <= b.end - ) return true; - // check b in a - if ( - b.start >= a.start && - b.start <= a.end && - b.end >= a.start && - b.end <= a.end - ) return true - return false; -} -function buildProofreadResult(correct: IDocumentProofread[], block: IDocumentCorrect, document: IDocumentDetail) { - const blockCorrect: IProofreadResult[] = []; - correct.forEach(item => { - // 处理涉政类型数据 - const result: IProofreadResult = { - ...item, - key: block.key, - document_id: document.id, - leader: item.type === ProofreadTypeEnum.leader ? document.leaders[item.mid] : undefined, - position: item.type === ProofreadTypeEnum.position ? document.positions[item.mid] : undefined, - quotation: item.type === ProofreadTypeEnum.quotation ? document.quotations[item.mid] : undefined, - relation:[] - } - for (const block of blockCorrect) { - if (inRange(result,block)) { - result.relation?.push(block) - block.relation?.push(result) - // if(result.tag != block.tag) - blockCorrect.push(result); - return; - } - } - blockCorrect.push(result); - }); - - return blockCorrect; -} - -export function parseProofreadList(document: IDocumentDetail) { - const result = document.correctedSet.filter(s => s.ranges && s.ranges.length > 0) - .map(s => buildProofreadResult(s.ranges!, s, document)); - // console.log(result) - return result.flat() -} \ No newline at end of file diff --git a/src/pages/home-deprecated/components/types.ts b/src/pages/home-deprecated/components/types.ts deleted file mode 100644 index 432516e..0000000 --- a/src/pages/home-deprecated/components/types.ts +++ /dev/null @@ -1,202 +0,0 @@ -export enum ProofreadTypeStatusEnum { - // 默认,未处理? - Default, - // 已采纳 - Accept = 2, - // 已忽略 - Ignore, - // 已复核 - Audited -} -export type EditorProofreadFormat = { - id: string|number; - suggest?: ProofreadTypeStatusEnum; - tag: string; - start: any; - end: any; - current: string -} -// 编辑器 -export type SelectionEditorProofread = { - proofread?:EditorProofreadFormat; - insert?:EditorProofreadFormat; - replace?:EditorProofreadFormat; - delete?:EditorProofreadFormat; - leader?:EditorProofreadFormat; - position?:EditorProofreadFormat; - quotation?:EditorProofreadFormat; -} - -// 校对分类 -export enum ProofreadTypeEnum { - characterError = 2, - /** - * 易错词 - */ - confusion = 18, - /** - * 语录 - */ - quotation = 16, - /** - * 领导人 - */ - leader = 17, - /** - * 黑名单 - */ - blacklist = 20, - /** - * 标点 - */ - punctuation = 22, - /** - * 敏感词 - */ - sensitive = 19, - /** - * 白名单 - */ - whitelist = 21, - /** - * 职位 - */ - position = 23, - /** - * 其他模型 - */ - model = 24, -} - -export interface IPositionInfo { - leaders: string[]; - position: string; -} - -export interface IQuotationInfo { - category: string; - content: string; - document_name: string; - hypelink: string; - id: string; -} - -export interface ILeaderInfo { - name?: string; - correct_name: string; - positions: string[]; - sort_error?: any; -} - -export interface IProofreadResult { - tag: 'r' | 'd' | 'i' | string; - old: string; - new: string; - start: number; - end: number; - id: number; - // 文档编号 - document_id: number; - idx: number; - // 对应句子hash - key: string; - suggest: ProofreadTypeStatusEnum; - // 对应领导 语录等的索引 - mid: number; - type: ProofreadTypeEnum; - // 关联领导数据 - leader?: ILeaderInfo; - // 关联职位数据 - position?: IPositionInfo; - // 关联语录数据 - quotation?: IQuotationInfo; - // 关联数据 - relation?:IProofreadResult[]; -} - -export type IProofreadTypeData = { - type: string, - key: string; - color: string; - text: string; - count?: number; - id: ProofreadTypeEnum | ProofreadTypeEnum[]; - // 采纳全部时要提交的类型 - acceptAll?: ProofreadTypeEnum[]; - // 忽略全部时要提交的类型 - ignoreAll?: ProofreadTypeEnum[]; -} -export const ProofreadTypeData: IProofreadTypeData[] = [ - { - id: [ProofreadTypeEnum.blacklist], - type: 'black', - acceptAll: [ProofreadTypeEnum.blacklist], - ignoreAll: [ProofreadTypeEnum.blacklist], - count: 0, - text: '黑名单', - color: '#2A2A2A', - key: 'blacklist' - }, - - {id: ProofreadTypeEnum.whitelist, type: 'unit', count: 0, text: '白名单', color: '#77F1AE', key: 'whitelistError'}, - {id: ProofreadTypeEnum.confusion, type: 'confusion', count: 0, text: '易错词', color: '#D6AA69', key: 'confusion'}, - { - id: ProofreadTypeEnum.punctuation, - type: 'symbol', - count: 0, - text: '标点错', - color: '#558CB7', - key: 'punctuationError' - }, - {id: ProofreadTypeEnum.sensitive, type: 'sensitive', count: 0, text: '敏感词', color: '#e971ba', key: 'sensitive'}, - { - id: ProofreadTypeEnum.characterError, - type: 'character', - count: 0, - text: '易错词', - color: '#e971ba', - key: 'characterError' - }, - {id: ProofreadTypeEnum.model, type: 'model', count: 0, text: '其他错误', color: '#E9D0A7', key: 'model'}, - - {id: ProofreadTypeEnum.quotation, type: 'quotation', count: 0, text: '语录', color: '#29CEC0', key: 'quotation'}, - {id: ProofreadTypeEnum.leader, type: 'leader', count: 0, text: '政要人物', color: '#c9c9c9', key: 'leader'}, - {id: ProofreadTypeEnum.position, type: 'position', count: 0, text: '职位', color: '#CDAFE5', key: 'positionError'}, -] - -export type ProofreadStatusType = 'all'| 'error'| 'sensitive'| 'blacklist'| 'politics' - -export const ProofreadTypeConfig: { - [key in ProofreadStatusType]: ProofreadTypeEnum[] -} = { - all: [], - error: [ - ProofreadTypeEnum.punctuation, - ProofreadTypeEnum.characterError, - ProofreadTypeEnum.confusion, - ProofreadTypeEnum.model - ], - sensitive: [ - ProofreadTypeEnum.sensitive - ], - blacklist: [ - ProofreadTypeEnum.blacklist - ], - politics: [ - ProofreadTypeEnum.leader, - ProofreadTypeEnum.quotation, - ProofreadTypeEnum.position, - ] -} - - -export type ProofreadItemActions = - 'ignore' - | 'adopt' - | 'review' - | 'revoke' - | 'addToLexicon' - | 'undo' - | 'revokeAll' - | 'acceptAll' - | 'ignoreAll'; \ No newline at end of file diff --git a/src/pages/home-deprecated/images/bg.png b/src/pages/home-deprecated/images/bg.png deleted file mode 100644 index 4b409ce..0000000 Binary files a/src/pages/home-deprecated/images/bg.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/btn_arrow_close.png b/src/pages/home-deprecated/images/btn_arrow_close.png deleted file mode 100644 index 9765b81..0000000 Binary files a/src/pages/home-deprecated/images/btn_arrow_close.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/btn_arrow_open.png b/src/pages/home-deprecated/images/btn_arrow_open.png deleted file mode 100644 index 86f182c..0000000 Binary files a/src/pages/home-deprecated/images/btn_arrow_open.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/check.gif b/src/pages/home-deprecated/images/check.gif deleted file mode 100644 index 2bea000..0000000 Binary files a/src/pages/home-deprecated/images/check.gif and /dev/null differ diff --git a/src/pages/home-deprecated/images/icon-export.png b/src/pages/home-deprecated/images/icon-export.png deleted file mode 100644 index d54047e..0000000 Binary files a/src/pages/home-deprecated/images/icon-export.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/icon-idle.png b/src/pages/home-deprecated/images/icon-idle.png deleted file mode 100644 index a2eef87..0000000 Binary files a/src/pages/home-deprecated/images/icon-idle.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/icon-perfect.png b/src/pages/home-deprecated/images/icon-perfect.png deleted file mode 100644 index b4e1fda..0000000 Binary files a/src/pages/home-deprecated/images/icon-perfect.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/icon-setting.png b/src/pages/home-deprecated/images/icon-setting.png deleted file mode 100644 index 6f15270..0000000 Binary files a/src/pages/home-deprecated/images/icon-setting.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/perfect.png b/src/pages/home-deprecated/images/perfect.png deleted file mode 100644 index b0dd393..0000000 Binary files a/src/pages/home-deprecated/images/perfect.png and /dev/null differ diff --git a/src/pages/home-deprecated/images/processing.gif b/src/pages/home-deprecated/images/processing.gif deleted file mode 100644 index 6f9d3f4..0000000 Binary files a/src/pages/home-deprecated/images/processing.gif and /dev/null differ diff --git a/src/pages/home-deprecated/index.tsx b/src/pages/home-deprecated/index.tsx deleted file mode 100644 index 6498441..0000000 --- a/src/pages/home-deprecated/index.tsx +++ /dev/null @@ -1,437 +0,0 @@ -import {useDebounceFn, useRequest} from "ahooks"; -import React, {useEffect, useState} from "react"; - -import {useBridge, useBridgeMessageListener} from "@/core/bridge.ts"; - -import ProofreadPanel from "./components"; -import './components/home-proofread.less' -import { - ProofreadLoading, - ProofreadError, - ProofreadPerfect, -} from "./notice.tsx"; -import {useUserinfoStore} from "@/service/userinfoStore.ts"; -import {proofread, create, save, proofreadDetail} from "@/service/api/document.ts"; -import {calcContentLengthLikeWord, formatTime, hidePhone} from "@/utils/strings.ts"; -import {getAuthCode} from "@/service/api/user.ts"; -import {TDocumentContentDetail} from "@/service/types/document.ts"; -import {AppUpgradeInfo, Settings, UpgradeInfo} from "@/service/types/settings.ts"; -import {compareVersion, getAppUpgradeInfo, getSettings} from "@/service/api/settings.ts"; -import {buildProofreadResult} from "./components/parse-proofread-result.ts"; -// import FakeDocument1862 from "../../service/fake/doc-2236.ts"; -// import {cloneDeep} from "../../utils/cloneDeep.ts"; -// import {sleep} from "../../utils/sleep.ts"; - -// 数据 主要是保存当前文档id -const CACHE_DATA: { - DOC_ID: number; - timer: number | null | undefined | object | object; - userinfo?: Account; - upgradeInfo: AppUpgradeInfo; - clearTimer: () => void; -} = { - DOC_ID: 0, - userinfo: undefined, - upgradeInfo: {}, - timer: null, - clearTimer: () => { - if (CACHE_DATA.timer) { - clearTimeout(Number(CACHE_DATA.timer)) - CACHE_DATA.timer = 0; - } - } -} - -const progressConfig = { - start: 30, - rangeUp: 20 -}; - -export default function Home() { - const {userinfo: globalUser, logout, init} = useUserinfoStore() - const {bridge} = useBridge(); - const [userinfo, setUserinfo] = useState() - const [proofreadProgress, setProofreadProgress] = useState(-1); - const [disabledList,setDisabledList] = useState([]) - // const [currentDocumentId,setCurrentDocumentId] = useState(0); - - // 获取文档内容 - const getDocumentData = async () => { - const content = await bridge.getDocumentData(); - return JSON.parse(content) as DocumentData; - }; - - - // 校对并获取校对结果 - const getProofreadData = (settings?: Settings) => { - return new Promise((resolve, reject) => { - let retryCount = 0; - const getProofreadResult = (needSetTimeout = true) => { - setProofreadProgress(99); - // 获取结果 - proofreadDetail(CACHE_DATA.DOC_ID).then((data) => { - CACHE_DATA.clearTimer(); - setProofreadProgress(100); - setTimeout(() => { - // setProofreadProgress(-1); - resolve(data) - }, 500) - }).catch((e) => { - const ex = e as BizError; - if (ex.message == '文稿未完成校对' && needSetTimeout) { - CACHE_DATA.clearTimer(); - CACHE_DATA.timer = setTimeout(getProofreadResult, 1500 + 2000 * Math.floor(retryCount / 10)) - retryCount ++; - } - }) - } - const startCountDown = (current: number, count: number) => { - // 倒计时最多到99 获取结果后再将进度设置为100 - if (current >= count - 1) { - // 等待剩余时间后再次获取校对结果 - setTimeout(getProofreadResult, 2500) - return; - } - if (current % 10 == 0) { - getProofreadResult(false) - } - const p = Math.floor(current / count * 100); - // fixed bug 51 当前校对进度条是先慢后快,体验不好。改成先快后慢,前50%进程快一些,逐渐变慢 - if (p >= progressConfig.start + progressConfig.rangeUp) setProofreadProgress(p); - else setProofreadProgress(Math.floor(current / count * progressConfig.rangeUp) + progressConfig.start); - // count down - CACHE_DATA.timer = setTimeout(() => { - startCountDown(current + 1, count) - }, 1000) - } - setProofreadProgress(20); - // 開始校對 - proofread(CACHE_DATA.DOC_ID, 1, settings).then(ret => { - setProofreadProgress(30); - if (ret.remainingTime > 0) { - // 如果有剩余时间则 - //setTimeout(getProofreadResult, ret.remainingTime * 1000) - // 计算进度 - startCountDown(1, ret.remainingTime); - } else { - setTimeout(getProofreadResult, 500) - } - }).catch(reject) - }) - } - const noteReg = /^\[footnoteRef:\d+\]|\[endnoteRef:\d+\]$/ - // 保存内容并校对 - const getContentAndProofread = async () => { - try { - setDisabledList([]) - CACHE_DATA.clearTimer(); - setProofreadProgress(2); - const start = Date.now(); - const doc = await getDocumentData(); - if(doc.code != 0){ - setProofreadProgress(-1); - bridge.ShowDialog(doc.message) - return; - } - // setCurrentDocumentId(doc.documentId); - const count = calcContentLengthLikeWord(doc.content.text) - console.log('doc',count,doc,'get document data spent',Date.now() - start) - // const fakeDoc = cloneDeep(FakeDocument1862) - // if(fakeDoc.abnormalCount.total > 0){ - // bridge?.ShowCurrentPane(); - // setProofreadProgress(99); - // buildProofreadResult(fakeDoc); - // await sleep(0.2) - // if(CACHE_DATA.DOC_ID < 1){ - // const bridgeDocId = Number((await bridge?.GetCurrentDocumentId()) || 0); - // if(bridgeDocId > 0){ - // CACHE_DATA.DOC_ID = bridgeDocId; - // }else { - // CACHE_DATA.DOC_ID = 1000001; - // bridge?.SetCurrentDocumentId(CACHE_DATA.DOC_ID); - // } - // } - // await bridge?.InitContent(JSON.stringify(fakeDoc.correctedSet), CACHE_DATA.DOC_ID); - // setProofreadProgress(-1) - // // throw new Error('初始化校对项失败') - // return fakeDoc; - // } - if (doc.content.list.length == 0) { - resetProofreadData() - // bridge?.showDialog('当前文档为空,无法进行校对') - return; - } - - if (APP_CONFIG.ALLOW_MAX_COUNT > 0 && count > APP_CONFIG.ALLOW_MAX_COUNT) { - // bridge?.showDialog('正在校对中,请稍后再试...') - bridge?.ShowDialog('校对内容超过最大字数,请删减后再试...') - return; - } - bridge?.ShowCurrentPane(); - - // 判断是否已经创建了文档id - if (CACHE_DATA.DOC_ID <= 0) { - // 避免无意刷新网页导致 id 丢失 - const bridgeDocId = Number((await bridge?.GetCurrentDocumentId()) || 0); - if(bridgeDocId > 0){ - CACHE_DATA.DOC_ID = bridgeDocId; - }else{ - const {info} = await create({ - name: doc.name || ('未命名文档-' + formatTime(Date.now(), 'MMDDHHmmss')) - }); - CACHE_DATA.DOC_ID = info.id; - bridge?.SetCurrentDocumentId(CACHE_DATA.DOC_ID); - } - } - bridge?.clearAllProofreadMarkById(CACHE_DATA.DOC_ID); - const content = doc.content.list - // 过滤掉空行、特殊行 - .filter(it=>(it.Text.trim().length > 0 && !noteReg.test(it.Text))) - .map(it => ({ - insert: it.Text.replace(/\[endnoteRef:\d+\]|\[footnoteRef:\d+\]/ig,' '), - origin_text: it.Text, - hash: it.Hash, - insert_len: it.Text.length, - paragraph_num: it.ParagraphNumber, - } - )) - await save(CACHE_DATA.DOC_ID, content); - setProofreadProgress(5); - const settings = await getSettings(); - setProofreadProgress(15); - // fixed server bug at 240416 (cannot unmarshal string into Go struct field ProofreadReq.industry_publish of type int64) - // 如果是数字类型,则转换为数字类型 - Object.keys(settings).forEach(key => { - if (/^\d+$/.test(String(settings[key]))) { - settings[key] = Number(settings[key]) - } - }) - const result = await getProofreadData(settings); - buildProofreadResult(result); - const initSuccess = await bridge?.InitContent(JSON.stringify(result.correctedSet),CACHE_DATA.DOC_ID); - if(initSuccess == 'true') { - setProofreadProgress(-1) - }else{ - throw new Error('初始化校对项失败') - } - return result; - } catch (e) { - console.log('getContentAndProofread error:',e) - setProofreadProgress(-1); - throw e; - } - } - - // 在系统浏览器中打开链接 - const openUrlInOSBrowser = async (key: 'document' | 'lexicon') => { - const target = `${APP_CONFIG.WEB_PATH}/${key}?from=office-plugin`; - if (!CACHE_DATA.userinfo) { // 没有登录直接跳转 - bridge.OpenUrlWithOsBrowser(target) - return; - } - const {code} = await getAuthCode(); - const url = `${APP_CONFIG.WEB_PATH}/redirect?code=${code}&target=${encodeURIComponent(target)}`; - bridge.OpenUrlWithOsBrowser(url) - } - // 校对 - const { - data: document, loading, - run: startProofread, error, - mutate, - } = useRequest(getContentAndProofread, { - manual: true, - onError: () => { - //showToast('校对失败,请重试') - } - }) - const noticeLoginSuccess = () => { - if (CACHE_DATA.userinfo) { - setUserinfo(CACHE_DATA.userinfo) - const user = { - ...CACHE_DATA.userinfo, - nickname: hidePhone(CACHE_DATA.userinfo.nickname || CACHE_DATA.userinfo.phone), - expiration: '企业内测版' - } - bridge?.loginSuccess(JSON.stringify(user)) - } - } - - // 如果已经登录 则通知登录成功 - useEffect(() => { - if (globalUser || CACHE_DATA.userinfo) { - if (globalUser) CACHE_DATA.userinfo = globalUser - noticeLoginSuccess(); - } - }, [globalUser]) - - const getOldVersionUpgradeInfo = (up: UpgradeInfo)=>{ - return { - ...up, - clientType:up.client_type, - appName:up.app_name, - publishType:up.publish_type, - upgradeType:up.upgrade_type, - downloadUrl:up.download_url, - isShowPop:up.is_show_pop, - } - } - const getUpgradeInfo = (callback?: ()=>void)=>{ - bridge.GetAppVersion().then(version => { - // 版本小于 1.0.11 直接提示 - if(compareVersion(version, '1.0.11') === -1){ - getAppUpgradeInfo(version).then(info => { - // setUpgradeInfo(info) - console.log(info) - CACHE_DATA.upgradeInfo = info; - if(callback){ - callback(); - return; - } - if (info.upgradeAvailable && info.upgradeInfo.upgrade_type == 1) { - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(info.upgradeInfo))) - } - }) - } - }) - } - useEffect(getUpgradeInfo, []) - - // 开始校对 - const handleProofread = (force?: boolean) => { - // 没有登录则显示登录 - if (!CACHE_DATA.userinfo && !force) { - bridge?.ShowLoginForm("proofread") - return; - } - startProofread(); - } - // 避免来回乱跳 - const {run: setActiveBookMark} = useDebounceFn((id) => bridge?.SelectMarkById(id,CACHE_DATA.DOC_ID), {wait: 200,}) - const [currentSelectProofreadId, setCurrentSelectProofreadId] = useState(0) - const resetProofreadData = () => { - CACHE_DATA.clearTimer(); - mutate({ - abnormalCount: {total: -1}, - correctedSet: [], - }) - setProofreadProgress(-1) - bridge?.clearAllProofreadMarkById(CACHE_DATA.DOC_ID); - } - const checkLoginAndContinue = (callback: () => void, action = 'normal') => { - if (CACHE_DATA.userinfo) { - callback() - } else { - init().then((account) => { - if (account) { - CACHE_DATA.userinfo = account - callback() - } else { - bridge?.ShowLoginForm(action) - } - }) - } - } - - // 监听插件通知 - useBridgeMessageListener(({Message, Data}) => { - if (Message == 'start') { - // 添加强制更新检测 - if (CACHE_DATA.upgradeInfo.upgradeAvailable && CACHE_DATA.upgradeInfo.upgradeInfo!.upgrade_type == 1) { - // bridge.ShowUpgrade(JSON.stringify(CACHE_DATA.upgradeInfo.upgradeInfo)) - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(CACHE_DATA.upgradeInfo.upgradeInfo!))) - return; - } - // 开始校对 - checkLoginAndContinue(handleProofread); - // if (CACHE_DATA.userinfo) { - // handleProofread() - // } else { - // init().then((account) => { - // if (account) { - // CACHE_DATA.userinfo = account - // } else { - // bridge?.ShowLoginForm('normal') - // } - // }) - // } - } else if (Message == 'upgrade') { // 升级信息 - if (!CACHE_DATA.upgradeInfo.upgradeAvailable) { - bridge.ShowDialog("当前版本为最新版本,无需升级") - return; - } - if (CACHE_DATA.upgradeInfo.upgradeInfo) { - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(CACHE_DATA.upgradeInfo.upgradeInfo!))) - // bridge.ShowUpgrade(JSON.stringify(CACHE_DATA.upgradeInfo.upgradeInfo)) - } - } else if (Message == 'clear-tips') { // 显示词库 - resetProofreadData() - bridge.HideCurrentPane() // 隐藏当前面板 - } else if (Message == 'show-setting') { // 显示设置 - checkLoginAndContinue(() => { - bridge?.ShowSettingForm() - }, 'setting'); - } else if (Message == 'show-lexicon') { // 显示词库 - openUrlInOSBrowser('lexicon').catch(console.error) - } else if (Message == 'logout') { // 退出登录 - logout().then(() => { - resetProofreadData() - bridge?.Logout("async-info") - }) - } else if (Message == 'async-logout') { // 同步注销登录 - resetProofreadData() - CACHE_DATA.userinfo = undefined; - } else if (Message == 'async-login-success') { - init().then(console.log) - } else if (Message == 'select-proofread') { - const id = Number(Data) - if (id > 0) setCurrentSelectProofreadId(id) - } else if (Message == 'getParagraphTextByRange') { - console.log('getParagraphTextByRange', Data) - }else if(Message == 'disabled-proofread'){ - // console.log('disabled-proofread',Data) - setDisabledList(Data as number[]) - // - } else { - console.log('App useBridgeMessageListener:', Message,Data) - } - }) - // const xxx = ()=>{ - // //169567 169569 169564 - // // setDisabledList(disabledList => [...disabledList,169564]) - // // setProofreadProgress(100) - // const result = document?.correctedSet.filter(it=>it.diffs && it.diffs.length > 0).map(it=>{ - // it.diffs?.forEach(s=>{ - // console.log(s.idx,s,it.insert) - // }) - // return it - // }); - // console.log( - // result,disabledList - // ) - // } - return (
- {userinfo && proofreadProgress > 0 && openUrlInOSBrowser('document')}/>} - {userinfo && !loading && error && openUrlInOSBrowser('document')}/>} - {userinfo && !loading && !error && document && document.abnormalCount.total === 0 && } - - {/*
*/} - {/**/} - {/*
*/} - - {(!userinfo || (!loading && !error)) && { - // 还原标签状态 - bridge?.processMark(item.id, item.isAccept) - }} - onSelectProofreadItem={(item) => { - if (item) setActiveBookMark(item.id) - }} - onStartProofread={() => handleProofread()} - selectedProofreadItemId={currentSelectProofreadId} - />} -
) -} \ No newline at end of file diff --git a/src/pages/home-deprecated/notice.tsx b/src/pages/home-deprecated/notice.tsx deleted file mode 100644 index cfe4cd9..0000000 --- a/src/pages/home-deprecated/notice.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React from "react"; -import {Button, Space} from "antd"; -import Icon from "@ant-design/icons"; -import {ErrorNotice} from "./components/images/notice.tsx"; -import {IconLogo} from "./components/images/logo.tsx"; -import IconPerfect from "./images/perfect.png"; - -type NoticeProps = { - onOpenWebDocument?: () => void; - onStartProofread?: () => void; - progress?: number | string; -} - -export function ProofreadLoading({progress}: NoticeProps) { - // 加载中... - // 这里可以添加自定义的加载中逻辑 - // 例如,显示一个加载动画或提示信息 - return (
-
-
- -
-
-
{progress}
-
-
-
- {/*

正在返回校对结果...

*/} -
- {/**/} - {/* */} - {/* 等得太久?您也可以查看该任务*/} - {/**/} -
- -
) -} - -export function ProofreadError({onStartProofread, onOpenWebDocument}: NoticeProps) { - // 加载中... - // 这里可以添加自定义的加载中逻辑 - // 例如,显示一个加载动画或提示信息 - return (
-
- -
-

- 糟糕!校对出现了问题 -

-

请重新进行校对或前往网页端查看

-
-
- -
- - - - -
-
- -
) -} - -export function ProofreadPerfect({onStartProofread, onOpenWebDocument}: NoticeProps) { - return (
-
- -
- -

- 非常完美 -

-
-
-
-
); -} \ No newline at end of file diff --git a/src/pages/lexicon/components/columns.tsx b/src/pages/lexicon/components/columns.tsx deleted file mode 100644 index 0cc5cab..0000000 --- a/src/pages/lexicon/components/columns.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import {formatTime} from "../../../utils/strings.ts"; -import React from "react"; -import {TBlackLexiconItem, TWhitelistItem} from "@/service/types/lexicon.ts"; -import {ColumnGroupType, ColumnType} from "antd/es/table/interface"; -import {css} from "@emotion/css"; - - -export type LexiconType = TBlackLexiconItem | TWhitelistItem - -export interface EditableCellProps extends React.HTMLAttributes { - editing: boolean; - dataIndex: string; - title: any; - inputType: 'number' | 'text' | 'select'; - record: LexiconType; - index: number; - children: React.ReactNode; -} - - - -export type TableColumnType = { - dataIndex?: string; - editable?: boolean; -} & (ColumnGroupType | ColumnType) - -/** - * - * @param type 黑名单|白名单 - * @param indexRender 序号列 - * @param optionRender 操作列 - */ -export function getColumns( - type: 'white' | 'black', - indexRender: (id: any, item: LexiconType, index: number) => React.ReactNode, - optionRender: (_: any, item: LexiconType) => React.ReactNode -) { - const columns: TableColumnType[] = [ - { - title: '序号', - dataIndex: 'id', - key: 'id', - width: 100, - render: indexRender - }, - { - title: type === 'white' ? '放行词' : '拦截词', - dataIndex: 'word', - width: 350, - key: 'word', - editable: true, - }, - { - title: '领域', - dataIndex: 'type', - width: 150, - key: 'type', - editable: true, - render: (_, item: LexiconType) => { - return '通用' - } - }, - - ]; - if (type === 'black') { - columns.push(...[ - { - title: '操作建议', - dataIndex: 'actionType', - key: 'actionType', - editable: true, - width: 170, - render: (_: any, item: LexiconType) => { - return item.actionType == 1 ? '拦截' : '替换'; - } - }, - { - title: '替换词', - dataIndex: 'replaceWord', - key: 'replaceWord', - width: 350, - editable: true, - render: (_: any, item: LexiconType) => { - return item.actionType == 2 ? item.replaceWord : ''; - } - } - ]) - } - columns.push({ - title: '修改时间', - dataIndex: 'utime', - key: 'utime', - className:css(`min-width:200px`), - render: (_, item: LexiconType) => { - return formatTime((item.utime || item.ctime || 0) * 1000); - } - }) - columns.push({ - title: '操作', - key: 'operation', - width: 200, - render: optionRender - }) - return columns -} - diff --git a/src/pages/lexicon/components/import-file.tsx b/src/pages/lexicon/components/import-file.tsx deleted file mode 100644 index 472611c..0000000 --- a/src/pages/lexicon/components/import-file.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import {Button, Divider, Modal, Spin, Upload} from "antd"; -import React from "react"; -import {useBoolean, useSetState} from "ahooks"; -import {LoadingOutlined} from "@ant-design/icons"; -import type {UploadProps} from 'antd'; -import {blacklist, whitelist} from "@/service/api/lexicon.ts"; -import {showToast, useLoading} from "@/components/messages/Modal.tsx"; -import {TImportBlackResult} from "@/service/types/lexicon.ts"; - -type ImportFileProps = { - visible?: boolean; - onClose?: (refresh?: boolean) => void; - type: 'white' | 'black'; -} -const loadingIcon = ; -type UploadResult = { - onClose?: (refresh?: boolean) => void; - result?: TImportBlackResult -} -const UploadResult: React.FC = (props) => { - return (
-

批量导入词条

- -

本次共导入 {props.result?.totalWords?.length|| 0} 条,导入成功 {props.result?.words?.length || 0} 条;

-
- {props.result?.repeatWords && props.result?.repeatWords.length > 0 && -

{props.result?.repeatWords.map(s => `"${s}"`).join(',')} 因重复被过滤

} - {props.result?.formatErrorWords && props.result?.formatErrorWords.length > 0 && -

{props.result?.formatErrorWords.map(s => `"${s}"`).join(',')} 因格式错误被过滤

} -
-
-
- -
-
-
) -} - -export const ImportFileModal: React.FC = (props) => { - // const [loading,setLoading] = useState(false) - const [loading, {set: setLoading}] = useBoolean(false) - const [showResult, {setTrue}] = useBoolean(false); - const [state, setState] = useSetState<{ - showResult?: boolean; - loading?: boolean; - result?: TImportBlackResult - }>({}); - const downloadUrl = `https://staticplus.gachafun.com/aixiaodui/templates/${props.type}list.xlsx?s=${Math.random().toString(16).substring(2)}`; - - const uploadProps: UploadProps = { - multiple: false, - maxCount: 1, - accept: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - // itemRender:()=>null, - showUploadList: false, - withCredentials: true, - beforeUpload: (file) => { - setState({loading: true}) - const upload = props.type === 'black' ? blacklist.import : whitelist.import - upload(file) - .then(result => { - setState({ - showResult: true, - result - }) - }) - .catch(e => showToast(`导入失败(${e.message})`,'warning')) - .finally(() => setState({loading: false})) - return false; - }, - }; - const downloading = useLoading(); - const downloadTemplate = async (e:React.MouseEvent)=>{ - e.preventDefault() - e.stopPropagation() - // downloading.show('下载中请稍等'); - chrome.webview.hostObjects.host.Download(downloadUrl); - //await download(downloadUrl,`${props.type == 'white' ? '白名单' : '黑名单'}-模板.xlsx`) - // downloading.close() - } - - return ( props.onClose?.(state.showResult)} - footer={null} - width={600} - centered - > - {state.showResult ? : - 导入中} indicator={loadingIcon}> -
-

批量导入词条

- -
- 1、请下载模板后,严格按照模板进行填写;
- 2、仅支持“.xls/.xlsx”两种格式,每次导入的词条数量不超过1000个;
- 3、词条不可重复,不可包含空格及逗号,不符合要求的词条将被自动过滤. -
-
-
- - - -
- -
-
-
} -
) -} diff --git a/src/pages/lexicon/components/modify-modal.tsx b/src/pages/lexicon/components/modify-modal.tsx deleted file mode 100644 index 945f2ad..0000000 --- a/src/pages/lexicon/components/modify-modal.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import {Button, Form, Input, Modal, Select, Space} from "antd"; -import React from "react"; -import {useBoolean, useSetState} from "ahooks"; -import { - BlackCreateActionType, - TBlackLexiconItem, - TWhitelistItem -} from "@/service/types/lexicon.ts"; -import {blacklist, whitelist} from "@/service/api/lexicon.ts"; -import {showToast} from "../../../components/messages/Modal.tsx"; - -type LexiconType = TWhitelistItem | TBlackLexiconItem; -type SaveModalProps = { - visible?: boolean; - onClose?: (refresh?: boolean) => void; - lexicon: LexiconType; - type: 'white' | 'black' -} - - -const SuggestionList = [ - {value: 1, label: '拦截'}, - {value: 2, label: '替换'}, -] - -export const ModifyModal: React.FC = (props) => { - const [loading, {set: setLoading}] = useBoolean(false) - const [showResult, {setTrue}] = useBoolean(false); - - const handleSubmit = () => { - const params = form.getFieldsValue(); - // 执行保存 - const save = props.type == 'white' ? whitelist.modify : blacklist.modify; - setLoading(true) - save(props.lexicon.id, params as any).then(() => { - showToast('修改名单成功', 'success'); - props.onClose?.(true) - }).catch((e: BizError) => showToast(e.message || '修改名单失败','warning')).finally(() => setLoading(false)) - }; - - const [form] = Form.useForm() - const [state, setState] = useSetState<{ - actionType?: BlackCreateActionType - }>({ - actionType: props.lexicon.actionType - }) - - return ( props.onClose?.()} - footer={null} - > -
-

修改{props.type == 'white' ? '白' : '黑'}名单词条

-
- - - - - setState({actionType})} - /> - } - - {props.type === 'black' && state.actionType == BlackCreateActionType.Replace && ({ - validator(_, value) { - if (getFieldValue('word') === value) { - return Promise.reject(new Error('拦截词与替换词相同')); - } - return Promise.resolve(); - }, - }), - ]} - > - - - } -
- - - - -
-
-
-
) -} diff --git a/src/pages/lexicon/components/save-modal.tsx b/src/pages/lexicon/components/save-modal.tsx deleted file mode 100644 index b498f3d..0000000 --- a/src/pages/lexicon/components/save-modal.tsx +++ /dev/null @@ -1,243 +0,0 @@ -import {Button, Input, Modal, Select, Space} from "antd"; -import React, {useState} from "react"; -import {useBoolean} from "ahooks"; -import {cloneDeep} from "lodash" -import { - BlackCreateActionType, - TBatchCreateError, - TCreateBatch -} from "@/service/types/lexicon.ts"; -import {blacklist, whitelist} from "@/service/api/lexicon.ts"; -import {showToast} from "../../../components/messages/Modal.tsx"; -import {PlusOutlined} from "@ant-design/icons"; - -type SaveModalProps = { - visible?: boolean; - onClose?: (refresh?: boolean) => void; - type: 'white' | 'black' -} - -type LexiconField = { - words: string | number; - type: string | number; - suggestion: string | number; - replace: string | number; -} -type LexiconFieldList = keyof LexiconField; -type FieldValue = { - value: string | number; - message?: string; -} -type LexiconFieldItem = { - [field in LexiconFieldList]: FieldValue -}; -const defaultFieldRow = { - words: {value: '', message: undefined}, - type: {value: 1, message: undefined}, - suggestion: {value: BlackCreateActionType.Delete, message: undefined}, - replace: {value: '', message: undefined}, -} -const SuggestionList = [ - {value: 1, label: '拦截'}, - {value: 2, label: '替换'}, -] - -export const SaveModal: React.FC = (props) => { - const [loading, {set: setLoading}] = useBoolean(false) - const [showResult, {setTrue}] = useBoolean(false); - - const [fieldList, setFieldList] = useState([cloneDeep(defaultFieldRow)]) - const requireCheck = (row: LexiconFieldItem, key: string) => { - // @ts-ignore - const item = row[key] as FieldValue; - if (!item.value) { - item.message = '未填写' - return false; - } - if(key == 'replace' && item.value == row.words.value){ - item.message = '拦截词与替换词相同'; - return false; - } - return true; - } - const handleSubmit = () => { - const values: LexiconField[] = [] - let hasError = false; - const params: TCreateBatch = { - words: [], - actionTypes: [], - replaceWords: [], - } - // 验证是否填写 - fieldList.forEach(row => { - row.words.message = undefined; - row.replace.message = undefined; - if (!requireCheck(row, 'words')) hasError = true; - if (props.type === 'black' && row.suggestion.value === BlackCreateActionType.Replace && !requireCheck(row, 'replace')) hasError = true; - params.words.push(row.words.value as any); - if (props.type == 'black') { - params.actionTypes.push(row.suggestion.value as any); - params.replaceWords.push(row.replace.value as any); - } - values.push({ - words: row.words.value, - type: row.type.value, - suggestion: row.suggestion.value, - replace: row.replace.value, - }) - }) - if (hasError) { - setFieldList(cloneDeep(fieldList)); - return; - } - setFieldList(cloneDeep(fieldList)); - // 执行保存 - const save = props.type == 'white' ? whitelist.createBatch : blacklist.createBatch; - setLoading(true) - save(params).then(() => { - resetData() - showToast('添加成功','success'); - props.onClose?.(true) - }).catch((e: BizError) => { // - if (e.data && e.code == 2) { - console.log('create e', e, e.data) - //校验失败 - const data = e.data as TBatchCreateError[]; - data.forEach(it => { - // 是否存在该词条 - if (!fieldList[it.index]) return; - if (it.type !== 1) { // 拦截词 - if (props.type == 'black') { - fieldList[it.index].replace.message = it.msg - } - } else { - fieldList[it.index].words.message = it.msg - } - }) - setFieldList(cloneDeep(fieldList)); - return; - } - showToast(e.message || '批量添加名单失败','warning') - }).finally(() => setLoading(false)) - }; - const resetData = () => { - setFieldList([ - cloneDeep(defaultFieldRow) - ]) - } - const addItem = () => { - const item: LexiconFieldItem = cloneDeep(defaultFieldRow) - console.log('addItem', item) - setFieldList([ - ...fieldList, - item - ]) - } - const removeItem = (index: number) => { - if (fieldList.length == 1) return; - const list = cloneDeep(fieldList) - list.splice(index, 1) - setFieldList(list); - } - const setFieldValue = (key: string, index: number, value: any) => { - // @ts-ignore - const item = fieldList[index][key] as FieldValue; - item.value = value; - setFieldList(cloneDeep(fieldList)); - } - - return ( props.onClose?.()} - footer={null} - width={props.type == 'white' ? 700 : 850} - > -
-

添加{props.type == 'white' ? '白' : '黑'}名单词条

-
-
-
-
{props.type == 'white' ? '放行词' : '拦截词'}
-
词条类型
- {props.type == 'black' && <> -
操作建议
-
替换词
- } -
-
- {fieldList.map((it, index) => (
-
-
- { - setFieldValue('words', index, e.currentTarget.value) - }} - placeholder="请输入" - className={it.words.message ? 'has-error' : ''} - /> -
-
{it.words.message}
-
-
-
- setFieldValue('suggestion', index, value)} - value={it.suggestion.value} - options={SuggestionList} - /> -
-
{it.type.message}
-
-
-
- setFieldValue('replace', index, e.currentTarget.value)} - placeholder={it.suggestion.value == 'rep' ? "请输入" : ''} - className={it.replace.message ? 'has-error' : ''} - /> -
-
{it.replace.message}
-
- - } -
- {fieldList.length > 1 && - removeItem(index)}>删除} -
-
))} -
-
- -
- -
- - - - -
-
-
-
) -} diff --git a/src/pages/lexicon/index.tsx b/src/pages/lexicon/index.tsx deleted file mode 100644 index 8acef24..0000000 --- a/src/pages/lexicon/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import {Tabs} from "antd"; -import {useState} from "react"; -import "./lexicon.less" -import {Lexicon} from "./lexicon.tsx"; -import {useNavigate, useSearchParams} from "react-router-dom"; -import { AppTitleBar } from '@/components/app/title-bar.tsx'; - -export default function LexiconIndex() { - const [params] = useSearchParams(); - const navigate = useNavigate() - - const [activeTab, setActiveTab] = useState(params.get('tab') || 'white') - const onChange = (tab: string) => { - navigate(`?tab=${tab}`) - setActiveTab(tab) - } - return <> - -
- , - }, - { - label: `黑名单`, - key: 'black', - children: , - } - ]} - className="normal-tab" - /> -
- ; -}; diff --git a/src/pages/lexicon/lexicon.less b/src/pages/lexicon/lexicon.less deleted file mode 100644 index 3af6398..0000000 --- a/src/pages/lexicon/lexicon.less +++ /dev/null @@ -1,170 +0,0 @@ -.lexicon-wrapper { - height: calc(100vh - 50px); - overflow-y: auto; - padding: 20px; - box-sizing: border-box; - .lexicon { - - } - - .search-form { - margin: 20px 0; - } - - .data-table { - - .aui-table-container { - border: solid 1px var(--border-color); - border-radius: 0; - } - } - .modify-button{ - min-width: 60px; - height: 30px; - } - .del-link{ - color: #757575; - &:hover{ - color: #333; - } - } -} - -.modal-import-file { - .import-file-result { - font-weight: bold; - padding: 30px 20px; - } - - .count { - color: #FA674A; - } - - .import-message { - margin-top: 30px; - } -} -.modal-save-lexicon{ - .modify-modal-body{ - padding: 30px; - } -} -.modal-save-lexicon { - .save-modal-body{ - padding: 30px; - } - h2{ - margin-bottom: 20px; - } - .form-table { - border: solid 1px var(--border-color); - } - - .item { - border-left: solid 1px transparent; - flex: 2; - margin-left: 20px; - &:first-child{ - border-left: none; - margin-left: 0px; - } - } - .item-input{ - width: 170px; - } - .item-suggestion{ - flex:1; - } - .item-type{ - flex:1; - min-width: 130px; - } - - .header { - background-color: #fafafa; - font-weight: bold; - - .item { - border-left-color: var(--border-color); - padding-left: 10px; - &:first-child{ - padding-left: 0px; - } - } - .item-type{ - margin-left: 30px; - } - } - - .table-row { - display: flex; - align-items: flex-start; - justify-content: space-between; - border-top: solid 1px var(--border-color); - padding: 8px 10px; - &:first-child{ - border-top: none; - } - } - .aui-input-disabled{ - border:none; - } - - .item-operation { - width: 80px; - padding-top: 3px; - } - .add-row{ - margin: 20px 0; - } - .validate-message{ - color: #FA674A; - } - .has-error{ - border-color:#FA674A; - } - .save-modal-white{ - .item-words{ - display: flex; - align-items: center; - } - .validate-message{ - margin-left: 10px; - } - } -} - -// tab 样式 -.normal-tab { - .aui-tabs-nav { - background-color: var(--background-color); - margin-bottom: 0; - - .aui-tabs-tab { - background-color: transparent; - border-radius: 0 !important; - border: none; - font-weight: bold; - color: #ABABAB; - padding: 13px 40px; - justify-content: center; - - &.aui-tabs-tab-active { - background-color: #fff; - - .aui-tabs-tab-btn { - color: #000; - } - } - } - } - - .aui-tabs-ink-bar { - display: none; - } - - .aui-tabs-content-holder { - background-color: #fff; - padding: 40px; - } -} diff --git a/src/pages/lexicon/lexicon.tsx b/src/pages/lexicon/lexicon.tsx deleted file mode 100644 index a9ca599..0000000 --- a/src/pages/lexicon/lexicon.tsx +++ /dev/null @@ -1,355 +0,0 @@ -import React, {useEffect} from "react"; -import {Button, DatePicker, Divider, Form, Input, Select, Space, Table, Typography} from "antd"; -import {RightOutlined} from "@ant-design/icons"; -import {useRequest, useSetState} from "ahooks"; -import {ImportFileModal} from "./components/import-file.tsx"; -import {showToast, useConfirm} from "@/components/messages/Modal.tsx"; -import {SaveModal} from "./components/save-modal.tsx"; -import {Pagination} from "@/components/pagination"; -import {BlackCreateActionType, TListParam} from "@/service/types/lexicon.ts"; -import {whitelist, blacklist} from "@/service/api/lexicon.ts" -import {EditableCellProps, getColumns, LexiconType} from "./components/columns.tsx"; -import dayjs from "dayjs"; - -type PageType = 'white' | 'black' -// type Lexicon -type LexiconProps = { - type: PageType -} - - -// 是否隐藏删除提示的key -const HIDE_NOTICE_KEY = 'ai-proofread-hide-remove-notice', - Storage = window.sessionStorage // 采用session存储缓存 - -export const Lexicon: React.FC = (props) => { - const [form] = Form.useForm() - // 搜索为单独触发所以文本需要独立 - - const [searchParam, setSearchParam] = useSetState({ - pageSize: 10, - currentPage: 1 - }) - // 数据 - const {data: dataSource, run: loadingDataList, loading} = useRequest(() => { - return props.type === 'white' ? whitelist.list(searchParam) : blacklist.list(searchParam) - }, { - manual: true, - debounceWait: 500, - onSuccess: (data) => { - if(state.modifyItem){ - setState({modifyItem: undefined}) - } - // 处理页码错误 - if (data.list.length == 0 && data.pagination.total > 0) { - const maxPage = Math.ceil(data.pagination.total / data.pagination.pageSize); - if (data.pagination.current > maxPage) { - setSearchParam({currentPage: maxPage}) - } - } - } - }) - // const loadData - - const {confirmHolder, showConfirm} = useConfirm() - // 删除后重新加载数据 - const loadDataAfterDelete = (type: 'deleteAll' | 'delete' = 'deleteAll') => { - if (dataSource) { - const page = dataSource.pagination - // 判断是否需要到上一页 - const maxPage = Math.ceil(page.total / page.pageSize); - if (page.current >= maxPage && maxPage > 1) { // 如果在最后一页且该页大于第一页 则自动加载前一页数据 - if ( - (type == 'deleteAll' && state.selectedKeys.length == dataSource.list.length) - || (type == 'delete' && dataSource.list.length === 1)) { // 删除了该页所有数据 - setSearchParam({currentPage: maxPage - 1}) - return; - } - } - } - loadingDataList(); - } - // 处理多选删除 - const handleDeleteAll = () => { - if (state.selectedKeys.length == 0) return; - showConfirm({ - content: '是否删除选中结果? 请注意删除后不可恢复', - onYes() { - const remove = props.type === 'black' ? blacklist.removeBatch : whitelist.removeBatch - // 删除并刷新 - remove(state.selectedKeys) - .then(() => { - loadDataAfterDelete(); - setState({selectedKeys: []}) // 重置选择项 - }) - .catch((e: BizError) => showToast('删除失败:' + e.message || '请稍后重试', 'warning')) - } - }) - } - // 删除 - const deleteData = (item: LexiconType) => { - const remove = props.type === 'black' ? blacklist.remove : whitelist.remove - // 删除并刷新 - remove(item.id).then(() => { - loadDataAfterDelete('delete') - }).catch((e: BizError) => showToast('删除失败:' + e.message || '请稍后重试', 'warning')) - } - - const handleRemove = (item: LexiconType) => { - // 判断是否需要隐藏 - if (Storage.getItem(HIDE_NOTICE_KEY)) { - deleteData(item) // 直接走删除流程 - } else { - // 弹出提醒 - showConfirm({ - content: '是否删除选中结果? 请注意删除后不可恢复', - showNextAsk: true, // 是否显示下一次还问 - onYes(hideNextNotice) { - // 需要隐藏写入缓存 - if (hideNextNotice) Storage.setItem(HIDE_NOTICE_KEY, 'yes') - deleteData(item) // 走删除流程 - } - }) - } - } - // 页面状态 - const [state, setState] = useSetState<{ - importVisible?: boolean, - saveVisible?: boolean, - modifyVisible?: boolean, - saving?: boolean; - selectedKeys: any[], - modifyItem?: LexiconType; - }>({ - selectedKeys: [] - }) - // 全选 - const toggleSelectAll = () => { - if (!dataSource) return; - if (state.selectedKeys.length != dataSource.list.length) { - const selectedKeys = dataSource.list.map(s => s.id); - setState({selectedKeys}) - } else { - setState({selectedKeys: []}) - } - } - // 搜索表单 - const onFormSearch = () => { - const values = form.getFieldsValue(); - const timeParams:{startTime?: number, endTime?: number} = {startTime:undefined,endTime:undefined} - // 搜索时间 - if (values.time) { - const [start, end] = values.time; - const timeStart = start.format('YYYY-MM-DD') + ' 00:00:00'; - const endStart = end.format('YYYY-MM-DD') + ' 23:59:59'; - timeParams.startTime = dayjs(timeStart).unix() - timeParams.endTime = dayjs(endStart).unix() - } - setSearchParam({ - currentPage: 1, - word: values.word, - ...timeParams - }) - } - // 加载 - useEffect(loadingDataList, [searchParam]); - const [modifyForm] = Form.useForm(); - - const [modifyState, setModifyState] = useSetState<{ - category?:number; - action?:number; - }>({}) - const handleModifySave = async () => { - try{ - const params = (await modifyForm.validateFields()); - - params.actionType = modifyState.action; - params.type = modifyState.category; - if(modifyState.action == 1){ - // 修改为拦截则将替换词置为空 - params.replaceWord = ''; - } - // 执行保存 - const save = props.type == 'white' ? whitelist.modify : blacklist.modify; - setState({saving: true}) - save(state.modifyItem!.id, params).then(() => { - showToast('修改名单成功', 'success'); - loadingDataList(); - }).catch((e: BizError) => showToast(e.message || '修改数据失败', 'warning')) - .finally(() => setState({saving: false})) - }catch (e) {} - } - // 列配置 - const columns = getColumns(props.type, (_, _item, index) => { - return (index + 1) + ((dataSource?.pagination.current || 1) - 1) * (searchParam.pageSize || 10); - }, (_, item: LexiconType) => { - return (state.modifyItem && state.modifyItem.id == item.id ? - - - : - { - setModifyState({ - category:item.type, - action:item.actionType - }) - modifyForm.setFieldsValue({...item}); - // 修改 - setState({ - modifyItem: item, - modifyVisible: true - }) - }}>编辑 - - handleRemove(item)}>删除 - ) - }) - // 合并列 - const mergedColumns = columns.map((col) => { - if (!col.editable) { - return col; - } - const dataIndex = (col as any).dataIndex as string; - return { - ...col, - onCell: (record: LexiconType) => ({ - record, - inputType: (dataIndex === 'actionType' || dataIndex === 'type') ? 'select' : 'text', - dataIndex: dataIndex, - title: col.title, - editing: state.modifyItem && state.modifyItem.id == record.id, - }), - }; - }); - - // 修改数据 - const SuggestionList = [ - {value: 1, label: '拦截'}, - {value: 2, label: '替换'}, - ] - const ActionTypeSelect = () => (setModifyState({category})} className="w-full" options={[{value: 0, label: '通用'},]}/>) - // 自定义单元格渲染 - const EditableCell: React.FC = - ({ - editing, - dataIndex, - title, - inputType, - record, - index, - children, - ...restProps - }) => { - - const rules: any[] = dataIndex === 'replaceWord'?[]:[{required: true, message: `请填写${title}`}] - if (dataIndex === 'replaceWord') { - rules.push(({getFieldValue}: { getFieldValue: (key: string) => string }) => ({ - validator(_: any, value: string) { - // 替换时才判断 - if(modifyState.action == 2){ - if(value.length == 0){ - return Promise.reject(new Error('请填写替换词')); - } - if (getFieldValue('word') === value) { - return Promise.reject(new Error('拦截词与替换词相同')); - } - } - return Promise.resolve(); - }, - })) - } - return ( - - {editing ? ( - {dataIndex === 'actionType' ? : ( - dataIndex === 'type' ? : () - )} - ) : (children)} - - ); - }; - - return (
- {confirmHolder} - { - setState({saveVisible: false}) - if (refresh) loadingDataList(); - }}/> - {/*导入*/} - {state.importVisible && { - setState({importVisible: false}) - if (refresh) loadingDataList(); - }}/>} - - - - -
- - - - - } - - /> - - - - - - - -
-
-
-
- { - setState({selectedKeys}) - }, - }} - dataSource={dataSource?.list || []} - columns={mergedColumns as any} - pagination={false} - loading={loading} - /> - - - {dataSource && dataSource.pagination.total > 0 &&
-
-
{state.selectedKeys.length == dataSource?.list.length ? '取消全选' : '全选'}
- {state.selectedKeys.length > 0 &&
- {/**/} - 批量删除 -
} -
- {dataSource && setSearchParam({currentPage})} - emptyText={null} - />} -
} - - ) -} diff --git a/src/pages/login/components/terms/agreement.tsx b/src/pages/login/components/terms/agreement.tsx deleted file mode 100644 index e8b6402..0000000 --- a/src/pages/login/components/terms/agreement.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import React from "react"; -import {companyName,productName} from "./env.ts" - -export const AgreementContent: React.FC = () => { - return ( -
-

{productName}(以下统称“本产品”)是由{companyName}(下称“本公司”或“我们”)所有和负责运营,本协议双方为本公司与本产品注册用户(下称“用户”或“您”)签订的具有合同效力的文件。 -

-

- 请您在注册成为本产品用户前务必仔细阅读本协议内容,若您不同意本协议的任何内容,或者无法准确理解本公司对条款的解释,请不要进行后续操作;若您注册成为本产品用户,则表示您对本协议的全部内容已充分阅读并认可和同意遵守。同时,承诺遵守中国法律、法规、规章及其他政府规范性文件规定,如有违反而造成任何法律后果,您将以本人名义独立承担所有相应的法律责任。 -

-

如您未满18周岁,请在监护人陪同下仔细阅读并充分理解本协议,并征得监护人的同意后使用本产品及相关服务。 -

-

- 本公司有权根据需要不定时地制定、修改本协议或各类规则,经修订的协议、规则一经公布,立即自动生效。对新协议、规则生效之后注册的用户发生法律效力,对于协议、规则生效之前注册的用户,若用户在新规则生效后继续使用本产品提供的各项服务,则表明用户已充分阅读并认可和同意遵守新的协议或规则。若用户拒绝接受新的协议和规则,用户有权放弃或终止继续使用本产品提供的各项服务,但该用户应承担在本产品已经进行的交易下所应承担的任何法律责任,且应遵循该用户发生交易时有效的协议或规则内容。 -

-

发布日期:2023年 12 01

-

生效日期:2023 12 月01日

-

一、定义与解释

-

1、{productName}:是指一个可以为用户提供准确高效的内容审核、校对的工具,包含的形态包含SAAS产品,客户端,插件。 -

-

2、用户:本协议中的“用户”指在阅读本协议后选择接受本协议全部条款的使用者。用户可通过注册、登录本产品账号使用本产品的服务。 -

-

3、账号及密码:指您完成真实信息注册后,享有的用户账号及相应的密码,该用户账号和密码由您负责保管;您应当对以其用户账号下进行的所有行为负法律责任。 -

-

二、关于“账号”

-

1、账号的注册

-

- (1)您使用本产品可以自行申请注册账户进行授权登录,您的账号为您注册使用的手机号,通过账号+验证码方式注册和登录。您设置的账号作为登录、注册用户身份使用本产品的凭证。 -

-

- (2)您理解并承诺,您所设置的账号不得违反国家法律法规及本公司的相关规则,您的账号名称、头像和简介等注册信息及其他个人信息中不得出现违法和不良信息,未经他人许可不得用他人名义(包括但不限于冒用他人姓名、名称、字号、头像等足以让人引起混淆的方式)开设账号,不得恶意注册账号(包括但不限于频繁注册、批量注册账号等行为)。您在账号注册及使用过程中需遵守相关法律法规,不得实施任何侵害国家利益、损害其他公民合法权益,有害社会道德风尚的行为。本公司有权对您提交的注册信息进行审核。 -

-

- (3)您应保证注册/登录账号时需填写有效的手机号码,并使用手机验证短信来完成账户注册。若因您填写的手机号码不完整或不准确,则可能无法使用本产品或在使用过程中受到限制。 -

-

- (4)您应保证您注册时提供的信息的真实性,请您在注册、管理账号时使用真实、准确、合法、有效的相关信息认证材料及必要信息。若您提交的材料或提供的信息不准确、不真实、不合法或者本公司有理由怀疑为错误、不实或不合法的资料,则本公司有权拒绝为您提供相关服务或您可能无法使用本产品或在使用过程中部分功能受到限制。 -

-

2、账号使用

-

- (1)您在本产品中的注册账号所有权及有关权益均归本公司所有,您完成注册手续后仅享有该账号的使用权,您应当正确、适当地使用、运营、管理本产品账号。您的账号仅限于您本人使用,未经本公司书面同意,禁止以任何形式赠与、借用、出租、转让、售卖或以其他方式许可他人使用该账号。如果本公司发现或者有合理理由认为账号使用者并非您本人,本公司有权在未通知您的情况下,暂停或终止向该注册账号提供服务,并有权注销该账号,而无需向您户承担法律责任。 -

-

- (2)您有责任维护您的个人账号的安全性与保密性,并对您以注册账号名义所从事的活动承担全部法律责任,包括但不限于您通过本产品上进行的任何数据修改、言论发表等操作行为。您应高度重视对账号的保密,在任何情况下不向他人透露账号。若发现他人未经许可使用您的账号或发生其他任何安全漏洞问题时,您应当立即通知本公司。 -

-

- (3)您的账号在丢失后,可遵照本公司的申诉途径及时申诉请求找回账号。您理解并认可,本公司的账号找回机制仅需要识别申诉单上所填资料与系统记录资料具有一致性,若您提供的信息不真实或不完整,导致无法核实您的身份或判断您的需求而未进行及时处理所造成的一切损失由您自行承担。同时,您理解我们的回复和采取措施需要合理期限。我们不对非本团队原因造成的任何损失承担责任。 -

-

- (4)本公司特别提醒您应妥善保管您的账号。当您使用完毕后,应安全退出。因您保管不当可能导致遭受盗号,责任由您自行承担。如您的账户遭到第三方使用或发生其他任何问题,您有义务及时通知本公司(包括但不限于提供您的身份信息和相关身份资料、相关事实情况及您的要求等)。 -

-

- (5)为保障您和本公司利益,本公司有权审查您提交的相关材料(如自然人持有的身份证照片、企业法人营业执照副本复印件、事业单位法人证书复印件)并有权决定是否核准您的申请,并有权视情况要求您提供声明/说明、服务资质、服务范围及其他等材料。若您拒绝提供材料或提交的材料或填写的信息不真实、不准确、不完整或不合法的,则您可能无法使用本产品或在使用过程中受到限制。本公司的审查不代表对您提交的材料和信息的真实性、准确性、合法性负责。您应当对该材料和信息独立承担责任。 -

-

(6)为更好地为您提供服务,本公司有权对使用本产品的用户进行分级、分类管理,并有权根据级别设置相应的权限、提供相应的服务。 -

-

3、账号的注销

-

- 您有权注销您的本公司账户,您可以根据本协议所述的方式联系我们的客服协助您注销账号。我们收到您的请求后需要您提供账号(手机号码)以及短信验证码,以核对身份,核验成功后我们将在15个工作日内为您完成注销。为了保障安全,我们可能需要您提供相应方式证明您的身份和请求的正当性。您注销成功后,我们将根据法律法规的要求尽快删除您的个人信息或作匿名化处理。 -

-

三、本产品服务内容

-

- 1、您可能可以通过电脑、手机等终端以网页等形式使用本产品,具体以本公司提供的为准,同时,本公司会不断丰富您使用本软件的终端、形式等。当您使用本产品时,您应选择与您的终端、系统等相匹配的本产品版本,否则,您可能无法正常使用本产品。 -

-

- 2、本产品为您提供的服务包括文字审核、文档审核、图片审核,可以为上述形式提供文本纠错或内容安全审核。文本纠错包含拼写错误、语法错误、标点错误、数字错误、量与单位错误、政治领域错误、语法语义错误。内容安全审核包含涉政、违禁、色情、暴恐、辱骂、广告导流等风险内容的审核。 -

-

3、服务费用

-

- (1)本产品的某些服务是以收费方式提供的,由于云服务的虚拟产品性质和特征,您所获取的虚拟产品不能够进行退货、换货。一旦用户凭个人账户和密码订购收费服务,将视为是您本人订购了该项收费服务,您有义务按照有关的收费标准、付款方式按时支付相应的服务费用,本公司也将按照相关服务的收费标准与付款方式进行收费。关于具体的服务资费,将会在本公司应用或官方网站相应的服务页面上有详细说明。如果您未能按时支付相应的服务费用,本公司将有权利自动取消您所订购的收费服务而无需另行通知。 -

-

- (2)本公司将在您付款前,针对您提交的使用本服务请求的相应费用在订单相关界面给予确认;本公司有权根据纠错能力价格、敏感审核能力价格、服务器调整等因素等因素调整服务的费用同时给出定价说明,并由您通过本公司相关页面进行操作确定及支付。订单一旦进入“处理中”状态,将不接受任何形式的取消和退款。使用本产品不接受任何形式的议价,如对产品使用的费用产生疑问,可在本产品的相关界面联系客服咨询,使用本产品的价格信息具体可参见本软件内的价格说明。 -

-

(3)您同意:本公司有权根据市场报价、经营成本等因素,对本产品服务的收费标准进行调整。 -

-

- (4)您有权在费用支付完成后,通过本协议提供的方式向本公司索取使用本产品实付费用的等额合规正式发票;本公司固定在每月批量开具发票,并将自发票开具之日起10个工作日内完成发票发布(邮箱),遇节假日或其他不可抗力因素顺延。 -

-

四、用户使用规范

-

- 1、本公司授权您非商业性使用本产品,但是如果要进行商业性使用(包括但不限于:销售、复制、散发、预装、捆绑或用于其他商业活动)时,必须事先获得本公司的书面授权和许可。 -

-

- 2、您可以就本产品的下载、安装、使用或卸载问题向本公司提出咨询,本公司解答的义务不应超过本公司的合理承受限度。如果您对本产品有任何意见,或有如何改进的建议,请通过在线沟通发表您的意见或建议。 -

-

- 3、用户充分了解并同意,本产品的用户上传、分享、传播的信息,均不代表本公司的观点,本公司对此不承担任何责任。同时,用户应对本产品的其他用户提供的内容自行加以判断,并承担因使用该内容而引起的所有风险,包括因对内容的正确性、完整性或合法性的依赖而产生的风险,本平台对此不承担任何法律责任。 -

-

- 4、您不得修改、复制、传播与本产品相关的材料。如果您复制和修改传播这些材料,因此而造成对其他人的损害,或者造成对本公司的形象损害,要承担相应的法律责任。您不得删除、掩盖或更改本公司的版权声明、商标或其它权利声明。 -

-

- 5、用户使用本产品将图片、文字、音频等信息公开发布、传播、分享的行为代表了用户有权且同意在全世界范围内,永久性的、不可撤销的、免费的授予本公司:对该信息行使使用、发布、复制、修改、改编、出版、翻译、据以创作衍生作品、传播、表演和展示等权利;将信息的全部或部分编入其他任何形式的作品、媒体、技术中的权利;对用户的上传、发布信息进行商业开发的权利;通过有线或无线网络向用户的计算机终端、移动通讯终端(包括但不限于便携式通讯设备如手机和智能平板电脑等)等提供信息的下载、点播、数据传输及其相关的宣传和推广等服务的权利。 -

-

- 6、用户在本产品上传、发布、传播的符号、文字、图片等内容的,应保证其内容不违反法律法规及其规范性文件,亦不侵犯任何第三方的合法权益,否则导致的一切不利后果均由用户自行承担,造成本公司损失的,还应向本公司承担赔偿责任。对于相关权利人因用户违反本款约定向本公司主张权利的,本公司有权不通知上传用户直接删除、下线、屏蔽相关争议内容。 -

-

- 7、用户应当保证,不会利用本产品侵犯本公司以及他人的合法权益,禁止通过网络漏洞、恶意软件或其他非法手段破坏本平台的正常经营。否则,本公司有权根据情节严重而对该用户及用户账号进行冻结、封号等处理。构成犯罪的,本公司有权移交司法部门处理。 -

-

8、禁止用户从事以下行为:

-

(1)使用未经公司授权或许可的任何插件、外挂、系统或第三方工具对本产品的正常运行进行干扰、破坏、修改或施加其他影响。 -

-

(2)利用或针对本产品进行任何危害计算机网络安全的行为,包括但不限于: -

-

1)非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动; -

-

2)提供专门用于从事侵入网络、干扰网络正常功能及防护措施、窃取网络数据等危害网络安全活动的程序、工具; -

-

3)明知他人从事危害网络安全的活动的,为其提供技术支持、广告推广、支付结算等帮助; -

-

4)使用未经许可的数据或进入未经许可的服务器/账号;

-

5)未经允许进入公众计算机网络或者他人计算机系统并删除、修改、增加存储信息; -

-

6)未经许可,企图探查、扫描、测试本服务系统或网络的弱点或其它实施破坏网络安全的行为; -

-

7)企图干涉、破坏本服务系统或网站的正常运行,故意传播恶意程序或病毒以及其他破坏干扰正常网络信息服务的行为; -

-

8)伪造TCP/IP数据包名称或部分名称。

-

(3)对本产品进行反向工程、反向汇编、编译或者以其他方式尝试发现本产品的源代码。 -

-

(4)恶意注册本产品账号,包括但不限于频繁、批量注册账号。

-

(5)不得制作、复制、上传、发布、传播法律、行政法规禁止的下列信息内容:

-

1)反对宪法确定的基本原则的;

-

2)危害国家安全,泄露国家秘密的;

-

3)颠覆国家政权,推翻社会主义制度、煽动分裂国家、破坏国家统一的;

-

4)损害国家荣誉和利益的;

-

5)宣扬恐怖主义、极端主义的;

-

6)宣扬民族仇恨、民族歧视,破坏民族团结的;

-

7)煽动地域歧视、地域仇恨的;

-

8)破坏国家宗教政策,宣扬邪教和迷信的;

-

9)编造、散布谣言、虚假信息,扰乱经济秩序和社会秩序、破坏社会稳定的;

-

10)散布、传播暴力、淫秽、色情、赌博、凶杀、恐怖或者教唆犯罪的;

-

11)侵害未成年人合法权益或者损害未成年人身心健康的;

-

12)未获他人允许,偷拍、偷录他人,侵害他人合法权利的;

-

13)包含恐怖、暴力血腥、高危险性、危害表演者自身或他人身心健康内容的; -

-

14)危害网络安全、利用网络从事危害国家安全、荣誉和利益的;

-

15)侮辱或者诽谤他人,侵害他人合法权益的;

-

16)对他人进行暴力恐吓、威胁,实施人肉搜索的;

-

17)涉及他人隐私、个人信息或资料的;

-

18)散布污言秽语,损害社会公序良俗的;

-

19)侵犯他人隐私权、名誉权、肖像权、知识产权、商业秘密等合法权益内容的; -

-

20)未经公司许可,利用本产品为自己或第三方进行推广、发布广告的(包括但不限于加入第三方链接、广告等行为); -

-

21)过度营销信息,骚扰信息和/或垃圾信息、低俗类信息、垃圾广告的;

-

22)使用本产品常用语言文字以外的其他语言文字制作、复制、上传、发布、传播的内容、留言、评论的; -

-

23)与所制作、复制、上传、发布、传播的内容、留言、评论的信息毫无关系的; -

-

24)所发布、传播的内容毫无意义的,或刻意使用字符组合以逃避技术审核的; -

-

25)其他违反法律法规、政策及公序良俗、干扰本产品合作平台正常运营或侵犯其他用户或第三方合法权益内容的其他信息。 -

-

五、权利声明及保密

-

1、本公司拥有本产品的知识产权等相关权利,受国际版权公约、中华人民共和国著作权法、专利法及其他知识产权方面的法律法规的保护。 -

-

2、本公司授予您对本产品可撤销的、有限的、非排他的、不可转让的使用权,您仅限于以非商业使用本公司为目的进行使用。 -

-

除本协议另有约定外,未经您的允许,{companyName}不会向第三方公开或传播您的信息、语及文字稿件内容。

-

3、保密

-

- (1)本公司将采取特殊保密措施,利用VAD等技术对语音文件进行切分、打散等处理,通过这些严格措施努力保护您的信息不被未经授权的访问、使用或泄漏。维护本服务的安全与正常使用是本公司和您的共同责任,本公司将采取适当的安全措施和技术手段维护本产品。 -

-

(2)您理解并同意,若非因本公司人为原因,如因天灾、盗窃、抢劫、黑客攻击等造成信息泄露的,本公司不承担法律责任。 -

-

(3)本公司在下述情况下不再承担保密义务:

-

1)因非本公司的原因,您提供的信息、语音、视频及文字稿件被公开的;

-

2)法律法规要求、行政司法机关要求、或其他有权机关要求披露的;

-

3)事先获得您的授权;

-

4)为查找、预防或处理欺诈、安全或技术方面的问题;

-

5)为执行相关服务协议或本政策、维护社会公共利益;

-

6)为保护我们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益等合理且必要的用途。 -

-

六、无担保声明

-

- 1、虽然本产品(包括其升级版)经过本公司详细的测试,但本公司不能保证其与所有的软硬件、系统完全兼容。如果出现不兼容的情况您可将情况通知我们,以获得技术支持。如果无法解决问题,您可以选择停止使用本产品。 -

-

2、本公司对以下事宜不作任何类型的担保,不论是明确的或隐含的:

-

(1)本协议项下本产品提供的相关网络服务将符合用户的要求;

-

- (2)本协议项下本产品提供的相关服务将不受不可抗力、计算机病毒、黑客攻击、系统不稳定、用户所在位置、用户关机、电信部门原因及其他任何网络、技术、通信线路等外界或人为因素的影响; -

-

3、第三方产品和服务

-

- (1)您知悉并同意,若您在使用通过本产品的链接和标签所指向的第三方提供的产品或服务时,除遵守本协议约定外,还应遵守第三方的用户协议,您使用第三方提供的产品或服务可能出现的纠纷由您自行解决并承担风险。 -

-

- (2)因您使用本软件或要求本产品提供特定服务时,本软件可能会调用第三方系统或者通过第三方支持您的使用或访问,使用或访问的结果由该第三方提供(包括但不限于第三方通过本软件插件提供的服务),本公司不保证通过第三方提供服务及内容的安全性、准确性、有效性及其他不确定的风险,由此若引发的任何争议及损害由您自行承担。 -

-

- (3)前述通过各种形式展现的相关协议或其他文件,均是本协议不可分割的组成部分,与本协议具有同等的法律效力,您应当遵守这些要求。如果您没有遵守这些要求,该第三方或者国家机关可能会对您提起诉讼、罚款或采取其他制裁措施,并要求本公司给予协助,您应当自行承担法律责任。 -

-

七、隐私保护

-

隐私保护相关条款以《隐私政策》内容为准

-

八、违约处理

-

- 1、针对您违反本协议或其他服务条款的行为,本公司有权独立判断并视情况采取预先警示、拒绝发布、要求整改、立即停止提供服务、删除内容、暂停更新、限制账号部分或者全部功能直至永久关闭账号等措施。本公司有权公告处理结果,且有权根据实际情况决定是否恢复使用。对涉嫌违反法律法规、涉嫌违法犯罪的行为将保存有关记录,并依法向有关主管部门报告、配合有关主管部门调查。 -

-

- 2、因您违反本协议或其他服务条款规定,引起第三方投诉或诉讼索赔的,您应当自行承担全部法律责任。因您的违法或违约行为导致本公司向任何第三方赔偿或遭受国家机关处罚的,您还应足额赔偿本公司及其关联公司、控制公司因此遭受的全部损失。 -

-

- 3、本公司尊重并保护法人、公民的知识产权、名誉权、姓名权、隐私权等合法权益。您保证,在使用本产品时上传的文字、图片、链接等不侵犯任何第三方的知识产权、名誉权、姓名权、隐私权等权利及合法权益。否则,本公司有权在收到权利方或者相关方通知的情况下移除该涉嫌侵权内容。针对第三方提出的全部权利主张,您应自行承担全部法律责任;如因您的侵权行为导致本公司及其关联公司、控制公司遭受损失的(包括经济、商誉等损失),您还应足额赔偿本公司及其关联公司、控制公司遭受的全部损失。 -

-

九、服务的变更、中断和终止

-

- 1、您理解并同意,本公司提供的本产品及相关服务是按照现有技术和条件所能达到的现状提供的。本公司会尽最大努力向您提供服务,确保服务的连贯性和安全性。您理解,本公司不能随时预见和防范技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵及其他各种安全问题的侵扰等原因可能导致的服务中断、数据丢失以及其他的损失和风险。 -

-

2、您理解并同意,本公司为了服务整体运营的需要,有权在公告通知后修改、中断、中止或终止本产品的服务,而无须向您负责或承担任何赔偿责任。 -

-

- 3、本公司有权提前30天通知您解除本协议,该情况下,本公司解除本协议时您的账户内仍有已支付且未完成订单的,本公司将以该订单的实付金额为限向您提供适当补偿。 -

-

十、通知和送达

-

- 1、您在使用本产品过程中有任何意见或建议,可通过本产品内【客服】提出,我们将向您及时做出反馈。您应保证您的联系方式畅通,以接收来自我们发出的电话或信息,我们不对您未收到通知而引起的任何损失承担责任。 -

-

2、如您在使用本产品的过程中对本用户服务协议有任何疑问或建议,请通过以下联系方式与我们联系: -

-

电子邮件: zhengjianxiong@guomai.cn -

-

电 话: 021-64386496-228

-

- 3、为保障我们高效处理您的问题并及时向您反馈,需要您提交身份证明、有效联系方式和书面请求及相关证据,我们会在验证您的身份后处理您的请求。一般情况下,我们将在三十天内回复。 -

-

十一、其他

-

- 1、本协议的订立、执行和解释及争议的解决均应适用中国法律并受中国法院管辖。如双方就本协议内容或其执行发生任何争议,双方应尽量友好协商解决;协商不成时,任何一方均可向本公司所在地的人民法院提起诉讼。 -

-

2、本协议构成双方对本协议之约定事项及其他有关事宜的完整协议,除本协议规定的之外,未赋予本协议各方其他权利。 -

-

3、如本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,本协议的其余条款仍应有效并且有约束力。 -

-

4、本服务仅限于在中国大陆地区使用,如您擅自在中国大陆以外(特别是欧盟)地区使用,公司不承担因此而产生的任何责任。 -

-

- 5、本协议自用户同意勾选或网上签署并成功注册成为本平台用户之日起生效,除非本公司终止本协议或者用户丧失本平台用户资格,否则本协议始终有效。本协议终止并不免除用户根据本协议或其他有关协议、规则所应承担的义务和责任。 -

-
- ) -} diff --git a/src/pages/login/components/terms/env.ts b/src/pages/login/components/terms/env.ts deleted file mode 100644 index 5ae2daf..0000000 --- a/src/pages/login/components/terms/env.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const productName = "AI校对王" -export const companyName = "果麦文化" diff --git a/src/pages/login/components/terms/privacy.tsx b/src/pages/login/components/terms/privacy.tsx deleted file mode 100644 index 547ed88..0000000 --- a/src/pages/login/components/terms/privacy.tsx +++ /dev/null @@ -1,526 +0,0 @@ -import React from "react"; -import {companyName,productName} from "./env.ts" - -export const PrivacyContent: React.FC = () => { - return ( - -
-

发布日期:2023年12月01日

-

生效日期:2023年12月01日

-

{productName}隐私政策》(以下简称“本政策”)仅适用于{companyName}(以下简称“{companyName}”或“我们”)为您提供的{productName}产品与服务。您在使用本软件前,请仔细阅读本政策,以了解我们处理您个人信息的详情。其中有关个人敏感信息以及与您个人信息权益相关的重要内容我们已用加粗形式提示,请特别关注。如您是未满14周岁的未成年人,请在您的父母或其他监护人陪同下仔细阅读并充分理解本政策,并征得您的父母或其他监护人的同意后使用{productName}产品与服务。

-

特别说明:

-

1.本政策适用对象为访问、注册、登录及使用{productName}产品与服务的访问者和使用者。

-

2.如您使用{productName}提供的产品与服务,则应承诺:

-

1)使用{productName}过程中,遵守可适用的法律法规,包括但不限于《中华人民共和国网络安全法》《中华人民共和国数据安全法》《中华人民共和国个人信息保护法》等。 -

-

2)不会以非法、不合理的途径注册或使用{productName}

-

本政策将帮助您了解以下内容:

-

一、定义与解释

-

二、我们如何收集和使用您的个人信息

-

三、我们如何使用 Cookie 和同类技术

-

四、我们如何委托处理、共享、转让、公开披露您的个人信息

-

五、我们如何保护您的个人信息

-

六、我们如何存储您的个人信息

-

七、您如何实现管理您个人信息的权利

-

八、我们如何保护未成年人的个人信息

-

九、您的个人信息如何在全球范围转移

-

十、我们如何更新本政策

-

十一、如何联系我们

-

十二、其他

-

一、定义与解释

-

1. {productName}产品与服务

-

包括{productName}网站,客户端,插件及{productName}能提供的所有功能与解决方案。

-

2. 用户

-

是指{productName}网站、客户端、插件注册、登录以及使用{productName}产品与服务,并通过启用、浏览或上传数据至{productName}的访问者和用户。在本政策中更多地称为“您”。

-

3. 账号

-

指您完成真实信息注册后,享有的用户账号,该用户账号由您负责保管;您应当对以您账号下进行的所有行为负法律责任。 -

-

4. 个人信息

-

个人信息是以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息。为免疑义,个人信息包括但不限于敏感个人信息。 -

-

5. 敏感个人信息

-

敏感个人信息是一旦泄露或者非法使用,容易导致自然人的人格尊严受到侵害或者人身、财产安全受到危害的个人信息,包括生物识别、宗教信仰、特定身份、医疗健康、金融账号、行踪轨迹等信息,以及不满十四周岁未成年人的个人信息。 -

-

6. 个人信息的处理

-

个人信息的处理包括个人信息的收集、存储、使用、加工、传输、提供、公开、删除等。 -

-

7. 个人信息处理者

-

个人信息处理者是指在个人信息处理活动中自主决定处理目的、处理方式的组织、个人。 -

-

8. 个人信息主体

-

个人信息主体指个人信息所标识或者关联的自然人。

-

9. 自动化决策

-

自动化决策是指通过计算机程序自动分析、评估个人的行为习惯、兴趣爱好或者经济、健康、信用状况等,并进行决策的活动。 -

-

10. 去标识化

-

去标识化指个人信息经过处理,使其在不借助额外信息的情况下,无法识别特定自然人的过程。 -

-

11. 匿名化

-

匿名化指个人信息经过处理无法识别特定自然人且不能复原的过程。

-

12. 设备

-

设备是指可用于{productName}服务的装置,例如台式计算机、笔记本电脑、平板电脑或智能手机。

-

13. 唯一设备标识符

-

唯一设备标识符(专属 ID 或 UID)是指由设备制造商编入到设备中的一串字符,可用于以独有方式标识相应设备(移动设备的 IMEI 号)。唯一设备标识符有多种用途,包括可在不能使用Cookies时用以提供广告。 -

-

14. IP地址

-

每台上网的设备都会指定一个编号,称为互联网协议 (IP) 地址。这些编号通常都是根据地理区域指定的。IP 地址通常可用于识别设备连接至互联网时所在的位置。 -

-

15. 基站

-

- 基站,即公用移动通信基站,是无线电台站的一种形式,是指在一定的无线电覆盖区中,通过移动通信交换中心,与移动电话终端之间进行信息传递的无线电收发信电台。 -

-

16. SSL

-

SSL(Secure Socket Layer)又称为安全套接层,是在传输通信协议(TCP/IP)上实现的一种安全协议。SSL支持各种类型的网络,同时提供三种基本的安全服务,均通过使用公开密钥和对称密钥技术以达到信息保密的效果。 -

-

17. 信息收集技术

-

{productName}在本政策中所述的“自动收集”包括以下方式:

-

- 1)Cookie:Cookie是您浏览网页时,网站服务器放在客户端(您的计算机、移动电话或其他智能终端内)里面的一个小小的文本文件,可用于改善您的使用体验。 -

-

- 2)Web:beacon(网络信标) Web beacon是装嵌在网站或电邮内的电子图像文件或其他技术,可用于计算访客数目、记录您是否及何时阅览电邮或网站,或用以使用某些Cookie。 -

-

3)Log files(日志文件):Log files储存自动收集的若干数据。该等数据包括互联网协议(IP)地址、浏览器类型、互联网服务提供商(ISP)、引用/退出页面、操作系统、日期/时间戳和点击流数据等。 -

-

- 4)ET Tag(实体标签):ET Tag是在互联网浏览器与互联网服务器之间背后传送的HTTP协议标头,可代替Cookie,用以追踪个别使用者,使我们可更深入地了解和改善我们的服务。 -

-

- 5)JavaScript:JavaScript是一种编程语言,用于制作更具互动性和动态的网页。JavaScript可以设定Cookie、阅读Cookie及删除Cookie。 -

-

二、我们如何收集和使用您的个人信息

-

{companyName}作为个人信息的处理者,会遵循合法、正当、必要、诚信的原则,仅将您主动提供的个人信息和我们主动收集的个人信息用于本政策所限定的收集个人信息的使用用途并与实现产品或服务的业务功能有直接关联,以为您提供{productName}优质的产品与服务。以及用于身份验证、安全防范、反诈骗监测、存档备份、客户的安全服务用途以提高产品和服务的安全性。具体地,我们将出于如下所述的目的收集和使用您的个人信息。 -

-

1. 向您提供产品与服务过程中您主动提供的个人信息

-

1.1为实现我们的基本业务功能,您仅需要向我们提供该功能所对应的基本必要的个人信息,相关法律法规和规范性文件有特殊要求的除外。若您拒绝提供,我们将无法向您提供相应的服务。提示您注意:如果您提供的是非本人的个人信息,请您确保已取得相关主体的同意。 -

-

a.账号注册/登录及使用

-

如果您选择使用{productName}的功能,为便于使用我们为您提供的完整的{productName}产品与服务,您需要注册一个{productName}账号。在您使用手机号注册或登录{productName}账号时,您需要提供手机号码,并且通过输入短信验证码,以便我们对您的用户身份进行核验,以保护您的账号不被未经授权的进入。如果您仅需使用输入、查看、搜索等访问相关服务,您不需要注册{productName}账号及提供上述个人信息。

-

b.文字、文档审核

-

在您使用{productName}网站提供的文字、文档审核时,我们会收集您提供的文本信息。请您知悉,当您体验{productName}的前述功能时,您所输入的文本内容中虽然可能包含您或他人的个人信息,但我们不会依据所涉个人信息的内容识别到个人。如果您拒绝输入前述信息,您将无法体验前述完整的服务。 -

-

您理解并同意,上述服务可能需要您在您的设备中开启您的摄像头(相机)、相册(图片库)的访问权限,以实现这些权限所涉及信息的收集和使用。您可在您的设备设置中逐项查看上述权限的状态,并可自行决定这些权限随时的开启或关闭。请您注意,您开启任一权限即代表您授权我们可以收集和使用相关个人信息来为您提供对应服务,您一旦关闭任一权限即代表您取消了授权,我们将不再基于对应权限继续收集和使用相关个人信息,也无法为您提供该权限所对应的服务。但是,您关闭权限的决定不会影响此前基于您的授权所进行的信息收集及使用。 -

-

1.2为了向您提供更优质的{productName}产品与服务,我们可能需要收集下述信息。如果您拒绝提供下述信息,不影响您正常使用第1.1条下的基本业务功能,但您可能无法获得这些扩展业务功能给您带来的用户体验。 -

-

a.订单生成

-

当您选择购买我们的产品与服务时,系统会生成购买该产品服务的订单,您至少需要填写收货人姓名、联系电话、收货地址。同时该订单会载明订单号、您购买的产品服务内容、应支付的货款金额以及支付方式。上述所有信息将构成您的“订单信息”。我们将通过订单为您提供相应的订单查询、支付结算、完成配送、提供客服咨询与售后服务。 -

-

b.支付

-

- 在您下单后,您可以通过支付宝支付所提供的第三方支付服务。支付功能本身并不收集您的个人信息,但我们需要将您的订单号与交易金额信息与这些支付机构共享以实现其确认您的支付指令并完成支付。 -

-

c.活动参与和服务改进

-

当您通过我们的客服或参加{productName}举办的活动时,我们会收集您自愿参与填写的信息。如您参与{productName}线上活动时填写的调查问卷中可能包含您的姓名、电话、电子邮箱、家庭地址信息。并且,当您在{productName}注册、登录或后续使用过程中,您可以进入{productName}的账号信息页面自愿选择填写昵称、性别、生日和所在地信息。我们可能会利用前述信息向您进行活动反馈,或进行用户和市场调研分析(如判断您的大致用户属性),以提升、改进我们的产品设计,为您提供个性化的推荐和更优的服务体验。但如果您不提供这些个人信息,并不会影响您正常使用{productName}的所有基本功能和服务。

-

2. 向您提供产品与服务过程中我们主动收集的个人信息

-

在符合法律法规前提下,为了保障您的账号安全和更好地为您提供优质的服务,我们会收集和使用您在使用{productName}产品与服务中产生的如下信息:

-

系统日志

-

当您使用{productName}的产品与服务时,系统可能会通过Cookies或其他方式自动收集某些信息作为系统日志保存。收集此类信息的目的在于:通过数据统计改进和优化产品体验、保障服务稳定和网络安全。此类信息包含:您使用{productName}时的详细使用情况,包括您的产品服务使用记录、搜索查询内容、访问的页面地址、登录IP、浏览器的类型、网络状态、运营商、使用的语言、访问日期和时间、系统活动及您访问的网页记录。 -

-

三、我们如何使用Cookie和同类技术

-

1. Cookie

-

为确保网站正常运转,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件,通过Cookies收集和使用您的信息。我们使用自己的Cookies,目的是为您提供更个性化的用户体验和服务,并用于以下用途: -

-

(1)记住您的身份。例如:Cookies有助于我们辨认您作为我们的注册用户的身份,或保存您向我们提供的有关您的喜好或其他信息; -

-

(2)分析您使用我们服务的情况。例如,我们可利用Cookies来了解您使用我们的服务进行什么活动,或哪些网页或服务最受您的欢迎; -

-

2. 网站信标和像素标签

-

除 Cookie 外,我们还可能会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的点击 URL。如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的产品或服务偏好并改善客户服务。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。如果您不希望自己的活动以这种方式被追踪,则可以随时从我们的寄信名单中退订。 -

-

四、我们如何委托处理、共享、转让、公开披露您的个人信息

-

1.委托处理

-

为了向您提供更完善、更优质的产品和服务,我们可能会委托第三方(包括公司、组织和个人)处理您的某些个人信息。对我们委托处理您个人信息的第三方,我们会与其签署严格的数据处理协议,明确约定委托处理的目的、期限、处理方式、个人信息的种类、保护措施以及双方的权利和义务等,并对第三方的个人信息处理活动进行监督,要求第三方仅按照我们的要求、本政策的规定以及其他任何相关的保密和安全措施来处理您的个人信息,不得超出约定的处理目的、处理方式等处理个人信息。如果您拒绝我们的第三方在提供服务时收集为提供服务所必需的个人信息,将可能导致您在使用{productName}产品与服务的过程中无法享受该第三方提供的服务。

-

例如,当您使用{productName}提供的产品与服务时,根据相关法律法规要求,需要您进行实名认证。我们会通过国家信用评级业务主管部门认可的征信公司核实这些信息。 如果您拒绝与我们合作的征信公司收集为提供服务所必需的个人信息,将可能导致您在使用{productName}产品与服务的过程中无法享受该供应商提供的实名认证相关服务。

-

2.共享

-

我们不会与第三方(包括公司、组织和个人)共享您的个人信息,但以下情况除外: -

-

(1)在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。 -

-

(2)在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。 -

-

对我们与之共享个人信息的公司、组织和个人,我们会与其签署严格的保密协定,要求他们按照我们的说明、本隐私政策以及其他任何相关的保密和安全措施来处理个人信息,并且要求他们的处理行为不得违反中国个人信息保护和数据安全相关的法律法规、国家标准和其他规范性文件。原则上,我们与之共享个人信息的公司、组织和个人无权将我们共享的个人信息用于本政策之外的其他任何用途。 -

-

3.转让

-

我们不会将您的个人信息转让给任何第三方(包括公司、组织和个人),但以下情况除外: -

-

1)在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息; -

-

2)根据适用的法律法规、法律程序的要求、强制性的行政或司法要求所必须的情况下进行提供; -

-

3)在本产品服务提供者发生合并、收购或破产清算情形,或其他涉及合并、收购或破产清算情形时,如涉及到个人信息转让,我们会告知您接收方的名称或者姓名和联系方式,并要求新的持有您个人信息的接收方继续受本政策的约束,对于接收方变更原先的处理目的、处理方式的,我们将要求该接收方重新向您征求授权同意。 -

-

4. 公开披露

-

我们仅会在以下情况下,公开披露您的个人信息:

-

1)获得您单独同意或基于您的主动选择,我们可能会公开披露您的个人信息; -

-

2)在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息。 -

-

3)如果我们确定您出现违反法律法规或严重违反本产品相关协议规则的情况,或为保护本产品及其关联公司用户或公众的人身财产安全免遭侵害,我们可能依据法律法规或本产品相关协议规则披露关于您的个人信息,包括相关违规行为以及本产品已对您采取的措施。 -

-

5. 委托处理、共享、转让、披露个人信息时事先征得授权同意的例外

-

以下情形中,共享、转让、公开披露您的个人信息无需事先征得您的授权同意: -

-

1)与我们履行法律法规规定的义务相关的;

-

2)与国家安全、国防安全有关的;

-

3)与公共安全、公共卫生、重大公共利益有关的;

-

4)与犯罪侦查、起诉、审判和判决执行等有关的;

-

5)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; -

-

6)您自行向社会公众公开的个人信息;

-

7)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。 -

-

- 请您知悉,根据法律规定,共享、转让经去匿名化处理的个人信息,不属于个人信息的对外共享、转让及公开披露行为,对此类数据的保存及处理将无需另行向您通知并征得您的同意。 -

-

五、我们如何保护您的个人信息

-

1.我们非常重视用户的隐私和个人信息保护,也会采取合理的措施保护用户的个人信息。除法律法规规定或本政策另有约定的情形外,{companyName}将运用各种安全技术和程序建立完善的管理制度来保护您的个人信息,以免遭受未经授权的访问、使用或披露。未经用户许可我们不会向第三方公开、透露用户个人信息,并会对相关信息采用专业加密存储与传输方式,保障用户个人信息的安全。 -

-

2.您理解并同意,在不透露单个用户隐私资料的前提下,{companyName}有权对整个用户数据库进行技术分析,只有对进行分析、整理后达到匿名化后的用户数据方才进行商业上的利用。 -

-

3.数据安全措施

-

1){productName}已采用符合业界标准的安全防护措施,包括建立合理的制度规范、安全技术来防止您的个人信息遭到未经授权的访问使用、修改,避免数据的损坏或丢失。例如,{productName}的网络服务采取了传输层安全协议等加密技术,通过https等方式提供浏览服务,确保用户数据在传输过程中的安全;我们采取加密技术(TLS、SSL)、匿名化处理和保护机制对用户个人信息进行加密保存,并通过隔离技术进行隔离;我们通过建立数据分类分级制度、数据安全管理规范、数据安全开发规范来管理规范个人信息的存储和使用;我们通过信息接触者保密协议等方式,仅允许有必要知晓这些信息的{productName}{productName}关联方的员工、合作伙伴访问个人信息,并为此设置了严格的访问权限控制和监控机制,同时要求接触到您个人信息的所有人员履行相应的保密义务。如果未能履行这些义务,会被追究法律责任或被中止与{productName}的合作关系;我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识。 -

-

- 3)我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。 -

-

- 4)互联网并非绝对安全的环境,而且电子邮件、即时通讯、及与其他用户的交流方式并未加密,我们强烈建议您不要通过此类方式发送个人信息。请使用复杂密码,协助我们保证您的账号安全。 -

-

5)在不幸发生个人信息安全事件后,{companyName}将按照法律法规的要求,及时向您告知:安全事件发生的原因、可能造成的危害、涉及个人信息的种类、{companyName}已采取或将要采取的处置措施、您可自主防范和降低风险的建议和可采取的措施等。{companyName}将及时将事件相关情况以邮件、短信、电话、发送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。同时,{companyName}还将按照监管部门要求,主动上报个人信息安全事件的处置情况。请您知悉,根据可适用法律法规的规定,如采取措施能够有效避免信息泄露、篡改、丢失造成危害的,{companyName}可以不向您进行告知。

-

六、我们如何存储您的个人信息

-

- 本产品与服务仅面向中国大陆地区(仅为本政策之目的,不包含香港特别行政区、澳门特别行政区和台湾地区)提供。原则上,我们在中华人民共和国境内收集产生的个人信息,存储在中华人民共和国境内,不会进行跨境传输。 -

-

1.存储信息的地点

-

{companyName}遵守法律法规的规定,收集的有关您的信息和资料将保存在中华人民共和国境内大陆地区{companyName}的服务器上。以下情形除外:

-

• 法律法规有明确规定;

-

• 获得您的明确授权;

-

• 您通过互联网进行跨境交易等个人主动行为。

-

2.存储信息的期限

-

一般而言,我们将在您使用{productName}产品与服务期间为实现本政策所述目的所必需的时间内保留您的个人信息,除非可适用的法律法规或国家规范性文件另有规定。在超过上述期限,或您主动要求删除您的个人信息或注销您的账号后,我们将根据适用法律法规的要求尽快删除您的个人信息,除非可适用的法律法规或国家规范性文件要求在更长的期间内保留这些信息。但在下列情况下,{companyName}因需符合法律要求,更改个人信息的存储时间:

-

• 为遵守适用的法律法规等有关规定;

-

• 为遵守法院判决、裁定或其他法律程序的规定;

-

• 为遵守相关政府机关或法定授权组织的要求;

-

{companyName}有理由确信需要遵守法律法规等有关规定;

-

• 为执行相关服务协议或本政策、维护社会公共利益,为保护{companyName}的客户、{companyName}、其他用户或雇员的人身财产安全或其他合法权益所合理必需的用途。

-

在您终止使用{productName}后,{companyName}会停止对您的信息的收集和使用,法律法规或监管部门另有规定的除外。

-

{productName}的相关服务发生停止运营的情形时,{companyName}将采取包括发送通知和公告形式通知您,并在合理的期限内删除服务器中留存的您的个人信息。 -

-

七、您如何实现管理您个人信息的权利

-

按照中国相关的法律、法规、标准,您在个人信息处理活动中享有若干权利,具体包括: -

-

• 您对个人信息处理享有知情权、决定权,有权限制或者拒绝他人对您个人信息进行处理,法律、行政法规另有规定的除外; -

-

• 您有权向个人信息处理者查阅、复制您的个人信息,法律另有规定情形的除外; -

-

• 您有权请求将您的个人信息转移至您指定的个人信息处理者;

-

• 您发现您的个人信息不准确或不完整的,有权请求个人信息处理者更正、补充; -

-

• 您有权请求删除您的个人信息;

-

• 您有权要求个人信息处理者对其个人信息处理规则进行解释说明。

-

当您是使用{productName}的产品与服务的开发者时:

-

您可以参考下面的步骤进行相关操作:

-

1. 查阅您的个人信息

-

您可以通过以下步骤查阅昵称、电子邮箱、手机号、登录密码等基本信息:

-

1)进入{productName}网站,登录您的{productName}账号;

-

2)点击已登录的账号名称,点击基本资料菜单;

-

3)点击个人资料;

-

4)查看所需信息。 {productName}是网站业务,具体操作可能随着版本迭代略有差异。如果您无法通过上述操作、页面访问这些个人信息,您可以通过{productName}客服,随时与我们联系。或根据本政策第十一章所述的方式联系我们的客服,我们将在15个工作日内对您的请求进行处理。 -

-

2. 更正/补充您的个人信息

-

您可以通过以下步骤更正/补充邮箱、手机号、登录密码等基本信息:

-

1)进入{productName}网站,登录您的{productName}账号;

-

2)点击已登录的账号名称,点击基本资料菜单;

-

3)点击基本资料或安全设置栏;

-

4)更改所需信息。 不同版本的{productName}具体操作可能略有差异。当您发现我们处理的关于您的个人信息有错误时,您有权要求我们作出更正。如果您无法通过上述操作、页面更正这些个人信息,您可以通过{productName}-客服服务,随时与我们联系。或根据本政策第十一章所述的方式联系我们的客服,我们将在15个工作日内对您的请求进行处理。 -

-

3. 删除您的个人信息

-

您可以通过{productName}-客服服务,随时与我们联系。或根据本政策第十一章所述的方式联系我们的客服,我们将在15个工作日内对您的请求进行处理。 -

-

若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。 -

-

4. 获取您的个人信息副本

-

您有权获取您的个人信息副本,您可以通过您可以通过{productName} – 客服服务,随时与我们联系。或根据本政策第十一章所述的方式联系我们的客服,我们将在15个工作日内对您的请求进行处理。 -

-

5. 转移您的个人信息

-

您有权请求将您的个人信息转移至您指定的个人信息处理者,符合国家网信部门规定条件的,我们会为您提供转移的途径。您可以通过您可以通过{productName}- 在线咨询 - 人工服务,随时与我们联系。或根据本政策第十一章所述的方式联系我们的客服,我们将在15个工作日内对您的请求进行处理。 -

-

6. 改变您授权同意的范围或撤回您的授权

-

您可以通过注销账号的方式改变您授权我们继续收集个人信息的范围或撤回您的授权,您可以通过以下步骤进行:请通过{productName}客服服务,提交注销账号申请。当您撤回同意或授权后,我们无法继续为您提供撤回同意或授权所对应的服务,也不再处理您相应的个人信息。但您撤回同意或授权的决定,不会影响此前基于您的授权而开展的个人信息处理。 -

-

7. 注销账户

-

您可以通过以下步骤进行: 请通过{productName}- 客服服务,提交注销账号申请。经过线下的核实,告知注销账号相应风险后,为您进行注销操作。{productName}提供的产品服务需通过{productName}网站账号使用和管理,注销账号会导致该账号下全部服务停止。

-

8. 响应您的上述请求

-

我们将采取适当的技术手段,保证您对于自己的个人资料可进行查阅、补充、更正、删除,或通过{productName}产品与服务发布的反馈或投诉渠道申请我们对相关信息进行补充、更正、删除、复制、转移;我们收到您的申请后将按流程予以处理,为保障安全,按照流程,{companyName}可能会先要求您验证自己的身份,我们需要您提供账号(手机号码)以及短信验证码,待核验成功后再处理您的请求。我们将在15个工作日内做出答复,对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视情况收取一定成本费用。对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际(例如,涉及备份磁带上存放的信息)的请求,我们可能会予以拒绝。 -

-

- 如果您无法查阅、补充、更正、删除、复制、转移您的个人信息,或改变您授权同意的范围或撤回授权、注销账号、限制自动化决策和关闭定向推送,或您需要查阅、补充、更正、删除、复制、转移您在使用{productName}时所产生的其他个人信息,或您认为我们存在任何违反法律法规或与您关于个人信息的收集或使用的约定,您可通过我们对外公布的相关产品或服务的官方反馈渠道与我们联系。 -

-

请您知悉,在以下情形中,我们将无法响应您的请求:

-

1)与我们履行法律法规规定的义务相关的;

-

2)与国家安全、国防安全直接相关的;

-

3)与公共安全、公共卫生、重大公共利益直接相关的;

-

4)与犯罪侦查、起诉、审判和执行判决等直接相关的;

-

5)我们有充分证据表明您存在主观恶意或滥用权利的;

-

6)出于您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; -

-

7)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;

-

8)涉及商业秘密的。

-

八、我们如何保护未成年人的个人信息

-

1.{companyName}非常重视对未成年人个人信息的保护,我们将根据国家相关法律法规的规定保护未成年人的个人信息。 -

-

2.我们将不满18周岁的任何人均视为未成年人。根据相关法律法规的规定,若您是年满14周岁的未成年人,我们在收集您的个人信息之前,会征得您或您的监护人的同意,并且当您、父母或者其他监护人要求我们更正、删除未成年人个人信息的,我们将及时采取措施予以更正、删除,但法律、行政法规另有规定的除外。 -

-

3.若您是不满14周岁的未成年人(下称儿童),我们在收集您的个人信息之前,会征得您的父母或其他监护人的同意。 -

-

4.我们在处理儿童个人信息时,将采取以下措施予以保障:对于收集到的儿童个人信息,我们除遵守本政策关于用户个人信息的约定外,还会秉持正当必要、知情同意、目的明确、安全保障、依法利用的原则,严格遵循《儿童个人信息网络保护规定》等法律法规的要求进行存储、使用、披露,且不会超过实现收集、使用目的所必须的期限,到期后我们会对儿童个人信息进行删除。 -

-

5.若您是未成年人的父母或监护人,如您对本政策中所述相关事宜有任何疑问、意见、建议或投诉、举报需求,请通过第十一章所述方式与我们进行反馈。 -

-

九、您的个人信息如何在全球范围转移

-

原则上,我们在中华人民共和国境内收集产生的个人信息,会存储在中华人民共和国境内,不会进行跨境传输。如因业务等需要,确需向境外提供您的个人信息的,我们会向您告知境外接收方的名称或者姓名、联系方式、处理目的、处理方式、个人信息的种类以及您向境外接收方行使本法规定权利的方式和程序等事项,并在获得您的单独同意和法律法规规定的跨境提供应具备的条件后,才会将您的个人信息转移到您使用产品与服务所在国家/地区的境外管辖区,或者使您的个人信息受到来自这些管辖区的访问。 -

-

请您知悉,此类管辖区可能设有不同的个人信息保护相关法律法规,我们会遵守管辖区内相关法律法规的要求确保您的个人信息得到充分保护。如此类管辖区未设立个人信息保护相关的法律法规,我们会尽力保障您的个人信息得到在中华人民共和国境内足够同等的保护。 -

-

十、我们如何更新本政策

-

1.为给您提供更好的服务,{productName}产品与服务将不时更新与变化,我们会适时对本政策进行修订,这些修订构成本政策的一部分。但是未经您明确同意,我们不会削减您按照本政策所应享有的权利。同时{productName}会将本政策的旧版本存档,供您查阅。

-

2.对于重大变更,{productName}还会提供更为显著的通知,包括{productName}会通过网站公示的方式进行通知甚至向您提供弹窗提示。如果您不同意本政策,或对本政策修改、更新的内容有异议,您可以选择停止使用{productName}产品与服务或者注销{productName}账号。但请您知悉,您账号注销之前、停止使用本服务之前的行为和活动仍受本政策的约束。 -

-

本政策所指的重大变更包括但不限于:

-

{productName}的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等; -

-

{productName}在控制权等方面发生重大变化。如并购重组等引起的所有者变更等;

-

• 个人信息共享、转让或公开披露的主要对象发生变化;

-

• 您参与个人信息处理方面的权利及其行使方式发生重大变化;

-

{productName}负责处理个人信息安全的责任部门、联络方式及投诉渠道发生变化时;

-

• 个人信息安全影响评估报告表明存在高风险时;

-

• 伴随政策或法律发布实施,为响应国家政策或者法律规范,做出变更。

-

十一、如何联系我们

-

为更好地保护您的个人信息,我们设立有专门的网络安全与个人信息保护部门。如您在使用{productName}的过程中对本隐私政策有任何疑问或建议,请通过以下联系方式与我们联系: -

-

电 话:021-64386496-228

-

邮 箱: zhengjianxiong@guomai.cn -

-

地址:上海市徐汇区古宜路181号B座401 -

-

为保障我们高效处理您的问题并及时向您反馈,需要您提交身份证明、有效联系方式和书面请求及相关证据,我们会在验证您的身份后处理您的请求。一般情况下,我们将在十五个工作日内回复。 如果您对我们的回复不满意,特别是您认为我们的个人信息处理行为损害了且在您向我们反馈后我们无法提供让您满意的回复且拒绝改进的,您可以向相关监管机构进行投诉和举报。 -

-

十二、其他

-

与本政策相关的任何纠纷,双方应经友好协商解决;若不能协商解决,您在此同意向安上海市徐汇区人民法院提起诉讼。 -

-

- 如果有管辖权的任何法院裁定或判决本政策的任何条款无效,则该条款将从本政策中移除,但该条款的无效不影响本政策其余条款的效力。本政策的其余条款将继续执行。 -

-
- ) -} diff --git a/src/pages/login/components/user/avatar.tsx b/src/pages/login/components/user/avatar.tsx deleted file mode 100644 index 8638a1b..0000000 --- a/src/pages/login/components/user/avatar.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { useUserinfoStore } from "@/service/userinfoStore"; -import {Avatar} from "antd"; -import React from "react"; -import DefaultAvatar from '@/assets/avatar.png' - -export const UserAvatar = ({size,className}: { className?:string;size?: "large" | "small" | "default" | number }) => { - const {userinfo} = useUserinfoStore() - return false} alt="点击替换头像" className={className} src={userinfo?.avatar || DefaultAvatar} size={size}/> -} diff --git a/src/pages/login/components/user/input.tsx b/src/pages/login/components/user/input.tsx deleted file mode 100644 index f26cfc7..0000000 --- a/src/pages/login/components/user/input.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import {Button, Input, Space} from "antd"; -import {useCountDown, useSetState} from "ahooks"; -import React from "react"; -import {cx} from "@emotion/css"; -import { isPhone } from "@/utils/strings"; -import { sendCode } from "@/service/api/user"; - -export const InputValidateCode: React.FC<{ - className?: string; - show?: boolean; - defaultValue?: string; - value?: string; - onInput?: (v: string) => void; - onChange?: (v: string) => void; - phone?: string; - onError?: (err: string, isPhone?: boolean) => void; -}> = (props) => { - const [data, setData] = useSetState<{ - targetDate?: number; - sending?: boolean - }>({}); - // 倒计时 - const [countdown] = useCountDown({ - targetDate: data.targetDate, - }); - // 发送验证码 - const handleSendCode = () => { - if (!props.phone) { - props.onError && props.onError('请填写手机号', true); - return; - } - if (!isPhone(props.phone)) { - props.onError && props.onError('请填写正确的手机号', true); - return; - } - props.onError && props.onError(''); - setData({sending: true}) - // 发送 - sendCode(props.phone).then(() => { - setData({ - targetDate: Date.now() + 60000 - }) - }).catch((e: BizError) => { - props.onError && props.onError(e.message || '发送失败,请重新发送'); - }).finally(() => setData({sending: false})) - } - return (
- -
- { - props.onChange && props.onChange(e.currentTarget.value); - }}/> -
- -
-
) -} diff --git a/src/pages/login/components/user/login-form.tsx b/src/pages/login/components/user/login-form.tsx deleted file mode 100644 index 000bff2..0000000 --- a/src/pages/login/components/user/login-form.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import React, {ChangeEvent, useState} from "react"; -import { Button, Form, Input, Space } from 'antd'; -import {useRequest, useSetState} from "ahooks"; -import css from "./user.module.less"; -import {InputValidateCode} from "./input.tsx"; -import {isPhone} from "@/utils/strings.ts"; -import {useUserinfoStore} from "@/service/userinfoStore.ts"; - -export type LoginFormProp = { - type?: string; - agreeTerms?: boolean; - onSuccess: (data: Account) => void; -} - -export const LoginForm: React.FC = (props) => { - const {login, confirmLogin} = useUserinfoStore(); - // 输入数据 - const [data, setData] = useSetState<{ - phone?: string; - code?: string; - }>({ - phone: '', - code: '' - }) - const [confirmState,setConfirmState] = useSetState({ - loginConfirmVisible: false, - confirmLoginKey: '' - }) - const handleConfirmLogin = ()=>{ - confirmLogin({ - confirm_login_key: confirmState.confirmLoginKey - }).then((data)=>{ - props.onSuccess(data); - }) - } - // 错误 - const [err, setErr] = useState<{ - phone?: string; - code?: string; - all?: string; - }>({}) - // const {login, loginTarget} = useUserinfoStore(); - // 执行登录 - const {run, loading} = useRequest(() => { - setErr({}) - if (!data.phone) { - setErr({phone: '请填写手机号'}) - return Promise.reject(); - } else if (!isPhone(data.phone)) { - setErr({phone: '手机号错误,请填写的正确的手机号'}) - return Promise.reject(); - } else if (!data.code) { - setErr({code: '请填写验证码'}) - return Promise.reject(); - } else if (!props.agreeTerms) { - setErr({code: '请阅读并同意服务协议和隐私政策'}) - return Promise.reject(); - } - return login(data) - }, { - manual: true, - async onSuccess(data) { - props.onSuccess(data); - }, - onError(e) { - const err = e as BizError - if(err.code == 11){ - // 已在别处登录 - setConfirmState({ - loginConfirmVisible: true, - confirmLoginKey: String(err.data) - }) - return; - } - setErr({all: e.message || `${props.type == 'link' ? '关联' : '登录'}失败,请重试`}) - } - }) - const handlePhoneInput = (e: ChangeEvent) => { - if (e.currentTarget.value) setErr({phone: undefined}) - setData({phone: e.currentTarget.value}) - } - - return (
- {/* 登录确认 */} -
-
-
-
登录提醒
-
-
您的账号已在别处登录,是否继续在当前设备登录?
-
*注:选择当前设备登录,将自动为您退出别处登录状态
-
- - - - -
-
-
-

{props.type == 'link' ? '关联手机号' : '手机号登录/注册'}

-
-
- -
-
- { - setErr({code: undefined}) - setData({code}) - }} - onError={(err, isPhone) => setErr({ - phone: isPhone ? err : undefined, - all: isPhone ? undefined : err - })}/> -
-
{err.phone || err.code || err.all}
- - -
) -} diff --git a/src/pages/login/components/user/login-modal.tsx b/src/pages/login/components/user/login-modal.tsx deleted file mode 100644 index f87308f..0000000 --- a/src/pages/login/components/user/login-modal.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from "react"; -import { Button, Checkbox, Modal, Space } from 'antd'; -import {LoginForm} from "./login-form"; -import {QrLogin} from "./qr-login.tsx"; -import css from './user.module.less' -import {useSetState} from "ahooks"; -import {AgreementContent} from "../terms/agreement.tsx"; -import {PrivacyContent} from "../terms/privacy.tsx"; - - -const ModalContent: { - [key: string]: { title: string; content: React.ReactNode } -} = { - agreement: { - title: 'AI校对王服务协议', - content: - }, - privacy: { - title: 'AI校对王隐私政策', - content: - } -} -export const LoginModal: React.FC<{ - onSuccess: (data: Account) => void -}> = (props) => { - const [state, setState] = useSetState({ - termsChecked: true, - modalVisible: false, - modalType: '', - agreement: false, - privacy: false, - showLinkPhone: false - }); - const hideLinkPhone = () => { - setState({showLinkPhone: false}) - } - - return (<> - {/* 登录-扫码 */} -
-
- -
- { - if (showBind) setState({showLinkPhone: true}) - else props.onSuccess(data) - }}/> -
-
- - {/* 扫码成功后绑定手机号 */} - {state.showLinkPhone && setState({showLinkPhone: false})} - > -
- -
-
} - {/* 协议 */} - setState({modalVisible: false})} - zIndex={10001} - footer={null} - > -
-

- {ModalContent[state.modalType]?.title} -

-
- {ModalContent[state.modalType]?.content} -
-
-
- - ) -} diff --git a/src/pages/login/components/user/qr-login.tsx b/src/pages/login/components/user/qr-login.tsx deleted file mode 100644 index 364a4a1..0000000 --- a/src/pages/login/components/user/qr-login.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, {useEffect} from "react"; -import {useRequest, useSetState} from "ahooks"; -import {Spin} from "antd"; - -import css from './user.module.less' -import {getLoginQR, qrLoginQRStatus} from "@/service/api/user"; - -export const QrLogin: React.FC<{ - agreeTerms?: boolean; - onSuccess: (data: Account,showBind?:boolean) => void -}> = (props) => { - const [state, setState] = useSetState<{ - qrUrl?: string; - ticket?: string; - invalid?: boolean; - }>({}) - - let invalidTImer: number | string | null | undefined| any; - // 查询状态 - const queryQRState = async () => { - try { - // 查询登录状态 - const ret = await qrLoginQRStatus(); - const state = parseInt(ret.state); - if (state == 3 || state == 2) { - cancel(); - invalidTImer && clearTimeout(invalidTImer) - // 扫码成功 - props.onSuccess?.(ret,state == 2) // state == 2 执行关联 需要绑定手机号 - } - } catch (e) { - // 已过期 - cancel(); // 停止 - // loadQrImage();// 重新加载 - setState({invalid: true}) - } - } - // 定时 - const {run, cancel} = useRequest(queryQRState, {pollingInterval: 3000,manual: true}) - const setQrInvalid = () => { - setState({invalid: true}) - cancel(); - } - // 加载qr - const loadQrImage = () => { - getLoginQR().then(ret => { - setState({ - qrUrl: ret.img_url, - ticket: ret.ticket, - invalid: false - }) - setTimeout(run, 2000) - invalidTImer = setTimeout(() => { - setQrInvalid(); - invalidTImer = null; - }, 6000 * 100) - }).catch(setQrInvalid) - } - - - useEffect(() => { - loadQrImage(); - return () => { - cancel();// 停止轮询 - } - }, []); - - - return (
-

扫码登录

-
- {state.qrUrl ? :
} - {state.invalid &&
} - {!props.agreeTerms &&
- 请阅读并同意
服务协议和隐私政策
-
} -
-
请用微信扫一扫 登录/注册
-
) - -} diff --git a/src/pages/login/components/user/s/user.module.less b/src/pages/login/components/user/s/user.module.less deleted file mode 100644 index 30f1bee..0000000 --- a/src/pages/login/components/user/s/user.module.less +++ /dev/null @@ -1,94 +0,0 @@ -.userIndex { - padding-bottom: 50px; -} - -.title { - margin-top: 50px; - line-height: 50px; -} - -.userinfoContent { - padding: 50px 0; - background-color: #fff; - min-height: calc(100vh - 150px - var(--header-height, 60px)); -} - -.avatarContainer { - text-align: center; - margin-bottom: 15px; -} - -.nicknameContainer { - text-align: center; - margin-bottom: 35px; -} - -.bindWechat { - color: var(--primary-color); - padding: 0 10px; - cursor: pointer; -} - -.qrContainer { - padding: 20px 0; -} -.qrImageContainer{ - width: 180px; - height: 180px; - border: solid 1px #eee; - border-radius: 0; - padding: 5px; - margin: 10px auto; - display: flex; - align-items: center; - justify-items: center; - overflow: hidden; - position: relative; -} -.qrSpin{ - margin: auto; -} - -.qrImage { - height: 100%; - width: 100%; - scale: 1.15; - - canvas { - display: block; - width: 100% !important; - height: 100% !important; - } -} - -.invalidMask{ - cursor: pointer; - position: absolute; - left:10px; - top:10px; - right:10px; - bottom: 10px; - background: url(./../../assets/qr-invalid-mask.png) center; -} -.btn{ - border: solid 1px #333; - color: #333; - border-radius: 5px; - padding: 3px 15px; - cursor: pointer; - outline: none; - margin-left: 20px; - &:hover{ - background-color: var(--background-hover-color); - } -} -.saveBtn { - .btn; - background-color: #5d91ba; - color:white; - border-color:#5d91ba; - &:hover{ - background-color: var(--btn-primary-hover-color); - border-color:var(--btn-primary-hover-color); - } -} diff --git a/src/pages/login/components/user/user.module.less b/src/pages/login/components/user/user.module.less deleted file mode 100644 index 6a7df82..0000000 --- a/src/pages/login/components/user/user.module.less +++ /dev/null @@ -1,81 +0,0 @@ - -.loginTitle { - font-size: var(--title-font-size, 16px); - font-weight: bold; -} -.modalContainer{ - display: flex; - justify-content: center; -} -.modalContent { -} - -.formItem { - margin-top: 20px; -} - -.loginError { - height: 30px; - color: var(--error-color, red); - text-align: center; - margin:30px 0 5px; -} - -.dividerLine { - margin: 0 30px; - border-right: solid 1px #DFDFDF; - min-height: 100%; - //height: 230px; -} - -// 二维码 -.qrLogin{ - margin-right: 20px; -} -.qrContainer { - padding: 4px; - border: solid 1px #eee; - margin: 10px 0; - position: relative; - overflow: hidden; - width: 180px; - height: 180px; - display: flex; - align-items: center; - img{ - scale: 1.15; - display: block; - height: 100%; - } -} -.qrSpin{ - margin: auto; -} -.invalidMask{ - cursor: pointer; - position: absolute; - left:10px; - top:10px; - right:10px; - bottom: 10px; - background: url(./../../assets/qr-invalid-mask.png) center; -} -.qrTip{ -} -.qrTermsTip{ - position: absolute; - left:0px; - top:0; - right:0px; - bottom: 0; - background-color: rgba(255,255,255,0.95); - display: flex; - align-items: center; - justify-content: center; - span{ - padding: 15px; - margin: auto; - color: var(--primary-color); - font-size: 14px; - } -} diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx deleted file mode 100644 index 79a89b2..0000000 --- a/src/pages/login/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, {useEffect} from "react"; -import {AppTitleBar} from "../../components/app/title-bar.tsx"; -import {LoginModal} from "./components/user/login-modal.tsx"; -import {useBridge} from "../../core/bridge.ts"; -import {useSearchParams} from "react-router-dom"; -import {useUserinfoStore} from "../../service/userinfoStore.ts"; - -const PageLogin: React.FC = () => { - const {userinfo} = useUserinfoStore() - const {bridge} = useBridge() - const [params] = useSearchParams() - const action = params.get('action') || 'default' - const asyncLoginInfo = (data: Account) => { - console.log('asyncLoginInfo',data,action) - if (action == 'proofread') { // 登录后需要立即 - bridge?.StartProofread() // 启动校对 - }else if(action == 'setting'){ - bridge?.ShowSettingForm() // 启动设置 - } - bridge?.loginSuccess?.(JSON.stringify(data)) // 登录成功 通知插件 - } - const handleLoginSuccess = (data: Account) => { - asyncLoginInfo(data) - } - useEffect(() => { - if (userinfo) { - asyncLoginInfo(userinfo) - } - }, [userinfo]) - - return (
- -
- -
-
- ) -} -export default PageLogin \ No newline at end of file diff --git a/src/pages/login/login.less b/src/pages/login/login.less deleted file mode 100644 index 9a3cf0a..0000000 --- a/src/pages/login/login.less +++ /dev/null @@ -1,22 +0,0 @@ -.login-page { - //display: flex; - //place-items: center; - .login-container{ - height: calc(100vh - 60px); - overflow: auto; - } - .login-content{ - width: 300px; - margin: auto; - padding: 50px 0; - } - .qr-login-container { - width: 100%; - display: flex; - justify-content: center; - } - - .login-method-switch { - margin-top: 20px; - } -} \ No newline at end of file diff --git a/src/pages/normal/Default.tsx b/src/pages/normal/Default.tsx deleted file mode 100644 index 735c5de..0000000 --- a/src/pages/normal/Default.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import {Breadcrumb, Button, Layout, Menu, Space} from "antd"; - -const {Header, Content, Footer} = Layout; - -const items = new Array(15).fill(null).map((_, index) => ({ - key: index + 1, - label: `nav ${index + 1}`, -})); -export default function DefaultPage() { - - const request = (url: string) => { - return fetch(`http://localhost:10800/${url}`).then(s => s.json()); - } - const init = () => { - request('?action=login').then(console.log) - } - const info = () => { - request('?action=info').then(console.log) - } - return ( - -
-
- -
- - - Home - List - App - -
-

default

- - - - - -
-
-
- Ant Design ©{new Date().getFullYear()} Created by Ant UED -
-
- ) - -} \ No newline at end of file diff --git a/src/pages/normal/Main.tsx b/src/pages/normal/Main.tsx deleted file mode 100644 index b2129bc..0000000 --- a/src/pages/normal/Main.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import {Button, Space} from "antd"; -import {AppTitleBar} from "../../components/app/title-bar.tsx"; - -export default function DefaultPage() { - - const request = (url: string) => { - return fetch(`http://localhost:10800/${url}`).then(s => s.json()); - } - const init = () => { - request('?action=login').then(console.log) - } - const info = () => { - request('?action=info').then(console.log) - } - const openLogin = () => { - chrome.webview.hostObjects.bridge.ShowLoginForm(""); - } - return ( - <> -
- -
-

default

- - - - - - -
-
- - ) - -} \ No newline at end of file diff --git a/src/pages/normal/contact.tsx b/src/pages/normal/contact.tsx deleted file mode 100644 index e9a86c5..0000000 --- a/src/pages/normal/contact.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import {Button} from "antd"; -import {AppTitleBar} from "@/components/app/title-bar.tsx"; -import {useBridge} from "@/core/bridge.ts"; -import ImageWechat from "./images/wechat_qrcode.png" - -const PageContact = () => { - const isDevMode = localStorage.getItem('plugin-dev-mode'); - const {bridge} = useBridge() - return (<> - -
-
-
使用过程中有任何疑问,请使用微信扫描二维码或发送邮件联系我们
-
- -
-
联系邮箱:
- - {isDevMode &&
- -
} -
-
- ) -} - -export default PageContact diff --git a/src/pages/normal/images/wechat_qrcode.png b/src/pages/normal/images/wechat_qrcode.png deleted file mode 100644 index a9727a8..0000000 Binary files a/src/pages/normal/images/wechat_qrcode.png and /dev/null differ diff --git a/src/pages/normal/test.tsx b/src/pages/normal/test.tsx deleted file mode 100644 index ef5ebe6..0000000 --- a/src/pages/normal/test.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import {useEffect, useState} from "react"; -import {useDebounceFn} from "ahooks"; - -const MaxCount = 20 -const centerItem = (activeIndex: number) => { - // 将提示显示在视图中间 - const div = document.querySelector(`div.proofread-index-${activeIndex}`) - if (div) { - div.scrollIntoView({ - behavior: 'smooth', - block: 'center' - }) - } -} -export const TestPage = () => { - const [lastIndex, setLastIndex] = useState(-1); - const [activeIndex, setActiveIndex] = useState(-1) - - const {run: setActiveLastIndex} = useDebounceFn((i) => setLastIndex(i), {wait: 200,}) - const processScroll = (e: WheelEvent) => { - const {deltaY} = e; - const newIndex = deltaY > 0 ? activeIndex + 1 : activeIndex - 1 - if (newIndex < 0 || newIndex >= MaxCount) return; - setActiveIndex(newIndex) - centerItem(newIndex) - setActiveLastIndex(newIndex) - } - - const {run: onMousewheel} = useDebounceFn((e) => processScroll(e), {wait: 10,}) - useEffect(() => { - // 绑定键盘事件 - // document.documentElement.addEventListener('keyup', handleUpAndDownEvent, false) - // 绑定滚动事件 - document.documentElement.addEventListener('wheel', onMousewheel, false) - return () => { - document.documentElement.removeEventListener('wheel', onMousewheel, false) - // document.documentElement.removeEventListener('keyup', handleUpAndDownEvent, false) - } - }, []); - return (
-

TEST ==》 {lastIndex}

-
- {Array(MaxCount).fill(0).map((_, i) => ( -
- {i} -
))} -
-
) -} \ No newline at end of file diff --git a/src/pages/proofread/components/editor.less b/src/pages/proofread/components/editor.less deleted file mode 100644 index 26759d0..0000000 --- a/src/pages/proofread/components/editor.less +++ /dev/null @@ -1,380 +0,0 @@ - -.proofread-container { - .proofread-items, .types { - box-sizing: border-box; - } - - .proofread-items { - display: flex; - flex-direction: column; - padding-bottom: 15px; - max-width: calc(100% - 60px); - } - - .operation-button { - padding: 10px 0; - } - - .btn-accept { - background-color: rgba(0, 0, 0, 0); - color:var(--selected-color); - border-color: var(--selected-color); - &:hover{ - background-color: #e7eaf0; - } - } - .btn-cancel{ - --btn-background-color: #c9c9c9; - &:hover{ - --btn-background-color: #a2a2a2; - } - } - - .btn-rollback { - border-color: var(--border-color); - background-color: transparent; - } -} - -.btn-process{ - background-color: #fff; - border: none;//solid 1px rgba(214, 170, 105, 0.7); - outline: none; - border-radius: 3px; - font-size: 12px; - padding: 8px 0; - min-width: 70px; - cursor: pointer; - color:#333; - .btn-icon{ - font-size: 20px; - color:var(--primary-color); - } - &:hover{ - background-color: var(--primary-color); - color:#fff; - .btn-icon{ - color: #fff; - } - } - &[disabled]{ - color: #ccc; - cursor: not-allowed; - .btn-icon{ - color: #ccc; - } - } - &[disabled]:hover{ - background-color: #fff; - color: #ccc; - } -} -.proofread-list { - - - - span { - display: inline-block; - } - - .item:last-child + .selected-line{ - display: none; - } - - .info{ - max-width: 100%; - min-width: 0; - flex: 1; - } - - .origin,.replaced { - max-width: 80%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - padding: 2px 4px; - //height: 30px; - } - .origin { - color:#000; - } - .replaced { - background-color: var(--primary-color, #558CB7); - color: #fff; - border-radius: 3px; - } - .select{ - .replaced { - - } - .origin,.replaced { - white-space: normal; - //max-width: 100px; - } - } - .proofread-replace-item-replace{ - .origin,.replaced { - max-width: 50%; - } - } - .proofread-replace-item-delete, - .proofread-replace-item-insert{ - .origin { - //max-width: 180px; - } - &.select{ - .origin,.replaced { - white-space: inherit; - //max-width: 160px; - } - } - } - - .action-text { - color: var(--primary-color); - margin-left:20px; - font-weight: bold; - min-width: 40px; - white-space: nowrap; - } - - .arrow { - margin: 0 10px; - } -} - -// 右侧面板 -.panel-right-state-wrapper { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - color: #979797; - - .desc { - margin: 5px 0 20px; - } - - .proofread-state-perfect { - .desc { - font-size: 18px; - margin-top: 10px; - } - } - .proofread-state-analyzing{ - font-size: 18px; - color: #000; - .remain{ - font-weight: bold; - } - .remain-time{ - margin-top: 10px; - } - .value{ - color: #FA674A; - font-size: 20px; - } - .unit{ - font-size: 14px; - margin-left: 3px; - } - .control{ - color: #979797; - margin-top: 30px; - line-height: 26px; - - .small{ - font-size: 14px; - } - } - .back-to-document{ - margin-top: 30px; - } - } -} - -// tihuan -.text-replace-item { - position: relative; - cursor: pointer; - padding: 5px 0; - &:before{ - content:' '; - display: none; - position: absolute; - left:-1px; - right:-1px; - bottom: -5px; - top:-5px; - background-color: rgba(253, 102, 67, 0.4); - } - &.replace-type-replace{ - padding-bottom: 7px; - --background-image:url(./../../assets/editor/replace.svg); - background-image:var(--background-image); - background-size: 12px 5px; - background-repeat: repeat-x; - background-position:0 26px; - &:after{ - //content:'\2000\2000\2000\2000'; - //display: block; - //position: absolute; - //left:0;right:0; - //bottom: -7px; - //height: 5px; - //background-image:linear-gradient(135deg, transparent 40%, var(--current-color,#f00), transparent 60%), - //linear-gradient(45deg, transparent 40%, var(--current-color,#f00), transparent 60%); - //background-size: 10px 10px; - //background-repeat: repeat-x; - //background-position: 0 0rem; - } - } - &.text-replace-none{ - text-decoration:none; - border-bottom:none; - color: inherit; - cursor: inherit; - } - &.processed-accept{ - --current-color:var(--primary-color) !important; - &.replace-type-replace{ - --background-image:url(./../../assets/editor/replace-accept.svg); - background-image: var(--background-image); - } - } - &.processed-ignore{ - border-color:#c9c9c9 !important; - --current-color:#c9c9c9 !important; - &.replace-type-replace{ - --background-image:url(./../../assets/editor/replace-ignore.svg); - background-image: var(--background-image); - } - } - &.replace-type-insert{ - --background-image:url(./../../assets/editor/insert.svg); - min-width: 15px; - background-size: 16px 30px; - background-repeat: repeat-x; - background-position: 0 1px; - - &:not(.processed){ - background-image: var(--background-image); - color: transparent; - &::selection{ - color: transparent; - text-decoration-color: #fff; - } - } - &.processed-ignore{ - display: none; - } - } - - &.selection { - //background-color: rgba(253, 102, 67, 0.4); - background-image: var(--background-image),linear-gradient(to bottom,rgba(253, 102, 67, .4),rgba(253, 102, 67, .4)) !important; - background-size: 12px 5px,100% 28px; - background-position:0 26px,0 0; - &.replace-type-delete,&.replace-type-insert.processed{ - background-image: linear-gradient(to bottom,rgba(253, 102, 67, .4),rgba(253, 102, 67, .4)) !important; - background-size: 100% 28px; - background-position: 0 0; - } - &.replace-type-insert:not(.processed){ - background-size: 16px 30px,100% 28px; - background-position:0 1px,0 0; - } - - } - &.replace-type-delete{ - text-decoration: line-through; - text-decoration-color: var(--current-color,#f00); - text-decoration-thickness: 2px; - border-bottom:none; - &.processed-ignore{ - border-color:gray !important; - --current-color: gray !important; - //text-decoration:none; - } - } - - &.processed { - &.processed-ignore{ - //text-decoration:none; - //border-bottom:none; - } - &.processed-delete:not(.processed-delete-init) { - &:before { - //content: attr(data-replace-text); - text-decoration: line-through; - } - } - } -} - - -.text-replace-item.processed-delete,.replace-type-insert.processed-ignore{ - width: 4px; - max-width: 4px; - min-width: 4px; - display: inline-block !important; - height: 30px; - vertical-align: middle; -} -.gov-extra-panel{ - span{ - display: inline; - } - - .link{ - text-decoration: underline; - color: #535bf2; - } -} -.collapse-info-panel{ - overflow: hidden; - display: flex; - margin:10px 0; - padding: 6px; - border-radius: 2px; - background: #ebebeb; - - .arrow-icon{ - min-width: 0; - min-width: 20px; - height: 20px; - display: flex; - align-items: center; - justify-content: center; - } - .caret-icon{ - transition: transform 0.2s; - transform: rotate(0deg); - } - - .content{ - flex: 1; - max-width: 100%; - margin-right: 10px; - overflow: hidden; - } - .more-text{ - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - &.open{ - .caret-icon{ - transform: rotate(90deg); - } - .gov-extra-panel{ - margin-right: 0; - } - .more-text{ - word-break: break-all; - white-space: normal; - overflow: auto; - } - } -} \ No newline at end of file diff --git a/src/pages/proofread/components/gov/collapse-info.tsx b/src/pages/proofread/components/gov/collapse-info.tsx deleted file mode 100644 index b009ba9..0000000 --- a/src/pages/proofread/components/gov/collapse-info.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { ReactNode,useState } from 'react'; -import {CaretRightFilled} from '@ant-design/icons' - -export default function CollapseInfo({ children }: { children: ReactNode }) { - const [open, setOpen] = useState(false); - return
setOpen(!open)}> - -
{children}
-
; -} \ No newline at end of file diff --git a/src/pages/proofread/components/gov/gov-extra.tsx b/src/pages/proofread/components/gov/gov-extra.tsx deleted file mode 100644 index 797c5f4..0000000 --- a/src/pages/proofread/components/gov/gov-extra.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ReactNode } from 'react'; -import CollapseInfo from './collapse-info.tsx'; -import { bridge } from '@/core/bridge.ts'; - -function GovExtraPanel({ children }: { children: ReactNode }) { - return
- {children} -
; -} -// 显示领导人职位 -function LeaderInfo({info}:{info: V3.GovInfo}){ - return -
【职位】{info.data?.origin}是现任{info.content}
-
-} -// 语录 -function QuotationInfo({info}:{info: V3.GovInfo}){ - const showHyperlink = ()=>{ - if(!info.data?.link || info.data?.link?.trim().length == 0) return; - bridge.OpenUrlWithOsBrowser(info.data.link) - } - return <> - -
【修改建议】{info.content}
-
- - -
- 【来源】 - {info.data?.from} -
-
-
- -} - -export function GovExtra({list}:{list: V3.GovInfo[]}) { - return (<> - {list.map((info,idx)=>
- {info.type == 'quotation' && } - {info.type == 'position' && } - {info.type == 'leader' && } -
)} - ) -} \ No newline at end of file diff --git a/src/pages/proofread/components/gov/leader-position.tsx b/src/pages/proofread/components/gov/leader-position.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/proofread/components/gov/leader-saying.tsx b/src/pages/proofread/components/gov/leader-saying.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/proofread/components/gov/parse-gov-extra.ts b/src/pages/proofread/components/gov/parse-gov-extra.ts deleted file mode 100644 index d603a87..0000000 --- a/src/pages/proofread/components/gov/parse-gov-extra.ts +++ /dev/null @@ -1,77 +0,0 @@ -type QuotationResult = { - [key: string]: { - error_type: string; - notice: { - category: string; - content: string; - document_name: string; - hypelink: string; - id: string; - publish_time: string; - source: string; - } - } -} - -type PositionResult = { - [key: string]: { - error_type: string; - notice: { - leaders: string[]; - position: string; - } - } -} -type LeaderResult = { - [key: string]: { - error_type: string; - notice: { - positions: string[]; - correct_name: string; - } - } -} - -export function parseLeader(key:string,result: LeaderResult) { - // split by '、' when has leaders - const nameArray = key.split('、') - // if has leaders, return leaders - return nameArray.map(name=>{ - const { notice } = result[name]; - return { - type:'leader', - content: `${notice.positions.join('、')}`, - data:{ - origin: name - } - } as V3.GovInfo - }) -} - -export function parsePosition(key:string,result: PositionResult) { - const { notice } = result[key]; - const position = notice.position.trim() - const noLeader = position.length == 0 || notice.leaders[0] == '该职位组合无对应领导人' - return { - type:'position', - // 如果没有 position 表示 无对应领导人 - content: noLeader ? notice.leaders[0] : `担任${position}的有${notice.leaders.join('、')}`, - data:{ - origin: key, - source: noLeader?'position-error':'' - } - } as V3.GovInfo -} - -export function parseQuotation(key:string,result: QuotationResult) { - const { notice } = result[key]; - return { - type:'quotation', - content: notice.content, - data:{ - origin: notice.category, - from: notice.document_name, - link: notice.hypelink - } - } as V3.GovInfo -} \ No newline at end of file diff --git a/src/pages/proofread/components/gov/readme.md b/src/pages/proofread/components/gov/readme.md deleted file mode 100644 index 78b5271..0000000 --- a/src/pages/proofread/components/gov/readme.md +++ /dev/null @@ -1,9 +0,0 @@ -## 政务校对 -### 文档 - -https://pu7y37y121.feishu.cn/docx/ZAOzdGxRJoYztbxu7k0cAosNnDe - -### 说明 -给AI校对王增加政务信息的校对,包括领导人排序、领导人讲话溯源和落马官员。 - -## \ No newline at end of file diff --git a/src/pages/proofread/components/icons.tsx b/src/pages/proofread/components/icons.tsx deleted file mode 100644 index 95254b4..0000000 --- a/src/pages/proofread/components/icons.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React, {CSSProperties} from "react"; -import Icon from "@ant-design/icons"; -import {cx} from "@emotion/css"; - -type SvgIconProps = { - size?: number; - className?: string; - style?: CSSProperties; - onClick?: (e: React.MouseEvent) => void; - component: React.ComponentType -} - -export const SvgIcon: React.FC = (props) => { - const styles: CSSProperties = props.style || {} - if (props.size) { - styles.fontSize = props.size + 'px'; - } - - return (); -} - -export const IconClose = () => ( - // width="28" height="40" - - - - -) -export const IconOpen = () => ( - - - -) -export const IconArrowRight = () => ( - - - -) -export const IconDotMore = () => ( - - - - - -) -export const IconArrowDown = () => ( - - - -) - -export const IconAccept = () => ( - - - -) -export const IconIgnore = () => ( - - - -) -export const IconReviewOutlined = () => ( - - - - - -) - -export const IconReview = () => ( - - - -) - -export const IconPlus = () => ( - - - - - - -) -export const IconRollback = () => ( - - - -) -export const IconRollbackOld = () => ( - - - - -) -export const IconRollbackCircle = () => ( - - - -) -export const IconMinus = () => ( - - - -) -export const IconCheckOutline = () => ( - - - -) - -export const IconDotMore2 = ()=>( - - - - -) -export const IconStartProofread = () => ( - - - -) \ No newline at end of file diff --git a/src/pages/proofread/components/images/arrow-icon.tsx b/src/pages/proofread/components/images/arrow-icon.tsx deleted file mode 100644 index 785b763..0000000 --- a/src/pages/proofread/components/images/arrow-icon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export default function ArrowIcon() { - return ( - - - ); -} \ No newline at end of file diff --git a/src/pages/proofread/components/images/loading.svg b/src/pages/proofread/components/images/loading.svg deleted file mode 100644 index 3bb898a..0000000 --- a/src/pages/proofread/components/images/loading.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/pages/proofread/components/images/logo.tsx b/src/pages/proofread/components/images/logo.tsx deleted file mode 100644 index eb0214a..0000000 --- a/src/pages/proofread/components/images/logo.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from "react"; - -export const IconLogo = ({style}:{style?:React.CSSProperties}) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) \ No newline at end of file diff --git a/src/pages/proofread/components/images/notice.tsx b/src/pages/proofread/components/images/notice.tsx deleted file mode 100644 index 822880a..0000000 --- a/src/pages/proofread/components/images/notice.tsx +++ /dev/null @@ -1,391 +0,0 @@ -export const ErrorNotice = ()=>( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) \ No newline at end of file diff --git a/src/pages/proofread/components/index.tsx b/src/pages/proofread/components/index.tsx deleted file mode 100644 index 0d99bfb..0000000 --- a/src/pages/proofread/components/index.tsx +++ /dev/null @@ -1,576 +0,0 @@ -import React, {useCallback, useEffect, useMemo, useState} from "react"; -import Icon from "@ant-design/icons"; -import {useDebounceFn, useSetState} from "ahooks"; -import {Flex, Space} from "antd"; -import clsx from "clsx" - -import {ProofreadStateEnum,} from "@/service/types/document.ts"; -import {showToast} from "@/components/messages/Modal.tsx"; - -import './editor.less' - -import {IconCheckOutline, IconMinus, IconRollback, IconRollbackCircle, IconRollbackOld} from "./icons.tsx"; -import {ActionKey, ProofreadItem} from "./proofread-item.tsx"; - -import {IconLogo} from "./images/logo.tsx"; -import {parseV3ProofreadResult} from "@/core/proofread-util.ts"; -import {V3Enums} from "@/types/v3/enums.ts"; -import {stringIsEmpty} from "@/core/string-utils.ts"; -import {useBridge} from "@/core/bridge.ts"; -import {CACHE_DATA} from "@/core/cache.ts"; -import {process} from "@/service/api/v3/document.ts"; -import {VirtualListItem} from "@/pages/proofread/components/virtual-list-item.tsx"; - -type ProofreadPanelProps = { - children?: React.ReactNode; - sentences: V3.ProofreadSentence[]; - proofreadLoading?: boolean - onUpdateProofreadItem: (item: V3.ProofreadCorrect, action?: 'process' | 'redo') => void; - onSelectProofreadItem: (item: V3.ProofreadCorrect | null) => void; - activeProofreadItemId?: number; - disabledProofreadItemList: number[]; - onStartProofread: () => Promise | void; - selectedProofreadItemId?: number; - selectedAcceptStatus?: 1 | 2 | 3; - userinfo?: Account; - histories: V3.ProcessAction[]; - setHistories: (values: V3.ProcessAction[]) => void; - onStateChange?: (state: { activeItemId: number; acceptState: AcceptStatus; }) => void; -} - -enum AcceptStatus { - NotAdopted = 1, - Adopted = 2, - Default = 3 -} - - -const GovCheckKeys = [ - V3Enums.ProofreadType.leader.key, - V3Enums.ProofreadType.position.key, - V3Enums.ProofreadType.quotation.key, - V3Enums.ProofreadType.fallen_officers.key, -] -/** - * 是否需要复核 - * @param item - */ -function itemNeedReview(item:V3.ProofreadCorrect){ - if( - item.tag.trim().length == 0 // not delete insert replace - && ( - item.type == V3Enums.ProofreadType.sensitive.key - || item.type == V3Enums.ProofreadType.blacklist.key - || GovCheckKeys.includes(item.type) - - ) - ) { - return true - } - return false -} - -const ProofreadPanel: React.FC = (props) => { - const {userinfo, histories, setHistories} = props - const [state, setState] = useSetState<{ - // 当前选中分类 - currentType: string | null; - // 默认是否展开panel - open: boolean; - adoptAll?: boolean; - ignoreAll?: boolean; - listMaxCount: number; - activeIndex: number; - activeItemId: number; - acceptState: AcceptStatus; - }>({ - currentType: null, - open: true, - - adoptAll: false, - ignoreAll: false, - - activeIndex: -1, - activeItemId: -1, - listMaxCount: -1, - acceptState: AcceptStatus.NotAdopted - }) - - - const [proofreadResult, setProofreadResult] = useState() - - useEffect(() => { - handleTypeChange(null, false) - const result = parseV3ProofreadResult(props.sentences, props.disabledProofreadItemList) - setProofreadResult(result) - }, [props.sentences, props.proofreadLoading, props.disabledProofreadItemList]) - - const getCurrentProofreadTypeListByAcceptStatus = (_state?: AcceptStatus, disableType = false) => { - _state = _state || state.acceptState - let list = proofreadResult?.list || []; - if (_state == AcceptStatus.NotAdopted) { - // 获取未复核的校对项 - list = list.filter(s => s.isAccept == ProofreadStateEnum.Default); - } else if (_state == AcceptStatus.Adopted) { - // 获取已复核的校对项 - list = list.filter(s => s.isAccept != ProofreadStateEnum.Default) - } - if (state.currentType && !disableType) { - list = list.filter(s => { - if(state.currentType == 'gov-check'){ - return GovCheckKeys.includes(s.type) - } - if(state.currentType == 'error'){ - return s.type != 'blacklist' && s.type != 'sensitive' && !GovCheckKeys.includes(s.type) - } - return s.type == state.currentType - }) - } - return list; - } - // 当前校对数据 - const currentProofreadCount = useMemo(() => { - const all = ( proofreadResult?.list || []).length; - // 全局获取待复核的校对项 避免过滤后的数据为空 - const not_adopted = ( proofreadResult?.list || []).filter(s => s.isAccept == ProofreadStateEnum.Default).length; - const list = getCurrentProofreadTypeListByAcceptStatus(undefined, true) || []; - const count: V3.ProofreadResultCount = { - all, - adopted: 0, - not_adopted, - error:0, - total: not_adopted, - sensitive: 0, - blacklist: 0, - govCheck: 0, - }; - list.forEach(it => { - //count.total ++; - if (it.type === 'sensitive'){ - count.sensitive ++; - }else if(it.type === 'blacklist'){ - count.blacklist++; - }else if(GovCheckKeys.includes(it.type)){ - count.govCheck ++; - }else{ - count.error ++; - } - }) - count.adopted = all - count.not_adopted; - // if(state.acceptState == AcceptStatus.Adopted) { - // }else{ - // count.not_adopted = count.total; - // count.adopted = all - count.not_adopted; - // } - return count; - }, [proofreadResult, state.acceptState, state.activeItemId, props.histories]) - - // 当前状态校对列表 - const currentProofreadList = useMemo(() => { - const list = proofreadResult?.list || []; - if (!state.currentType) return list; - // Array.isArray(state.currentType?.id) ? state.currentType?.id.includes(s.type) : - return list.filter(s => { - if(state.currentType == 'error'){ - return s.type != 'blacklist' && s.type != 'sensitive' - } - return s.type == state.currentType - }) - }, [proofreadResult, state.currentType]) - - // 撤销操作 - const redoAction = async () => { - if (props.sentences.length == 0 || histories.length == 0) return; - const last = histories[histories.length - 1]; - // 获取最后一个历史的同一批次记录 - const currentList = histories.filter(s => s.id == last.id); - if (!currentList || currentList.length == 0) return; - currentList.forEach(it => { - // 状态调整为未处理 - const item = proofreadResult?.list?.find(s => s.id == it.correctId) - if (item) { - item.isAccept = ProofreadStateEnum.Default - props.onUpdateProofreadItem(item, 'redo') - } - }) - setHistories(histories.filter(s => s.id != last.id)); - setProofreadResult({ - count: proofreadResult!.count, - list: proofreadResult!.list - }) - // 将状态调整为未复核 - if (state.acceptState == AcceptStatus.Adopted) { - setState({acceptState: AcceptStatus.NotAdopted}) - } - // 选中第一个 - const actId = currentList[0]; - // 找到要选中的item的index - const item = currentProofreadList.find(s => s.id == actId.correctId) - if (item) { - centerItem(-1, item) - // setState({activeIndex: index}) - } - } - - /** - * 获取全部/类似校对项 - * @param isAccept - * @param p 如果不传入则获取该状态对应类型所有校对项 - */ - const getSameProofreadItems = (isAccept?: boolean, p?: V3.ProofreadCorrect) => { - const list = currentProofreadList.filter(s => { - // if (isAccept && s.type == V3Enums.ProofreadType.sensitive.key) return false; - return s.isAccept == ProofreadStateEnum.Default; - }) - // 获取当前类型下所有 - return p ? list.filter(s => { - return s.origin == p.origin && s.text == p.text; - }) : ( - [...list] - ) - } - - const addToHistory = (items: V3.ProofreadCorrect[]) => { - // 根据最后一个记录,生成新的批次id - const last = histories.length == 0 ? null : histories[histories.length - 1] - const id = last ? last.id + 1 : 1; - - setHistories([ - ...histories, - ...items.map(s => ({id, correctId: s.id})) - ]) - setProofreadResult(proofreadResult) - } - - // 批量处理 - const batchProcess = (status: ProofreadStateEnum, proofread?: V3.ProofreadCorrect) => { - const isAccept = status == ProofreadStateEnum.Accept; - const list = getSameProofreadItems(isAccept, proofread); - if (list.length > 0) { - const ids: number[] = []; - // 设置 状态 - list.map(s => { - ids.push(s.id) - // 处理以下复核情况 - s.isAccept = isAccept && itemNeedReview(s) ? ProofreadStateEnum.Review :status; - props.onUpdateProofreadItem(s, 'process'); - return s; - }) - addToHistory(list) - process(CACHE_DATA.DocumentID, { - ids, - action: status - }) - // 采用随机数 避免默认值均为-1 导致选中项不更新 - const activeItemId = 0 - Math.ceil(Math.random() * 10) - setTimeout(()=>{ - setState({activeItemId}) - },20) - } - } - - // 处理全部 - const handleProcessAll = (action: ActionKey) => { - return () => { - if (props.sentences.length == 0) return; - batchProcess(action == 'acceptAll' ? ProofreadStateEnum.Accept : ProofreadStateEnum.Ignore) - } - } - - - // 让当前选中的 item 居中 - const centerItem = (activeIndex: number, item: V3.ProofreadCorrect, showInCenter = true) => { - if (item.id == state.activeItemId) return; - setState((origin) => ({ - ...origin, - activeIndex, - activeItemId: item.id - })) - if (showInCenter) { - // 将提示显示在视图中间 - const div = document.querySelector(`div.proofread-item-${item.id}`) - if (div) { - div.scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'nearest' // 水平对齐方式 - }) - } - } - // - props.onSelectProofreadItem(item); - } - useEffect(() => { - if (props.selectedProofreadItemId) { - const index = currentProofreadList.filter(s => (state.acceptState == AcceptStatus.Default - || (state.acceptState == AcceptStatus.Adopted && s.isAccept != ProofreadStateEnum.Default) - || (state.acceptState == AcceptStatus.NotAdopted && s.isAccept == ProofreadStateEnum.Default) - )).findIndex(s => s.id == props.selectedProofreadItemId) - if (index >= 0) { - centerItem(index, currentProofreadList[index]) - } - setState({activeItemId: props.selectedProofreadItemId}) - } - }, [props.selectedProofreadItemId]) - useEffect(() => { - if (props.selectedAcceptStatus) { - setState({ - acceptState: props.selectedAcceptStatus - }) - } - }, [props.selectedAcceptStatus]) - // 处理校对项 - const handleItemAction = async (key: ActionKey, item: V3.ProofreadCorrect, index: number) => { - try { - if (key == 'click') { - if (item) { - setState({activeIndex: index, activeItemId: item.id}) - } - centerItem(index, item, false) - return; - } else if (key == 'addToLexicon') { - // 添加到词库 - showToast('添加词库成功', "success") - } else { - if (key == 'ignoreAll' || key == 'acceptAll') { // 同类型处理 - batchProcess(key == 'acceptAll' ? ProofreadStateEnum.Accept : ProofreadStateEnum.Ignore, item) - } else { - if (key == 'ignore') { // 忽略 - item.isAccept = ProofreadStateEnum.Ignore; - } else if (key == 'accept') { // 采纳 - item.isAccept = ProofreadStateEnum.Accept; - } else if (key == 'review') { // 复核 - item.isAccept = ProofreadStateEnum.Review; - } - props.onUpdateProofreadItem(item, 'process') - - addToHistory([item]) - process(CACHE_DATA.DocumentID, { - ids: [item.id], - action: item.isAccept - }).catch(console.log) - // 自动定位下一个 - const currentList = state.acceptState == AcceptStatus.Default ? currentProofreadList : currentProofreadList.filter(s => (state.acceptState == AcceptStatus.Default - || (state.acceptState == AcceptStatus.Adopted && s.isAccept != ProofreadStateEnum.Default) - || (state.acceptState == AcceptStatus.NotAdopted && s.isAccept == ProofreadStateEnum.Default) - )); - if (currentList.length == 0) { - setTimeout(() => { - setState((prevState) => ( { - ...prevState, - activeIndex: -1, - activeItemId: 0 - Math.ceil(Math.random() * 100), - })) - }, 20) - return; - } - const _idx = index >= currentList.length ? index - 1 : (state.acceptState == AcceptStatus.Default ? index + 1 : index) - const _it = currentList[_idx]; - setTimeout(() => { - centerItem(_idx, _it,false) - }, 20) - - } - } - } catch (e) { // 处理错误了 - console.log('process item action error:', (e as Error).message) - } - } - - - // 切换类型 - const handleTypeChange = (currentType: string | null, resetIndex = true) => { - setState(_prev => ({ - currentType: _prev.currentType == currentType ? null : currentType, - activeIndex: resetIndex ? -1 : _prev.activeIndex - })) - window.scrollTo({ - top: 0, - behavior: 'smooth' - }) - } - const {bridge} = useBridge(); - const focusPane = useDebounceFn(() => bridge?.Focus(), {wait: 200,}) - // Focus - const movePrevOrNextProofreadItem = (action: 'prev' | 'next') => { - setState(state => { - // 方向键移动 - let list = getCurrentProofreadTypeListByAcceptStatus() || []; - if (list.length == 0) return state; - if (!stringIsEmpty(state.currentType)) { - list = list.filter(s => s.type == state.currentType) - } - // 当前选中项的索引 - const index = list.findIndex(s => s.id == state.activeItemId) - const maxCount = list.length; - if (maxCount == 0 - || (action == 'next' && index >= maxCount - 1) - || (action == 'prev' && index <= 0) - ) { - return state; - } - const activeIndex = index + (action == 'next' ? 1 : -1) - const item = list[activeIndex] - const div = document.querySelector(`div.proofread-item-${item.id}`) - if (div) { - div.scrollIntoView({behavior: 'smooth', block: 'center',inline: 'nearest'}) - } - props.onSelectProofreadItem(item); - setTimeout(focusPane.run, 50); - return { - ...state, - activeIndex, - activeItemId: item.id - } - }) - } - - const handleUpAndDownEvent = useCallback((e: KeyboardEvent) => { - const key = e.key.toLowerCase(); - if (key == 'arrowup' || key == 'arrowdown') { - console.log('handleUpAndDownEvent=>', proofreadResult) - if (proofreadResult) { - movePrevOrNextProofreadItem(key == 'arrowup' ? 'prev' : 'next') - } - } - }, [proofreadResult, state]) - - useEffect(() => { - // 绑定键盘事件 - document.documentElement.addEventListener('keyup', handleUpAndDownEvent, false) - return () => { - document.documentElement.removeEventListener('keyup', handleUpAndDownEvent, false) - } - }, [handleUpAndDownEvent]); - - - const currentProofreadTotal = useMemo(() => { - //const list = getCurrentProofreadTypeListByAcceptStatus(undefined,true) || []; - return currentProofreadCount.total; - // return proofreadResult?.count.total && proofreadResult?.count.total > 0 ? proofreadResult?.count.total : 0 - }, [currentProofreadCount]) - const _currentList = useMemo(() => { - return getCurrentProofreadTypeListByAcceptStatus() || [] - }, [currentProofreadList, state.acceptState, state.activeItemId]) - - const handleTabChange = (key: AcceptStatus) => { - let activeItemId = -1; - if (key == AcceptStatus.Adopted) { - // 如果切换到已复核 则自动定位到最后一个 - if (histories.length > 0) { - // const list = getCurrentProofreadTypeListByAcceptStatus(AcceptStatus.Adopted) - // if(list){ - // const last = list.length > 0 ? list[list.length - 1] : null - // if(last) { - // activeItemId = last.id - // } - // } - const last = histories[histories.length - 1]; - console.log('---last', last) - activeItemId = last.correctId; - bridge?.SelectMarkById(activeItemId, CACHE_DATA.DocumentID) - } - } - setState({acceptState: key, activeItemId}) - handleTypeChange(null) - props.onStateChange?.({acceptState: key, activeItemId}) - CACHE_DATA.selectStatus = key - // 如果是 - } - - return (
-
- -
- -
- - - - - - - - {props.children} -
-
-
- {[ - {title: '待复核', key: AcceptStatus.NotAdopted, count: currentProofreadCount.not_adopted}, - {title: '已复核', key: AcceptStatus.Adopted,count: currentProofreadCount.adopted}, - {title: '全部', key: AcceptStatus.Default,count: currentProofreadCount.all} - ].map((it, idx) => ( -
{handleTabChange(it.key)}} - className={clsx('tab-item d-flex justify-center item-center', {active: state.acceptState == it.key})} - > - {it.title} - {props.proofreadLoading?'...':it.count} -
- ))} -
-
-
-
-
- -
-
- {_currentList.map((it, index) => ( - - handleItemAction(key, it, index)} - previewMode={false} - /> - - ))} -
-
-
-
-
- { - [ - {title: '错误', key: 'error', count: currentProofreadCount.error}, - {title: '敏感词', key: 'sensitive', count: currentProofreadCount.sensitive}, - {title: '黑名单', key: 'blacklist', count: currentProofreadCount.blacklist}, - {title: '政务', key: 'gov-check', count: currentProofreadCount.govCheck,color:'hsla(179, 100%, 70%, 1)'} - ].map((it, idx) => ( - it.count <= 0 ? null :
handleTypeChange(it.key)} - className={`item ${state.currentType == it.key ? 'active' : ''}`}> -
{props.proofreadLoading ? '...' : it.count}
-
{it.title}
-
- )) - } -
-
-
-
) -} -export default ProofreadPanel; \ No newline at end of file diff --git a/src/pages/proofread/components/panel-right-state.tsx b/src/pages/proofread/components/panel-right-state.tsx deleted file mode 100644 index cfa26aa..0000000 --- a/src/pages/proofread/components/panel-right-state.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import {Button} from "antd"; -import IdleImage from "./../images/icon-idle.png" -import PerfectImg from "./../images/icon-perfect.png" - -export type TProofreadState = 'idle' | 'processing' | 'perfect' | 'edit' | 'analyzing' -type PanelRightStateProp = { - state: TProofreadState; - proofreadEndTime?: number; - onBack?:()=>void; -} - -// 状态配置 -const StateConfig: { - [key in TProofreadState]: {image: string, text: string} | null -} = { - 'idle': {image: IdleImage, text: '在左侧输入内容开始校验'}, - 'processing': {image: IdleImage, text: '正在校验中'}, - 'edit': {image: IdleImage, text: '正在编辑中'}, - 'perfect': null, - 'analyzing': null, -} - -const StateElement = ({state}: PanelRightStateProp) => { - return (
-
- {state} -
-
专业校验工具
-
全面检查语义、语法、敏感词、标点符号等问题
-
{StateConfig[state]?.text}
-
) -} - -const Perfect = () => (
-
- perfect -
-
非常完美
-
) - -const Analyzing = (props:PanelRightStateProp) => (
-
- {props.proofreadEndTime === -2 ?
排队校对中...
:<> -
预计还有
-
- {Math.round(props.proofreadEndTime! / 1000)} - -
- } -
-
-
- 校对时间太长? -
返回文稿同样可查看进度
-
-
-
- -
-
) - -const PanelElement = ({state,onBack,proofreadEndTime}: PanelRightStateProp)=>{ - if(state === 'perfect') return ; - if(state === 'analyzing') return ; - return ; -} - -export const PanelRightState: React.FC = (props) => ( -
- -
-) diff --git a/src/pages/proofread/components/parse-proofread-result.ts b/src/pages/proofread/components/parse-proofread-result.ts deleted file mode 100644 index 21a4c53..0000000 --- a/src/pages/proofread/components/parse-proofread-result.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - ProofreadTypeEnum, - TCorrectedContent, - TDocumentContentDetail, TProofreadCountResult, -} from "@/service/types/document.ts"; -import {ProofreadTypeData, ProofreadTypeKeys} from "@/types/proofread.ts"; -import {int} from "@/service/types/base.ts"; - -function getTypeData(type: ProofreadTypeEnum) { - return ProofreadTypeData.find(s => Array.isArray(s.id) ? s.id.includes(type) : s.id == type) -} - - -export function buildProofreadResult(document: TDocumentContentDetail){ - let offset = 0; - let paragraph_offset = 1; - document.correctedSet.forEach((item) => { - item.offset = offset;//Math.ceil(item.offset) + offset; - offset += item.insert_len; - item.diffs?.forEach(it => { - // it.start += item.offset + 1 - // it.end += item.offset + 1 - it.typeData = getTypeData(it.type) - it.color = '#80E9DABB';//it.typeData?.color; - }) - if(item.insert?.length > 1 && (item.insert.startsWith("\f") || item.insert.startsWith("\n"))){ - paragraph_offset ++; - } - // 当前是第几段 - item.paragraph_offset = paragraph_offset; - if(item.insert.endsWith("\n") || item.insert.endsWith("\f")){ - paragraph_offset ++; - } - }) -} -// 解析并处理校对结果 -export function parseProofreadResult(document: TDocumentContentDetail,disabled:number[] = []) { - const parseData = []; - const resultList: TCorrectedContent[] = []; - - const abnormalCount : { - [key:string]:int - }= { - total:0 - }; - - // 遍历内容 - document.correctedSet.forEach((item) => { - item.diffs?.forEach(it => { - // it.start += item.offset + 1 - // it.end += item.offset + 1 - // it.typeData = getTypeData(it.type) - // it.color = it.typeData?.color; - if(disabled.includes(it.id)) return; - resultList.push(it) - const type = ProofreadTypeKeys[it.type]; - if(!abnormalCount[type]) abnormalCount[type] = 0; - abnormalCount['total'] ++; - abnormalCount[type] ++; - }) - }) - - return { - parseData, - resultList, - abnormalCount: abnormalCount as TProofreadCountResult - } -} diff --git a/src/pages/proofread/components/proofread-item-description.tsx b/src/pages/proofread/components/proofread-item-description.tsx deleted file mode 100644 index 9e08c7f..0000000 --- a/src/pages/proofread/components/proofread-item-description.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import {V3Enums} from "@/types/v3/enums.ts"; -import { stringIsEmpty } from '@/core/string-utils.ts'; - -const ItemTipsConfig = { - 'term': '规范术语', - 'first_choice': '首选', - 'now_called': '现称', - 'alien': '异形词', - 'quoting_legal': '引用法律条文时', - 'coinage': '造字', - 'coinage_first_choice': '造字 首选', - // 'incorrect_expression': '表述有误', - 'serial_number': '作为标题序号时', - 'after_a_certain_year': '现称', -} -const GovTipConfig = { - 'quotation': '引用领导人讲话', - 'fallen_officers': '疑似落马官员', - 'leader': '政要人物', - 'leader-sort': '政要人物顺序', - 'leader-error': '政要人物缺失或顺序有误', - - 'position': '职位或人名有误', - 'position-error': '职位或人名有误', - 'position-sort': '政要人物的职位顺序', -} - -export default function ProofreadItemDescription({it}:{it: V3.ProofreadCorrect}) { - // 获取类型数据 敏感词、 - //const typeData = V3Enums.ProofreadType[it.type] || V3Enums.ProofreadType.other; - if(!ItemTipsConfig[it.type] && !GovTipConfig[it.type]) return null; - if(GovTipConfig[it.type]){ - if(it.gov && it.gov?.length > 0 && (it.type == 'position-error' || ( - it.type == 'position' && it.gov[0].content == '该职位组合无对应领导人' - ))){ - - return <> - {it.gov?.map((it,idx)=>( -
- 【提示】 - {it.content} -
- ) - )} - - } - return
- 【提示】 - {it.addition || GovTipConfig[it.type]} -
- } - if(it.tag == 'r'){ - const notice = it.type == V3Enums.ProofreadType.after_a_certain_year.key ? it.addition : ItemTipsConfig[it.type] || it.addition; - if(stringIsEmpty(notice)){ - return null; - } - // 有提示内容的情况仅包含下述四种:〈现称〉、〈XXXX 年后〉、〈作为标题序号时〉和〈引用法律条文时〉 - // 无提示内容的情况:如不属于上述四种情况,则不显示任何提示内容 - return
- 【提示】 - {notice} -
- // if(ItemTipsConfig[it.type]){ - // return `${}` - // } - // if(it.type == V3Enums.ProofreadType.after_a_certain_year.key){ - // return `【提示】${it.addition}` - // } - // return `【提示】${it.addition}` - } - if(it.tag == 'i' || it.tag == 'd' || [ - V3Enums.ProofreadType.blacklist.key, - V3Enums.ProofreadType.sensitive.key, - V3Enums.ProofreadType.incorrectExpression.key, // 无修改建议的的情况分为三种:敏感词、黑名单和表述有误。 - ].includes(it.type)){ - return ''; - } - return null; - // if (it.type == V3Enums.ProofreadType.blacklist.key) { - // str.push('请复核',it.tag == 'r' && !/^[*]+$/.test(it.text) ?`,将选用"${it.text}"`:'') - // } else if (it.tag == 'r') { - // str.push(`建议选用"${it.text}"`) - // } else { - // str.push('建议' + (it.tag == 'd' ? '删除' : '新增')) - // } - // const str = [`【提示】`] // ${typeData?.name} - // return str.join(''); - // return typeData?.text ? typeData?.text + ',' : ''}{props.it.tag == 'r' ? `选用"${props.it.text}"` : ( - // it.tag == 'd' ? '删除' : '新增' -} \ No newline at end of file diff --git a/src/pages/proofread/components/proofread-item.tsx b/src/pages/proofread/components/proofread-item.tsx deleted file mode 100644 index 8586cce..0000000 --- a/src/pages/proofread/components/proofread-item.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import React, {useMemo} from "react"; -import {RightOutlined} from "@ant-design/icons"; -import { Space} from "antd"; -import {css} from "@emotion/css"; -import {DropdownMenu} from "@/components/popover/dropdown-menu"; -import { - ProofreadStateEnum, -} from "@/service/types/document"; -import {showToast} from "@/components/messages/Modal.tsx"; -import {whitelist} from "@/service/api/lexicon.ts"; -import {useSetState} from "ahooks"; -import { - IconAccept, - IconIgnore, - IconReview, - SvgIcon -} from "./icons.tsx"; -import {V3Enums} from "@/types/v3/enums.ts"; -import {stringIsEmpty} from "@/core/string-utils.ts"; -import ProofreadItemDescription from '@/pages/proofread/components/proofread-item-description.tsx'; -import { GovExtra } from '@/pages/proofread/components/gov/gov-extra.tsx'; - - -export type ActionKey = 'click' | 'accept' | 'acceptAll' | 'ignore' | 'ignoreAll' | 'addToLexicon' | 'review' | 'redo' -type ProofreadItemProps = { - selected?: boolean; - className?: string | undefined; - previewMode?: boolean; - proofreading?: boolean; - last?: boolean; - onAction: (key: ActionKey) => void - it: V3.ProofreadCorrect - index?: number; -} - -// const ActionToolTip = (props: {open?:boolean; text: string; children: React.ReactNode }) => ( -// {props.children}) - -const ProofreadItemType = ({it}:{it: V3.ProofreadCorrect})=>{ - if(it.type == V3Enums.ProofreadType.blacklist.key){ - return 黑名单 - } - if(it.type == V3Enums.ProofreadType.sensitive.key){ - return 敏感词 - } - if(it.type == V3Enums.ProofreadType.incorrectExpression.key){ - return 表述有误 - } - return (stringIsEmpty(it.tag) || it.tag == 'r') ? null : {it.tag == 'd' ? '删除' : '新增'} -} - -function getBlankSpaceElement(regex:RegExp,content:string,id:number){ - if(!content || !content.match(regex)) return []; - const matched = content.match(regex); - if(!matched) return []; - return Array(matched[0].length).fill(0).map((_,index)=>( )) -} -function replaceWhiteSpaceToTag(content:string,id:number){ - if(!content || !content.match(/(\s)+/)) return content; - return [ - ...getBlankSpaceElement(/^(\s)+/,content,id), - (content.trim().length > 0 ?{content.trim()}:null), - ...getBlankSpaceElement(/(\s)+$/,content.trimStart(),id) - ] -} -export const ProofreadItem: React.FC = (props) => { - - const typeData = (V3Enums.ProofreadType[props.it.type] || V3Enums.ProofreadType.other) as V3.ProofreadTypeConfig; - const govCheck = props.it.type == V3Enums.ProofreadType.leader.key - || props.it.type == V3Enums.ProofreadType.position.key - || props.it.type == V3Enums.ProofreadType.fallen_officers.key - || props.it.type == V3Enums.ProofreadType.quotation.key; - const requireReview = useMemo(() => { - if(props.it.tag == 'r') return false; - // 敏感词或者要拦截的黑名单 - return govCheck - || props.it.type == V3Enums.ProofreadType.sensitive.key - || props.it.type == V3Enums.ProofreadType.incorrectExpression.key - || props.it.type == V3Enums.ProofreadType.blacklist.key - || ( props.it.type == V3Enums.ProofreadType.blacklist.key && props.it.tag == 'r' && /^[*]+$/.test(props.it.text) - ); - }, [props.it]) - // 当前类别颜色 - const colorStyle = css`--proofread-color: ${typeData.color || '#000000'}` - const [state, setState] = useSetState({ - addToLexiconVisible: true - }) - - // 添加到词库 - const handleAddToLexicon = () => { - whitelist.create({ - word: props.it.origin - }).then(() => { - showToast('加入白名单成功', 'success'); - // 隐藏添加按钮 - setState({ - addToLexiconVisible: false - }) - }).catch((e) => { - const error = e.message || '加入白名单失败' - if(error == '放行词已存在'){ - // 隐藏添加按钮 - setState({ - addToLexiconVisible: false - }) - } - showToast(error == '放行词已存在'?'已经加入白名单':error, 'warning') - }) - } - // const handleUndo = async () => { - // showToast('撤销成功') - // } - const AddToLexiconButton = ({disabled}:{disabled:boolean}) => { - if( - props.it.type == V3Enums.ProofreadType.sensitive.key - || props.it.type == V3Enums.ProofreadType.incorrectExpression.key - ) return null; - const AddButton = ; - return (props.selected && state.addToLexiconVisible && props.it.type != V3Enums.ProofreadType.blacklist.key) ? - disabled ? AddButton : (AddButton) : null - } - - return (<> -
props.onAction('click')} - className={`proofread-item ${props.it.isAccept == ProofreadStateEnum.Default?'':'processed'} proofread-action-${props.it.tag} proofread-item-${props.it.id} ${props.className} ${colorStyle} item ${props.selected ? 'select' : ''}`}> -
-
-
- - {replaceWhiteSpaceToTag(props.it.tag == 'i' ? props.it.text:props.it.origin,props.it.id)} - - { - props.it.tag == 'r' && <> - - {replaceWhiteSpaceToTag(props.it.text,props.it.id)} - - } - -
-
-
- -
-
-
- - {props.it.isAccept != ProofreadStateEnum.Default && -
- {props.it.isAccept == ProofreadStateEnum.Accept &&
- - 已采纳 -
} - {props.it.isAccept == ProofreadStateEnum.Review && -
- - 已复核 -
} - {props.it.isAccept == ProofreadStateEnum.Ignore &&
- - 已忽略 -
} -
} -
- {props.selected && (props.it.isAccept == ProofreadStateEnum.Default) && props.it.gov && props.it.gov?.length > 0 &&
- {/* 政务校对 */} - -
} - {/* 非预览模式 */} - {!props.previewMode &&
- {props.selected && (props.it.isAccept == ProofreadStateEnum.Default) && - {!requireReview && } - {requireReview && } - - {!govCheck && } - props.onAction('acceptAll')}, - {type: 'divider'}, - {key: 'accept',disabled:props.proofreading, label: '忽略全部相同结果', onClick: () => props.onAction('ignoreAll')}, - ] : [{key: 'accept',disabled:props.proofreading, label: '忽略全部相同结果', onClick: () => props.onAction('ignoreAll')}]} - > -
更多
-
-
} -
} -
- {props.selected && !props.last &&
} - ) -} diff --git a/src/pages/proofread/components/proofread.less b/src/pages/proofread/components/proofread.less deleted file mode 100644 index 0accf18..0000000 --- a/src/pages/proofread/components/proofread.less +++ /dev/null @@ -1,865 +0,0 @@ -.view-size-notice { - position: fixed; - //inset-inline: 0; - //inset-block-start: 0; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - background-color: rgba(255, 255, 255, 0.2); - padding: 10px; - line-height: 30px; - z-index: 9999; - text-align: center; - font-weight: bold; - font-size: 14px; - backdrop-filter: blur(2px); -} - -@keyframes progress-bar-animation { - 0% { - background-position: -150% 0, -150% 0 - } - 100% { - background-position: 250% 0, 250% 0 - } -} -@keyframes progress-bar-loading{ - 0%{left:-35%;right:100%;} - 60%{left:100%;right:-90%;} - 100%{left:100%;right:-90%;} -} -@keyframes progress-bar-loading-1{ - 0%{left:-200%;right:100%;} - 60%{left:107%;right:-8%;} - 100%{left:107%;right:-8%;} -} - -.proofread-notice-wrapper { - position: fixed; - inset: 0; - z-index: 999; - //url(./images/loading.svg) - background: center bottom no-repeat #f5f5f5; - background-size: contain; - text-align: center; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - - .error-notice { - p { - margin: 0; - color: rgba(140, 140, 140, 1); - font-size: 12px; - } - - .error-title { - color: #000; - font-size: 20px; - font-weight: bold; - } - } - - .buttons { - button { - width: 260px; - } - } -} - -.proofread-panel { - --btn-size: 40px; - --padding-right: 0px; - --padding-left: 0px; - --padding: 10px; - --type-width: 60px; - --header-height: 140px; - font-size: 14px; - - .panel-controls { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: calc(var(--padding-left) - var(--padding-right)); - background: #fafafa; - z-index: 1; - } - - .panel-btn-visible { - border-radius: 5px 0 0 5px; - width: 28px; - height: 40px; - background-color: var(--primary-color, #36cfc9); - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - color: #fff; - position: absolute; - top: 53px; - right: 0; - - svg { - transform: rotate(-180deg) translateX(-3px); - } - - &:hover { - box-shadow: 0 0 1px rgba(0, 0, 0, 0.1); - background-color: #009688; - } - } - - &.open { - - .panel-btn-visible svg { - transform: rotate(0deg); - } - } - - .proofread-count-tag { - border-radius: 8px; - line-height: 1; - padding: 2px 10px; - } - - .proofread-panel-tab-wrapper { - background-color: #fff; - margin: 0 var(--padding-right) 0 var(--padding-left); - } - - .ant-tabs-nav, .ant-tabs-nav-list { - width: 100%; - } - - .ant-tabs-tab { - flex: 1; - justify-content: center; - } - - .proofread-panel-tab { - width: 100%; - display: flex; - align-items: center; - - .tab-item { - flex: 1; - font-size: 14px; - color: #262626; - - &.Mui-selected { - color: #262626; - } - - // - } - } - - // - .proofread-status { - background-color: #fff; - border-radius: 0 0 4px 4px; - margin: 0 var(--padding-right) 20px var(--padding-left); - } - - .btn-all { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - height: 32px; - border: 1px solid #D9D9D9; - box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.016); - border-radius: 4px; - - &:hover { - border-color: #999; - } - } - - .btn-accept-all { - color: rgba(54, 207, 201, 1); - } - - .btn-ignore-all { - color: rgba(140, 140, 140, 1); - } -} -.system-font{ - font-family: 'Arial','SimHei','黑体'; - font-weight: bold; -} -.ui-font{ - font-family: 'Simsun','宋体'; - font-weight: normal; -} -.panel-header { - position: sticky; - top: 0; - background: #fff; - z-index: 10; - padding: 10px 10px 2px; - //border-bottom: solid 1px rgba(217, 217, 217, 0.5); - box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); - overflow: hidden; - - .btn-start-proofread { - display: flex; - align-items: center; - justify-content: center; - width: 150px; - border: none !important; - background: linear-gradient(to right, #E9C57E 0%, #CAA266 100%); - - &:hover { - background: linear-gradient(to right, #CAA266 0%, #CAA266 100%) !important; - } - } - - .text-tip { - color: #333; - } - - .count-value { - color: #E9C57E; - } -} -.header-logo{ - svg{ - height: 46px; - width: 120px; - } -} -.proofread-list-wrapper { - margin-right: var(--type-width); -} -.proofread-list{ - padding: 0 var(--padding); - margin-top: 13px; - margin-right: 5px; - // fixed 由于添加新的间距 导致高度过高显示内容不足 - height: calc(100vh - var(--header-height) - 20px); - bottom: 10px; - overflow: auto; - &::-webkit-scrollbar { - width: 8px; - } - &::-webkit-scrollbar-thumb { - background: #fff; - } - &::-webkit-scrollbar-track { - background: #fff; - } - - // hover时 显示滚动条 - &:hover{ - &::-webkit-scrollbar-thumb { - background: #d2d2d2; - &:hover{ - background: #b6b6b6; - } - } - &::-webkit-scrollbar-track { - background: #fff; - } - } - .stream-mode{ - .origin { - color: #000; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: justify; - font-family: '宋体'; - } - - .arrow { - color: var(--primary-golden-color); - font-size: 10px; - margin: 0 15px; - - svg { - display: block; - } - } - - .replaced { - font-family: '宋体'; - color: #000; - background: none; - border-radius: 3px; - display: block; - padding: 4px 5px; - line-height: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - .action-text{ - color: var(--primary-color); - } - } - .proofread-item.select{ - .stream-mode{ - .origin,.replaced{ - white-space: normal; - } - } - } -} -.operation-buttons { - position: sticky; - z-index: 10; - background: #fff; - top: calc(var(--header-height) - 1px); - button.ant-btn-default{ - &.btn-operation-batch{ - border-color: var(--primary-color,rgba(76, 182, 125, 1)); - color: var(--primary-color,rgba(76, 182, 125, 1)); - &:not(:disabled):hover{ - background-color: var(--primary-color,rgba(76, 182, 125, 1)); - color: #fff; - } - &:disabled{ - background-color: #f4f4f4; - border-color: #D9D9D9; - } - } - &.btn-ignore-all{ - border-color: #D9D9D9; - } - } -} -.test-item{ - background-color:#99ffff; - height:50px; - margin:10px auto; - justify-content: center; - align-items: center; - display: flex; - border-radius: 4px; - &:hover,&.active{ - background-color: #83d9d9; - } -} - -.proofread-item-wrapper { - --border-size: 2px; - --timeline-width: 14px; - --proofread-font-size: 16px; - --content-font-size: 12px; - --padding-size: 10px; - cursor: default; - padding: var(--border-size); - overflow: hidden; - margin-top: 15px; - margin-right: calc(var(--padding-right) - 10px); - margin-left: var(--padding-left); - border-radius: 4px; - background-image: linear-gradient(91.26deg, #fff, #fff); - transition: 0.5s; - outline: solid 1px transparent; - - .d-flex { - display: flex; - } - - .align-center { - align-items: center; - } - - &:first-child { - margin-top: 0; - } - - .content-container { - padding: 10px; - background: #fff; - border-radius: 4px; - } - - &:hover { - outline: solid 1px #ccc; - } - - .proofread-content { - display: none; - color: #666; - font-size: var(--content-font-size); - margin-top: 10px; - } - - .description-item { - display: flex; - background-color: #f6f5f6; - padding: 5px 6px; - border-radius: 3px; - text-align: justify; - width: 100%; - margin-bottom: 5px; - line-height: 20px; - align-items: flex-start; - - ::-webkit-scrollbar { - width: 3px; - } - - .error_sort { - color: #f00; - } - - .content { - flex: 1; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - height: 20px; - padding-right: 5px; - transition: all 0.5s; - - a { - color: var(--primary-color); - text-decoration: underline; - } - } - - .content-text { - display: none; - - span { - display: inline; - } - } - - .selection { - background-color: #fabeb0; - } - - .arrow-icon { - transform: rotate(-90deg); - } - - .desc-item { - display: flex; - background-color: #f6f5f6; - padding: 5px 6px; - border-radius: 3px; - text-align: justify; - width: 100%; - margin-bottom: 5px; - line-height: 20px; - align-items: flex-start; - } - - &.open { - .content { - white-space: normal; - height: 100%; - overflow: auto; - max-height: 120px; - } - - .content-text { - display: block; - max-height: 100px; - overflow: auto; - padding-right: 5px; - } - - .arrow-icon { - transform: rotate(0deg); - } - } - } - - &.active { - outline: solid 1px transparent; - border-color: transparent; - margin-left: 0px; - background-image: linear-gradient(91.26deg, #5E98FE -28.63%, #3DC3FF 13.62%, #FED700 51%, #B80BA7 94.06%, #CE5884 133.87%); - - .proofread-content { - display: block; - } - - .proofread-info { - .replaced, .origin { - white-space: normal; - } - } - } - - &.proofread-item-model { - outline: solid 1px transparent; - border-color: transparent; - background-image: linear-gradient(91.26deg, #5E98FE -28.63%, #3DC3FF 13.62%, #FED700 51%, #B80BA7 94.06%, #CE5884 133.87%); - } - - .proofread-item-container { - display: flex; - overflow-x: hidden; - max-width: 100%; - border-bottom: 1px solid #F0F0F0; - padding: var(--padding-size) 0; - } - - // - .proofread-item { - position: relative; - padding: 0 var(--padding-size); - font-size: var(--proofread-font-size); - inset-inline-start: 10px; - - &:last-child { - .proofread-item-dot:before { - display: none; - } - - .proofread-item-container { - border-bottom: none; - } - } - } - - .proofread-info { - position: relative; - margin-inline-end: 0; - margin-block-start: 0; - margin-block-end: 0; - line-height: 1.2; - flex: 1; - min-width: 0; - - .proofread-text { - display: flex; - align-items: center; - - &.has-tag { - align-items: flex-start; - } - } - - .proofread-tag { - font-size: 16px; - font-weight: 400; - line-height: 19px; - text-align: center; - color: var(--item-type-color, #f00); - margin-inline-start: 10px; - margin-block-start: -1px; - white-space: nowrap; - } - - .text { - width: 100%; - } - - .origin-mode { - color: #000; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: justify; - font-family: -apple-system, Helvetica, Arial, "pingfang-sc", "micrsoft yahei", sans-serif; - } - - .arrow { - color: rgba(119, 119, 119, 1); - font-size: 10px; - margin: 0 15px; - - svg { - display: block; - } - } - - .replaced { - background: rgba(255, 0, 0, 1); - color: #fff; - border-radius: 3px; - display: block; - padding: 4px 5px; - line-height: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - } - - .proofread-item-dot { - width: var(--timeline-width); - position: absolute; - top: 13px; - bottom: -20px; - left: -10px; - - &:before { - content: ""; - display: block; - position: absolute; - inset-block-start: 10px; - inset-inline-start: 6px; - height: calc(100% - 10px); - border-inline-start: 1px solid rgba(255, 133, 192, 1); - } - - .dot { - width: var(--timeline-width); - height: var(--timeline-width); - border-radius: 50%; - background: var(--item-type-color, #36cfc9); - position: absolute; - border: solid 3px #fff; - left: 0; - } - - } - - .actions { - margin-inline-start: 10px; - white-space: nowrap; - } - - &:hover, &.active { - .proofread-action { - visibility: visible; - } - } - - .proofread-action { - visibility: hidden; - display: flex; - --btn-size: 20px; - - &.processed { - visibility: visible; - } - - .process-state-container { - - } - - .process-state-actions { - - } - - button { - width: var(--btn-size); - height: var(--btn-size); - outline: none; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - line-height: 1; - padding: 0; - color: #999; - cursor: pointer; - background: none; - border: solid 1px transparent; - border-radius: 4px; - - &:not[disabled]:hover { - color: #36CFC9; - border-color: #36CFC9; - } - } - - .btn-accept { - color: #36CFC9; - border-color: #36CFC9; - } - - .btn-review { - color: #9747FF; - border-color: #9747FF; - } - - .btn-ignore { - color: #fff; - background-color: #D9D9D9; - border-color: #D9D9D9; - - &:not[disabled]:hover { - color: #fff; - background-color: #ccc; - border-color: #999; - } - } - - .btn-add-to-lexicon { - color: #D9D9D9; - border-color: #D9D9D9; - } - - .btn-more { - font-size: 10px; - color: rgba(182, 182, 182, 1); - background-color: rgba(245, 245, 245, 1); - border-color: rgba(245, 245, 245, 1); - } - - // 已处理状态 - .process-state { - display: flex; - font-size: 12px; - align-items: center; - background-color: #f0f0f0; - border-radius: 3px; - padding: 0 4px; - height: var(--btn-size); - } - - .state-accept { - color: var(--primary-color-main, #08979C); - } - - .state-ignore { - color: #C9C9C9; - } - - .ml-2 { - margin-left: 2px; - } - - .rollback { - border-radius: 4px; - padding: 2px 4px; - - &:hover { - background-color: var(--background-hover-color); - } - } - } - -} - -.types { - background: #f0f0f0; - position: fixed; - right: 0; - bottom: 0; - top: var(--header-height); - width: var(--type-width); - - .item { - text-align: center; - padding: 10px 0; - cursor: pointer; - .count{ - color: red; - font-weight: bold; - font-size: 16px; - } - &.active { - background: #fff; - box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.1); - } - } -} - -.proofread-item{ - .action { - .btn { - background: #fff; - outline: none; - width: 20px; - height: 20px; - border: solid 1px var(--primary-color); - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--action-btn-radius); - color: var(--primary-color); - cursor: pointer; - box-sizing: border-box; - - &:disabled{ - background-color: var(--primary-disabled-color); - border: solid 1px var(--primary-disabled-color); - color:#fff; - } - - &:not(:disabled):hover { - background-color: var(--primary-color); - color: #fff; - } - } - .btn-odd{ - background-color: var(--primary-color); - color: #fff; - &:hover { - background-color: #fff; - color: var(--primary-color); - } - } - .btn-review{ - .icon-type{ - transform: translateY(0.5px); - } - } - .btn-accept { - } - - .btn-ignore { - } - - .more-action { - box-sizing: border-box; - width: 20px; - height: 20px; - border-radius: var(--action-btn-radius); - border: solid 1px var(--primary-color); - background-color: var(--primary-color); - color: #fff; - text-align: center; - - &:hover { - background-color: #fff; - color: var(--primary-color); - } - } - - .btn-add-to-lexicon { - } - - .processed-wrapper { - font-size: 12px; - } - - .state-accept { - color: var(--primary-process-color,#aaaaaa); - margin-right: 12px; - } - .state-review{ - //color: #3FD4CF; - } - - .state-ignore { - color: #C9C9C9; - margin-right: 12px; - } - - .rollback { - border-radius: 4px; - padding: 2px 4px; - - &:hover { - background-color: var(--background-hover-color); - } - } - } -} -.ant-popover.black-bg{ - //--antd-arrow-background-color: var(--primary-color); - .ant-popover-inner{ - transform: translateY(1px); - // background-color: var(--primary-color); - padding: 5px 10px; - // .ant-popover-inner-content{ - // color: #fff; - // } - } -} \ No newline at end of file diff --git a/src/pages/proofread/components/tools.ts b/src/pages/proofread/components/tools.ts deleted file mode 100644 index a233bf8..0000000 --- a/src/pages/proofread/components/tools.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {IDocumentCorrect, IDocumentDetail, IDocumentProofread} from "@/types/document"; -import {IProofreadResult, ProofreadTypeEnum} from "./types.ts"; - -type Range = { - start:number; - end:number; -} -export function inRange(a:Range,b:Range){ - if(a.start == b.start && a.end == b.end) return true; - // check a in b - if( - a.start >= b.start && - a.start <= b.end && - a.end >= b.start && - a.end <= b.end - ) return true; - // check b in a - if ( - b.start >= a.start && - b.start <= a.end && - b.end >= a.start && - b.end <= a.end - ) return true - return false; -} -function buildProofreadResult(correct: IDocumentProofread[], block: IDocumentCorrect, document: IDocumentDetail) { - const blockCorrect: IProofreadResult[] = []; - correct.forEach(item => { - // 处理涉政类型数据 - const result: IProofreadResult = { - ...item, - key: block.key, - document_id: document.id, - leader: item.type === ProofreadTypeEnum.leader ? document.leaders[item.mid] : undefined, - position: item.type === ProofreadTypeEnum.position ? document.positions[item.mid] : undefined, - quotation: item.type === ProofreadTypeEnum.quotation ? document.quotations[item.mid] : undefined, - relation:[] - } - for (const block of blockCorrect) { - if (inRange(result,block)) { - result.relation?.push(block) - block.relation?.push(result) - // if(result.tag != block.tag) - blockCorrect.push(result); - return; - } - } - blockCorrect.push(result); - }); - - return blockCorrect; -} - -export function parseProofreadList(document: IDocumentDetail) { - const result = document.correctedSet.filter(s => s.ranges && s.ranges.length > 0) - .map(s => buildProofreadResult(s.ranges!, s, document)); - // console.log(result) - return result.flat() -} \ No newline at end of file diff --git a/src/pages/proofread/components/types.ts b/src/pages/proofread/components/types.ts deleted file mode 100644 index e68327a..0000000 --- a/src/pages/proofread/components/types.ts +++ /dev/null @@ -1,202 +0,0 @@ -export enum ProofreadTypeStatusEnum { - // 默认,未处理? - Default, - // 已采纳 - Accept = 2, - // 已忽略 - Ignore, - // 已复核 - Audited -} -export type EditorProofreadFormat = { - id: string|number; - suggest?: ProofreadTypeStatusEnum; - tag: string; - start: any; - end: any; - current: string -} -// 编辑器 -export type SelectionEditorProofread = { - proofread?:EditorProofreadFormat; - insert?:EditorProofreadFormat; - replace?:EditorProofreadFormat; - delete?:EditorProofreadFormat; - leader?:EditorProofreadFormat; - position?:EditorProofreadFormat; - quotation?:EditorProofreadFormat; -} - -// 校对分类 -export enum ProofreadTypeEnum { - characterError = 2, - /** - * 易错词 - */ - confusion = 18, - /** - * 语录 - */ - quotation = 16, - /** - * 领导人 - */ - leader = 17, - /** - * 黑名单 - */ - blacklist = 20, - /** - * 标点 - */ - punctuation = 22, - /** - * 敏感词 - */ - sensitive = 19, - /** - * 白名单 - */ - whitelist = 21, - /** - * 职位 - */ - position = 23, - /** - * 其他模型 - */ - model = 24, -} - -export interface IPositionInfo { - leaders: string[]; - position: string; -} - -export interface IQuotationInfo { - category: string; - content: string; - document_name: string; - hypelink: string; - id: string; -} - -export interface ILeaderInfo { - name?: string; - correct_name: string; - positions: string[]; - sort_error?: any; -} - -export interface IProofreadResult { - tag: 'r' | 'd' | 'i' | string; - old: string; - new: string; - start: number; - end: number; - id: number; - // 文档编号 - document_id: number; - idx: number; - // 对应句子hash - key: string; - suggest: ProofreadTypeStatusEnum; - // 对应领导 语录等的索引 - mid: number; - type: ProofreadTypeEnum; - // 关联领导数据 - leader?: ILeaderInfo; - // 关联职位数据 - position?: IPositionInfo; - // 关联语录数据 - quotation?: IQuotationInfo; - // 关联数据 - relation?:IProofreadResult[]; -} - -export type IProofreadTypeData = { - type: string, - key: string; - color: string; - text: string; - count?: number; - id: ProofreadTypeEnum | ProofreadTypeEnum[]; - // 采纳全部时要提交的类型 - acceptAll?: ProofreadTypeEnum[]; - // 忽略全部时要提交的类型 - ignoreAll?: ProofreadTypeEnum[]; -} -export const ProofreadTypeData: IProofreadTypeData[] = [ - { - id: [ProofreadTypeEnum.blacklist], - type: 'black', - acceptAll: [ProofreadTypeEnum.blacklist], - ignoreAll: [ProofreadTypeEnum.blacklist], - count: 0, - text: '黑名单', - color: '#2A2A2A', - key: 'blacklist' - }, - - {id: ProofreadTypeEnum.whitelist, type: 'unit', count: 0, text: '白名单', color: '#77F1AE', key: 'whitelistError'}, - {id: ProofreadTypeEnum.confusion, type: 'confusion', count: 0, text: '易错词', color: '#D6AA69', key: 'confusion'}, - { - id: ProofreadTypeEnum.punctuation, - type: 'symbol', - count: 0, - text: '标点错', - color: '#558CB7', - key: 'punctuationError' - }, - {id: ProofreadTypeEnum.sensitive, type: 'sensitive', count: 0, text: '敏感词', color: '#e971ba', key: 'sensitive'}, - { - id: ProofreadTypeEnum.characterError, - type: 'character', - count: 0, - text: '易错词', - color: '#e971ba', - key: 'characterError' - }, - {id: ProofreadTypeEnum.model, type: 'model', count: 0, text: '其他错误', color: '#E9D0A7', key: 'model'}, - - {id: ProofreadTypeEnum.quotation, type: 'quotation', count: 0, text: '语录', color: '#29CEC0', key: 'quotation'}, - {id: ProofreadTypeEnum.leader, type: 'leader', count: 0, text: '领导人', color: '#c9c9c9', key: 'leader'}, - {id: ProofreadTypeEnum.position, type: 'position', count: 0, text: '职位', color: '#CDAFE5', key: 'positionError'}, -] - -export type ProofreadStatusType = 'all'| 'error'| 'sensitive'| 'blacklist'| 'politics' - -export const ProofreadTypeConfig: { - [key in ProofreadStatusType]: ProofreadTypeEnum[] -} = { - all: [], - error: [ - ProofreadTypeEnum.punctuation, - ProofreadTypeEnum.characterError, - ProofreadTypeEnum.confusion, - ProofreadTypeEnum.model - ], - sensitive: [ - ProofreadTypeEnum.sensitive - ], - blacklist: [ - ProofreadTypeEnum.blacklist - ], - politics: [ - ProofreadTypeEnum.leader, - ProofreadTypeEnum.quotation, - ProofreadTypeEnum.position, - ] -} - - -export type ProofreadItemActions = - 'ignore' - | 'adopt' - | 'review' - | 'revoke' - | 'addToLexicon' - | 'undo' - | 'revokeAll' - | 'acceptAll' - | 'ignoreAll'; \ No newline at end of file diff --git a/src/pages/proofread/components/virtual-list-item.tsx b/src/pages/proofread/components/virtual-list-item.tsx deleted file mode 100644 index d94623d..0000000 --- a/src/pages/proofread/components/virtual-list-item.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { useEffect, useState } from "react" - -export const VirtualListItem:React.FC<{children?:React.ReactNode;id:number;index:number}> = ({children,id,index})=>{ - const ref = React.useRef(null) - const [visible,setVisible] = useState(false); - useEffect(()=>{ - const observer = new IntersectionObserver(entries => { - if(entries.length >0 && entries[0].isIntersecting){ - setVisible(true) - } - // setTimeout(()=>{ - // setVisible(entries.length >0 && entries[0].isIntersecting) - // },20) - }); - if(ref.current){ - observer.observe(ref.current!) - } - return ()=>{ - observer.disconnect() - } - },[ref]) - return
- {visible ? children :
-
-
-
-
-
} -
-} \ No newline at end of file diff --git a/src/pages/proofread/images/bg.png b/src/pages/proofread/images/bg.png deleted file mode 100644 index 4b409ce..0000000 Binary files a/src/pages/proofread/images/bg.png and /dev/null differ diff --git a/src/pages/proofread/images/btn_arrow_close.png b/src/pages/proofread/images/btn_arrow_close.png deleted file mode 100644 index 9765b81..0000000 Binary files a/src/pages/proofread/images/btn_arrow_close.png and /dev/null differ diff --git a/src/pages/proofread/images/btn_arrow_open.png b/src/pages/proofread/images/btn_arrow_open.png deleted file mode 100644 index 86f182c..0000000 Binary files a/src/pages/proofread/images/btn_arrow_open.png and /dev/null differ diff --git a/src/pages/proofread/images/check.gif b/src/pages/proofread/images/check.gif deleted file mode 100644 index 2bea000..0000000 Binary files a/src/pages/proofread/images/check.gif and /dev/null differ diff --git a/src/pages/proofread/images/icon-export.png b/src/pages/proofread/images/icon-export.png deleted file mode 100644 index d54047e..0000000 Binary files a/src/pages/proofread/images/icon-export.png and /dev/null differ diff --git a/src/pages/proofread/images/icon-idle.png b/src/pages/proofread/images/icon-idle.png deleted file mode 100644 index a2eef87..0000000 Binary files a/src/pages/proofread/images/icon-idle.png and /dev/null differ diff --git a/src/pages/proofread/images/icon-perfect.png b/src/pages/proofread/images/icon-perfect.png deleted file mode 100644 index b4e1fda..0000000 Binary files a/src/pages/proofread/images/icon-perfect.png and /dev/null differ diff --git a/src/pages/proofread/images/icon-setting.png b/src/pages/proofread/images/icon-setting.png deleted file mode 100644 index 6f15270..0000000 Binary files a/src/pages/proofread/images/icon-setting.png and /dev/null differ diff --git a/src/pages/proofread/images/perfect.png b/src/pages/proofread/images/perfect.png deleted file mode 100644 index b0dd393..0000000 Binary files a/src/pages/proofread/images/perfect.png and /dev/null differ diff --git a/src/pages/proofread/images/processing.gif b/src/pages/proofread/images/processing.gif deleted file mode 100644 index 6f9d3f4..0000000 Binary files a/src/pages/proofread/images/processing.gif and /dev/null differ diff --git a/src/pages/proofread/index.tsx b/src/pages/proofread/index.tsx deleted file mode 100644 index 1cf1064..0000000 --- a/src/pages/proofread/index.tsx +++ /dev/null @@ -1,997 +0,0 @@ -import {useDebounceFn, useInterval, useSetState} from "ahooks"; -import React, {useEffect, useState} from "react"; -import {Modal} from "antd"; - -import {useBridge, useBridgeMessageListener} from "@/core/bridge.ts"; - -import ProofreadPanel from "./components"; -import './components/proofread.less' -import {ProofreadLoading, ProofreadError, ProofreadPerfect,} from "./notice.tsx"; -import {useUserinfoStore} from "@/service/userinfoStore.ts"; -import {formatTime, hidePhone} from "@/utils/strings.ts"; -import {getAuthCode} from "@/service/api/user.ts"; -import {UpgradeInfo} from "@/service/types/settings.ts"; -import { getAppUpgradeInfo, getSettings,} from "@/service/api/settings.ts"; -import * as ProofreadQueue from '@/core/proofread-queue.ts' - -import { - base64Encode, - getAndRemoveInvisibleChars, - isBlankOrInvisibleContent, - isFootnote, stringIsEmpty -} from '@/core/string-utils.ts'; -import {useProofread} from "@/service/use-proofread.ts"; -import {CACHE_DATA, SentenceListCache} from "@/core/cache.ts"; -import { - buildProofreadSentenceList, - loadProofreadCache, - parseProofreadSentence, - saveProofreadCache -} from "@/core/proofread-util.ts"; -import * as proofreadAPI from "@/service/api/v3/document.ts"; -import {V3Enums} from "@/types/v3/enums.ts"; -import { ApplicationInfo, ProofreadModelConfig } from '@/core/config.ts'; -// import streamMockData from "@/pages/proofread/_local/gray_test_511.ts"; -// import {cloneDeep} from "@/utils/cloneDeep.ts"; -// import {Button, Space} from "antd"; -import { parseLeader,parsePosition,parseQuotation } from '@/pages/proofread/components/gov/parse-gov-extra.ts'; - -export default function Home() { - const {userinfo: globalUser, logout, init} = useUserinfoStore() - const {bridge, getAppInfo,showView} = useBridge(); - // 用户信息 - const [userinfo, setUserinfo] = useState() - const [proofreadProgress, setProofreadProgress] = useState(-1); - - const [disabledList, setDisabledList] = useState([]) - // const [currentDocumentId,setCurrentDocumentId] = useState(0); - const {subscribe, endSubscribe} = useProofread() - const [state, setState] = useSetState<{ - proofreading: boolean; - error?: string; - activeItemId: number; - activeAcceptState: 1 | 2 | 3; - savedCache: boolean; - contentParsing: boolean; - }>({ - proofreading: false, - activeItemId: -1, - activeAcceptState: 1, - savedCache: false, - contentParsing: false - }) - const [proofreadSentences, setProofreadSentences] = useState([]) - const [histories, setHistories] = useState([]) - - // 获取文档内容 - const getDocumentData = async (documentId = -1) => { - setState({ - contentParsing: true - }) - const content = await bridge.getDocumentData(documentId); - setState({ - contentParsing: false - }) - return JSON.parse(content) as DocumentData; - }; - - // 保存内容并校对,如果有错误或者同步返回false,开始异步校对则返回true - const getContentAndProofread = async (modelId:string) => { - // if (!proofreadCacheData.client) { - // throw new Error('client init error'); - // } - // 用于后端进行标记 - ProofreadQueue.init() - - // 获取当前文档数据 - const doc = await getDocumentData(0); - if (doc.code != 0) { - CACHE_DATA.clearProgressTimer(); - bridge.HideCurrentPane(); - bridge.ShowMessage(doc.message, 3000, false); - return; - } - CACHE_DATA.wordCount = doc.content.text.length - // 没有数据 - if (doc.content.list.length == 0) { - resetProofreadData() - return; - } - CACHE_DATA.originData = {}; - let totalLength = 0; - const content = doc.content.list - // 过滤掉空行、脚注等特殊内容 - .filter(it => (!isBlankOrInvisibleContent(it.Text) && !isFootnote(it.Text))) - .map((it,index) => { - const parseData = getAndRemoveInvisibleChars(it.Text) - totalLength += it.Text?.length || 0; - CACHE_DATA.originData[index] = { - insert_len: it.Text.length, - paragraph_num: it.ParagraphNumber, - origin_text: it.Text, - hash: it.Hash, - parseData - } - return { - insert: parseData.newStr.replace(/\[endnoteRef:\d+\]|\[footnoteRef:\d+\]/ig, ' '), - insert_len: it.Text.length, - paragraph_num: index + 1,//it.ParagraphNumber, - ext: base64Encode(JSON.stringify({ - index - })) - } - }); - if (APP_CONFIG.ALLOW_MAX_COUNT > 0 && totalLength > APP_CONFIG.ALLOW_MAX_COUNT) { - // bridge?.showDialog('正在校对中,请稍后再试...') - const number = Math.ceil(APP_CONFIG.ALLOW_MAX_COUNT / 10000); - bridge?.ShowMessage(`文档超过${number}万字会影响校对质量,请调整字数后再校对。`,2500,false) - resetProofreadData() - bridge.HideCurrentPane(); - return false; - } - // console.log('client', client) - // console.log('start proofread use content', content) - // 判断是否已经创建了文档id - const settings = await getSettings(); - const proofreadSetting = { - // ...settings, - isBlackWord: settings.word_black == '2', - isWhiteWord: settings.word_white == '2', - - isLeaderInfo: settings.leader_info == '2', - isLeaderQuotes: settings.leader_quotes == '2', - isFallenOfficers: settings.fallen_officers == '2', - // 模型id - model_id:modelId - } - // rollback to cache document id - // 接口支持服用文档id - if (CACHE_DATA.DocumentID <= 0) { - // 避免无意刷新网页导致 id 丢失 - const bridgeDocId = Number((await bridge?.GetCurrentDocumentId()) || 0); - if (bridgeDocId > 0) { - CACHE_DATA.DocumentID = bridgeDocId; - } else { - const {info} = await proofreadAPI.create({ - name: doc.name || ('未命名文档-' + formatTime(Date.now(), 'MMDDHHmmss')), - ...proofreadSetting - }); - CACHE_DATA.DocumentID = info.id; - bridge?.SetCurrentDocumentId(CACHE_DATA.DocumentID); - } - } else if (doc.documentId <= 0) { - bridge?.SetCurrentDocumentId(CACHE_DATA.DocumentID); - } - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,true,true,false); - // 校对参数 - const proofreadParams = { - content, - id: CACHE_DATA.DocumentID, - } - if(totalLength < APP_CONFIG.SYNC_CHECK_MAX_WORD_COUNT){ - // 开始异步倒计时,最长95s - const maxProgressValue = 95; - let progress = 0; - // 计算进度的增长step - const progressStep = Math.ceil(maxProgressValue / (totalLength / 500) * 1.2); - const progressInterval = setInterval(()=>{ - // 不能小于原始进度 - setProofreadProgress(prev=>{ - if(progress < prev){ - return prev - } - return progress > 0 ? (progress > maxProgressValue ? maxProgressValue : progress) : 0 - }) - if(progress >= maxProgressValue){ - clearInterval(progressInterval) - return - } - progress += progressStep - },1000) - - try{ - // 校对内容长度小于配置数量,直接进行同步校对 - await proofreadAPI.proofreadSync(proofreadParams,3,proofreadSetting); - clearInterval(progressInterval) - }catch (e){ - clearInterval(progressInterval) - throw e; - } - setProofreadProgress(95) - // 检查校对状态是否结束并获取结果 - setTimeout(checkProofreadStatusAndMergeResult,500) - return false - } - const ret = await proofreadAPI.proofread(proofreadParams,3,proofreadSetting); - // 订阅并解析返回结果 - subscribe({ - clientId: ret.clientID, - path: ret.path, - topic: ret.topic - }, parseProofreadResult) - // 检查角度与是否结束 - checkProofreadStatusAndMergeResult() - return true; - // const result = await proofreadAPI.detail(CACHE_DATA.DocumentID); - // console.log('proofread->detail', result) - - // MOCK PROOFREAD - // subscribe(`proofread/${CACHE_DATA.DocumentID}`, parseProofreadResult) - // send('proofread', JSON.stringify({ - // id: CACHE_DATA.DocumentID - // })) - } - - /** - * 检查校对状态,若结束则合并结果 - */ - const checkProofreadStatusAndMergeResult = () => { - const nextRequest = ()=>{ - // 60s check proofread status - CACHE_DATA.timer = setTimeout(checkProofreadStatusAndMergeResult,5000) //每5s获取校对状态与进度 - } - proofreadAPI.status(CACHE_DATA.DocumentID).then(ret=>{ - CACHE_DATA.clearTimer() - if(ret.is_finish){ - bridge.SetBtnStatus('proofread-status', true) - setState({ - proofreading: false - }) - CACHE_DATA.state = 'finish' - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,true,false,true); - CACHE_DATA.clearProgressTimer() - setProofreadProgress(100) - setTimeout(()=>{ - setProofreadProgress(-1) - },800) - }else{ - if(ret.paragraph_num) { - CACHE_DATA.clearProgressTimer() - console.log('proofreadAPI.status===>',JSON.stringify(ret)) - const progress = Math.ceil(ret.paragraph_num / ret.paragraph_total * 100) - // 不能小于原始进度 - setProofreadProgress(prev=>{ - if(progress < prev){ - return prev - } - return progress > 0 ? progress : 0 - }) - } - nextRequest() - } - }).catch(()=>{ - nextRequest() - }) - - // 校对完成 - proofreadAPI.detail(CACHE_DATA.DocumentID).then(result=>{ - if(!result.corrected_set || result.corrected_set.length == 0){ - CACHE_DATA.currentSentenceList = []; - setProofreadSentences([]) - return; - } - - // 将结果和缓存合并 - const list = buildProofreadSentenceList(result.corrected_set, SentenceListCache) - CACHE_DATA.currentSentenceList = list; - list.forEach(data=>{ - // 处理常见错误 - parseDiffNotice(data) - // 处理校对内容 - parseProofreadSentence(data) - // 将数据提交到word中进行标记 - ProofreadQueue.push(data) - }) - setProofreadSentences([...list]) - saveCache(true) - }).catch((e:Error)=>{ - if(e.message != '文稿未完成校对') { - console.log('error', e) - } - }); - } - - const parseDiffNotice = (data: V3.ProofreadSentence)=>{ - const requestNotice = async (idx:string,error_type:string)=>{ - const notice = await proofreadAPI.getConfusionNotice({idx,error_type}) - setProofreadSentences(originList => { - CACHE_DATA.currentSentenceList = originList; - const sentence = originList.find(it=>it.paragraph_num === data.paragraph_num && it.sentence_num === data.sentence_num) - if(sentence){ - const diff = sentence.diffs.find(it=>it.index === idx) - if(diff){ - diff.addition = notice - } - } - return originList; - }) - } - const buildGovExtra = (govInfo:V3.GovInfo[],error_type:string,id:number)=>{ - if(govInfo.length > 0){ - setProofreadSentences(originList => { - CACHE_DATA.currentSentenceList = originList; - const sentence = originList.find(it => it.paragraph_num === data.paragraph_num && it.sentence_num === data.sentence_num) - if (sentence) { - const diff = sentence.diffs.find(it=>it.id === id) - if(diff){ - if(error_type == 'position') { - if(govInfo[0].data?.source == 'position-error'){ - //diff.type = 'position-error' - diff.addition = govInfo[0].content - } - }else{ - diff.gov = govInfo - diff.addition = '' - } - } - } - return originList; - }) - } - } - const requestGovExtra = async (idx:string,error_type:string,id:number)=>{ - if(stringIsEmpty(idx) || stringIsEmpty(error_type) || idx == '-1'){ - return; - } - const key = `${error_type}-${idx}`; - // 判断是否已经缓存 - if(typeof(ProofreadQueue.getQueue().govExtra[key]) != "undefined"){ - buildGovExtra(ProofreadQueue.getQueue().govExtra[key],error_type,id) - return; - } - // cache not exists - const params = error_type == 'leader'?idx.split('、').map(name=>({idx:name,error_type})):[{idx,error_type}]; - const result = await proofreadAPI.getCorrectionExtraForGov(params) - const govInfo:V3.GovInfo[] = []; - // 根据类型进行处理 - switch (error_type){ - case V3Enums.ProofreadType.leader.key: - govInfo.push(...parseLeader(idx,result)) - break; - case V3Enums.ProofreadType.position.key: - govInfo.push(parsePosition(idx,result)) - break; - case V3Enums.ProofreadType.quotation.key: - govInfo.push(parseQuotation(idx,result)) - break; - default: - break; - } - if(govInfo.length > 0){ - ProofreadQueue.getQueue().govExtra[key] = govInfo; - buildGovExtra(ProofreadQueue.getQueue().govExtra[key],error_type,id) - } - } - data.diffs.forEach(async (it)=>{ - if(it.type == V3Enums.ProofreadType.quotation.key){ - // 获取语录信息 - await requestGovExtra(it.index,it.type,it.id) - return; - } - if(it.type == V3Enums.ProofreadType.leader.key){ - // 获取语录信息 - await requestGovExtra(it.tag == 'r'?it.text:it.origin,it.type,it.id) - return; - } - if(it.type == V3Enums.ProofreadType.position.key){ - await requestGovExtra(it.origin,it.type,it.id) - return; - } - // 判断是否已经缓存 - if(typeof(ProofreadQueue.getQueue().confusionNotice[it.index]) != "undefined"){ - return; - } - // xx 年以后 - if(it.type == V3Enums.ProofreadType.after_a_certain_year.key || it.index != "-1"){ - // 缓存数据 避免重复请求 - ProofreadQueue.getQueue().confusionNotice[it.index] = '' - try{ - await requestNotice(it.index,it.type) - }catch (e){ - console.log('getConfusionNotice error',e) - bridge.ShowLog(`getConfusionNotice error ${(e as Error).message}`) - } - } - }) - - } - // 启动队列将校对内容发送到word中进行标记 - const parseProofreadResult = (data: V3.ProofreadSentence) => { - // console.log('got data', data) - if(data.code && data.code === 1001){ - CACHE_DATA.clearProgressTimer() - setProofreadProgress(-1) - // proofreadAPI.detail(CACHE_DATA.DocumentID).then(result=>{ - // console.log('proofread->detail', result) - // }); - endSubscribe() - checkProofreadStatusAndMergeResult(); - return; - } - // 只处理有校对数据的结果 - if (!data.diffs || data.diffs.length == 0) return; - // 处理校对内容 - parseProofreadSentence(data) - const dataList = [data] - - // 将data插入到数据队列合适的位置 - const list = buildProofreadSentenceList(dataList, SentenceListCache) - // 将数据提交到word中进行标记 - ProofreadQueue.push(dataList[0]) - // console.log('parseProofreadResult==>',data) - CACHE_DATA.currentSentenceList = list; - setProofreadSentences([...list]) - // xx年后、政务的处理 - try{ - parseDiffNotice(data) - }catch (e){ - console.log('parseDiffNotice==>',e) - } - } - - const startLoadProofreadCache = () => { - if (CACHE_DATA.state == 'proofreading') { - bridge.ShowMessage('文档正在校对中,请稍后加载文件', 3000, false); - return; - } - loadProofreadCache().then(async (ret) => { - console.log('loadProofreadCache ==>', ret) - if(CACHE_DATA.DocumentID < 1){ - bridge.SetCurrentDocumentId(ret.documentId) - CACHE_DATA.DocumentID = ret.documentId - } - - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,true,false,true); - bridge.ShowCurrentPane() - CACHE_DATA.proofreadMode = ret.proofreadMode - CACHE_DATA.state = 'finish' - ret.sentences = ret.sentences.filter(s=>s.diffs?.length) - CACHE_DATA.currentSentenceList = ret.sentences - setDisabledList(ret.disabled) - setProofreadSentences(ret.sentences); - setCurrentSelectProofreadId(()=>{ - return ret.activeItemId - }) - if(ret.activeAcceptState){ - setState({ - activeAcceptState:ret.activeAcceptState - }) - } - await bridge.InitProofreadCacheList(JSON.stringify(ret.sentences),ret.originData ? JSON.stringify(ret.originData):''); - bridge.SelectMarkById(ret.activeItemId,CACHE_DATA.DocumentID) - }).catch((e) => { - // cache - if (e.message == 'cache-not-exists') { - bridge.ShowMessage('未找到缓存⽂件,请重新校对',3000,false) - } else { - bridge.ShowMessage(e.message,3000,false) - } - }); - } - - // 在系统浏览器中打开链接 - const openUrlInOSBrowser = async (key: 'document' | 'lexicon') => { - const target = `${APP_CONFIG.WEB_PATH}/${key}?from=office-plugin`; - if (!CACHE_DATA.userinfo) { // 没有登录直接跳转 - bridge.OpenUrlWithOsBrowser(target) - return; - } - const {code} = await getAuthCode(); - const url = `${APP_CONFIG.WEB_PATH}/redirect?code=${code}&target=${encodeURIComponent(target)}`; - bridge.OpenUrlWithOsBrowser(url) - } - - const startProofread = async (modelId:string) => { - const saved = await bridge.Saved(0); - if(!saved){ - bridge.ShowMessage('请保存文档后再进行校对',3000,false) - return; - } - CACHE_DATA.state = 'proofreading' - // 将未找到的校对项列表置为空 - setDisabledList(() => ([])) - setProofreadSentences(() => []) - SentenceListCache.length = 0; - // 设置进度为未知 - CACHE_DATA.clearProgressTimer() - setProofreadProgress(0) - const firstProgressTimeout = setTimeout(()=>{ - setProofreadProgress(p=>Math.max(p,1)) - },2000) - - setState({ - proofreading: true, - error: undefined, - savedCache: false - }) - //bridge.SetBtnStatus('proofread-status', false) - // 显示校对面板 - bridge?.ShowCurrentPane(); - // 清空标记 - bridge.ClearCurrentDocumentMarks() - getContentAndProofread(modelId).then(checking => { - // setState({ - // proofreading: false, - // error: undefined - // }) - // 如果没有内容或没有校对则 - if(!checking || CACHE_DATA.wordCount == 0){ - CACHE_DATA.clearProgressTimer() - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,true,false,true); - setProofreadProgress(-1) - clearTimeout(firstProgressTimeout) - return; - } - - const firstCount = CACHE_DATA.wordCount > 5000 ? 5000 : Math.floor(CACHE_DATA.wordCount * 0.3) // 大于5000则5000为一段,否则30%为一段 - const firstProgress = Math.floor(firstCount / CACHE_DATA.wordCount * 100) - const step = Math.ceil(firstProgress / 13) - CACHE_DATA.progress_timer = setInterval(()=>{ - if(CACHE_DATA.progress_count ++ >= 13){ - CACHE_DATA.clearProgressTimer(); - return; - } - setProofreadProgress(prevProgress => { - // 计算第一段内容的理论进度 - const progress = (prevProgress <= 0 ? 0 : prevProgress) + step; - if(firstProgress < prevProgress || firstProgress < 1){ // 已经小于当前进度 或 第一次的进度小于1% - CACHE_DATA.clearProgressTimer(); - return Math.max(prevProgress,firstProgress,1); - } - - // 判断进度该使用原始进度还是当前进度 - return progress - }); - },1000) // 一开始0%,2秒后1% - }).catch((e: Error) => { - if((e as BizError).code == 401){ - logout().finally(()=>{ - CACHE_DATA.userinfo = undefined - resetProofreadData() - bridge?.Logout("disabled-send") - }); - setTimeout(function (){ - bridge?.ShowLoginForm('proofread') - },50) - return; - } - clearTimeout(firstProgressTimeout) - CACHE_DATA.clearProgressTimer() - //bridge.SetBtnStatus('proofread-status', true) - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,true,false,true); - console.log('proofread error', e) - setProofreadProgress(-1) - setState({ - proofreading: false, - error: e.message - }) - }) - // bridge.DeleteCache() - } -// const loadDocumentData = async ()=>{ -// // const content = await bridge.getDocumentData(-1); -// // console.log(content) -// // const data = JSON.parse(content) as DocumentData; -// // console.log(data) -// // } -// // const loadStreamMockData = async ()=>{ -// // // const it = bridge.ShowConfirm('测试一下','提示','确认','去表') -// // // it?.then?.((s)=>{ -// // // console.log(s) -// // // }) -// // // if(it) return; -// // CACHE_DATA.state = 'finish' -// // CACHE_DATA.currentSentenceList = [] -// // CACHE_DATA.DocumentID = 2853; -// // bridge.ShowCurrentPane() -// // await bridge.SetCurrentDocumentId(CACHE_DATA.DocumentID) -// // // 将未找到的校对项列表置为空 -// // setDisabledList(() => ([])) -// // setProofreadSentences(() => []) -// // ProofreadQueue.init(); -// // SentenceListCache.length = 0; -// // setState({ -// // proofreading: true, -// // error: undefined, -// // savedCache: false -// // }) -// // setProofreadProgress(200) -// // setTimeout(()=>{ -// // setProofreadProgress(90) -// // },1500) -// // bridge.ClearCurrentDocumentMarks() -// // // const list = buildProofreadSentenceList(result.corrected_set, SentenceListCache) -// // // CACHE_DATA.currentSentenceList = list; -// // // setProofreadSentences([...list]) -// // const testList = cloneDeep(streamMockData) as V3.ProofreadSentence[]; -// // CACHE_DATA.originData = {}; -// // -// // const it = testList[0]; -// // console.log(it) -// // testList.forEach((it)=>{ -// // const index = JSON.parse(base64Decode(it.ext)).index; -// // //parseProofreadSentence(it) -// // //parseProofreadResult(it) -// // CACHE_DATA.originData[index] = { -// // insert_len: it.insert.length, -// // paragraph_num: it.paragraph_num, -// // origin_text: it.insert, -// // hash: '', -// // parseData:{ -// // newStr: it.insert, -// // invisibleChars: [] -// // } -// // } -// // }) -// // setTimeout(()=>{ -// // setState({ -// // proofreading: false -// // }) -// // testList.forEach((it: V3.ProofreadSentence)=>{ -// // parseProofreadSentence(it) -// // //parseProofreadResult(it) -// // }) -// // -// // // 将data插入到数据队列合适的位置 -// // const list = buildProofreadSentenceList(testList, SentenceListCache) -// // -// // testList.forEach((it: V3.ProofreadSentence)=>{ -// // // 将数据提交到word中进行标记 -// // ProofreadQueue.push(it) -// // }) -// // CACHE_DATA.currentSentenceList = list; -// // setProofreadSentences(list) -// // -// // setProofreadProgress(-1) -// // },1000) -// // } - - // 但登录成功后通知插件登录成功 - const noticeLoginSuccess = () => { - if (CACHE_DATA.userinfo) { - setUserinfo(CACHE_DATA.userinfo) - const user = { - ...CACHE_DATA.userinfo, - nickname: hidePhone(CACHE_DATA.userinfo.nickname || CACHE_DATA.userinfo.phone), - expiration: '企业内测版' - } - bridge?.loginSuccess(JSON.stringify(user)) - } - } - - const getOldVersionUpgradeInfo = (up: UpgradeInfo) => { - return { - ...up, - clientType: up.client_type, - appName: up.app_name, - publishType: up.publish_type, - upgradeType: up.upgrade_type, - downloadUrl: up.download_url, - isShowPop: up.is_show_pop, - } - } - const getUpgradeInfo = (callback?: () => void) => { - getAppInfo().then(({version}) => { - // 获取信息 - getAppUpgradeInfo(version).then(info => { - CACHE_DATA.upgradeInfo = info; - if (callback) { - callback(); - return; - } - if (info.upgradeAvailable && info.upgradeInfo.upgrade_type == 1) { - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(info.upgradeInfo)),true) - } - }) - }) - } - // 只要校对了 就自动保存缓存 - useInterval(()=>{ - if(CACHE_DATA.state == 'finish') saveCache(true) - },1000 * 60) - useEffect(getUpgradeInfo, []) - - // 如果已经登录 则通知登录成功 - useEffect(() => { - if (globalUser || CACHE_DATA.userinfo) { - if (globalUser) CACHE_DATA.userinfo = globalUser - noticeLoginSuccess(); - } - }, [globalUser]) - - /** - * 开始校对 - * @param mode 校对模式 - * @param force - */ - const handleProofread = (mode:string,force?: boolean) => { - // 没有登录则显示登录 - if (!CACHE_DATA.userinfo && !force) { - bridge?.ShowLoginForm("proofread") - return; - } - CACHE_DATA.proofreadMode = mode; - const modeInfo = ProofreadModelConfig[mode] || ProofreadModelConfig.full - startProofread(modeInfo.id).catch(e=>console.log('proofread error',e)); - } - // 避免来回乱跳 - const {run: setActiveBookMark} = useDebounceFn((id) => bridge?.SelectMarkById(id, CACHE_DATA.DocumentID), {wait: 200,}) - const [currentSelectProofreadId, setCurrentSelectProofreadId] = useState(0) - - const resetProofreadData = () => { - CACHE_DATA.clearProgressTimer() - CACHE_DATA.clearTimer(); - CACHE_DATA.state = 'ready' - CACHE_DATA.wordCount = 0 - setCurrentSelectProofreadId(0) - // setProofreadResult({count: {total: -1}, list: [],}) - setProofreadProgress(-1) - bridge?.clearAllProofreadMarkById(CACHE_DATA.DocumentID); - setProofreadSentences(() => ([])) - } - const checkLoginAndContinue = (callback: () => void, action = 'normal') => { - if (CACHE_DATA.userinfo) { - callback() - } else { - init().then((account) => { - if (account) { - CACHE_DATA.userinfo = account - callback() - } else { - logout().finally(()=>{ - CACHE_DATA.userinfo = undefined - resetProofreadData() - bridge?.Logout("disabled-send") - }); - setTimeout(function (){ - bridge?.ShowLoginForm(action) - },50) - } - }).catch(e=>{ - console.log('===>',e) - }) - } - } - - /** - * - * @param silent 是否静默保存 - */ - const saveCache = async (silent: boolean) => { - //const sentences = proofreadSentences && proofreadSentences.length > 0 ? proofreadSentences : CACHE_DATA.currentSentenceList - const sentences = CACHE_DATA.currentSentenceList.filter(s=>s.diffs?.length) - if (!silent && sentences.length == 0) { - bridge.ShowMessage('保存失败,没有可用的校对结果', 3000, false); - return - } - // 获取文档所有校对项标记的原始信息 -> 用于撤销时还原 - const originData = await bridge.GetProofreadOriginData(); - saveProofreadCache({ - documentId: CACHE_DATA.DocumentID, - activeItemId: CACHE_DATA.selectId, - activeAcceptState: CACHE_DATA.selectStatus, - proofreadMode: CACHE_DATA.proofreadMode, - disabled: disabledList, - sentences, - originData: JSON.parse(originData) - },true).then(()=>{ - if(!silent) bridge.ShowMessage('保存成功',2000,false) - }).catch(e => { - console.log('save error', e) - }); - setState({ - savedCache: true - }) - } - - const exportProofreadResultToExcel = async () => { - if (CACHE_DATA.state == 'ready') { - bridge.ShowMessage('请先完成校对,再执行导出', 3000, false); - return; - } - try{ - await bridge.ExportProofreadResult(CACHE_DATA.proofreadMode || 'exact') - }catch (e){ - console.log(e) - bridge.ShowMessage('导出失败', 3000, false); - } - } - - const showAppVersion = async ()=>{ - const version = `插件版本:${ApplicationInfo.platformVersion} -WEB环境版本:${AppVersion.version} -编译版本:${AppVersion.buildVersion} -运行平台:${ApplicationInfo.platform}-${ApplicationInfo.environment}` - Modal.info({ - title:'版本信息', - content:
{version}
, - width:400 - }) - //bridge.ShowMessage(version,0,false) - } - - // 监听插件通知 - useBridgeMessageListener(({Message, Data}) => { - console.log('-->bridge message callback:', Message, Data) - if (Message == 'start') { - // 添加强制更新检测 - if (CACHE_DATA.upgradeInfo.upgradeAvailable && CACHE_DATA.upgradeInfo.upgradeInfo!.upgrade_type == 1) { - // bridge.ShowUpgrade(JSON.stringify(CACHE_DATA.upgradeInfo.upgradeInfo)) - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(CACHE_DATA.upgradeInfo.upgradeInfo!)),false) - return; - } - // 开始校对 - checkLoginAndContinue(()=>{ - handleProofread(String(Data)) - },'proofread'); - } else if (Message == 'upgrade') { // 升级信息 - if (!CACHE_DATA.upgradeInfo.upgradeAvailable) { - bridge.ShowMessage("当前版本为最新版本,无需升级", 3000, false); - return; - } - if (CACHE_DATA.upgradeInfo.upgradeInfo) { - bridge.ShowUpgrade(JSON.stringify(getOldVersionUpgradeInfo(CACHE_DATA.upgradeInfo.upgradeInfo!)),false) - // bridge.ShowUpgrade(JSON.stringify(CACHE_DATA.upgradeInfo.upgradeInfo)) - } - } else if (Message == 'clear-tips') { // 显示词库 - resetProofreadData() - bridge.DeleteCache() - bridge.clearAllProofreadMarkById(CACHE_DATA.DocumentID) - bridge.SetCurrentDocumentProofreadStatus(CACHE_DATA.DocumentID,false,false,false); - bridge.HideCurrentPane() // 隐藏当前面板 - } else if (Message == 'show-setting') { // 显示设置 - checkLoginAndContinue(() => { - // bridge?.ShowSettingForm() - showView('/setting',620,450,true) - }, 'setting'); - } else if (Message == 'show-lexicon') { // 显示词库 - // openUrlInOSBrowser('lexicon').catch(console.error) - // ShowLexiconForm - checkLoginAndContinue(() => { - bridge.ShowLexiconForm(); - }); - } else if (Message == 'logout') { // 退出登录 - logout().finally(() => { - CACHE_DATA.userinfo = undefined - resetProofreadData() - bridge?.Logout("disabled-send") - }) - } else if (Message == 'async-logout') { // 同步注销登录 - resetProofreadData() - CACHE_DATA.userinfo = undefined; - } else if (Message == 'async-login-success') { - init().then(console.log) - } else if (Message == 'select-proofread') { - const id = Number(Data) - if (id > 0) setCurrentSelectProofreadId(()=>id) - } else if (Message == 'getParagraphTextByRange') { - console.log('getParagraphTextByRange', Data) - } else if (Message == 'disabled-proofread') { - // console.log('disabled-proofread',Data) - setDisabledList(originList => ([...originList, ...(Data as number[])])) - // - } else if(Message == 'export-result'){ - checkLoginAndContinue(async () => { - exportProofreadResultToExcel() - }); - } else if (Message == 'save-cache') { - checkLoginAndContinue(()=>{ - if (CACHE_DATA.state != 'finish') { - bridge.ShowMessage('保存失败,请校对完成后再进行保存', 3000, false); - return; - } - saveCache(false); - }) - } else if (Message == 'load-cache') { - checkLoginAndContinue(()=> { - startLoadProofreadCache(); - }); - - } else if (Message == 'show-check-all') { - checkLoginAndContinue(()=> { - bridge.SendNoticeToCheckAll() - }); - } else if (Message == 'show-check-range') { - const data = (()=>{ - try{ - return Data ? JSON.parse(Data as string) : null; - }catch (e){ - console.log('show-check-range error',e) - } - return null; - })(); - checkLoginAndContinue(()=> { - if(data && data.end){ - bridge.SendNoticeToCheckRange(data.start,data.end) - }else{ - bridge.SendNoticeToCheckRange(-1,-1) - } - }); - } else if (Message == 'show-check-history') { - checkLoginAndContinue(()=> { - bridge.SendNoticeToShowCheckHistory(); - }); - } else if (Message == 'show-panel') { - if (CACHE_DATA.state == 'ready') return; - bridge.ShowCurrentPane(); - } else if(Message == 'show-version') { - showAppVersion().then(); - } else if(Message == 'confirm-logout'){ - bridge.ShowConfirmMessage?.(`${userinfo?.phone} 退出AI校对王?`, '确定', 'logout') - }else { - console.log('App useBridgeMessageListener:', Message, Data) - } - }) - // 监听校对结果并根据禁用列表更新数据 - // useEffect(() => { - // const result = parseV3ProofreadResult(proofreadSentences, disabledList); - // setProofreadResult(result) - // }, [proofreadSentences, state.proofreading, disabledList]) - return (
- {/* 未完成校对时显示进度 */} - {userinfo && proofreadProgress >= 0 && 0} - parsing={state.contentParsing} - onOpenWebDocument={() => openUrlInOSBrowser('document')} - />} - {/* 显示错误 */} - {userinfo && !state.proofreading && state.error && handleProofread('full')} - onOpenWebDocument={() => openUrlInOSBrowser('document')} - />} - {/* 没有错误 */} - {userinfo && CACHE_DATA.state == 'finish' && proofreadProgress == -1 && !state.proofreading && !state.error && proofreadSentences.length == 0 && } - {/*
*/} - {/**/} - {/*
*/} - {/**/} - {/* */} - {/* */} - {/**/} - {/* 校对面板 */} - {(!userinfo || !state.error) && <> - { - // 还原标签状态 - bridge?.processMark(item.id, item.isAccept) - // 保存最新数据 - CACHE_DATA.currentSentenceList = proofreadSentences - //saveCache(true) - }} - onSelectProofreadItem={(item) => { - setActiveBookMark(item?item.id:-1) - setState({ - activeItemId: item?.id || -1 - }) - CACHE_DATA.selectId = item?.id || -1 - //setCurrentSelectProofreadId(item?.id || -1) - }} - onStartProofread={() => handleProofread('full')} - selectedProofreadItemId={currentSelectProofreadId} - selectedAcceptStatus={state.activeAcceptState} - onStateChange={({activeItemId, acceptState}) => { - CACHE_DATA.selectId = activeItemId - CACHE_DATA.selectStatus = acceptState - // setState({ - // activeAcceptState:acceptState, - // activeItemId - // }) - //setCurrentSelectProofreadId(activeItemId) - }} - > - {/**/} - - } -
) -} \ No newline at end of file diff --git a/src/pages/proofread/notice.tsx b/src/pages/proofread/notice.tsx deleted file mode 100644 index ce93f28..0000000 --- a/src/pages/proofread/notice.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React from "react"; -import {Button, Space} from "antd"; -import Icon, {DownOutlined} from "@ant-design/icons"; -import {ErrorNotice} from "./components/images/notice.tsx"; -import {IconLogo} from "./components/images/logo.tsx"; -import IconPerfect from "./images/perfect.png"; -import {useSetState} from "ahooks"; - -type NoticeProps = { - onOpenWebDocument?: () => void; - onStartProofread?: () => void; - progress?: number; - hasResult?: boolean; - parsing?:boolean; -} -const ContentParingView = ()=>(
正在解析文档内容,请稍候...
) - -export function ProofreadLoading({progress,hasResult,parsing}: NoticeProps) { - const [state,setState] = useSetState({ - shown: true - }) - return (<> - {progress && progress !== 200 && progress >= 0 && hasResult ?
-
-
- {parsing ? :<> -
-
校对中 {progress && progress <=100? `${progress <= 1?1:progress}%`:'100%'} ...
-
-
-
-
- } -
-
-
校对中 {progress && progress <=100? `${progress <= 1?1:progress}%`:'100%'} ...
- -
:
-
-
- -
- -
- {parsing ? :<> -
校对中 {progress}%
-
-
-
- } -
- {/**/} - {/* */} - {/* 等得太久?您也可以查看该任务*/} - {/**/} -
- -
} - ) -} - -export function ProofreadError({onStartProofread, onOpenWebDocument}: NoticeProps) { - // 加载中... - // 这里可以添加自定义的加载中逻辑 - // 例如,显示一个加载动画或提示信息 - return (
-
- -
-

- 糟糕!校对出现了问题 -

-

请重新进行校对或前往网页端查看

-
-
- -
- - {/**/} - - -
-
- -
) -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function ProofreadPerfect({onStartProofread, onOpenWebDocument}: NoticeProps) { - return (
-
- -
- -

- 非常完美 -

-
-
-
-
); -} \ No newline at end of file diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx deleted file mode 100644 index a320045..0000000 --- a/src/pages/setting/index.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import {Button, Checkbox, Col, Row, Space, Typography} from 'antd' -import {AppTitleBar} from "../../components/app/title-bar.tsx"; -import './style.less' -import {useEffect, useState} from 'react'; -import {getSettings, saveSettings} from '../../service/api/settings.ts'; -import {Settings} from "../../service/types/settings.ts"; -import {showToast} from "../../components/messages/Modal.tsx"; -import {useRequest} from "ahooks"; - -type ConfigValues = { - [key: string]: string | number; -} - -enum SettingValue { - UnChecked = 1, - Checked = 2, -} - -const SETTING_OPTION_LIST = [ - { - options: [ - {label: '个人黑名单', value: 'word_black'}, - {label: '个人白名单', value: 'word_white'}, - ], - type: 'lexicon' - }, - { - options: [ - {label: '出版社词库', value: 'industry_publish'} - ], - type: 'domain' - }, - { - options: [ - { label: '领导人名称、职务、排序', value: 'leader_info' }, - { label: '领导人语录', value: 'leader_quotes' }, - { label: '落马官员', value: 'fallen_officers' } - ], - type: 'gov' - } -]; - -const PageSetting = () => { - // const [defaultChecked, setDefaultChecked] = useState(); - const [checkedSetting, setCheckedSetting] = useState([]); - - const handleClose = () => { - chrome.webview.hostObjects.event.Close() - } - // 保存 - const {loading, run: handleSave} = useRequest(() => { - const values: ConfigValues = {}; - SETTING_OPTION_LIST - .map(s => s.options).flat() - .forEach(s => { - values[s.value] = checkedSetting.includes(s.value) ? SettingValue.Checked : SettingValue.UnChecked - }) - return saveSettings(values as Settings) - }, { - manual: true, - onSuccess(){ - showToast('保存成功',"success") - }, - onError:()=>{ - showToast('保存设置失败,请稍后重试','error') - } - }) - useEffect(() => { - getSettings().then(values => { - const checked = SETTING_OPTION_LIST - .map(s => s.options).flat() // 扁平获取所有选项 - .filter(s => values[s.value] && values[s.value] == SettingValue.Checked) // 获取已设置 - .map(s => s.value); - setCheckedSetting(checked) - }); - }, []) - - return (<> - -
- - 校对设置 -
- - {SETTING_OPTION_LIST.map((it) => - (
- - {it.options.map((item, index) => - {item.label} - )} - -
) - )} -
-
-
-
- - - - -
-
- ) -} -export default PageSetting; \ No newline at end of file diff --git a/src/pages/setting/style.less b/src/pages/setting/style.less deleted file mode 100644 index ec62fd2..0000000 --- a/src/pages/setting/style.less +++ /dev/null @@ -1,24 +0,0 @@ -.page-setting{ - --content-padding-size:40px; - padding: var(--content-padding-size); - - - .setting-checkbox-wrapper{ - margin-top: 10px; - .setting-row{ - width: 100%; - margin-bottom: 10px; - } - } - .setting-footer{ - position: fixed; - inset-block-end: 0; - inset-inline: 0; - padding: var(--content-padding-size); - text-align: right; - background-color: #fff; - } - .gov-setting{ - padding-left: 24px; - } -} \ No newline at end of file diff --git a/src/pages/test/mqtt.tsx b/src/pages/test/mqtt.tsx deleted file mode 100644 index 15e4f62..0000000 --- a/src/pages/test/mqtt.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import {Button} from "antd"; -import {useProofread} from "@/service/use-proofread.ts"; -import {getDeviceId} from "@/core/device-id.ts"; -import {useSetState} from "ahooks"; - -let idx = 1; -export default function MqttTest() { - const {isConnected, subscribe, endSubscribe, currentMessage, send} = useProofread({ - connectUrl: 'ws://43.136.175.109:8083/mqtt', - clientId: getDeviceId() - }) - const [state, setState] = useSetState({ - subscribed: false, - }) - - const connectOrDisconnect = () => { - if (isConnected) { - endSubscribe(); - } else { - //connect(); - setState({subscribed: true}) - if (!state.subscribed) { - subscribe({clientId: "xxx", path: "", topic:'proofread/1'}, (message) => { - console.log('receive', message) - }) - } - } - } - const sendMessage = () => { - const topic = 'proofread' - const data = { - id: idx++, - time: Date.now(), - content: 'hello world' - } - console.log('publish', topic, data) - send(topic, JSON.stringify(data)) - } - - return
- MQTT - - {isConnected &&
- -
} -
- {JSON.stringify(currentMessage)} -
-
-} \ No newline at end of file diff --git a/src/routes/index.tsx b/src/routes/index.tsx deleted file mode 100644 index f6e9750..0000000 --- a/src/routes/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import {Navigate, Route, Routes, BrowserRouter} from "react-router-dom"; -import {lazy} from "react"; -// import Home from "../pages/home"; -// import Correct from "@/pages/proofread"; -import Login from "../pages/login"; -import PageContact from "../pages/normal/contact.tsx"; -import PageSetting from "../pages/setting"; -import DefaultPage from "../pages/normal/Default.tsx"; -import Main from "../pages/normal/Main.tsx"; -import Lexicon from '@/pages/lexicon'; -const Home = lazy(()=>import("@/pages/home-deprecated/index.tsx")); -const Correct = lazy(()=>import("@/pages/proofread")); -const CommonsenseDetection = lazy(()=>import("@/pages/detection/sense.tsx")); -// const Example = lazy(()=>import("@/examples/state.tsx")) - -export default function AppRoutes() { - return ( - - }/> - }/> - }/> - }/> - }/> - }/> - }/> - }/> - }/> - }/> - - ) -} \ No newline at end of file diff --git a/src/service/api/detection.ts b/src/service/api/detection.ts deleted file mode 100644 index dbe8b02..0000000 --- a/src/service/api/detection.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {post} from "../request.ts"; - -/** - * 请求大模型并创建key接口为请求大模型后返回的key - * (为了及时响应接口返回,大模型可能会比较慢)key有时效性(有效期1小时) - * @param content - */ -export function sendContentToDetection(content:string, content_type:number) { - content = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n') - return post<{assistantKey:string}>('/api/v1/assistant/get_key',{content, content_type}) -} - -/** - * 后续接口通过key来获取真正的内容。(需要等待2.1接口异步处理完成后,才会有结果,没有处理完或者过期时效会为空) - * @param assistant_key - */ -export function getDetectionResult(assistant_key:string, content_type:number) { - return post('/api/v1/assistant/get_content_by_key',{assistant_key,content_type}) -} - -export function parseDetectionResult(originResult:V3.DetectionContent) { - const data = JSON.parse(originResult.result) as { - results: V3.DetectionResult[] - }; - if(!data.results || data.results.length == 0) return "未检测到常识性错误"; - return data.results.map(it=>{ - return `## 第 ${it.ID} 处:\n\n错误内容: “${it.source}”\n\n错误原因: ${it.reason}` - }).join('\n\n') -} \ No newline at end of file diff --git a/src/service/api/document.ts b/src/service/api/document.ts deleted file mode 100644 index b4bd9f4..0000000 --- a/src/service/api/document.ts +++ /dev/null @@ -1,142 +0,0 @@ -import {get, post, put} from '../request.ts' -import { - AcceptParam, - TAcceptParam, TDocumentContentDetail, - TProofreadData, -} from "../types/document.ts"; - -/** - * proofread process_data 两接口timeout设置成30分钟吧 - */ -const _request_timeout = 30 * 60 * 1000; - -/** - * 1 word 2 ppt 3 txt - */ -export enum DocumentTypeEnum { - Word = 1, - PPT, - TEXT, -} -export enum DocumentInputModeEnum { - // 1上传文档 - FileUpload = 1, - // 2录入文本 - PlainText, -} - -export type TCreateParam = { - //文档名称 - name: string; - //文档格式 1word 2ppt 3txt - fileFormat?: DocumentTypeEnum; - // 1上传文档 2 录入文本 - mode?: DocumentInputModeEnum; - [setting:string]:any; -} - -/** - * 1:纯文本 2:文档纠错 3:文档合规 4:图片合规 5:视频合规 - */ -export enum ProofreadTypeEnum { - Text = 1, - /** - * 文档纠错 - */ - DocumentErrorCorrect, - /** - * 文档合规 - */ - DocumentCompliant, - Picture, - Video -} - -/** - * - * @param fileId 文档编号 - * @param type 类型(1:纯文本 2:文档纠错 3:文档合规 4:图片合规 5:视频合规) - * @settings settings - * @exception - * 错误码 错误信息
- * 1 id不能为空
- * 2 参数错误
- * 3 参数错误
- * 4 文档校对中
- * 5 校审结果更新失败
- */ -export function proofread(fileId: number | string, type: ProofreadTypeEnum = 1,settings?: object) { - // return new Promise((resolve) => { - // setTimeout(() => { - // resolve({"remainingTime": 0, "status": 3}) - // }, 200) - // }) - return post(`/api/v2/document/plugin/proofread/${fileId}`, { - type, - _request_timeout, - ...settings - }) -} - -export function proofreadDetail(id: number) { - // return new Promise((resolve) => { - // setTimeout(() => { - // resolve(JSON.parse(JSON.stringify({ - // ...mockData, - // id, - // }))) - // }, 200) - // }) - return get(`/api/v2/document/plugin/detail/${id}`) -} - -/** - * 保存文档内容 - * @param id - * @param content - * @param action 1新建2采纳/忽略等按修改3人工修改 - */ -export function save(id: number, content: object|string, action: 1 | 2 | 3 = 3) { - return post(`/api/v2/document/plugin/save/${id}`, {content:JSON.stringify(content),obj:content, action}); -} - -// 创建新文档 -export function create({name, fileFormat = DocumentTypeEnum.TEXT, mode = 2}: TCreateParam) { - return post<{ info: { id: number } }>('/api/v2/document/plugin/create', {name, fileFormat, mode}) -} - - -/** - * 采纳校对结果 - * @param params - * @exception 错误码:
- * 错误码 错误信息
- * 1 参数错误
- * 2 fid参数不合法
- * 3 内部错误
- * 4 文档未校对
- * 5 文档未校对
- * 6 fid参数不合法
- * 7 更新失败
- * 8 校对状态,更新失败
- */ -export function processProofread(params: TAcceptParam) { - return put(`/api/v1/document/accept`, params); -} - -export function accept(id: number, params: AcceptParam) { - return post(`/api/v2/document/suggest/${id}`, params) -} - -/** - * @param fileId 文档编号 - * @param type 类型(1docx 2doc) - * @exception - * 错误码 错误信息
- * 1 删除失败
- */ -export function download(fileId: number | string, type: 1 | 2) { - return get<{ - download_url:string - }>(`/api/v2/document/export/${fileId}?type=${type}`); -} \ No newline at end of file diff --git a/src/service/api/index.ts b/src/service/api/index.ts deleted file mode 100644 index 2f8b1b8..0000000 --- a/src/service/api/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as userApi from './user' -import * as documentApi from './document.ts' - -export const user = userApi -export const document = documentApi diff --git a/src/service/api/lexicon.ts b/src/service/api/lexicon.ts deleted file mode 100644 index 15a7fd9..0000000 --- a/src/service/api/lexicon.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { get, post, put, uploadFile} from '../request.ts' -import {getListResult} from "./util"; -import { - TBlackLexicon, - TBlackLexiconItem, - TImportBlackResult, - TListParam, - TWhiteLexicon, - TWhitelistItem -} from "../types/lexicon.ts"; - - -export const blacklist = { - /** - * 黑名单列表。 - * @param params - */ - async list(params: TListParam) { - return getListResult(await get('/api/v1/word/black/list', params, true)); - }, - /** - * 创建黑名单记录。 - * @param param - */ - create(param: TBlackLexicon) { - return post(`/api/v1/word/black/create`, param) - }, - /** - * 批量创建黑名单记录 - * @param params - */ - createBatch(params:any){ - return post(`/api/v1/word/black/batch_create`, params) - }, - /** - * 修改一条黑名单记录。 - * @param id - * @param param - */ - modify(id: number, param: TBlackLexicon) { - return put(`/api/v1/word/black/modify/${id}`, param) - }, - /** - * 删除一条黑名单记录 - * @param id - */ - remove(id: number) { - return post(`/api/v1/word/black/del/${id}`) - }, - /** - * 批量删除多条黑名单记录 - * @param ids - */ - removeBatch(ids: number[]) { - return post(`/api/v1/word/black/batch_del`, {ids}) - }, - /** - * 批量导入excel黑名单记录
- * 错误码 - * 1 参数错误 - * 2 每次导入词条的数量,必须大于1 - * 3 获取词条数据源失败 - * 4 批量添加黑名单失败 - * @param file - */ - import(file: File) { - return uploadFile(`/api/v1/word/black/import`, { - file, - fileName:'file' - }) - } -} -export const whitelist = { - /** - * 白名单列表。 - * @param params - */ - async list(params: TListParam) { - return getListResult(await get('/api/v1/word/white/list', params, true)); - }, - /** - * 创建白名单记录。 - * @param param - */ - create(param: TWhiteLexicon) { - return post(`/api/v1/word/white/create`, param) - }, - /** - * 批量创建白名单记录 - * @param params - */ - createBatch(params:any){ - return post(`/api/v1/word/white/batch_create`, params) - }, - /** - * 修改一条白名单记录。 - * @param id - * @param param - */ - modify(id: number, param: TWhiteLexicon) { - return put(`/api/v1/word/white/modify/${id}`, param) - }, - /** - * 删除一条白名单记录 - * @param id - */ - remove(id: number) { - return post(`/api/v1/word/white/del/${id}`) - }, - /** - * 批量删除多条白名单记录 - * @param ids - */ - removeBatch(ids: number[]) { - return post(`/api/v1/word/white/batch_del`, {ids}) - }, - /** - * 错误码 - * 1 参数错误 - * 2 每次导入词条的数量,必须大于1 - * 3 获取词条数据源失败 - * 4 批量添加白名单失败 - * @param file - */ - import(file: File) { - return uploadFile(`/api/v1/word/white/import`, { - file, - fileName:'file' - }) - } -} diff --git a/src/service/api/settings.ts b/src/service/api/settings.ts deleted file mode 100644 index 402c58b..0000000 --- a/src/service/api/settings.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {post, get} from "../request.ts"; -import {Settings, UpgradeInfo} from "../types/settings.ts"; - -export function getSettings() { - return get(`/api/v1/word/settings`); -} - -export function saveSettings(settings: Settings) { - return post(`/api/v1/word/settings`, settings); -} - -export function compareVersion(version1: string, version2: string) { - const v1 = version1.split('.').map(Number); - const v2 = version2.split('.').map(Number); - const maxLength = Math.max(v1.length, v2.length); - for (let i = 0; i < maxLength; i++) { - const num1 = v1[i] || 0; - const num2 = v2[i] || 0; - if (num1 > num2) return 1 - else if (num1 < num2) return -1; - } - return 0; -} - -/** - * 获取升级信息 - * @param currentVersion - */ -export async function getAppUpgradeInfo(currentVersion: string) { - const upgradeInfo = await get('/api/v1/common/download/version', { - _header_config: { - 'X-client-platform': 'win-plugin' - } - }) - return { - upgradeAvailable: compareVersion(currentVersion, upgradeInfo.version) === -1, - currentVersion, - upgradeInfo - } -} \ No newline at end of file diff --git a/src/service/api/user.ts b/src/service/api/user.ts deleted file mode 100644 index f984eec..0000000 --- a/src/service/api/user.ts +++ /dev/null @@ -1,126 +0,0 @@ -import {get, post, request} from "../request.ts"; - -/** - * 发送验证码 - * @param phone 手机号 - */ -export function sendCode(phone: string) { - return post('/api/v1/send_login_code', { - phone - }) -} - -/** - * 登录 - * @description
- * 登录注册是后端种cookie给浏览器,cookie 有两个字段,一个access_token,一个refresh_token。
- * access_token是其他接口鉴权,有效期为暂定为2个小时,如果过期则通过刷新token接口重新获取。
- * refresh_token是用来刷新access_token和refresh_tokende ,有效期暂定30天,如果过期则提醒用户重新登录。 - * @param phone - * @param code - */ -export function login(data: { phone?: string, code?: string }) { - return post('/api/v1/login', data) -} - - -export function confirmLogin(data: { phone?: string; code?: string; confirm_login_key: string }) { - return post('/api/v1/confirm_login', data) -} - -//获取用户信息 -export function info() { - return request(`/api/v1/userinfo`, 'get', null, false, false) -} - -//登出 -export function logout() { - return get(`/api/v1/logout`) -} - -/** - * 用于刷新access_token 和 refresh_token。
- * 在access_token失效的时候需要前端主动调用该接口,access_token失效的 code 为 403,只有这个状态码才能触发该接口。 - */ -export function refresh() { - return get(`/api/v1/refresh`) -} - -export type WechatScene = 'login' | 'register' | 'bind' -type WechatQRResult = { - // 二维码 url - img_url: string; - // 微信返回的二维码票据 - ticket: string; -} - -/** - * 获取微信登录二维码 - * @param scene - */ -export function getLoginQR(scene: WechatScene = 'login') { - return post('/api/v1/login_qrcode', {scene}) -} - -/** - * 检查微信登录二维码状态 - * 如果是第一次登录,则会返回已扫码的状态,过用户已经绑定过微信,则会直接跳转登录成功。 - * 此接口为轮询接口,5-10s轮询一次,10分钟后结束轮询。如果返回的code为非0,则停止轮询。 - * @param scene - * @param sid - */ -export function qrLoginQRStatus(scene: WechatScene = 'login', sid?: string) { - return post<{ - /** - * code为0状态下 1 为未扫码 2 已扫码,code非0则为二维码过期 - */ - state: string; - } & Account>('/api/v1/qrcode_state', {scene, sid}) -} - -/** - * 更新昵称 - * @param nickname - */ -export function updateNickname(nickname: string) { - return post('/api/v1/update_nickname', {nickname}) -} - -/** - * 更新用户信息 - * @param params - */ -export function updateUserinfo(params: any) { - return post('/api/v1/update_userinfo', params) -} - -/** - * 绑定微信 - * 个人信息页面,获取绑定微信的二维码,根据用户信息接口的 is_bind_wechat 的字段来判断是否需要获取二维码 - * @param scene - */ -export function getBindWechatQR(scene: WechatScene = 'bind') { - return post(`/api/v1/bind_wechat`, {scene}) -} - -export function unbindWechat() { - return post(`/api/v1/unbind_wechat`) -} - -/** - * 绑定微信状态 - * 个人信息页面,获取绑定微信二维码后,轮询此接口,查看绑定状态。code 非0都将二维码置为失效状态,然后点击刷新,重新请求绑定二维码 - */ -export function wechatBindStatus() { - return post<{ - /** - * 二维码扫码状态 1 未扫 2已扫(并且绑定成功) - */ - state: string; - }>('/api/v1/bind_state',) -} - - -export function getAuthCode() { - return get<{ code: string }>('/api/v1/auth_code') -} \ No newline at end of file diff --git a/src/service/api/util.ts b/src/service/api/util.ts deleted file mode 100644 index 743c6e5..0000000 --- a/src/service/api/util.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {TPaginationResult} from "../types/base.ts"; - -type OriginResponse = { - code:number; - msg:string; - data:{ - list:T[] - }; - pagination: TPaginationResult; -} -export function getListResult(response: OriginResponse){ - return { - list: response.data.list, - pagination: response.pagination - } -} diff --git a/src/service/api/v3/document.ts b/src/service/api/v3/document.ts deleted file mode 100644 index c3f861a..0000000 --- a/src/service/api/v3/document.ts +++ /dev/null @@ -1,104 +0,0 @@ -import {get, post} from "@/service/request.ts"; -import { DocumentInputModeEnum, DocumentTypeEnum, TCreateParam } from '@/service/api/document.ts'; -import {ProofreadAction} from "./enums.ts"; - -type DocumentData = { - id: number | string; - content: V3.ProofreadDocumentData[]; - data?: string; -} -export type ProcessParam = { - ids?: number[]; - // 异常类型 0未知 1个人黑名单 2字错 3词错 4数字错 5标点错 6计量单位错 7语法错误 8知识性差错 9倾向性差错 10不一致 11格式错 12 敏感词 14 黑名单替换 15 黑名单拦截 - type?: number; - // 是否采纳 0默认 1复核 2采纳 3忽略 - action: number; - //1 全部 - isAll?: 1 | number; -} -/** - * 创建文档 - * @param data - */ -export function create(data: TCreateParam) { - if(typeof(data['fileFormat']) == 'undefined'){ - data.fileFormat = DocumentTypeEnum.TEXT - } - if(typeof(data['mode']) == 'undefined'){ - data.mode = DocumentInputModeEnum.PlainText - } - return post<{ info: { id: number } }>('/api/v3/document/plugin/create',data) -} - -/** - * 保存当前文档数据并开始校对 - *

校对接口 proofread v3,合并v2的 save和proofread。

- * @param document - * @param action - * @param settings - */ -export function proofread(document: DocumentData, action: ProofreadAction = 3, settings?: object) { - return post<{ - clientID: string; - topic: string; - path: string; - }>(`/api/v3/document/plugin/proofread/${document.id}`, { - action, - obj: document.content, - ...settings - }) -} - -/** - * 同步校对 - * @param document - * @param action - * @param settings - */ -export async function proofreadSync(document: DocumentData, action: ProofreadAction = 3, settings?: object) { - return post<{ - clientID: string; - topic: string; - path: string; - }>(`/api/v3/document/plugin/proofread_synchs/${document.id}`, { - action, - obj: document.content, - ...settings - }) -} - -/** - * 文档详情 detail v3 - * @param documentId 文档id - */ -export function detail(documentId: number) { - return get<{ - corrected_set: V3.ProofreadSentence[] - }>(`/api/v3/document/plugin/detail/${documentId}`) -} - -export function status(documentId: number) { - return get(`/api/v3/document/plugin/state/${documentId}`) -} -export async function getConfusionNotice(params: {idx:string;error_type:string}){ - const ret = await post<{ - data: { - notice: string[] - } - }>('/api/v3/document/plugin/get_confusion_notice', {index:[params]}) - return ret.data.notice[0] -} -export async function getCorrectionExtraForGov(param: { - error_type: 'quotation' | 'position' | 'leader' | string; - idx: string; -}[]){ - const ret = await post<{ - data:any - }>('/api/v3/document/plugin/get_correction_extra', {index:param}) - console.log('getCorrectionExtraForGov->result==》',ret) - return ret.data -} - -export function process(id:number,params:ProcessParam){ - return post(`/api/v2/document/suggest/${id}`,params) -} \ No newline at end of file diff --git a/src/service/api/v3/enums.ts b/src/service/api/v3/enums.ts deleted file mode 100644 index 6d56706..0000000 --- a/src/service/api/v3/enums.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * 1 新建 - * 2 采纳/忽略等按钮修改 - * 3 人工修改 - */ -export enum ProofreadAction { - NEW = 1, - PROOFREAD = 2, - MODIFY = 3 -} \ No newline at end of file diff --git a/src/service/create-new-document.ts b/src/service/create-new-document.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/service/exportDocument.ts b/src/service/exportDocument.ts deleted file mode 100644 index 3c1e37b..0000000 --- a/src/service/exportDocument.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {download as downloadDocument} from "./api/document.ts"; -// import {saveAs} from "file-saver" -import {getFileBlob} from "./request.ts"; - -export enum ExportTypeEnum { - DOCX = 1, - DOC -} - -type FileTypes = 'doc' | 'docx' | 'xls' | 'xlsx' | 'txt' | 'jpg' | 'png' | 'gif' | 'default' | string -export const MimeTypeConfig: Record = { - doc: 'application/msword', - docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - xls: 'application/vnd.ms-excel', - xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - txt: 'text/plain', - jpg: 'image/jpeg', - png: 'image/png', - gif: 'image/gif', - default: 'application/octet-stream', -} - -export async function exportDocument(id: number, fileName: string, exportType: ExportTypeEnum = 1) { - const ret = await downloadDocument(id, exportType); - //saveAs(ret.download_url,fileName) - // console.log('export',data) - // const type = exportType == ExportTypeEnum.DOC ? MimeTypeConfig.doc : MimeTypeConfig.docx - // // 先自行转换数据加快速度 - // const blob = new Blob([data as any], {type}); - // saveAs(blob, fileName, {autoBom: false}) -} - -export async function download(url: string, fileName: string) { - const data = await getFileBlob(url); - const extPos = fileName.indexOf('.') - const type = extPos == -1 ? MimeTypeConfig.default : (MimeTypeConfig[fileName.substring(extPos)] || MimeTypeConfig.default); - // 先自行转换数据加快速度 - const blob = new Blob([data as any], {type}); - //saveAs(blob, fileName) - alert('开始下载') -} - diff --git a/src/service/fake/api.ts b/src/service/fake/api.ts deleted file mode 100644 index 9b2575c..0000000 --- a/src/service/fake/api.ts +++ /dev/null @@ -1,74 +0,0 @@ -import {TDocumentContentDetail} from "../types/document.ts"; -import {sleep} from "@/utils/sleep"; - -export async function login(params: Partial) { - console.log('fake login', params) - return { - token: Math.random().toString(16).substring(2) - } -} - -export async function sendCode(phone: string) { - console.log('fake sendCode', phone) - return { - token: Math.random().toString(16).substring(2) - } -} - -export async function getLoginQR() { - console.log('fake getLoginQR',) - const ticket = Math.random().toString(16).substring(2); - return { - ticket, - img_url: `https://api.wm-app.xyz/qr/?data=${ticket+ticket}` - } -} - -export async function qrLoginQRStatus() { - console.log('fake qrLoginQRStatus') - return { - state: '1' - } -} - - -export async function createWhitelist(params: {word:string}) { - console.log('fake whitelist',params) - return { - state: '1' - } -} - -export async function proofread(){ - const data:TDocumentContentDetail = { - "abnormalCount": { - "blackWord": 2, - "characterError": 9, - "wordError": 0, - "numberError": 0, - "unitsError": 0, - "punctuationError": 0, - "grammarError": 0, - "knowledgeableError": 0, - "tendentiousError": 0, - "inconsistentError": 0, - "formatError": 0, - "total": 12, - "untreated": 12, - "sensitive": 1 - }, - "correctedSet": [ - - ], - "id": 1326, - "isBlackWord": true, - "isWhiteWord": true, - "name": "失业在家的日子-最新", - "status": 3 - } - await sleep(0.5); - if(Math.random() < 0.2){ - throw new Error('系统错误') - } - return data; -} \ No newline at end of file diff --git a/src/service/fake/doc-2236.ts b/src/service/fake/doc-2236.ts deleted file mode 100644 index 305ea71..0000000 --- a/src/service/fake/doc-2236.ts +++ /dev/null @@ -1,10927 +0,0 @@ -export const otherResult = { - "abnormalCount": { - "blackWord": 0, - "characterError": 15, - "wordError": 0, - "numberError": 0, - "unitsError": 0, - "punctuationError": 0, - "grammarError": 0, - "knowledgeableError": 0, - "tendentiousError": 0, - "inconsistentError": 0, - "formatError": 0, - "total": 15, - "untreated": 15, - "sensitive": 0 - }, - "correctedSet": [ - { - "key": "6a166fdfd391f2ac713479fb88e666bd", - "offset": 0, - "new_text": "《直到春天过去》作者:明前雨后(出版书推荐《忽而今夏》成长版姐妹篇)[完结]", - "diffs": [ - { - "tag": "r", - "origin": " [", - "text": "[", - "start": 35, - "end": 37, - "id": 192941, - "idx": 2, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "]", - "text": "]", - "start": 39, - "end": 40, - "id": 192942, - "idx": 3, - "isAccept": 0, - "type": 2 - } - ], - "insert": "《直到春天过去》作者:明前雨后(出版书推荐 《忽而今夏》成长版姐妹篇) [完结]\n", - "insert_len": 41, - "paragraph_offset": 0, - "sentence_offset": 0, - "paragraph_num": 3 - }, - { - "key": "d7fbeb9640d6f1cce400910dff4a2cc2", - "offset": 41, - "new_text": "13.7月出书版完结", - "insert": "13.7月出书版完结\n", - "insert_len": 11, - "paragraph_offset": 1, - "sentence_offset": 0, - "paragraph_num": 5 - }, - { - "key": "a9eddaeed6745fc8746bc9411de3a4aa", - "offset": 52, - "new_text": "直到春天过去(明前雨后《忽而今夏》成长版姐妹篇!", - "insert": "直到春天过去(明前雨后《忽而今夏》成长版姐妹篇!\n", - "insert_len": 25, - "paragraph_offset": 2, - "sentence_offset": 0, - "paragraph_num": 6 - }, - { - "key": "45964a687ca719641e7a220f94721113", - "offset": 77, - "new_text": "内容推荐", - "insert": "内容推荐\n", - "insert_len": 5, - "paragraph_offset": 3, - "sentence_offset": 0, - "paragraph_num": 8 - }, - { - "key": "a9ecf0ff18ec01ca3c56d73f4ef649bd", - "offset": 82, - "new_text": "这世界上有千千万万的人。", - "insert": "这世界上有千千万万的人。\n", - "insert_len": 13, - "paragraph_offset": 4, - "sentence_offset": 0, - "paragraph_num": 9 - }, - { - "key": "871ec0d6be2515af2799234256914854", - "offset": 95, - "new_text": "你在一生中能遇到的,比仰望夜空时所能看见的星星还多。", - "insert": "你在一生中能遇到的,比仰望夜空时所能看见的星星还多。\n", - "insert_len": 27, - "paragraph_offset": 5, - "sentence_offset": 0, - "paragraph_num": 10 - }, - { - "key": "0248d49bc380b69c7e6f1c0222652859", - "offset": 122, - "new_text": "然而我的星空看不到南十字星座,便不在意它是否存在;正如同我以为再也见不到你,便佯作若无其事,在茫茫人海中继续生活下去。", - "insert": "然而我的星空看不到南十字星座,便不在意它是否存在;正如同我以为再也见不到你,便佯作若无其事,在茫茫人海中继续生活下去。\n", - "insert_len": 60, - "paragraph_offset": 6, - "sentence_offset": 0, - "paragraph_num": 11 - }, - { - "key": "b458d5272fc73ed3e4d4afaad581d62f", - "offset": 182, - "new_text": "在莫靖言最美好的青春时光里,与她相爱的人却飞越重洋,到地球的另一端,到全世界的尽头去。", - "insert": "在莫靖言最美好的青春时光里,与她相爱的人却飞越重洋,到地球的另一端,到全世界的尽头去。", - "insert_len": 43, - "paragraph_offset": 7, - "sentence_offset": 0, - "paragraph_num": 12 - }, - { - "key": "7817adb8c7eaa7bb104bee1c3cfb5d1c", - "offset": 225, - "new_text": "那里和我们的国度颠倒晨昏,对换冬夏。", - "insert": "那里和我们的国度颠倒晨昏,对换冬夏。", - "insert_len": 18, - "paragraph_offset": 7, - "sentence_offset": 43, - "paragraph_num": 12 - }, - { - "key": "79e010302966ee8baaa0ee9ef7431fc5", - "offset": 243, - "new_text": "他们的世界就此分为两半,划分的标准不是时间或距离,而是“有你”和“没有你”。", - "insert": "他们的世界就此分为两半,划分的标准不是时间或距离,而是“有你”和“没有你”。", - "insert_len": 38, - "paragraph_offset": 7, - "sentence_offset": 61, - "paragraph_num": 12 - }, - { - "key": "8da46631d074b4e65bdcfd6ba0510267", - "offset": 281, - "new_text": "这两部分泾渭分明,参商相隔。", - "insert": "这两部分泾渭分明,参商相隔。\n", - "insert_len": 15, - "paragraph_offset": 7, - "sentence_offset": 99, - "paragraph_num": 12 - }, - { - "key": "9c5cfa999098c8db3eed6163ca935ec5", - "offset": 296, - "new_text": "当年无法预期,在无尽的人生长途中,将于何时何地再次相逢。", - "insert": "当年无法预期,在无尽的人生长途中,将于何时何地再次相逢。\n", - "insert_len": 29, - "paragraph_offset": 8, - "sentence_offset": 0, - "paragraph_num": 13 - }, - { - "key": "a9e215cee8278260f491eca5429d1e40", - "offset": 325, - "new_text": "所谓看透、看穿、各自幸福的人,有多少,是因为已经再也没有破镜重圆的机会?", - "insert": "所谓看透、看穿、各自幸福的人,有多少,是因为已经再也没有破镜重圆的机会?\n", - "insert_len": 37, - "paragraph_offset": 9, - "sentence_offset": 0, - "paragraph_num": 14 - }, - { - "key": "a8751eefeab664fcebdd2db1db14327c", - "offset": 363, - "new_text": "如果把所有的晦涩还给冬夜,把所有的笑容还给春风,把所有的梦想还给无知且无虑的岁月,那下一刻,你是否能够回到我身边,陪我看繁华落尽,直到春天过去……", - "insert": "如果把所有的晦涩还给冬夜,把所有的笑容还给春风,把所有的梦想还给无知且无虑的岁月,那下一刻,你是否能够回到我身边,陪我看繁华落尽,直到春天过去……\n", - "insert_len": 74, - "paragraph_offset": 10, - "sentence_offset": 0, - "paragraph_num": 15 - }, - { - "key": "8ea551f0e4a607b176beba846fb89fa4", - "offset": 437, - "new_text": "且将回忆中最美好的段落,送给当年懵懂的少年、此后历经沧桑的我们,以及少年时见过听过的种种爱情。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 21, - "end": 22, - "id": 192943, - "idx": 4, - "isAccept": 0, - "type": 2 - } - ], - "insert": "且将回忆中最美好的段落,送给当年懵懂的少年,此后历经沧桑的我们,以及少年时见过听过的种种爱情。\n", - "insert_len": 48, - "paragraph_offset": 11, - "sentence_offset": 0, - "paragraph_num": 16 - }, - { - "key": "295472c64f36650f987f961ef93ef5d8", - "offset": 485, - "new_text": "编辑推荐", - "insert": "编辑推荐\n", - "insert_len": 5, - "paragraph_offset": 12, - "sentence_offset": 0, - "paragraph_num": 18 - }, - { - "key": "583c6ed8d30aae7e825ffe5db4234f56", - "offset": 490, - "new_text": "★《忽而今夏》唯一姊妹篇,畅销青春言情作家明前雨后继《忽而今夏》之后再续唯美青春【时光话本】。", - "insert": "★《忽而今夏》唯一姊妹篇,畅销青春言情作家明前雨后继《忽而今夏》之后再续唯美青春【时光话本】。\n", - "insert_len": 48, - "paragraph_offset": 13, - "sentence_offset": 0, - "paragraph_num": 19 - }, - { - "key": "4dea4c0f89e1318f1f71c24d2149f088", - "offset": 538, - "new_text": "★每个人的青春里,都应该有一场奋不顾身,以此铭记那个刻在生命里的男孩。", - "insert": "★每个人的青春里,都应该有一场奋不顾身,以此铭记那个刻在生命里的男孩。", - "insert_len": 35, - "paragraph_offset": 14, - "sentence_offset": 0, - "paragraph_num": 20 - }, - { - "key": "2454f934df732567e04b9e2cc0cc1008", - "offset": 573, - "new_text": "比“致青春”更清澈细腻感人的“怀旧青春,回忆之恋”。", - "insert": "比“致青春”更清澈细腻感人的“怀旧青春,回忆之恋”。", - "insert_len": 26, - "paragraph_offset": 14, - "sentence_offset": 35, - "paragraph_num": 20 - }, - { - "key": "81197c2d02b3a7c54cbd498ce55a73c8", - "offset": 599, - "new_text": "。", - "insert": "。\n", - "insert_len": 2, - "paragraph_offset": 14, - "sentence_offset": 61, - "paragraph_num": 20 - }, - { - "key": "c1c18c79abf14cf4d7889748c8780ad9", - "offset": 601, - "new_text": "★言情届大神作家缪娟、施定柔扛鼎真诚推荐。", - "insert": "★言情届大神作家缪娟、施定柔扛鼎真诚推荐。", - "insert_len": 21, - "paragraph_offset": 15, - "sentence_offset": 0, - "paragraph_num": 21 - }, - { - "key": "7d12d550e2e7c5e15b61303394129f4e", - "offset": 622, - "new_text": "此书是你绝对不能错过的大神级作品!", - "insert": "此书是你绝对不能错过的大神级作品!\n", - "insert_len": 18, - "paragraph_offset": 15, - "sentence_offset": 21, - "paragraph_num": 21 - }, - { - "key": "fbd4f11760cb48a9d7f459ec5569240d", - "offset": 640, - "new_text": "★超丰富内容+引人入胜的情节+经典语录+作者肺腑后记,你值得拥有!", - "diffs": [ - { - "tag": "d", - "origin": "回味", - "text": "", - "start": 17, - "end": 19, - "id": 192944, - "idx": 5, - "isAccept": 0, - "type": 2 - } - ], - "insert": "★超丰富内容+引人入胜的情节+经典回味语录+作者肺腑后记,你值得拥有!", - "insert_len": 35, - "paragraph_offset": 16, - "sentence_offset": 0, - "paragraph_num": 22 - }, - { - "key": "b64207ffbb4a52afaa45f7f9e6ca2517", - "offset": 675, - "new_text": "甜蜜/安静/泪水/微笑/留恋/回忆……", - "insert": "甜蜜/安静/泪水/微笑/留恋/回忆……", - "insert_len": 19, - "paragraph_offset": 16, - "sentence_offset": 35, - "paragraph_num": 22 - }, - { - "key": "94e006e90ca21b5dff9bdccecf158ebe", - "offset": 694, - "new_text": "都是青春沿途的好风景。", - "insert": "都是青春沿途的好风景。", - "insert_len": 11, - "paragraph_offset": 16, - "sentence_offset": 54, - "paragraph_num": 22 - }, - { - "key": "b1ccef5936f11cc86927f5a9ae765d68", - "offset": 705, - "new_text": "★明前雨后畅销大作《眼泪的上游:全新珍藏版》震撼上市!", - "insert": "★明前雨后畅销大作《眼泪的上游:全新珍藏版》震撼上市!", - "insert_len": 27, - "paragraph_offset": 16, - "sentence_offset": 65, - "paragraph_num": 22 - }, - { - "key": "4f5525d144c6919077d9a1775b9e8ff9", - "offset": 733, - "new_text": "亲笔修订未删节,白金珍藏!", - "insert": "亲笔修订未删节,白金珍藏!", - "insert_len": 13, - "paragraph_offset": 16, - "sentence_offset": 92, - "paragraph_num": 22 - }, - { - "key": "b7d282250bed4f9070e424bedda234c6", - "offset": 746, - "new_text": "超值奉送时光卡贴+全新后记,万人牵挂夏小橘“并非结局的结局”!", - "insert": "超值奉送时光卡贴+全新后记,万人牵挂夏小橘“并非结局的结局”!\n", - "insert_len": 32, - "paragraph_offset": 16, - "sentence_offset": 105, - "paragraph_num": 22 - }, - { - "key": "9fc022d55ee7212085baf670b37f6687", - "offset": 778, - "new_text": "【正文】", - "insert": "【正文】\n", - "insert_len": 5, - "paragraph_offset": 17, - "sentence_offset": 0, - "paragraph_num": 27 - }, - { - "key": "9766f32ba20ae74426bf4a239a47ddf9", - "offset": 787, - "new_text": "直到春天过去。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "。", - "start": 6, - "end": 6, - "id": 192945, - "idx": 6, - "isAccept": 0, - "type": 2 - } - ], - "insert": "直到春天过去\n", - "insert_len": 7, - "paragraph_offset": 18, - "sentence_offset": 0, - "paragraph_num": 28 - }, - { - "key": "ffb9efc7054103223bad1cf7b8952dbe", - "offset": 798, - "new_text": "作者:明前雨后", - "insert": "作者:明前雨后\n", - "insert_len": 8, - "paragraph_offset": 19, - "sentence_offset": 0, - "paragraph_num": 29 - }, - { - "key": "7ac42f43bf484a34e688f7959b3a12cd", - "offset": 810, - "new_text": "楔子", - "insert": "楔子\n", - "insert_len": 3, - "paragraph_offset": 20, - "sentence_offset": 0, - "paragraph_num": 30 - }, - { - "key": "de6c9bc11cdb28735af84c601296ddb4", - "offset": 817, - "new_text": "Quién escribe tu nombre con letras de humo entre las estrellas del sur?", - "insert": "Quién escribe tu nombre con letras de humo entre las estrellas del sur?\n", - "insert_len": 72, - "paragraph_offset": 21, - "sentence_offset": 0, - "paragraph_num": 31 - }, - { - "key": "fb24b8bd7f67e041183096c74e3548d4", - "offset": 893, - "new_text": "“谁在南方群星之间,用烟写你的名字。”", - "insert": "“谁在南方群星之间,用烟写你的名字。”", - "insert_len": 19, - "paragraph_offset": 22, - "sentence_offset": 0, - "paragraph_num": 32 - }, - { - "key": "85ec1d9281ef8bf627e6e154896fec17", - "offset": 916, - "new_text": "——聂鲁达", - "insert": "——聂鲁达\n", - "insert_len": 6, - "paragraph_offset": 22, - "sentence_offset": 19, - "paragraph_num": 32 - }, - { - "key": "3417434a83d49185706958cf811b93e3", - "offset": 922, - "new_text": "这里的一月是一年中的炎夏。", - "insert": "这里的一月是一年中的炎夏。", - "insert_len": 13, - "paragraph_offset": 23, - "sentence_offset": 0, - "paragraph_num": 33 - }, - { - "key": "7081ac3bea2bad08bf6f6eb85e336f92", - "offset": 939, - "new_text": "满城繁花似锦,绿树千重。", - "insert": "满城繁花似锦,绿树千重。", - "insert_len": 12, - "paragraph_offset": 23, - "sentence_offset": 13, - "paragraph_num": 33 - }, - { - "key": "1667f8de548b9294ac38b8e837d36ed3", - "offset": 951, - "new_text": "蔚蓝的大西洋和起伏的山岭交织出蜿蜒的海岸线,金色的沙滩和秀丽的山丘星罗棋布。", - "insert": "蔚蓝的大西洋和起伏的山岭交织出蜿蜒的海岸线,金色的沙滩和秀丽的山丘星罗棋布。\n", - "insert_len": 39, - "paragraph_offset": 23, - "sentence_offset": 25, - "paragraph_num": 33 - }, - { - "key": "d1d0ab29a6544f46a3075dd4778a160f", - "offset": 990, - "new_text": "三角滑翔翼掠过南半球晴澈的天空,飞越波光粼粼的水面,盘旋在青翠的丘陵之间。", - "insert": "三角滑翔翼掠过南半球晴澈的天空,飞越波光粼粼的水面,盘旋在青翠的丘陵之间。", - "insert_len": 37, - "paragraph_offset": 24, - "sentence_offset": 0, - "paragraph_num": 34 - }, - { - "key": "6241bcc357ddc285fb5a792351c319ad", - "offset": 1031, - "new_text": "巨大的救世基督像屹立在科克瓦多山颠,张开双臂,悲悯地俯瞰着这座充满激情与活力的城市——里约热内卢。", - "insert": "巨大的救世基督像屹立在科克瓦多山颠,张开双臂,悲悯地俯瞰着这座充满激情与活力的城市——里约热内卢。\n", - "insert_len": 50, - "paragraph_offset": 24, - "sentence_offset": 37, - "paragraph_num": 34 - }, - { - "key": "c84f677a1da853885e89f350a9fd7d05", - "offset": 1081, - "new_text": "两个年轻人驾车穿过市区,斑驳的树影划过车窗,音响里醇和的女声慵懒地唱着巴莎诺瓦。", - "insert": "两个年轻人驾车穿过市区,斑驳的树影划过车窗,音响里醇和的女声慵懒地唱着巴莎诺瓦。", - "insert_len": 40, - "paragraph_offset": 25, - "sentence_offset": 0, - "paragraph_num": 35 - }, - { - "key": "393690d8f22fa0fc0f401ff83f9d1c67", - "offset": 1125, - "new_text": "车子驶过科帕卡巴纳海滩,来自世界各地的游人、活力性感的比基尼女郎、兜售五彩游泳圈的小贩、举着冲浪板奔向大海的少年,每一日生活都在此上演着最热烈的华彩。", - "insert": "车子驶过科帕卡巴纳海滩,来自世界各地的游人、活力性感的比基尼女郎、兜售五彩游泳圈的小贩、举着冲浪板奔向大海的少年,每一日生活都在此上演着最热烈的华彩。\n", - "insert_len": 76, - "paragraph_offset": 25, - "sentence_offset": 40, - "paragraph_num": 35 - }, - { - "key": "826dd68b8c60ae3e1886c74c93a9d1c2", - "offset": 1201, - "new_text": "马洛斯摇下车窗,大声夸赞路边身材惹火的姑娘,换回对方一个飞吻。", - "insert": "马洛斯摇下车窗,大声夸赞路边身材惹火的姑娘,换回对方一个飞吻。", - "insert_len": 31, - "paragraph_offset": 26, - "sentence_offset": 0, - "paragraph_num": 36 - }, - { - "key": "56cc71541199ce2268603d5c965a101a", - "offset": 1236, - "new_text": "他兴奋地拍着同伴:“我真是太爱这个城市了,从矿山回到里约真好,你说是不是,伊戈尔?”", - "insert": "他兴奋地拍着同伴:“我真是太爱这个城市了,从矿山回到里约真好,你说是不是,伊戈尔?”\n", - "insert_len": 43, - "paragraph_offset": 26, - "sentence_offset": 31, - "paragraph_num": 36 - }, - { - "key": "0286c7e4070c5079f2296a9306dc4718", - "offset": 1279, - "new_text": "伊戈尔有一张这座城市中少见的东方面孔,已经被灼热的阳光镀上了最流行的古铜色,未曾细心打理的头发倔强地支着,下巴上覆着一层青黑的胡茬。", - "insert": "伊戈尔有一张这座城市中少见的东方面孔,已经被灼热的阳光镀上了最流行的古铜色,未曾细心打理的头发倔强地支着,下巴上覆着一层青黑的胡茬。", - "insert_len": 66, - "paragraph_offset": 27, - "sentence_offset": 0, - "paragraph_num": 37 - }, - { - "key": "c62e6f4dcd203ce04becec2ac7e3f063", - "offset": 1349, - "new_text": "他一路上沉默着,此时“嗯”了一声,算是回答。", - "insert": "他一路上沉默着,此时“嗯”了一声,算是回答。\n", - "insert_len": 23, - "paragraph_offset": 27, - "sentence_offset": 66, - "paragraph_num": 37 - }, - { - "key": "ec66b6989cc69f09b5f743ba72bc7014", - "offset": 1372, - "new_text": "说话间马洛斯随手换了一张唱碟,热情洋溢的桑巴舞曲响起,他加大油门,汽车轰鸣着加速向前。", - "insert": "说话间马洛斯随手换了一张唱碟,热情洋溢的桑巴舞曲响起,他加大油门,汽车轰鸣着加速向前。\n", - "insert_len": 44, - "paragraph_offset": 28, - "sentence_offset": 0, - "paragraph_num": 38 - }, - { - "key": "0150c5ca8f9562b59489030a5e7256fd", - "offset": 1420, - "new_text": "他们将车停在科克瓦多山脚下,拿出后备厢的装备,沿着小径向半山腰走去,沿路穿过茂密的森林,参天乔木间透出一束束阳光,濡湿的空气中充满着泥土和落叶混合的气息。", - "diffs": [ - { - "tag": "r", - "origin": "箱", - "text": "厢", - "start": 18, - "end": 19, - "id": 192946, - "idx": 7, - "isAccept": 0, - "type": 2 - } - ], - "insert": "他们将车停在科克瓦多山脚下,拿出后备箱的装备,沿着小径向半山腰走去,沿路穿过茂密的森林,参天乔木间透出一束束阳光,濡湿的空气中充满着泥土和落叶混合的气息。", - "insert_len": 77, - "paragraph_offset": 29, - "sentence_offset": 0, - "paragraph_num": 39 - }, - { - "key": "6cf789daa885311c52d0e06a64b0a302", - "offset": 1501, - "new_text": "两人很快到达了大岩壁的起点,将装备一一整理穿戴好,安全带、攀岩鞋、头盔、粉袋、动力绳、快挂……", - "insert": "两人很快到达了大岩壁的起点,将装备一一整理穿戴好,安全带、攀岩鞋、头盔、粉袋、动力绳、快挂……", - "insert_len": 47, - "paragraph_offset": 29, - "sentence_offset": 77, - "paragraph_num": 39 - }, - { - "key": "63e97bf3980baed9189d766e677da668", - "offset": 1548, - "new_text": "两人准备妥当,击掌后相视一笑,便一前一后结组向山顶爬去。", - "insert": "两人准备妥当,击掌后相视一笑,便一前一后结组向山顶爬去。\n", - "insert_len": 29, - "paragraph_offset": 29, - "sentence_offset": 124, - "paragraph_num": 39 - }, - { - "key": "f0c868c187ea6667aed6f703f3f23891", - "offset": 1577, - "new_text": "科克瓦多山终年游人如织,大多坐着汽车、小火车来到半山,再搭乘观光梯来到基督像脚下。", - "insert": "科克瓦多山终年游人如织,大多坐着汽车、小火车来到半山,再搭乘观光梯来到基督像脚下。", - "insert_len": 41, - "paragraph_offset": 30, - "sentence_offset": 0, - "paragraph_num": 40 - }, - { - "key": "0d3cb52f4dd3916ada0b0da897fe46ff", - "offset": 1622, - "new_text": "他们接踵摩肩,在台阶和平台上寻找着最佳角度,兴奋地平伸双臂,模仿基督像的造型拍照留念。", - "insert": "他们接踵摩肩,在台阶和平台上寻找着最佳角度,兴奋地平伸双臂,模仿基督像的造型拍照留念。\n", - "insert_len": 44, - "paragraph_offset": 30, - "sentence_offset": 41, - "paragraph_num": 40 - }, - { - "key": "7e2e57d62294de7a11db9d6cda7e08af", - "offset": 1666, - "new_text": "就在山侧的岩壁上,马洛斯和伊戈尔暴露在烈日下,紧绷的双臂肌理流畅,T恤衫被汗水沁透。", - "insert": "就在山侧的岩壁上,马洛斯和伊戈尔暴露在烈日下,紧绷的双臂肌理流畅,T恤衫被汗水沁透。", - "insert_len": 42, - "paragraph_offset": 31, - "sentence_offset": 0, - "paragraph_num": 41 - }, - { - "key": "d3e0c385376ec53870ac94f4a827971f", - "offset": 1712, - "new_text": "两个年轻人凝神上攀,专注地寻找着岩石上每一处适宜的凸起和裂缝,敏捷而沉稳地转身腾挪。", - "insert": "两个年轻人凝神上攀,专注地寻找着岩石上每一处适宜的凸起和裂缝,敏捷而沉稳地转身腾挪。", - "insert_len": 42, - "paragraph_offset": 31, - "sentence_offset": 42, - "paragraph_num": 41 - }, - { - "key": "dbf26fb8a90a7a90898f912abeccc948", - "offset": 1754, - "new_text": "在他们身后,里约的高楼和街景缩小得像沙盘一样,山丘涌向碧海,天空湛蓝遥远。", - "insert": "在他们身后,里约的高楼和街景缩小得像沙盘一样,山丘涌向碧海,天空湛蓝遥远。\n", - "insert_len": 38, - "paragraph_offset": 31, - "sentence_offset": 84, - "paragraph_num": 41 - }, - { - "key": "f180e2edf207716c079104e73407b280", - "offset": 1792, - "new_text": "伊戈尔更喜欢领攀的感觉,尤其是在翻越难点时,人很容易进入一种忘我的状态。", - "insert": "伊戈尔更喜欢领攀的感觉,尤其是在翻越难点时,人很容易进入一种忘我的状态。", - "insert_len": 36, - "paragraph_offset": 32, - "sentence_offset": 0, - "paragraph_num": 42 - }, - { - "key": "537a2fd83391575864cf4cebe91787d1", - "offset": 1832, - "new_text": "眼前和心中只有岩壁,他要克服它,但又不是征服和对抗。", - "insert": "眼前和心中只有岩壁,他要克服它,但又不是征服和对抗。", - "insert_len": 26, - "paragraph_offset": 32, - "sentence_offset": 36, - "paragraph_num": 42 - }, - { - "key": "5a78f2b8bcf6aa126acb98d2d23d8deb", - "offset": 1858, - "new_text": "在更多时候,他和它在这一段时空内是交融的,他将自己交付给山石,平衡着体态和力量,在竖直的峭壁上舞蹈。", - "insert": "在更多时候,他和它在这一段时空内是交融的,他将自己交付给山石,平衡着体态和力量,在竖直的峭壁上舞蹈。", - "insert_len": 50, - "paragraph_offset": 32, - "sentence_offset": 62, - "paragraph_num": 42 - }, - { - "key": "c869a48c1b6e4803edd3120af07b61e0", - "offset": 1908, - "new_text": "只有在这一刻,他才能真正心无旁骛,在一种空灵的状态中找到内心的平静。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "才", - "start": 8, - "end": 8, - "id": 192947, - "idx": 8, - "isAccept": 0, - "type": 2 - } - ], - "insert": "只有在这一刻,他能真正心无旁骛,在一种空灵的状态中找到内心的平静。\n", - "insert_len": 34, - "paragraph_offset": 32, - "sentence_offset": 112, - "paragraph_num": 42 - }, - { - "key": "263c7240f119f7387be76dea1dc0d423", - "offset": 1942, - "new_text": "山顶众多游客中,两个日裔姑娘开心地笑闹着。", - "insert": "山顶众多游客中,两个日裔姑娘开心地笑闹着。\n", - "insert_len": 22, - "paragraph_offset": 33, - "sentence_offset": 0, - "paragraph_num": 43 - }, - { - "key": "15966034a6ced0f577d76650b8eed827", - "offset": 1968, - "new_text": "穿着红色露肩裙的女孩跑到平台边,背倚栏杆,大声呼喊同伴在人潮空当给自己拍一张照片。", - "insert": "穿着红色露肩裙的女孩跑到平台边,背倚栏杆,大声呼喊同伴在人潮空当给自己拍一张照片。", - "insert_len": 41, - "paragraph_offset": 34, - "sentence_offset": 0, - "paragraph_num": 44 - }, - { - "key": "eadf9b681b1f3b4bbef95272f7c3c829", - "offset": 2013, - "new_text": "她摆好pose,灿烂地笑着,忽然听到同伴惊讶地“啊”了一声,随即有人贴在脸侧,耳边一个陌生的男声响起:“Cheese!”", - "insert": "她摆好pose,灿烂地笑着,忽然听到同伴惊讶地“啊”了一声,随即有人贴在脸侧,耳边一个陌生的男声响起:“Cheese!”\n", - "insert_len": 61, - "paragraph_offset": 34, - "sentence_offset": 41, - "paragraph_num": 44 - }, - { - "key": "8229c9b80c7ac3215d448132f514797d", - "offset": 2074, - "new_text": "女孩惊得后退了一步,只见身材高大的卷发男子从栏杆后探身,咧着嘴做了一个“V”字手势。", - "insert": "女孩惊得后退了一步,只见身材高大的卷发男子从栏杆后探身,咧着嘴做了一个“V”字手势。", - "insert_len": 42, - "paragraph_offset": 35, - "sentence_offset": 0, - "paragraph_num": 45 - }, - { - "key": "ef91ceef229c2ffd7945d9ae810318b8", - "offset": 2120, - "new_text": "他戴着头盔,汗湿的T恤上沾了泥土,腰间安全带上一串快挂叮当作响。", - "insert": "他戴着头盔,汗湿的T恤上沾了泥土,腰间安全带上一串快挂叮当作响。\n", - "insert_len": 33, - "paragraph_offset": 35, - "sentence_offset": 42, - "paragraph_num": 45 - }, - { - "key": "e898ab96674940304c8cb11acc2db7d5", - "offset": 2153, - "new_text": "“Welcome to Brazil!”", - "insert": "“Welcome to Brazil!”", - "insert_len": 20, - "paragraph_offset": 36, - "sentence_offset": 0, - "paragraph_num": 46 - }, - { - "key": "00f8317f60917a051f8e709b7eec226f", - "offset": 2177, - "new_text": "马洛斯大笑,伸开双臂。", - "insert": "马洛斯大笑,伸开双臂。\n", - "insert_len": 12, - "paragraph_offset": 36, - "sentence_offset": 20, - "paragraph_num": 46 - }, - { - "key": "fa842e9616f6344d9198ba7b4f3ba399", - "offset": 2189, - "new_text": "两个女孩对望一眼,笑得捧腹,用葡萄牙语回应:“我们就是巴西人,从圣保罗来。”", - "insert": "两个女孩对望一眼,笑得捧腹,用葡萄牙语回应:“我们就是巴西人,从圣保罗来。”\n", - "insert_len": 39, - "paragraph_offset": 37, - "sentence_offset": 0, - "paragraph_num": 47 - }, - { - "key": "a52fde62b271a5a579c5a3da96a3c212", - "offset": 2232, - "new_text": "“你怎么上来的,是从峭壁爬上来的吗?”", - "insert": "“你怎么上来的,是从峭壁爬上来的吗?”", - "insert_len": 19, - "paragraph_offset": 38, - "sentence_offset": 0, - "paragraph_num": 48 - }, - { - "key": "2568805872f3151f55c7ed3069caa57c", - "offset": 2255, - "new_text": "红衣姑娘惊讶,扶着栏杆俯身向下看。", - "insert": "红衣姑娘惊讶,扶着栏杆俯身向下看。", - "insert_len": 17, - "paragraph_offset": 38, - "sentence_offset": 19, - "paragraph_num": 48 - }, - { - "key": "e0f137bfa405ee271c68413d92cac7bf", - "offset": 2272, - "new_text": "在她探身的一瞬,正对上一双抬望的眼睛。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "睛", - "start": 17, - "end": 17, - "id": 192948, - "idx": 9, - "isAccept": 0, - "type": 2 - } - ], - "insert": "在她探身的一瞬,正对上一双抬望的眼。\n", - "insert_len": 19, - "paragraph_offset": 38, - "sentence_offset": 36, - "paragraph_num": 48 - }, - { - "key": "46e6f9f64da5cefb60fb4bde6caa43c4", - "offset": 2291, - "new_text": "她感到自己微卷的长发,几乎已经拂到对方的面颊上了。", - "insert": "她感到自己微卷的长发,几乎已经拂到对方的面颊上了。\n", - "insert_len": 26, - "paragraph_offset": 39, - "sentence_offset": 0, - "paragraph_num": 49 - }, - { - "key": "bc8726381a7ac733bc5a2ca64f2284d7", - "offset": 2321, - "new_text": "因为距离太近,反而看不清他的长相,只是瞬间陷入深邃的眼眸中,心倏然间有沉坠的失重感。", - "diffs": [ - { - "tag": "d", - "origin": "到", - "text": "", - "start": 23, - "end": 24, - "id": 192949, - "idx": 10, - "isAccept": 0, - "type": 2 - } - ], - "insert": "因为距离太近,反而看不清他的长相,只是瞬间陷入到深邃的眼眸中,心倏然间有沉坠的失重感。\n", - "insert_len": 44, - "paragraph_offset": 40, - "sentence_offset": 0, - "paragraph_num": 50 - }, - { - "key": "2a952f069673def0852d3ba13f72901c", - "offset": 2369, - "new_text": "“对不起。”", - "insert": "“对不起。”", - "insert_len": 6, - "paragraph_offset": 41, - "sentence_offset": 0, - "paragraph_num": 51 - }, - { - "key": "0837b3f008af05eb8c4df26e350c0181", - "offset": 2379, - "new_text": "她退后两步,用日语喃喃说道。", - "insert": "她退后两步,用日语喃喃说道。\n", - "insert_len": 15, - "paragraph_offset": 41, - "sentence_offset": 6, - "paragraph_num": 51 - }, - { - "key": "db0a99dfa791b02188bbd088f8bd8209", - "offset": 2394, - "new_text": "伊戈尔将一捆动力绳背在身后,默然地翻过围栏。", - "insert": "伊戈尔将一捆动力绳背在身后,默然地翻过围栏。\n", - "insert_len": 23, - "paragraph_offset": 42, - "sentence_offset": 0, - "paragraph_num": 52 - }, - { - "key": "6f04781c88cadb0f5198c791c3a5a2c9", - "offset": 2421, - "new_text": "马洛斯拍着他的肩膀大笑:“这位老兄多数时候是静音状态,也有可能是他忘了怎么和漂亮的女士们打招呼。”", - "insert": "马洛斯拍着他的肩膀大笑:“这位老兄多数时候是静音状态,也有可能是他忘了怎么和漂亮的女士们打招呼。”\n", - "insert_len": 50, - "paragraph_offset": 43, - "sentence_offset": 0, - "paragraph_num": 53 - }, - { - "key": "b8b75276e6fe80d8db5833c2d559d098", - "offset": 2475, - "new_text": "伊戈尔微微一笑,在平台上收整装备。", - "insert": "伊戈尔微微一笑,在平台上收整装备。", - "insert_len": 17, - "paragraph_offset": 44, - "sentence_offset": 0, - "paragraph_num": 54 - }, - { - "key": "c1a60e9568016fd9b5f4ba643ce8e664", - "offset": 2496, - "new_text": "女孩感到新奇,指指点点叽叽喳喳提着问题。", - "insert": "女孩感到新奇,指指点点叽叽喳喳提着问题。", - "insert_len": 20, - "paragraph_offset": 44, - "sentence_offset": 17, - "paragraph_num": 54 - }, - { - "key": "b6e72c6b461834d91dae746e6e72f1c2", - "offset": 2516, - "new_text": "马洛斯耐心作答,还留下联系方式,邀请她们有空时参加攀岩俱乐部的聚会。", - "insert": "马洛斯耐心作答,还留下联系方式,邀请她们有空时参加攀岩俱乐部的聚会。\n", - "insert_len": 35, - "paragraph_offset": 44, - "sentence_offset": 37, - "paragraph_num": 54 - }, - { - "key": "602077b3a9c3224598a7f72acf9e77ff", - "offset": 2551, - "new_text": "“你也是日裔么?”", - "insert": "“你也是日裔么?”", - "insert_len": 9, - "paragraph_offset": 45, - "sentence_offset": 0, - "paragraph_num": 55 - }, - { - "key": "1255fc888509ae9d49aba7bcc3e9c9f8", - "offset": 2564, - "new_text": "红衣女孩扶着膝盖,俯身问道。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "盖", - "start": 7, - "end": 7, - "id": 192950, - "idx": 11, - "isAccept": 0, - "type": 2 - } - ], - "insert": "红衣女孩扶着膝,俯身问道。\n", - "insert_len": 14, - "paragraph_offset": 45, - "sentence_offset": 9, - "paragraph_num": 55 - }, - { - "key": "76e1b1834ec74182254ba9f216194140", - "offset": 2578, - "new_text": "“不,我是中国人。”", - "insert": "“不,我是中国人。”\n", - "insert_len": 11, - "paragraph_offset": 46, - "sentence_offset": 0, - "paragraph_num": 56 - }, - { - "key": "7ff92f27effe44f7963d65cc857734b7", - "offset": 2593, - "new_text": "“你长得有些像竹野内丰呢。”", - "insert": "“你长得有些像竹野内丰呢。”", - "insert_len": 14, - "paragraph_offset": 47, - "sentence_offset": 0, - "paragraph_num": 57 - }, - { - "key": "a87d986c78bf87089c11266e8be1ef4c", - "offset": 2611, - "new_text": "她眉眼弯弯地笑着。", - "insert": "她眉眼弯弯地笑着。\n", - "insert_len": 10, - "paragraph_offset": 47, - "sentence_offset": 14, - "paragraph_num": 57 - }, - { - "key": "30434b6405973f37a3af9834d367616a", - "offset": 2621, - "new_text": "伊戈尔听不懂日文人名,也不追问。", - "insert": "伊戈尔听不懂日文人名,也不追问。", - "insert_len": 16, - "paragraph_offset": 48, - "sentence_offset": 0, - "paragraph_num": 58 - }, - { - "key": "1468317803a2c8eee150ef0f69e3876e", - "offset": 2641, - "new_text": "他将理好的装备背在身后,扬手道:“祝你旅途愉快。Ciao。”", - "insert": "他将理好的装备背在身后,扬手道:“祝你旅途愉快。Ciao。”\n", - "insert_len": 31, - "paragraph_offset": 48, - "sentence_offset": 16, - "paragraph_num": 58 - }, - { - "key": "078c984fbe1a678fe9d03323e6523676", - "offset": 2672, - "new_text": "“那个,你叫什么名字?”", - "insert": "“那个,你叫什么名字?”", - "insert_len": 12, - "paragraph_offset": 49, - "sentence_offset": 0, - "paragraph_num": 59 - }, - { - "key": "f73953370e51a86e71b6a23194a89597", - "offset": 2688, - "new_text": "她轻快地追上,“我叫Asuka。”", - "insert": "她轻快地追上,“我叫Asuka。”\n", - "insert_len": 18, - "paragraph_offset": 49, - "sentence_offset": 12, - "paragraph_num": 59 - }, - { - "key": "493fa4613d53aec3bf251f16ecd875e4", - "offset": 2706, - "new_text": "Asuka Shimizu,清水明日香,二十二岁,有四分之一拉丁血统,即将大学毕业。", - "insert": "Asuka Shimizu,清水明日香,二十二岁,有四分之一拉丁血统,即将大学毕业。", - "insert_len": 42, - "paragraph_offset": 50, - "sentence_offset": 0, - "paragraph_num": 60 - }, - { - "key": "e30fd45f5794f1693156361c09e0dc75", - "offset": 2752, - "new_text": "为达成幼年时参加嘉年华游行的心愿,她来到里约参加一所桑巴学校的排练。", - "insert": "为达成幼年时参加嘉年华游行的心愿,她来到里约参加一所桑巴学校的排练。", - "insert_len": 34, - "paragraph_offset": 50, - "sentence_offset": 42, - "paragraph_num": 60 - }, - { - "key": "48e73374af9dcc167c775f6b77addeac", - "offset": 2786, - "new_text": "最大的梦想是环游世界,体验各地不同的生活。", - "insert": "最大的梦想是环游世界,体验各地不同的生活。\n", - "insert_len": 22, - "paragraph_offset": 50, - "sentence_offset": 76, - "paragraph_num": 60 - }, - { - "key": "485f9110948dfdd3f4f14c9843bd5590", - "offset": 2808, - "new_text": "大部分桑巴学校都有自己固定的成员,每年只招收极少的外来学员,收取费用以贴补开支。", - "insert": "大部分桑巴学校都有自己固定的成员,每年只招收极少的外来学员,收取费用以贴补开支。", - "insert_len": 40, - "paragraph_offset": 51, - "sentence_offset": 0, - "paragraph_num": 61 - }, - { - "key": "9ed445dc184875cc29d84cb987c54192", - "offset": 2852, - "new_text": "明日香要在短短两个月内融入这个集体中,她每天听着游行要用的主题曲,要让每一个细胞都和其中的节奏共鸣。", - "diffs": [ - { - "tag": "d", - "origin": "到", - "text": "", - "start": 13, - "end": 14, - "id": 192951, - "idx": 12, - "isAccept": 0, - "type": 2 - } - ], - "insert": "明日香要在短短两个月内融入到这个集体中,她每天听着游行要用的主题曲,要让每一个细胞都和其中的节奏共鸣。\n", - "insert_len": 52, - "paragraph_offset": 51, - "sentence_offset": 40, - "paragraph_num": 61 - }, - { - "key": "4d92f4e954ad04b8d4ef30467cf14f6c", - "offset": 2904, - "new_text": "而现在,那些奔放热烈的音符、飞旋跳动的舞步,因为她激动而愉悦的心情变得更加鲜活。", - "insert": "而现在,那些奔放热烈的音符、飞旋跳动的舞步,因为她激动而愉悦的心情变得更加鲜活。\n", - "insert_len": 41, - "paragraph_offset": 52, - "sentence_offset": 0, - "paragraph_num": 62 - }, - { - "key": "e0af49aff10ce6c6754ff76f4830ee7a", - "offset": 2949, - "new_text": "嘉年华的演出服上缀满了羽毛和亮片,她在千万人狂欢的海洋中像一朵小小的浪花。", - "insert": "嘉年华的演出服上缀满了羽毛和亮片,她在千万人狂欢的海洋中像一朵小小的浪花。", - "insert_len": 37, - "paragraph_offset": 53, - "sentence_offset": 0, - "paragraph_num": 63 - }, - { - "key": "f82d0541b830d1dfa790278a9990ab1b", - "offset": 2990, - "new_text": "走出赛场,一颗心似乎还跟着鼓点剧烈地跳动着。", - "insert": "走出赛场,一颗心似乎还跟着鼓点剧烈地跳动着。", - "insert_len": 22, - "paragraph_offset": 53, - "sentence_offset": 37, - "paragraph_num": 63 - }, - { - "key": "3d35995b66edc577782815bedd78e215", - "offset": 3012, - "new_text": "明日香将高跟鞋拎在手中,一路跑到攀岩俱乐部平素聚会的酒吧里,引来朋友们连连的口哨声。", - "insert": "明日香将高跟鞋拎在手中,一路跑到攀岩俱乐部平素聚会的酒吧里,引来朋友们连连的口哨声。\n", - "insert_len": 43, - "paragraph_offset": 53, - "sentence_offset": 59, - "paragraph_num": 63 - }, - { - "key": "ffce34d2f16a5703838dccbb537a26cf", - "offset": 3055, - "new_text": "她气喘吁吁,寻找到众人身后那双宁静深邃的目光时,终于欣慰地笑了。", - "diffs": [ - { - "tag": "r", - "origin": "眼睛", - "text": "目光", - "start": 20, - "end": 22, - "id": 192952, - "idx": 13, - "isAccept": 0, - "type": 2 - } - ], - "insert": "她气喘吁吁,寻找到众人身后那双宁静深邃的眼睛时,终于欣慰地笑了。\n", - "insert_len": 33, - "paragraph_offset": 54, - "sentence_offset": 0, - "paragraph_num": 64 - }, - { - "key": "65a8503c0f1bec643ea867f3ac7c33c0", - "offset": 3092, - "new_text": "属于她的狂欢在此后刚刚上演,不需要璀璨的华服,不需要震耳欲聋的音乐。", - "insert": "属于她的狂欢在此后刚刚上演,不需要璀璨的华服,不需要震耳欲聋的音乐。", - "insert_len": 34, - "paragraph_offset": 55, - "sentence_offset": 0, - "paragraph_num": 65 - }, - { - "key": "aafef242e8bb040289692d25a0afb559", - "offset": 3130, - "new_text": "伊戈尔的房间里弥漫着朗姆酒醉人的香气,明日香趴在他胸前,看着散落一地的绚烂羽毛,忽然有一时怔忡。", - "insert": "伊戈尔的房间里弥漫着朗姆酒醉人的香气,明日香趴在他胸前,看着散落一地的绚烂羽毛,忽然有一时怔忡。", - "insert_len": 48, - "paragraph_offset": 55, - "sentence_offset": 34, - "paragraph_num": 65 - }, - { - "key": "0053130c9da79fe6ee24a9b3bd367e68", - "offset": 3178, - "new_text": "她想到古老神话中的天女,失去了羽衣,便再也无法飞回天上的世界了。", - "insert": "她想到古老神话中的天女,失去了羽衣,便再也无法飞回天上的世界了。\n", - "insert_len": 33, - "paragraph_offset": 55, - "sentence_offset": 82, - "paragraph_num": 65 - }, - { - "key": "45fbde559e5abe73f9a74ff9c5bf4922", - "offset": 3211, - "new_text": "伊戈尔在睡梦中忽然喃喃地说了什么,明日香侧耳去听,他只是蹙了蹙眉,将她紧拥在怀里。", - "insert": "伊戈尔在睡梦中忽然喃喃地说了什么,明日香侧耳去听,他只是蹙了蹙眉,将她紧拥在怀里。", - "insert_len": 41, - "paragraph_offset": 56, - "sentence_offset": 0, - "paragraph_num": 66 - }, - { - "key": "cd5e6d475323327b2ad1675a077db5ec", - "offset": 3256, - "new_text": "她靠在他肩头,心底甜蜜地要开出一朵花来,旅程大概就此结束了吧,谁还需要天女的羽衣呢?", - "insert": "她靠在他肩头,心底甜蜜地要开出一朵花来,旅程大概就此结束了吧,谁还需要天女的羽衣呢?\n", - "insert_len": 43, - "paragraph_offset": 56, - "sentence_offset": 41, - "paragraph_num": 66 - }, - { - "key": "c71798157df67020e2e9d191e7f404b9", - "offset": 3299, - "new_text": "窗帘外透进一线路灯橘黄的光。", - "diffs": [ - { - "tag": "r", - "origin": "投", - "text": "透", - "start": 3, - "end": 4, - "id": 192953, - "idx": 14, - "isAccept": 0, - "type": 2 - } - ], - "insert": "窗帘外投进一线路灯橘黄的光。\n", - "insert_len": 15, - "paragraph_offset": 57, - "sentence_offset": 0, - "paragraph_num": 67 - }, - { - "key": "e2146413864df53607b8d798a8a190d9", - "offset": 3318, - "new_text": "他说:莫莫。", - "insert": "他说:莫莫。\n", - "insert_len": 7, - "paragraph_offset": 58, - "sentence_offset": 0, - "paragraph_num": 68 - }, - { - "key": "eca1514d1cbb3b9099a147e6bfd6fe2e", - "offset": 3329, - "new_text": "作者有话要说:聂鲁达写的是西班牙语,巴西讲葡萄牙语。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "是", - "start": 12, - "end": 12, - "id": 192954, - "idx": 15, - "isAccept": 0, - "type": 2 - } - ], - "insert": "作者有话要说:聂鲁达写的西班牙语,巴西讲葡萄牙语。", - "insert_len": 25, - "paragraph_offset": 59, - "sentence_offset": 0, - "paragraph_num": 69 - }, - { - "key": "5cda663e50cc9c0bfd359c239f2831c0", - "offset": 3358, - "new_text": "西语是我在网上google的,如果有错,请行家指出。", - "insert": "西语是我在网上google的,如果有错,请行家指出。", - "insert_len": 26, - "paragraph_offset": 59, - "sentence_offset": 25, - "paragraph_num": 69 - }, - { - "key": "00f106146f3945d0477e92ec630d87ee", - "offset": 3384, - "new_text": "为了更好地理解这一段,请看下面的里约攀岩视频", - "insert": "为了更好地理解这一段,请看下面的里约攀岩视频\n", - "insert_len": 23, - "paragraph_offset": 59, - "sentence_offset": 51, - "paragraph_num": 69 - }, - { - "key": "c91c2fd24f5be5f30bbd1d8251e6d7b8", - "offset": 3407, - "new_text": "第一章 相逢非偶然", - "insert": "第一章 相逢非偶然\n", - "insert_len": 10, - "paragraph_offset": 60, - "sentence_offset": 0, - "paragraph_num": 70 - }, - { - "key": "fdf3993324fb5b2708f55e7b53585677", - "offset": 3421, - "new_text": "北京在十月末便下了第一场雪,这是莫靖言记忆中来的最早的一个冬天,因此便显得分外漫长。", - "insert": "北京在十月末便下了第一场雪,这是莫靖言记忆中来的最早的一个冬天,因此便显得分外漫长。", - "insert_len": 42, - "paragraph_offset": 61, - "sentence_offset": 0, - "paragraph_num": 71 - }, - { - "key": "336eb5214532477f3438697703163d45", - "offset": 3467, - "new_text": "在隆冬正式粉墨登场前,几件冬装已经显得单薄,莫靖言想要添置新衣,于是约了好友夏小橘周末去逛街。", - "insert": "在隆冬正式粉墨登场前,几件冬装已经显得单薄,莫靖言想要添置新衣,于是约了好友夏小橘周末去逛街。\n", - "insert_len": 48, - "paragraph_offset": 61, - "sentence_offset": 42, - "paragraph_num": 71 - }, - { - "key": "e13638db1c33af32aaa915915e71e73f", - "offset": 3515, - "new_text": "路上难得没有堵车,她早到了十多分钟,便在顶层的美食街买了一只香草泡芙,边吃边走,顺便研究一下各家专卖店的打折信息。", - "insert": "路上难得没有堵车,她早到了十多分钟,便在顶层的美食街买了一只香草泡芙,边吃边走,顺便研究一下各家专卖店的打折信息。", - "insert_len": 57, - "paragraph_offset": 62, - "sentence_offset": 0, - "paragraph_num": 72 - }, - { - "key": "fdccc3c457b7436734218fc9b4c79ea4", - "offset": 3576, - "new_text": "直到在路的尽头出现了电影院的巨幅海报,滔天洪水中,里约热内卢的救世基督像倾斜倒下。", - "insert": "直到在路的尽头出现了电影院的巨幅海报,滔天洪水中,里约热内卢的救世基督像倾斜倒下。\n", - "insert_len": 42, - "paragraph_offset": 62, - "sentence_offset": 57, - "paragraph_num": 72 - }, - { - "key": "4ff31ed499dccc40a264e840b6f086f8", - "offset": 3618, - "new_text": "莫靖言有些恍惚,她盯着海报沉默片刻,本已经转身离开,又忍不住折返,拿出电话拨给夏小橘:“我请你看电影如何?《2012》。”", - "insert": "莫靖言有些恍惚,她盯着海报沉默片刻,本已经转身离开,又忍不住折返,拿出电话拨给夏小橘:“我请你看电影如何?《2012》。”\n", - "insert_len": 62, - "paragraph_offset": 63, - "sentence_offset": 0, - "paragraph_num": 73 - }, - { - "key": "184f63716a339ccf16c44a07b0ac1768", - "offset": 3684, - "new_text": "“啊,你不是说冬天太长,所以需要更多的冬装吗?”", - "diffs": [ - { - "tag": "r", - "origin": "么", - "text": "吗", - "start": 21, - "end": 22, - "id": 192955, - "idx": 16, - "isAccept": 0, - "type": 2 - } - ], - "insert": "“啊,你不是说冬天太长,所以需要更多的冬装么?”", - "insert_len": 24, - "paragraph_offset": 64, - "sentence_offset": 0, - "paragraph_num": 74 - }, - { - "key": "f9bfb72837d63112988ca1b91fc4356f", - "offset": 3712, - "new_text": "夏小橘本来也不痴迷购物,“我是没所谓,不过你不和黄骏一起看?”", - "insert": "夏小橘本来也不痴迷购物,“我是没所谓,不过你不和黄骏一起看?”\n", - "insert_len": 32, - "paragraph_offset": 64, - "sentence_offset": 24, - "paragraph_num": 74 - } - ], - "id": 2422, - "isBlackWord": false, - "isWhiteWord": false, - "name": "直到春天过去-mark-cannot-select.docx", - "status": 3 -} - -export default { - "abnormalCount": { - "blackWord": 0, - "characterError": 269, - "wordError": 0, - "numberError": 0, - "unitsError": 0, - "punctuationError": 0, - "grammarError": 0, - "knowledgeableError": 0, - "tendentiousError": 0, - "inconsistentError": 0, - "formatError": 0, - "total": 269, - "untreated": 269, - "sensitive": 0 - }, - "correctedSet": [ - { - "key": "aa3200ff37217356da1214edd5242582", - "offset": 0, - "new_text": "高考语文18个文言虚词的用法及其举例", - "insert": "高考语文18个文言虚词的用法及其举例\n", - "insert_len": 19, - "paragraph_offset": 0, - "sentence_offset": 0, - "paragraph_num": 1 - }, - { - "key": "dd26e4dd3b25bbd07d0d8ec487600d8a", - "offset": 19, - "new_text": "[而、何、乎、乃、其且、若、所、为、焉、也、以、因、于,与、则、者、之]\u000b\u000b1.【而】\u000b(一)用作连词。", - "diffs": [ - { - "tag": "d", - "origin": "、", - "text": "", - "start": 10, - "end": 11, - "id": 187092, - "idx": 1, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "、", - "text": ",", - "start": 28, - "end": 29, - "id": 187093, - "idx": 2, - "isAccept": 0, - "type": 2 - } - ], - "insert": "[而、何、乎、乃、其、且、若、所、为、焉、也、以、因、于、与、则、者、之] \u000b\u000b1.【而】 \u000b(一)用作连词。", - "insert_len": 55, - "paragraph_offset": 1, - "sentence_offset": 0, - "paragraph_num": 2 - }, - { - "key": "bc356cd72b741e08e0c4771cc227cc15", - "offset": 74, - "new_text": "1.表示并列关系。", - "insert": "1.表示并列关系。", - "insert_len": 9, - "paragraph_offset": 1, - "sentence_offset": 55, - "paragraph_num": 2 - }, - { - "key": "3c061f7f8007bc936f49c8d0400a254e", - "offset": 84, - "new_text": "一般不译,有时可译为“又” 。", - "insert": "一般不译,有时可译为“又” 。", - "insert_len": 15, - "paragraph_offset": 1, - "sentence_offset": 64, - "paragraph_num": 2 - }, - { - "key": "4766b01245a7fca771e6e692fdedce73", - "offset": 99, - "new_text": "①蟹六跪而二螯,非蛇鳝之穴无可寄者(《劝学》)②剑阁峥嵘而崔嵬,一夫当关,万夫莫开(《蜀道难》)\u000b③北救赵而西却秦,此五霸之伐也(《信陵君窃符救赵》)2.表示递进关系。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 76, - "end": 78, - "id": 187094, - "idx": 6, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①蟹六跪而二螯,非蛇鳝之穴无可寄者(《劝学》)②剑阁峥嵘而崔嵬,一夫当关,万夫莫开(《蜀道难》) \u000b③北救赵而西却秦,此五霸之伐也(《信陵君窃符救赵》) \u000b2.表示递进关系。", - "insert_len": 87, - "paragraph_offset": 1, - "sentence_offset": 79, - "paragraph_num": 2 - }, - { - "key": "246e744dc9047e5d57bfd816f2cfe7d6", - "offset": 188, - "new_text": "可译为“并且”或“而且”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187095, - "idx": 7, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 6, - "end": 7, - "id": 187096, - "idx": 8, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 8, - "end": 9, - "id": 187097, - "idx": 9, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 11, - "end": 12, - "id": 187098, - "idx": 10, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"并且\"或\"而且\"。", - "insert_len": 13, - "paragraph_offset": 1, - "sentence_offset": 166, - "paragraph_num": 2 - }, - { - "key": "fd740eedaa8ec92e05bada2f05d48032", - "offset": 201, - "new_text": "①君子博学而日参省乎己。", - "insert": "①君子博学而日参省乎己。", - "insert_len": 12, - "paragraph_offset": 1, - "sentence_offset": 179, - "paragraph_num": 2 - }, - { - "key": "22388b52f7343c1dc50282d2e049dabb", - "offset": 215, - "new_text": "(《劝学》)②楚怀王贪而信张仪,遂绝齐(《屈原列传》)③回视日观以西峰,或得日,或否,绛皜驳色,而皆若偻(《登泰山记》)", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 31, - "end": 33, - "id": 187099, - "idx": 12, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《劝学》) ②楚怀王贪而信张仪,遂绝齐(《屈原列传》) \u000b③回视日观以西峰,或得日,或否,绛皜驳色,而皆若偻(《登泰山记》)\n", - "insert_len": 67, - "paragraph_offset": 1, - "sentence_offset": 191, - "paragraph_num": 2 - }, - { - "key": "a3e8a64bdf26328cf16c9a389529e0b4", - "offset": 283, - "new_text": "④以其求思之深而无不在也(《游褒禅山记》)\u000b3.表示承接关系。", - "insert": "④以其求思之深而无不在也(《游褒禅山记》) \u000b3.表示承接关系。", - "insert_len": 32, - "paragraph_offset": 2, - "sentence_offset": 0, - "paragraph_num": 3 - }, - { - "key": "4f3270138ed0e1d97ab0bda97c798431", - "offset": 315, - "new_text": "可译为“就”“接着”,或不译。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187100, - "idx": 14, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 5, - "end": 7, - "id": 187101, - "idx": 15, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 9, - "end": 10, - "id": 187102, - "idx": 16, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"就\"\"接着\",或不译。", - "insert_len": 15, - "paragraph_offset": 2, - "sentence_offset": 32, - "paragraph_num": 3 - }, - { - "key": "8147f3e97000c30da1fa90fce1911f8a", - "offset": 330, - "new_text": "①故舍汝而旅食京师,以求斗斛之禄(《陈情表》)②置之地,拔剑撞而破之。", - "insert": "①故舍汝而旅食京师,以求斗斛之禄(《陈情表》)②置之地,拔剑撞而破之。", - "insert_len": 35, - "paragraph_offset": 2, - "sentence_offset": 47, - "paragraph_num": 3 - }, - { - "key": "092e3d909e434853744005b117f2abce", - "offset": 367, - "new_text": "(《鸿门宴》)", - "insert": "(《鸿门宴》)\n", - "insert_len": 8, - "paragraph_offset": 2, - "sentence_offset": 82, - "paragraph_num": 3 - }, - { - "key": "432545958c10160b65ce0d176e3dc845", - "offset": 376, - "new_text": "③人非生而知之者,孰能无惑(《师说》)\u000b4.表示转折关系。", - "insert": "③人非生而知之者,孰能无惑(《师说》) \u000b4.表示转折关系。", - "insert_len": 30, - "paragraph_offset": 3, - "sentence_offset": 0, - "paragraph_num": 4 - }, - { - "key": "0e70930af165201f7b809c7d1ed98fa2", - "offset": 406, - "new_text": "可译为“但是”“却”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187103, - "idx": 18, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 6, - "end": 8, - "id": 187104, - "idx": 19, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 9, - "end": 10, - "id": 187105, - "idx": 20, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"但是\"\"却\"。", - "insert_len": 11, - "paragraph_offset": 3, - "sentence_offset": 30, - "paragraph_num": 4 - }, - { - "key": "36410760fc1ea1820d1e7f56f2707773", - "offset": 417, - "new_text": "①青,取之于蓝,而青于蓝(《劝学》)②有如此之势,而为秦人积威之所劫(《六国论》)", - "insert": "①青,取之于蓝,而青于蓝(《劝学》) ②有如此之势,而为秦人积威之所劫(《六国论》)\n", - "insert_len": 44, - "paragraph_offset": 3, - "sentence_offset": 41, - "paragraph_num": 4 - }, - { - "key": "8d9fbd0f1d32198073a83d518408c401", - "offset": 464, - "new_text": "③信也,吾兄之盛德而夭其嗣乎(《陈情表》)\u000b5.表示假设关系。", - "insert": "③信也,吾兄之盛德而夭其嗣乎(《陈情表》) \u000b5.表示假设关系。", - "insert_len": 32, - "paragraph_offset": 4, - "sentence_offset": 0, - "paragraph_num": 5 - }, - { - "key": "4289772e14d5033bbfba0a1219c46618", - "offset": 496, - "new_text": "可译为“如果”“假如”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187106, - "idx": 23, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 6, - "end": 8, - "id": 187107, - "idx": 24, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 10, - "end": 11, - "id": 187108, - "idx": 25, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"如果\"\"假如\"。", - "insert_len": 12, - "paragraph_offset": 4, - "sentence_offset": 32, - "paragraph_num": 5 - }, - { - "key": "99f2515c55ceb8156804178830dc4996", - "offset": 508, - "new_text": "①诸君而有意,瞻予马首可也。", - "insert": "①诸君而有意,瞻予马首可也。", - "insert_len": 14, - "paragraph_offset": 4, - "sentence_offset": 44, - "paragraph_num": 5 - }, - { - "key": "cfa60d903f8a80918db270dfc00533a2", - "offset": 524, - "new_text": "(《冯婉贞》)", - "insert": "(《冯婉贞》)\n", - "insert_len": 8, - "paragraph_offset": 4, - "sentence_offset": 58, - "paragraph_num": 5 - }, - { - "key": "ac09a706e307334fec629e631dc4bfd2", - "offset": 533, - "new_text": "②死而有知,其几何离(《祭十二郎文》)\u000b6.表示修饰关系,即连接状语。", - "insert": "②死而有知,其几何离(《祭十二郎文》) \u000b6.表示修饰关系,即连接状语。", - "insert_len": 36, - "paragraph_offset": 5, - "sentence_offset": 0, - "paragraph_num": 6 - }, - { - "key": "b63cfc913d1d53bb41d8ff18b197f245", - "offset": 569, - "new_text": "可不译。", - "insert": "可不译。", - "insert_len": 4, - "paragraph_offset": 5, - "sentence_offset": 36, - "paragraph_num": 6 - }, - { - "key": "d4069fe81347027f8bf6d6e759d514e8", - "offset": 573, - "new_text": "①吾尝跂而望矣,不如登高之博见也(《劝学》)②填然鼓之,兵刃既接,弃甲曳兵而走(《寡人之于国也》)", - "insert": "①吾尝跂而望矣,不如登高之博见也(《劝学》) ②填然鼓之,兵刃既接,弃甲曳兵而走(《寡人之于国也》)\n", - "insert_len": 52, - "paragraph_offset": 5, - "sentence_offset": 40, - "paragraph_num": 6 - }, - { - "key": "5ecc0c4074cc41302af40e217168f504", - "offset": 627, - "new_text": "③项王按剑而跽曰:“客何为者?”", - "insert": "③项王按剑而跽曰:“客何为者?”", - "insert_len": 16, - "paragraph_offset": 6, - "sentence_offset": 0, - "paragraph_num": 7 - }, - { - "key": "0de17cb076c7308100251ee3028d6715", - "offset": 643, - "new_text": "(《鸿门宴》)\u000b7.表示因果关系,①余亦悔其随之而不得极夫游之乐也(《游褒禅山记》)②表恶其能而不用也(《赤壁之战》)8.表示目的关系,\u000b①缦立远视,而望幸焉(《阿房宫赋》)②籍吏民,封府库,而待将军(《鸿门宴》)\u000b(二)通“尔”,用作代词,第二人称,译为“你的”;偶尔也做主语,译为“你\"。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 18, - "end": 20, - "id": 187109, - "idx": 29, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 65, - "end": 67, - "id": 187110, - "idx": 31, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 142, - "end": 143, - "id": 187111, - "idx": 35, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 145, - "end": 146, - "id": 187112, - "idx": 36, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 150, - "end": 151, - "id": 187113, - "idx": 37, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 156, - "end": 157, - "id": 187114, - "idx": 38, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b7.表示因果关系, \u000b①余亦悔其随之而不得极夫游之乐也(《游褒禅山记》) ②表恶其能而不用也(《赤壁之战》) \u000b8.表示目的关系, \u000b①缦立远视,而望幸焉(《阿房宫赋》) ②籍吏民,封府库,而待将军(《鸿门宴》) \u000b(二)通“尔”,用作代词,第二人称,译为\"你的\";偶尔也作主语,译为\"你\"。", - "insert_len": 160, - "paragraph_offset": 6, - "sentence_offset": 16, - "paragraph_num": 7 - }, - { - "key": "27f431acf3aef2ae20a0d1bf8400e415", - "offset": 803, - "new_text": "①而翁归,自与汝复算耳(《促织》)②妪每谓余曰:“某所,而母立于兹(《项脊轩志》)(三)通“如”:好像,如同。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 44, - "end": 46, - "id": 187115, - "idx": 40, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①而翁归,自与汝复算耳(《促织》) ②妪每谓余曰:“某所,而母立于兹(《项脊轩志》) \u000b(三)通“如”:好像,如同。", - "insert_len": 60, - "paragraph_offset": 6, - "sentence_offset": 176, - "paragraph_num": 7 - }, - { - "key": "c43021c3adca0233738865ebd31af442", - "offset": 865, - "new_text": "①军惊而坏都舍。", - "insert": "①军惊而坏都舍。", - "insert_len": 8, - "paragraph_offset": 6, - "sentence_offset": 236, - "paragraph_num": 7 - }, - { - "key": "c20726e59a206b42385262030a18ea4d", - "offset": 874, - "new_text": "(《察今》)\u000b【而已】放在句末,表示限止的语气助词,相当于“罢了”。", - "insert": "(《察今》) \u000b【而已】放在句末,表示限止的语气助词,相当于“罢了”。", - "insert_len": 35, - "paragraph_offset": 6, - "sentence_offset": 244, - "paragraph_num": 7 - }, - { - "key": "3c77c48c0265175c474a997493ba445f", - "offset": 909, - "new_text": "①未几而摇头顿足者,得数十人而已(《虎丘记》)②闻道有先后,术业有专攻,如是而已(《师说》)\u000b③我决起而飞,枪榆枋而止,时则不至,而控于地而已矣(《逍遥游》)【而后】才,方才。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 82, - "end": 84, - "id": 187116, - "idx": 44, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①未几而摇头顿足者,得数十人而已(《虎丘记》) ②闻道有先后,术业有专攻,如是而已(《师说》) \u000b③我决起而飞,枪榆枋而止,时则不至,而控于地而已矣(《逍遥游》) \u000b【而后】才,方才。", - "insert_len": 93, - "paragraph_offset": 6, - "sentence_offset": 279, - "paragraph_num": 7 - }, - { - "key": "7903dcc5b0cb2dd432765ab08539ddf1", - "offset": 1004, - "new_text": "①臣鞠躬尽瘁,死而后已。", - "insert": "①臣鞠躬尽瘁,死而后已。", - "insert_len": 12, - "paragraph_offset": 6, - "sentence_offset": 372, - "paragraph_num": 7 - }, - { - "key": "b8e3fed2888d2625e3719768c20dd433", - "offset": 1018, - "new_text": "②三月而后成。", - "insert": "②三月而后成。", - "insert_len": 7, - "paragraph_offset": 6, - "sentence_offset": 384, - "paragraph_num": 7 - }, - { - "key": "ee0f8a74f3b36e2e9fd5bbed7d0d8c2e", - "offset": 1025, - "new_text": "【而况】即“何况”,用反问的语气表示更进一层的意思。", - "insert": "【而况】即“何况”,用反问的语气表示更进一层的意思。", - "insert_len": 26, - "paragraph_offset": 6, - "sentence_offset": 391, - "paragraph_num": 7 - }, - { - "key": "01daa079ed1cfdccde82a5faf6d7438e", - "offset": 1053, - "new_text": "①今以钟磬置水中,虽大风浪不能鸣也。", - "insert": "①今以钟磬置水中,虽大风浪不能鸣也。", - "insert_len": 18, - "paragraph_offset": 6, - "sentence_offset": 417, - "paragraph_num": 7 - }, - { - "key": "9a7fb3a09fb0a5dad758e45019290b27", - "offset": 1073, - "new_text": "而况石乎!", - "insert": "而况石乎!", - "insert_len": 5, - "paragraph_offset": 6, - "sentence_offset": 435, - "paragraph_num": 7 - }, - { - "key": "0ede6b4434bd8b7914eaeb8ef588d459", - "offset": 1078, - "new_text": "②技经肯綮之未尝,而况大軱乎!", - "insert": "②技经肯綮之未尝,而况大軱乎!", - "insert_len": 15, - "paragraph_offset": 6, - "sentence_offset": 440, - "paragraph_num": 7 - }, - { - "key": "42093c3a1a4466d2b9347396eefb14b7", - "offset": 1094, - "new_text": "③臣虽下愚,知其不可,而况于明哲乎(《谏太宗十思疏》)\u000b【既而】不久,一会儿。", - "insert": "③臣虽下愚,知其不可,而况于明哲乎(《谏太宗十思疏》) \u000b【既而】不久,一会儿。", - "insert_len": 40, - "paragraph_offset": 6, - "sentence_offset": 455, - "paragraph_num": 7 - }, - { - "key": "46e79902fb2b9c00378742413470cd44", - "offset": 1136, - "new_text": "①既而以吴民之乱请于朝,按诛五人(《五人墓碑记》)", - "insert": "①既而以吴民之乱请于朝,按诛五人(《五人墓碑记》)\n", - "insert_len": 26, - "paragraph_offset": 6, - "sentence_offset": 495, - "paragraph_num": 7 - }, - { - "key": "0b04d9a00b6570eaa7555acf472ef9f0", - "offset": 1164, - "new_text": "②既而得其尸于井,因而化怒为悲,抢呼欲绝(《促织》)", - "insert": "②既而得其尸于井,因而化怒为悲,抢呼欲绝(《促织》)\n", - "insert_len": 27, - "paragraph_offset": 7, - "sentence_offset": 0, - "paragraph_num": 8 - }, - { - "key": "ae8d6c34b7d29f9c64c9b1cfaf13a198", - "offset": 1191, - "new_text": "③既而将诉于舅姑,舅姑爱其子,不能御(《柳毅传》)", - "insert": "③既而将诉于舅姑,舅姑爱其子,不能御(《柳毅传》)\n", - "insert_len": 26, - "paragraph_offset": 8, - "sentence_offset": 0, - "paragraph_num": 9 - }, - { - "key": "feedd71b4d2eb1dede0f0c747fec5727", - "offset": 1220, - "new_text": "2.【何】\u000b(一)用作疑问代词。", - "insert": "2.【何】 \u000b(一)用作疑问代词。", - "insert_len": 17, - "paragraph_offset": 9, - "sentence_offset": 0, - "paragraph_num": 10 - }, - { - "key": "0815bd227586432f1e2e99a7e0fb4ef3", - "offset": 1237, - "new_text": "1.单独做谓语,后面常有语气助词“哉”“也”,可译为“为什么”“什么原因”。", - "diffs": [ - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 4, - "end": 5, - "id": 187117, - "idx": 47, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 16, - "end": 17, - "id": 187118, - "idx": 48, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 18, - "end": 20, - "id": 187119, - "idx": 49, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 21, - "end": 22, - "id": 187120, - "idx": 50, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 26, - "end": 27, - "id": 187121, - "idx": 51, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 30, - "end": 32, - "id": 187122, - "idx": 52, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 36, - "end": 37, - "id": 187123, - "idx": 53, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.单独作谓语,后面常有语气助词\"哉\"\"也\",可译为\"为什么\"\"什么原因\"。", - "insert_len": 38, - "paragraph_offset": 9, - "sentence_offset": 17, - "paragraph_num": 10 - }, - { - "key": "41f713bc0096dc3a459f164a96af8d30", - "offset": 1277, - "new_text": "①何者?", - "insert": "①何者?", - "insert_len": 4, - "paragraph_offset": 9, - "sentence_offset": 55, - "paragraph_num": 10 - }, - { - "key": "d70584dda9de377c89f50b6135b0d8cf", - "offset": 1283, - "new_text": "严大国之威以修敬也。", - "insert": "严大国之威以修敬也。", - "insert_len": 10, - "paragraph_offset": 9, - "sentence_offset": 59, - "paragraph_num": 10 - }, - { - "key": "d2c51461ce0610d83e92e9dec1b52c3f", - "offset": 1293, - "new_text": "(《廉颇蔺相如列传》)\u000b②予尝求古仁人之心,或异二者之为,何哉?", - "insert": "(《廉颇蔺相如列传》) \u000b②予尝求古仁人之心,或异二者之为,何哉?", - "insert_len": 33, - "paragraph_offset": 9, - "sentence_offset": 69, - "paragraph_num": 10 - }, - { - "key": "0c4c5025f0e2694a1dc262a1e84d9079", - "offset": 1326, - "new_text": "(《岳阳楼记》)\u000b③齐人未尝赂秦,终继五国迁灭,何哉?", - "insert": "(《岳阳楼记》) \u000b③齐人未尝赂秦,终继五国迁灭,何哉?", - "insert_len": 28, - "paragraph_offset": 9, - "sentence_offset": 102, - "paragraph_num": 10 - }, - { - "key": "f3f48c4d680616db17143c6cf6de9950", - "offset": 1354, - "new_text": "(《六国论》)\u000b2.作动词或介词的宾语,可译为“哪里”“什么”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 24, - "end": 25, - "id": 187124, - "idx": 57, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 27, - "end": 29, - "id": 187125, - "idx": 58, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 31, - "end": 32, - "id": 187126, - "idx": 59, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《六国论》) \u000b2.作动词或介词的宾语,可译为\"哪里\"\"什么\"。", - "insert_len": 33, - "paragraph_offset": 9, - "sentence_offset": 130, - "paragraph_num": 10 - }, - { - "key": "2848f946fb578ed3018752b8c8c1bd61", - "offset": 1387, - "new_text": "译时,“何“要后置。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187127, - "idx": 60, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 5, - "end": 6, - "id": 187128, - "idx": 61, - "isAccept": 0, - "type": 2 - } - ], - "insert": "译时,\"何\"要后置。", - "insert_len": 10, - "paragraph_offset": 9, - "sentence_offset": 163, - "paragraph_num": 10 - }, - { - "key": "56a9d3be3deca3f6f5197325d7a377ea", - "offset": 1397, - "new_text": "①豫州今欲何至?", - "insert": "①豫州今欲何至?", - "insert_len": 8, - "paragraph_offset": 9, - "sentence_offset": 173, - "paragraph_num": 10 - }, - { - "key": "47946403cb419c01038320752873ea7a", - "offset": 1407, - "new_text": "(《赤壁之战》)\u000b②大王来何操?", - "insert": "(《赤壁之战》) \u000b②大王来何操?", - "insert_len": 17, - "paragraph_offset": 9, - "sentence_offset": 181, - "paragraph_num": 10 - }, - { - "key": "4b7c1af986338eca029f8a6eee7f6d1f", - "offset": 1424, - "new_text": "(《鸿门宴》)\u000b③一旦山陵崩,长安君何以自托于赵?", - "insert": "(《鸿门宴》) \u000b③一旦山陵崩,长安君何以自托于赵?", - "insert_len": 26, - "paragraph_offset": 9, - "sentence_offset": 198, - "paragraph_num": 10 - }, - { - "key": "1e1575daaf143a28c91c7447abfd2849", - "offset": 1450, - "new_text": "(《触龙说赵太后》)\u000b3.作定语,可译为“什么”“哪”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 21, - "end": 22, - "id": 187129, - "idx": 65, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 24, - "end": 26, - "id": 187130, - "idx": 66, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 27, - "end": 28, - "id": 187131, - "idx": 67, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《触龙说赵太后》) \u000b3.作定语,可译为\"什么\"\"哪\"。", - "insert_len": 29, - "paragraph_offset": 9, - "sentence_offset": 224, - "paragraph_num": 10 - }, - { - "key": "321f33e69291e1e9887886111d78a92f", - "offset": 1479, - "new_text": "①其间旦暮闻何物,杜鹃啼血猿哀鸣。", - "insert": "①其间旦暮闻何物,杜鹃啼血猿哀鸣。", - "insert_len": 17, - "paragraph_offset": 9, - "sentence_offset": 253, - "paragraph_num": 10 - }, - { - "key": "7b44b44423a65e7406b1a1219182b064", - "offset": 1498, - "new_text": "(《琵琶行》)\u000b②然则何时而乐耶?", - "insert": "(《琵琶行》) \u000b②然则何时而乐耶?", - "insert_len": 18, - "paragraph_offset": 9, - "sentence_offset": 270, - "paragraph_num": 10 - }, - { - "key": "e83e6837e06509af4507842f6e2b3a46", - "offset": 1516, - "new_text": "(《岳阳楼记》)\u000b(二)用作疑问副词。", - "insert": "(《岳阳楼记》) \u000b(二)用作疑问副词。", - "insert_len": 20, - "paragraph_offset": 9, - "sentence_offset": 288, - "paragraph_num": 10 - }, - { - "key": "4e48a70cd491ef725d090c1457f6e6a9", - "offset": 1536, - "new_text": "1.用在句首或动词前,常表示反问,可译为“为什么”“怎么”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 20, - "end": 21, - "id": 187132, - "idx": 70, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 24, - "end": 26, - "id": 187133, - "idx": 71, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 28, - "end": 29, - "id": 187134, - "idx": 72, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.用在句首或动词前,常表示反问,可译为\"为什么\"\"怎么\"。", - "insert_len": 30, - "paragraph_offset": 9, - "sentence_offset": 308, - "paragraph_num": 10 - }, - { - "key": "a5976d9752d7ba0c686383c196cf48b8", - "offset": 1568, - "new_text": "①何不按兵束甲,北面而事之?", - "insert": "①何不按兵束甲,北面而事之?", - "insert_len": 14, - "paragraph_offset": 9, - "sentence_offset": 338, - "paragraph_num": 10 - }, - { - "key": "cbb20c40e2d39415e163be590c581310", - "offset": 1584, - "new_text": "(《赤壁之战》)\u000b②徐公何能及君也?", - "insert": "(《赤壁之战》) \u000b②徐公何能及君也?", - "insert_len": 19, - "paragraph_offset": 9, - "sentence_offset": 352, - "paragraph_num": 10 - }, - { - "key": "32c263af7982a0d5942174a600f6dd10", - "offset": 1603, - "new_text": "(《邹忌讽齐王纳谏》)\u000b2.用在形容词前,表示程度深,可译为“怎么”“多么”“怎么这样”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 31, - "end": 32, - "id": 187135, - "idx": 75, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 34, - "end": 36, - "id": 187136, - "idx": 76, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 38, - "end": 40, - "id": 187137, - "idx": 77, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 44, - "end": 45, - "id": 187138, - "idx": 78, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《邹忌讽齐王纳谏》) \u000b2.用在形容词前,表示程度深,可译为\"怎么\"\"多么\"\"怎么这样\"。", - "insert_len": 46, - "paragraph_offset": 9, - "sentence_offset": 371, - "paragraph_num": 10 - }, - { - "key": "47932591cafb78fb2a08738fa5ebd88c", - "offset": 1649, - "new_text": "①至于誓天断发,泣下沾襟,何其衰也!", - "insert": "①至于誓天断发,泣下沾襟,何其衰也!", - "insert_len": 18, - "paragraph_offset": 9, - "sentence_offset": 417, - "paragraph_num": 10 - }, - { - "key": "6ff88447dc11e8d7a73aa0b742b93f93", - "offset": 1669, - "new_text": "(《伶官传序》)\u000b(三)作语助词,相当于“啊”。", - "insert": "(《伶官传序》) \u000b(三)作语助词,相当于“啊”。", - "insert_len": 25, - "paragraph_offset": 9, - "sentence_offset": 435, - "paragraph_num": 10 - }, - { - "key": "6877f06f93f3dfd305e4df75d5e2ab74", - "offset": 1694, - "new_text": "①新妇车在后,隐隐何甸甸。", - "insert": "①新妇车在后,隐隐何甸甸。", - "insert_len": 13, - "paragraph_offset": 9, - "sentence_offset": 460, - "paragraph_num": 10 - }, - { - "key": "9b984f72f6b9ab761f979c2893bc2a9c", - "offset": 1710, - "new_text": "(《孔雀东南飞》)\u000b(四)何:通“呵”,喝问。", - "insert": "(《孔雀东南飞》) \u000b(四)何:通“呵”,喝问。", - "insert_len": 24, - "paragraph_offset": 9, - "sentence_offset": 473, - "paragraph_num": 10 - }, - { - "key": "1f4967c9c58cb5bb322a2420424c4cf8", - "offset": 1734, - "new_text": "①信臣精卒陈利兵而谁何。", - "insert": "①信臣精卒陈利兵而谁何。", - "insert_len": 12, - "paragraph_offset": 9, - "sentence_offset": 497, - "paragraph_num": 10 - }, - { - "key": "c56e6e72d06f50131151131a41934811", - "offset": 1748, - "new_text": "(谁何:呵问他是谁何。意思是检查盘问。)", - "insert": "(谁何:呵问他是谁何。意思是检查盘问。)", - "insert_len": 20, - "paragraph_offset": 9, - "sentence_offset": 509, - "paragraph_num": 10 - }, - { - "key": "d7a285b5b861a53f27c1a03c03513a95", - "offset": 1768, - "new_text": "(《过秦论》)\u000b【何如】【奈何】【若何】表示疑问或反问,译为“怎么样”“怎么办”“为什么”。", - "insert": "(《过秦论》) \u000b【何如】【奈何】【若何】表示疑问或反问,译为“怎么样”“怎么办”“为什么”。", - "insert_len": 47, - "paragraph_offset": 9, - "sentence_offset": 529, - "paragraph_num": 10 - }, - { - "key": "f9bc373a890bd193e18bb0ac525748e0", - "offset": 1815, - "new_text": "①以五十步笑百步,则何如(《季氏将伐颛臾》)\u000b②其辱人贱行,视五人之死,轻重固何如哉(《五人墓碑记》)③沛公大惊,曰:“为之奈何?“(《鸿门宴》)\u000b④奈何取之尽锱铢,用之如泥沙(《阿房宫赋》)【何以】即“以何”,介宾短语,用于疑问句中做状语,根据”以“的不同用法,分别相当于”拿什么“”凭什么“等。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 52, - "end": 54, - "id": 187139, - "idx": 83, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 62, - "end": 63, - "id": 187140, - "idx": 84, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "?\"", - "text": "?“", - "start": 67, - "end": 69, - "id": 187141, - "idx": 85, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 100, - "end": 102, - "id": 187142, - "idx": 87, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 123, - "end": 124, - "id": 187143, - "idx": 88, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 129, - "end": 130, - "id": 187144, - "idx": 89, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 131, - "end": 132, - "id": 187145, - "idx": 90, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 143, - "end": 144, - "id": 187146, - "idx": 91, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "“”", - "start": 147, - "end": 149, - "id": 187147, - "idx": 92, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 152, - "end": 153, - "id": 187148, - "idx": 93, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①以五十步笑百步,则何如(《季氏将伐颛臾》) \u000b②其辱人贱行,视五人之死,轻重固何如哉(《五人墓碑记》) \u000b③沛公大惊,曰:\"为之奈何?\"(《鸿门宴》) \u000b④奈何取之尽锱铢,用之如泥沙(《阿房宫赋》) \u000b【何以】即“以何”,介宾短语,用于疑问句中作状语,根据\"以\"的不同用法,分别相当于\"拿什么\"\"凭什么\"等。", - "insert_len": 155, - "paragraph_offset": 9, - "sentence_offset": 576, - "paragraph_num": 10 - }, - { - "key": "0662c21c3349640afc6cb931582b888c", - "offset": 1972, - "new_text": "①一旦山陵崩,长安君何以自托于赵(《触龙说赵太后》)\u000b②不为者与不能者之形何以异(《齐桓晋文之事》)③吾王庶几无疾病与,何以能鼓乐也(《庄暴见孟子》)\u000b【无何】译为“不久”“没多久”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 51, - "end": 53, - "id": 187149, - "idx": 95, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①一旦山陵崩,长安君何以自托于赵(《触龙说赵太后》) \u000b②不为者与不能者之形何以异(《齐桓晋文之事》) \u000b③吾王庶几无疾病与,何以能鼓乐也(《庄暴见孟子》) \u000b【无何】译为“不久”“没多久”。", - "insert_len": 96, - "paragraph_offset": 9, - "sentence_offset": 731, - "paragraph_num": 10 - }, - { - "key": "197b90ac223e313111f1911911087f91", - "offset": 2070, - "new_text": "①抚军不忘所自,无何,宰以卓异闻,宰悦,免成役(《促织》)\u000b【何乃】译为“怎能”①阿母谓府吏:何乃太区区(《孔雀东南飞》)", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 41, - "end": 43, - "id": 187150, - "idx": 98, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①抚军不忘所自,无何,宰以卓异闻,宰悦,免成役(《促织》) \u000b【何乃】译为“怎能” \u000b①阿母谓府吏:何乃太区区(《孔雀东南飞》)\n", - "insert_len": 65, - "paragraph_offset": 9, - "sentence_offset": 827, - "paragraph_num": 10 - }, - { - "key": "d41a17ae4855e1a9f3dd03a5d85dd354", - "offset": 2140, - "new_text": "3.【乎】\u000b(一)用作语气助词。", - "insert": "3.【乎】 \u000b(一)用作语气助词。", - "insert_len": 17, - "paragraph_offset": 10, - "sentence_offset": 0, - "paragraph_num": 16 - }, - { - "key": "7bd096b65638ca0156d57ef7ec49cd98", - "offset": 2157, - "new_text": "1.表疑问语气。", - "insert": "1.表疑问语气。", - "insert_len": 8, - "paragraph_offset": 10, - "sentence_offset": 17, - "paragraph_num": 16 - }, - { - "key": "e5126d63c376a89c13a06b58d0f8fdcf", - "offset": 2167, - "new_text": "可译为“吗”“呢”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187151, - "idx": 100, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 5, - "end": 7, - "id": 187152, - "idx": 101, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 8, - "end": 9, - "id": 187153, - "idx": 102, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"吗\"\"呢\"。", - "insert_len": 10, - "paragraph_offset": 10, - "sentence_offset": 25, - "paragraph_num": 16 - }, - { - "key": "0e8e06cf5fea3d220b46a91d448fe09c", - "offset": 2177, - "new_text": "①几寒乎?", - "insert": "①几寒乎?", - "insert_len": 5, - "paragraph_offset": 10, - "sentence_offset": 35, - "paragraph_num": 16 - }, - { - "key": "fd466e2fe8fbc6246e3df0805e634343", - "offset": 2184, - "new_text": "欲食乎?", - "insert": "欲食乎?", - "insert_len": 4, - "paragraph_offset": 10, - "sentence_offset": 40, - "paragraph_num": 16 - }, - { - "key": "3ae87c6978db55665815f91c31ab06ee", - "offset": 2188, - "new_text": "(《项脊轩志》)\u000b②技盖至此乎?", - "insert": "(《项脊轩志》) \u000b②技盖至此乎?", - "insert_len": 17, - "paragraph_offset": 10, - "sentence_offset": 44, - "paragraph_num": 16 - }, - { - "key": "48f52b1d8caf7db3e5e50d3dd5e0e93b", - "offset": 2205, - "new_text": "(《庖丁解牛》)\u000b③欲安所归乎?", - "insert": "(《庖丁解牛》) \u000b③欲安所归乎?", - "insert_len": 17, - "paragraph_offset": 10, - "sentence_offset": 61, - "paragraph_num": 16 - }, - { - "key": "2fa6c1062a0ee824d768ebfa8678a285", - "offset": 2222, - "new_text": "(《赤壁之战》)\u000b2.表示反问语气,相当于“吗”、“呢”。", - "insert": "(《赤壁之战》) \u000b2.表示反问语气,相当于“吗”、“呢”。", - "insert_len": 30, - "paragraph_offset": 10, - "sentence_offset": 78, - "paragraph_num": 16 - }, - { - "key": "533e4e1052004d57cb565d0e190dc7d4", - "offset": 2252, - "new_text": "①布衣之交尚不相欺,况在国乎?", - "insert": "①布衣之交尚不相欺,况在国乎?", - "insert_len": 15, - "paragraph_offset": 10, - "sentence_offset": 108, - "paragraph_num": 16 - }, - { - "key": "a3af98e172400db8f511836ade8b8849", - "offset": 2270, - "new_text": "(《鸿门宴》)\u000b②吾师道也,夫庸知其年之先后生于吾乎?", - "insert": "(《鸿门宴》) \u000b②吾师道也,夫庸知其年之先后生于吾乎?", - "insert_len": 28, - "paragraph_offset": 10, - "sentence_offset": 123, - "paragraph_num": 16 - }, - { - "key": "98561e03aae7ea7817cf9a8d68ef2ffe", - "offset": 2298, - "new_text": "(《师说》)\u000b③然豫州新败之后,安能抗此难乎?", - "insert": "(《师说》) \u000b③然豫州新败之后,安能抗此难乎?", - "insert_len": 24, - "paragraph_offset": 10, - "sentence_offset": 151, - "paragraph_num": 16 - }, - { - "key": "43a83a3b5b0713fd3f4f8d01d98a6cc8", - "offset": 2322, - "new_text": "(《赤壁之战》)\u000b3.表测度或商量语气,可译为“吧”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 24, - "end": 25, - "id": 187154, - "idx": 109, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 26, - "end": 27, - "id": 187155, - "idx": 110, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《赤壁之战》) \u000b3.表测度或商量语气,可译为\"吧\"。", - "insert_len": 28, - "paragraph_offset": 10, - "sentence_offset": 175, - "paragraph_num": 16 - }, - { - "key": "429be02d387c84ce7503b13d5518b28f", - "offset": 2350, - "new_text": "①王之好乐甚,则齐其庶几乎。", - "insert": "①王之好乐甚,则齐其庶几乎。", - "insert_len": 14, - "paragraph_offset": 10, - "sentence_offset": 203, - "paragraph_num": 16 - }, - { - "key": "f2f7948be4ae58f5ff19c5cbbfabc353", - "offset": 2366, - "new_text": "(《庄暴见孟子》)\u000b②圣人之所以为圣,愚人之所以为愚,其皆出于此乎?", - "insert": "(《庄暴见孟子》) \u000b②圣人之所以为圣,愚人之所以为愚,其皆出于此乎?", - "insert_len": 35, - "paragraph_offset": 10, - "sentence_offset": 217, - "paragraph_num": 16 - }, - { - "key": "c523250ade56e511f46556cfbb9e2daf", - "offset": 2401, - "new_text": "③日食饮得无衰乎(《触龙说赵太后》)\u000b④今亡亦死,举大计亦死,等死,死国可乎?", - "insert": "③日食饮得无衰乎(《触龙说赵太后》) \u000b④今亡亦死,举大计亦死,等死,死国可乎?", - "insert_len": 40, - "paragraph_offset": 10, - "sentence_offset": 252, - "paragraph_num": 16 - }, - { - "key": "785ea477454ec1c0d8ccdba778bc4bfa", - "offset": 2443, - "new_text": "(《陈涉世家》)\u000b⑤无以,则王乎?", - "insert": "(《陈涉世家》) \u000b⑤无以,则王乎?", - "insert_len": 18, - "paragraph_offset": 10, - "sentence_offset": 292, - "paragraph_num": 16 - }, - { - "key": "9f4180ccafaec1021b7917204f747cf8", - "offset": 2461, - "new_text": "(《齐桓晋文之事》)\u000b4.用于感叹句或祈使句,可译为“啊”“呀”等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 27, - "end": 28, - "id": 187156, - "idx": 115, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 29, - "end": 31, - "id": 187157, - "idx": 116, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 32, - "end": 33, - "id": 187158, - "idx": 117, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《齐桓晋文之事》) \u000b4.用于感叹句或祈使句,可译为\"啊\"\"呀\"等。", - "insert_len": 35, - "paragraph_offset": 10, - "sentence_offset": 310, - "paragraph_num": 16 - }, - { - "key": "17b526723896b24153e341c5f941232c", - "offset": 2496, - "new_text": "①宜乎百姓之谓我爱也(《齐桓晋文之事》)\u000b②悔相道之不察兮,延伫乎吾将反(《离骚》)③西望夏口,东望武昌,山川相缪,郁乎苍苍(《赤壁赋》)\u000b④长铗归来乎!", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 43, - "end": 45, - "id": 187159, - "idx": 119, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①宜乎百姓之谓我爱也(《齐桓晋文之事》) \u000b②悔相道之不察兮,延伫乎吾将反(《离骚》) \u000b③西望夏口,东望武昌,山川相缪,郁乎苍苍(《赤壁赋》) \u000b④长铗归来乎!", - "insert_len": 81, - "paragraph_offset": 10, - "sentence_offset": 345, - "paragraph_num": 16 - }, - { - "key": "d2e53a82e3d12c44358b991f8bfe43e8", - "offset": 2579, - "new_text": "出无车(《冯谖客孟尝君》)\u000b5.用在句中的停顿处。", - "insert": "出无车(《冯谖客孟尝君》) \u000b5.用在句中的停顿处。", - "insert_len": 26, - "paragraph_offset": 10, - "sentence_offset": 426, - "paragraph_num": 16 - }, - { - "key": "a665e44d4e4b0bcc22e5a523b75ddb69", - "offset": 2605, - "new_text": "①于是乎书。", - "insert": "①于是乎书。", - "insert_len": 6, - "paragraph_offset": 10, - "sentence_offset": 452, - "paragraph_num": 16 - }, - { - "key": "51c7035a177d16636e9ba77204226d3b", - "offset": 2613, - "new_text": "(二)用作介词,相当于“于”,在文中有不同的翻译。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 11, - "end": 12, - "id": 187160, - "idx": 122, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 13, - "end": 14, - "id": 187161, - "idx": 123, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(二)用作介词,相当于\"于\",在文中有不同的翻译。", - "insert_len": 25, - "paragraph_offset": 10, - "sentence_offset": 458, - "paragraph_num": 16 - }, - { - "key": "e8cc8c272053a42a3edff4e62a9358fc", - "offset": 2640, - "new_text": "①醉翁之意不在酒,在乎山水之间也。", - "insert": "①醉翁之意不在酒,在乎山水之间也。", - "insert_len": 17, - "paragraph_offset": 10, - "sentence_offset": 483, - "paragraph_num": 16 - }, - { - "key": "951b22f2f96f7fd6c752ef5dbc43c494", - "offset": 2659, - "new_text": "(《岳阳楼记》)(乎:于)\u000b②今虽死乎此,比吾乡邻之死则已后矣。", - "insert": "(《岳阳楼记》)(乎:于) \u000b②今虽死乎此,比吾乡邻之死则已后矣。", - "insert_len": 33, - "paragraph_offset": 10, - "sentence_offset": 500, - "paragraph_num": 16 - }, - { - "key": "856cbb5aedba884487db32debab37cd4", - "offset": 2692, - "new_text": "(《捕蛇者说》)(乎:在)\u000b③生乎吾前,其闻道也固先乎吾?(《师说》)(前一个“乎”:在;后一个“乎”:比。)", - "diffs": [ - { - "tag": "r", - "origin": "?", - "text": "?", - "start": 29, - "end": 30, - "id": 187162, - "idx": 126, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《捕蛇者说》)(乎:在) \u000b③生乎吾前,其闻道也固先乎吾?(《师说》)(前一个“乎”:在;后一个“乎”:比。)", - "insert_len": 56, - "paragraph_offset": 10, - "sentence_offset": 533, - "paragraph_num": 16 - }, - { - "key": "9f008cc8d90c00c06944878bdf0a0b1d", - "offset": 2748, - "new_text": "④吾尝疑乎是。", - "insert": "④吾尝疑乎是。", - "insert_len": 7, - "paragraph_offset": 10, - "sentence_offset": 589, - "paragraph_num": 16 - }, - { - "key": "43cd96e0383f78282c70daa7cd094d34", - "offset": 2757, - "new_text": "(乎:对。)", - "insert": "(乎:对。)", - "insert_len": 6, - "paragraph_offset": 10, - "sentence_offset": 596, - "paragraph_num": 16 - }, - { - "key": "0af84adaad075d7ec26c5d77be257cf1", - "offset": 2763, - "new_text": "⑤君子博学而日参省乎己。", - "insert": "⑤君子博学而日参省乎己。", - "insert_len": 12, - "paragraph_offset": 10, - "sentence_offset": 602, - "paragraph_num": 16 - }, - { - "key": "42fe166b884c0ba83493b5ac37d232a6", - "offset": 2777, - "new_text": "(《论语》)(乎:对。)", - "insert": "(《论语》)(乎:对。)", - "insert_len": 12, - "paragraph_offset": 10, - "sentence_offset": 614, - "paragraph_num": 16 - }, - { - "key": "266b050e7d6d7aa733881056e2c6a4c0", - "offset": 2789, - "new_text": "⑥亦无怪乎其私之也。", - "insert": "⑥亦无怪乎其私之也。", - "insert_len": 10, - "paragraph_offset": 10, - "sentence_offset": 626, - "paragraph_num": 16 - }, - { - "key": "9d1f975f9129bd523b555b8afd271a3e", - "offset": 2801, - "new_text": "(乎:对于)\u000b⑦盖进乎技矣。", - "insert": "(乎:对于) \u000b⑦盖进乎技矣。", - "insert_len": 15, - "paragraph_offset": 10, - "sentence_offset": 636, - "paragraph_num": 16 - }, - { - "key": "d2fed477e31791d60679eeeb5898a5c3", - "offset": 2816, - "new_text": "(《庖丁解牛》)(乎:比)\u000b⑧以吾一日长乎尔。", - "insert": "(《庖丁解牛》)(乎:比) \u000b⑧以吾一日长乎尔。", - "insert_len": 24, - "paragraph_offset": 10, - "sentence_offset": 651, - "paragraph_num": 16 - }, - { - "key": "519e75f38112cbb02924fea378a70607", - "offset": 2840, - "new_text": "(尔:比。)", - "insert": "(尔:比。)", - "insert_len": 6, - "paragraph_offset": 10, - "sentence_offset": 675, - "paragraph_num": 16 - }, - { - "key": "ad52903c56dc9b0c28b7d448b43fbcae", - "offset": 2846, - "new_text": "(三)可作词尾,译为“……的样子”“……地”。", - "insert": "(三)可作词尾,译为“……的样子”“……地”。", - "insert_len": 23, - "paragraph_offset": 10, - "sentence_offset": 681, - "paragraph_num": 16 - }, - { - "key": "4e2a6e52321477e1adbe3052620614a2", - "offset": 2871, - "new_text": "①以无厚入有间,恢恢乎其于游刃必有余地矣(《庖丁解牛》)\u000b②浩浩乎如冯虚御风,而不知其所止;飘飘乎如遗世独立,羽化而登仙(《赤壁赋》)", - "insert": "①以无厚入有间,恢恢乎其于游刃必有余地矣(《庖丁解牛》) \u000b②浩浩乎如冯虚御风,而不知其所止;飘飘乎如遗世独立,羽化而登仙(《赤壁赋》)\n", - "insert_len": 69, - "paragraph_offset": 10, - "sentence_offset": 704, - "paragraph_num": 16 - }, - { - "key": "c38275cdacb261e8b5336e36fa0522ad", - "offset": 2945, - "new_text": "4.【乃】 \u000b(一)用作副词。", - "insert": "4.【乃】  \u000b(一)用作副词。", - "insert_len": 16, - "paragraph_offset": 11, - "sentence_offset": 0, - "paragraph_num": 24 - }, - { - "key": "296d0a09710428d61a2f1b4ce87aab62", - "offset": 2961, - "new_text": "1.表示前后两事在情理上的顺承或时间上的紧接,可译为“这才”“才”“就”等\u000b①设九宾于廷,臣乃敢上璧。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "这", - "start": 27, - "end": 27, - "id": 187163, - "idx": 131, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": "这", - "text": "", - "start": 30, - "end": 31, - "id": 187164, - "idx": 132, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.表示前后两事在情理上的顺承或时间上的紧接,可译为“才”“这才”“就”等 \u000b①设九宾于廷,臣乃敢上璧。", - "insert_len": 52, - "paragraph_offset": 11, - "sentence_offset": 16, - "paragraph_num": 24 - }, - { - "key": "4b8d8b1e2aaf9f47034ab6b40bde433d", - "offset": 3015, - "new_text": "(《廉颇蔺相如列传》)\u000b②悉使蠃兵负草填之,骑乃得过。", - "insert": "(《廉颇蔺相如列传》) \u000b②悉使蠃兵负草填之,骑乃得过。", - "insert_len": 28, - "paragraph_offset": 11, - "sentence_offset": 68, - "paragraph_num": 24 - }, - { - "key": "b86b1b241996639e61cffc61300f56b0", - "offset": 3043, - "new_text": "(《赤壁之战》)\u000b③度我至军中,公乃入。", - "insert": "(《赤壁之战》) \u000b③度我至军中,公乃入。", - "insert_len": 21, - "paragraph_offset": 11, - "sentence_offset": 96, - "paragraph_num": 24 - }, - { - "key": "e4b31247b07288f1685b16f4b43712d2", - "offset": 3064, - "new_text": "(《鸿门宴》)\u000b2.强调某一行为出乎意料或违背常理,可译为“却”“竟(然)”“反而”等;\u000b①问今是何世,乃不知不汉。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 30, - "end": 31, - "id": 187165, - "idx": 137, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 32, - "end": 34, - "id": 187166, - "idx": 138, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 38, - "end": 40, - "id": 187167, - "idx": 139, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 42, - "end": 43, - "id": 187168, - "idx": 140, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b2.强调某一行为出乎意料或违背常理,可译为\"却\"\"竟(然)\"\"反而\"等; \u000b①问今是何世,乃不知不汉。", - "insert_len": 60, - "paragraph_offset": 11, - "sentence_offset": 117, - "paragraph_num": 24 - }, - { - "key": "856013ba56b0cf32d61bef77f03788ea", - "offset": 3124, - "new_text": "(《桃花源记》)\u000b②今其智乃反不能及。", - "insert": "(《桃花源记》) \u000b②今其智乃反不能及。", - "insert_len": 20, - "paragraph_offset": 11, - "sentence_offset": 177, - "paragraph_num": 24 - }, - { - "key": "451019d3ebbb76d7dbbb4a0b36f7cf7a", - "offset": 3144, - "new_text": "(《师说》)\u000b③而陋者乃以斧斤考击而求之。", - "insert": "(《师说》) \u000b③而陋者乃以斧斤考击而求之。", - "insert_len": 22, - "paragraph_offset": 11, - "sentence_offset": 197, - "paragraph_num": 24 - }, - { - "key": "2fac5467ef2c11eaeb928166f1bcf3b3", - "offset": 3166, - "new_text": "(《石钟山记》)\u000b④夫赵强而燕弱,而君幸于赵王,故燕王欲结于君。", - "insert": "(《石钟山记》) \u000b④夫赵强而燕弱,而君幸于赵王,故燕王欲结于君。", - "insert_len": 33, - "paragraph_offset": 11, - "sentence_offset": 219, - "paragraph_num": 24 - }, - { - "key": "50fbf200ec3ddea2a5699b866cb47be8", - "offset": 3199, - "new_text": "今君乃亡赵走燕。", - "insert": "今君乃亡赵走燕。", - "insert_len": 8, - "paragraph_offset": 11, - "sentence_offset": 252, - "paragraph_num": 24 - }, - { - "key": "754cef44473e88af52e589a16ff8fa77", - "offset": 3207, - "new_text": "(《廉颇蔺相如列传》)\u000b3.可表示对事物范围的一种限制,可译为“只”“仅”等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 32, - "end": 33, - "id": 187169, - "idx": 146, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 34, - "end": 36, - "id": 187170, - "idx": 147, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 37, - "end": 38, - "id": 187171, - "idx": 148, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b3.可表示对事物范围的一种限制,可译为\"只\"\"仅\"等。", - "insert_len": 40, - "paragraph_offset": 11, - "sentence_offset": 260, - "paragraph_num": 24 - }, - { - "key": "5a64fcede1f9077c04dfd7e8c7cd8064", - "offset": 3247, - "new_text": "①项王乃复引兵而东,至东城,乃有二十八骑。", - "insert": "①项王乃复引兵而东,至东城,乃有二十八骑。", - "insert_len": 21, - "paragraph_offset": 11, - "sentence_offset": 300, - "paragraph_num": 24 - }, - { - "key": "0f4e7a5e229d21928607529bd4efa6bb", - "offset": 3270, - "new_text": "(《项羽本纪》)\u000b4.用在判断句中,起确认作用,可译为“是”“就是”等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 28, - "end": 29, - "id": 187172, - "idx": 150, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 30, - "end": 32, - "id": 187173, - "idx": 151, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 34, - "end": 35, - "id": 187174, - "idx": 152, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《项羽本纪》) \u000b4.用在判断句中,起确认作用,可译为\"是\"\"就是\"等。", - "insert_len": 37, - "paragraph_offset": 11, - "sentence_offset": 321, - "paragraph_num": 24 - }, - { - "key": "1610b1f66f24ee69d93001dcb3aff539", - "offset": 3307, - "new_text": "①若事之不济,此乃天也。", - "insert": "①若事之不济,此乃天也。", - "insert_len": 12, - "paragraph_offset": 11, - "sentence_offset": 358, - "paragraph_num": 24 - }, - { - "key": "51b46063600f9df72fd0bff9970315b9", - "offset": 3321, - "new_text": "(《赤壁之战》)\u000b②嬴乃夷门抱关者也。", - "insert": "(《赤壁之战》) \u000b②嬴乃夷门抱关者也。", - "insert_len": 20, - "paragraph_offset": 11, - "sentence_offset": 370, - "paragraph_num": 24 - }, - { - "key": "cdd907c41098d462a9db60ec5c3573c1", - "offset": 3341, - "new_text": "(《信陵君窃符救赵》)\u000b③无伤也,是乃仁术也,见牛未见羊也(《齐桓晋文之事》)(二)用作代词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 40, - "end": 42, - "id": 187175, - "idx": 155, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《信陵君窃符救赵》) \u000b③无伤也,是乃仁术也,见牛未见羊也(《齐桓晋文之事》) \u000b(二)用作代词。", - "insert_len": 50, - "paragraph_offset": 11, - "sentence_offset": 390, - "paragraph_num": 24 - }, - { - "key": "cdde5cfb8d362425621c3a380f5535ad", - "offset": 3391, - "new_text": "1.用作第二人称,常做定语,译为“你的”;也做主语,译为“你”。", - "diffs": [ - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 10, - "end": 11, - "id": 187176, - "idx": 156, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 16, - "end": 17, - "id": 187177, - "idx": 157, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 19, - "end": 20, - "id": 187178, - "idx": 158, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 22, - "end": 23, - "id": 187179, - "idx": 159, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 28, - "end": 29, - "id": 187180, - "idx": 160, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 30, - "end": 31, - "id": 187181, - "idx": 161, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.用作第二人称,常作定语,译为\"你的\";也作主语,译为\"你\"。", - "insert_len": 32, - "paragraph_offset": 11, - "sentence_offset": 440, - "paragraph_num": 24 - }, - { - "key": "df37c3afa6dea3c7b13edbf0f20d18d8", - "offset": 3425, - "new_text": "不能做宾语。", - "diffs": [ - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 2, - "end": 3, - "id": 187182, - "idx": 162, - "isAccept": 0, - "type": 2 - } - ], - "insert": "不能作宾语。", - "insert_len": 6, - "paragraph_offset": 11, - "sentence_offset": 472, - "paragraph_num": 24 - }, - { - "key": "5dc772c565045d8c894547a93641fc98", - "offset": 3431, - "new_text": "①王师北定中原日,家祭无忘告乃翁。", - "insert": "①王师北定中原日,家祭无忘告乃翁。", - "insert_len": 17, - "paragraph_offset": 11, - "sentence_offset": 478, - "paragraph_num": 24 - }, - { - "key": "15132bb0ebdb9dd1d9d03867f9ef495f", - "offset": 3450, - "new_text": "(陆游《示儿》)\u000b2.用作指示代词,译为“这样”。", - "diffs": [ - { - "tag": "d", - "origin": " ", - "text": "", - "start": 25, - "end": 26, - "id": 187183, - "idx": 164, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(陆游《示儿》) \u000b2.用作指示代词,译为“这样” 。", - "insert_len": 27, - "paragraph_offset": 11, - "sentence_offset": 495, - "paragraph_num": 24 - }, - { - "key": "8369d2e59b9fd8ae6ebcf4ff06b56dd3", - "offset": 3477, - "new_text": "①夫我乃行之,反而求之,不得吾心(《齐桓晋文之事》)\u000b3.还可做连词用,释为“若夫”、“至于”“如果”等。", - "diffs": [ - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 32, - "end": 33, - "id": 187184, - "idx": 166, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 39, - "end": 40, - "id": 187185, - "idx": 167, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 42, - "end": 43, - "id": 187186, - "idx": 168, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 44, - "end": 45, - "id": 187187, - "idx": 169, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 47, - "end": 49, - "id": 187188, - "idx": 170, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 51, - "end": 52, - "id": 187189, - "idx": 171, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①夫我乃行之,反而求之,不得吾心(《齐桓晋文之事》) \u000b3.还可作连词用,释为\"若夫\"、\"至于\"\"如果\"等。", - "insert_len": 54, - "paragraph_offset": 11, - "sentence_offset": 522, - "paragraph_num": 24 - }, - { - "key": "d5e2c826d5e905f03c20beedc3f8127f", - "offset": 3533, - "new_text": "(缺例文)\u000b【无乃】表猜测,译为“恐怕……”", - "insert": "(缺例文) \u000b【无乃】表猜测,译为“恐怕……”", - "insert_len": 23, - "paragraph_offset": 11, - "sentence_offset": 576, - "paragraph_num": 24 - }, - { - "key": "81197c2d02b3a7c54cbd498ce55a73c8", - "offset": 3558, - "new_text": "。", - "insert": "。", - "insert_len": 1, - "paragraph_offset": 11, - "sentence_offset": 599, - "paragraph_num": 24 - }, - { - "key": "baae7df6b79960201946af9b685fe6ee", - "offset": 3559, - "new_text": "①今君王既栖于会稽之上,然后乃求谋臣,无乃后乎(《勾践灭吴》)\u000b②无乃尔是过与(《季氏将伐颛臾》)③今少卿乃教以推贤进士,无乃与仆私心剌谬乎(《报任安书》)\u000b【乃尔】译为“这样”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 50, - "end": 52, - "id": 187190, - "idx": 174, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①今君王既栖于会稽之上,然后乃求谋臣,无乃后乎(《勾践灭吴》) \u000b②无乃尔是过与(《季氏将伐颛臾》) \u000b③今少卿乃教以推贤进士,无乃与仆私心剌谬乎(《报任安书》) \u000b【乃尔】译为“这样”。", - "insert_len": 94, - "paragraph_offset": 11, - "sentence_offset": 600, - "paragraph_num": 24 - }, - { - "key": "4a98d522ca8c0fb7b6bc849390386b37", - "offset": 3655, - "new_text": "①府吏再拜还,长叹空房中,作计乃尔立(《孔雀东南飞》)", - "insert": "①府吏再拜还,长叹空房中,作计乃尔立(《孔雀东南飞》)\n", - "insert_len": 28, - "paragraph_offset": 11, - "sentence_offset": 694, - "paragraph_num": 24 - }, - { - "key": "e22408b011f905bda382124231c3d71c", - "offset": 3688, - "new_text": "5.【其】\u000b(一)用作代词,又分几种情况:\u000b1.第三人称代词。", - "insert": "5.【其】 \u000b(一)用作代词,又分几种情况: \u000b1.第三人称代词。", - "insert_len": 33, - "paragraph_offset": 12, - "sentence_offset": 0, - "paragraph_num": 37 - }, - { - "key": "5553c85ed012eee2ca2c607803976981", - "offset": 3721, - "new_text": "作领属性定语,可译为“他的”,“它的”(包括复数)。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 10, - "end": 11, - "id": 187191, - "idx": 178, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 13, - "end": 14, - "id": 187192, - "idx": 179, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 15, - "end": 16, - "id": 187193, - "idx": 180, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 18, - "end": 19, - "id": 187194, - "idx": 181, - "isAccept": 0, - "type": 2 - } - ], - "insert": "作领属性定语,可译为\"他的\",\"它的\"(包括复数)。", - "insert_len": 26, - "paragraph_offset": 12, - "sentence_offset": 33, - "paragraph_num": 37 - }, - { - "key": "822951d06f552b90959bd98e59057a31", - "offset": 3747, - "new_text": "①臣从其计,大王亦幸赦臣。", - "insert": "①臣从其计,大王亦幸赦臣。", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 59, - "paragraph_num": 37 - }, - { - "key": "d213cd542a52c4dddde866a672128718", - "offset": 3762, - "new_text": "(《廉颇蔺相如列传》)\u000b2.第三人称代词。", - "insert": "(《廉颇蔺相如列传》) \u000b2.第三人称代词。", - "insert_len": 22, - "paragraph_offset": 12, - "sentence_offset": 72, - "paragraph_num": 37 - }, - { - "key": "5845b2090263c41d0d047845f8b5d0f8", - "offset": 3784, - "new_text": "作主谓短语中的小主语,应译为“他”“它”(包括复数)。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 14, - "end": 15, - "id": 187195, - "idx": 183, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 16, - "end": 18, - "id": 187196, - "idx": 184, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 19, - "end": 20, - "id": 187197, - "idx": 185, - "isAccept": 0, - "type": 2 - } - ], - "insert": "作主谓短语中的小主语,应译为\"他\"\"它\"(包括复数)。", - "insert_len": 27, - "paragraph_offset": 12, - "sentence_offset": 94, - "paragraph_num": 37 - }, - { - "key": "e4460319dc157845782e2735ce0363d2", - "offset": 3811, - "new_text": "①秦王恐其破壁。", - "insert": "①秦王恐其破壁。", - "insert_len": 8, - "paragraph_offset": 12, - "sentence_offset": 121, - "paragraph_num": 37 - }, - { - "key": "ccc1d23c81ef4f1fdb4973e1ac139788", - "offset": 3821, - "new_text": "(《廉颇蔺相如列传》)\u000b②其闻道也固先乎吾。", - "insert": "(《廉颇蔺相如列传》) \u000b②其闻道也固先乎吾。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 129, - "paragraph_num": 37 - }, - { - "key": "40754d8573d1e3e4b4f2deeff9c2e3c8", - "offset": 3844, - "new_text": "(《师说》)\u000b3.活用为第一人称或第二人称。", - "insert": "(《师说》) \u000b3.活用为第一人称或第二人称。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 152, - "paragraph_num": 37 - }, - { - "key": "b0857cb12d12835737f286754ec77d87", - "offset": 3867, - "new_text": "译为“我的”“我(自己)”或者“你的”“你”。", - "insert": "译为“我的”“我(自己)”或者“你的”“你”。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 175, - "paragraph_num": 37 - }, - { - "key": "2ea01f74aaed57dca430db3e503b488c", - "offset": 3890, - "new_text": "①今肃迎操,操当以肃还付乡党,品其名位,犹不失下曹从事。", - "insert": "①今肃迎操,操当以肃还付乡党,品其名位,犹不失下曹从事。", - "insert_len": 28, - "paragraph_offset": 12, - "sentence_offset": 198, - "paragraph_num": 37 - }, - { - "key": "5c2ad5e0705eb749a15166e4c783caf6", - "offset": 3920, - "new_text": "(《赤壁之战》)\u000b②而余亦悔其随之而不得极夫游之乐也。", - "insert": "(《赤壁之战》) \u000b②而余亦悔其随之而不得极夫游之乐也。", - "insert_len": 28, - "paragraph_offset": 12, - "sentence_offset": 226, - "paragraph_num": 37 - }, - { - "key": "8359975a98211b331052d4b7ea211d03", - "offset": 3948, - "new_text": "(《游褒禅山记》)\u000b③老臣以媪为长安君计短也,故以为其爱不若燕后(《触龙说赵太后》)4.指示代词,表示远指。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 43, - "end": 45, - "id": 187198, - "idx": 190, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《游褒禅山记》) \u000b③老臣以媪为长安君计短也,故以为其爱不若燕后(《触龙说赵太后》) \u000b4.指示代词,表示远指。", - "insert_len": 57, - "paragraph_offset": 12, - "sentence_offset": 254, - "paragraph_num": 37 - }, - { - "key": "8924aed63cd808b6eb1323a32bc7cb0c", - "offset": 4005, - "new_text": "可译为“那”“那个”“那些”“那里”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187199, - "idx": 191, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 5, - "end": 7, - "id": 187200, - "idx": 192, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 9, - "end": 11, - "id": 187201, - "idx": 193, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 13, - "end": 15, - "id": 187202, - "idx": 194, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 17, - "end": 18, - "id": 187203, - "idx": 195, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"那\"\"那个\"\"那些\"\"那里\"。", - "insert_len": 19, - "paragraph_offset": 12, - "sentence_offset": 311, - "paragraph_num": 37 - }, - { - "key": "c2008868336716a9bb5e0f81dcc7fe83", - "offset": 4024, - "new_text": "①及其出,则或咎其欲出者。", - "insert": "①及其出,则或咎其欲出者。", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 330, - "paragraph_num": 37 - }, - { - "key": "4c6c3759ad7a8f62903d72487f318820", - "offset": 4039, - "new_text": "(《游褒禅山记》)\u000b②今操得荆州,奄有其地。", - "insert": "(《游褒禅山记》) \u000b②今操得荆州,奄有其地。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 343, - "paragraph_num": 37 - }, - { - "key": "385ecbdd69d5e3cb0f8c6274f7a4bd49", - "offset": 4062, - "new_text": "(《赤壁之战》)\u000b③不嫁义郎体,其往欲何云?", - "insert": "(《赤壁之战》) \u000b③不嫁义郎体,其往欲何云?", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 366, - "paragraph_num": 37 - }, - { - "key": "62ae6507b77cf6f6de806060a8d32288", - "offset": 4085, - "new_text": "(《孔雀东南飞》)\u000b5.指示代词,表示近指,相当于“这”“这个”“这些”。", - "insert": "(《孔雀东南飞》) \u000b5.指示代词,表示近指,相当于“这”“这个”“这些”。", - "insert_len": 38, - "paragraph_offset": 12, - "sentence_offset": 389, - "paragraph_num": 37 - }, - { - "key": "d70816cc936edbb7ba41e18b6ec19279", - "offset": 4123, - "new_text": "①有蒋氏者,专其利三世矣。", - "insert": "①有蒋氏者,专其利三世矣。", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 427, - "paragraph_num": 37 - }, - { - "key": "0220c0555aa5f8c083b62b828fa04e44", - "offset": 4138, - "new_text": "(《捕蛇者说》)\u000b②今存其本不忍废。", - "insert": "(《捕蛇者说》) \u000b②今存其本不忍废。", - "insert_len": 19, - "paragraph_offset": 12, - "sentence_offset": 440, - "paragraph_num": 37 - }, - { - "key": "9166a955a8a464458a4945192f7b9685", - "offset": 4157, - "new_text": "(其:这)\u000b5.指示代词,表示“其中的”,后面多为数词。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 16, - "end": 17, - "id": 187204, - "idx": 201, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 20, - "end": 21, - "id": 187205, - "idx": 202, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(其:这) \u000b5.指示代词,表示\"其中的\",后面多为数词。", - "insert_len": 29, - "paragraph_offset": 12, - "sentence_offset": 459, - "paragraph_num": 37 - }, - { - "key": "e70e8cc8caa09d4263dd010add729cde", - "offset": 4186, - "new_text": "①于乱石间择其一二扣之。", - "insert": "①于乱石间择其一二扣之。", - "insert_len": 12, - "paragraph_offset": 12, - "sentence_offset": 488, - "paragraph_num": 37 - }, - { - "key": "b965be7ae2d1737959e668d2a94b1b34", - "offset": 4200, - "new_text": "(《石钟山记》)\u000b(二)用作副词。", - "insert": "(《石钟山记》) \u000b(二)用作副词。", - "insert_len": 18, - "paragraph_offset": 12, - "sentence_offset": 500, - "paragraph_num": 37 - }, - { - "key": "56dbef8b447613d74eaeb1a3f8094898", - "offset": 4218, - "new_text": "1.加强祈使语气,相当于“可”、“还是”。", - "insert": "1.加强祈使语气,相当于“可”、“还是”。", - "insert_len": 21, - "paragraph_offset": 12, - "sentence_offset": 518, - "paragraph_num": 37 - }, - { - "key": "94bf5a3dd688fd2da2f1cc9f6d688ef3", - "offset": 4241, - "new_text": "①寡人欲以五百里之地易安陵,安陵君其许寡人!", - "insert": "①寡人欲以五百里之地易安陵,安陵君其许寡人!", - "insert_len": 22, - "paragraph_offset": 12, - "sentence_offset": 539, - "paragraph_num": 37 - }, - { - "key": "3465691ac85dbee220f05690e878f9e3", - "offset": 4266, - "new_text": "(其:可要)\u000b②攻之不克,围之不继,吾其还也。", - "insert": "(其:可要) \u000b②攻之不克,围之不继,吾其还也。", - "insert_len": 24, - "paragraph_offset": 12, - "sentence_offset": 561, - "paragraph_num": 37 - }, - { - "key": "b8bd553cab3ea1e42996c205e7f138f7", - "offset": 4290, - "new_text": "(《烛之武退秦师》)\u000b③与尔三矢,尔其无忘乃父之志!", - "insert": "(《烛之武退秦师》) \u000b③与尔三矢,尔其无忘乃父之志!", - "insert_len": 27, - "paragraph_offset": 12, - "sentence_offset": 585, - "paragraph_num": 37 - }, - { - "key": "ea783ffcbc30fe3a79e07dd1b4734182", - "offset": 4317, - "new_text": "(《伶官传序》)\u000b2.加强揣测语气,相当于“恐怕”“或许”“大概”“可能”。", - "diffs": [ - { - "tag": "d", - "origin": "、", - "text": "", - "start": 26, - "end": 27, - "id": 187206, - "idx": 207, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": "、", - "text": "", - "start": 31, - "end": 32, - "id": 187207, - "idx": 208, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": "、", - "text": "", - "start": 36, - "end": 37, - "id": 187208, - "idx": 209, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《伶官传序》) \u000b2.加强揣测语气,相当于“恐怕”、“或许”、“大概”、“可能”。", - "insert_len": 42, - "paragraph_offset": 12, - "sentence_offset": 612, - "paragraph_num": 37 - }, - { - "key": "b75ac3272389c28b1cbbefb6a31d4d12", - "offset": 4359, - "new_text": "①圣人之所以为圣,愚人之所以为愚,其皆出于此乎?", - "insert": "①圣人之所以为圣,愚人之所以为愚,其皆出于此乎?", - "insert_len": 24, - "paragraph_offset": 12, - "sentence_offset": 654, - "paragraph_num": 37 - }, - { - "key": "9f15ff70b71b26831ac3d339992b5995", - "offset": 4386, - "new_text": "(《师说》)\u000b②王之好乐甚,则齐国其庶几乎?", - "insert": "(《师说》) \u000b②王之好乐甚,则齐国其庶几乎?", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 678, - "paragraph_num": 37 - }, - { - "key": "02ebcf49b8dc371f2d9cfa0102890352", - "offset": 4409, - "new_text": "(《庄暴见孟子》)\u000b3.加强反问语气,相当于“难道”、“怎么”。", - "diffs": [ - { - "tag": "d", - "origin": " ", - "text": "", - "start": 32, - "end": 33, - "id": 187209, - "idx": 212, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《庄暴见孟子》) \u000b3.加强反问语气,相当于“难道”、“怎么” 。", - "insert_len": 34, - "paragraph_offset": 12, - "sentence_offset": 701, - "paragraph_num": 37 - }, - { - "key": "694e90200e8257e7b1222b11f75d9d5a", - "offset": 4443, - "new_text": "①以残年余力,曾不能毁山之一毛,其如土石何?", - "insert": "①以残年余力,曾不能毁山之一毛,其如土石何?", - "insert_len": 22, - "paragraph_offset": 12, - "sentence_offset": 735, - "paragraph_num": 37 - }, - { - "key": "49f6a38c8de794f5046bba492205a661", - "offset": 4467, - "new_text": "(《愚公移山》)\u000b②尽吾志也而不能至者,可以无悔矣 ,其孰能讥之乎?", - "diffs": [ - { - "tag": "d", - "origin": " ", - "text": "", - "start": 20, - "end": 21, - "id": 187210, - "idx": 214, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《愚公移山》) \u000b②尽吾志也而不能至者 ,可以无悔矣 ,其孰能讥之乎?", - "insert_len": 36, - "paragraph_offset": 12, - "sentence_offset": 757, - "paragraph_num": 37 - }, - { - "key": "caf22ea81788da113d0b7d6220ba5b2a", - "offset": 4503, - "new_text": "(《游褒禅山记》)\u000b③且行千里,其谁不知?", - "insert": "(《游褒禅山记》) \u000b③且行千里,其谁不知?", - "insert_len": 22, - "paragraph_offset": 12, - "sentence_offset": 793, - "paragraph_num": 37 - }, - { - "key": "7a55f622bd39d7d8538385ade2743071", - "offset": 4525, - "new_text": "(三)用作连词。", - "insert": "(三)用作连词。", - "insert_len": 8, - "paragraph_offset": 12, - "sentence_offset": 815, - "paragraph_num": 37 - }, - { - "key": "72235bc8e5590e5dcfe68f21dc5e94ce", - "offset": 4535, - "new_text": "1.表示选择关系,相当于“是……还是……”", - "insert": "1.表示选择关系,相当于“是……还是……”", - "insert_len": 21, - "paragraph_offset": 12, - "sentence_offset": 823, - "paragraph_num": 37 - }, - { - "key": "81197c2d02b3a7c54cbd498ce55a73c8", - "offset": 4558, - "new_text": "。", - "insert": "。", - "insert_len": 1, - "paragraph_offset": 12, - "sentence_offset": 844, - "paragraph_num": 37 - }, - { - "key": "b57ef6778e3b88d39d818a09b7aece8f", - "offset": 4560, - "new_text": "①其真无马邪?", - "insert": "①其真无马邪?", - "insert_len": 7, - "paragraph_offset": 12, - "sentence_offset": 845, - "paragraph_num": 37 - }, - { - "key": "9c33dcf39a238f6cbcfc4ab766b91e9c", - "offset": 4569, - "new_text": "其真不知马也?", - "insert": "其真不知马也?", - "insert_len": 7, - "paragraph_offset": 12, - "sentence_offset": 852, - "paragraph_num": 37 - }, - { - "key": "cebce06f9b6c9a69e206919a6acccaf5", - "offset": 4576, - "new_text": "(《马说》)\u000b②呜呼!", - "insert": "(《马说》) \u000b②呜呼!", - "insert_len": 12, - "paragraph_offset": 12, - "sentence_offset": 859, - "paragraph_num": 37 - }, - { - "key": "0d2a9b5ebae6eedfa86a79bbb1da54b2", - "offset": 4588, - "new_text": "其信然邪?", - "insert": "其信然邪?", - "insert_len": 5, - "paragraph_offset": 12, - "sentence_offset": 871, - "paragraph_num": 37 - }, - { - "key": "b11f86e50508fc3028ca66efef28b419", - "offset": 4593, - "new_text": "其梦邪?", - "insert": "其梦邪?", - "insert_len": 4, - "paragraph_offset": 12, - "sentence_offset": 876, - "paragraph_num": 37 - }, - { - "key": "1d583eb4f560924ad0eaad1af5bee5d3", - "offset": 4597, - "new_text": "其传之非其真邪?", - "insert": "其传之非其真邪?", - "insert_len": 8, - "paragraph_offset": 12, - "sentence_offset": 880, - "paragraph_num": 37 - }, - { - "key": "7f66312c6739aa164266d248390d7070", - "offset": 4605, - "new_text": "(《祭十二郎文》)\u000b2.表示假设关系,相当于“如果”。", - "insert": "(《祭十二郎文》) \u000b2.表示假设关系,相当于“如果”。", - "insert_len": 28, - "paragraph_offset": 12, - "sentence_offset": 888, - "paragraph_num": 37 - }, - { - "key": "961bab177d171b3cbfe7afebed07bafb", - "offset": 4633, - "new_text": "①其业有不精,德有不成者,非天质之卑,则心不若余之专耳。", - "insert": "①其业有不精,德有不成者,非天质之卑,则心不若余之专耳。", - "insert_len": 28, - "paragraph_offset": 12, - "sentence_offset": 916, - "paragraph_num": 37 - }, - { - "key": "aa6267640f053d9f8b5b909e7d97ab44", - "offset": 4664, - "new_text": "②沛然下雨,则苗浡然兴之矣。", - "insert": "②沛然下雨,则苗浡然兴之矣。", - "insert_len": 14, - "paragraph_offset": 12, - "sentence_offset": 944, - "paragraph_num": 37 - }, - { - "key": "8eee18f2c11742bba8df3084085274ab", - "offset": 4680, - "new_text": "其若是,孰能御之?", - "insert": "其若是,孰能御之?", - "insert_len": 9, - "paragraph_offset": 12, - "sentence_offset": 958, - "paragraph_num": 37 - }, - { - "key": "617b8dd78d76a46261915e5aa2d3d732", - "offset": 4689, - "new_text": "(《孟子见梁襄王》)\u000b(四)助词,起调节音节的作用,不可译。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "不", - "start": 27, - "end": 27, - "id": 187211, - "idx": 219, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": "不", - "text": "", - "start": 28, - "end": 29, - "id": 187212, - "idx": 220, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《孟子见梁襄王》) \u000b(四)助词,起调节音节的作用,可不译。", - "insert_len": 31, - "paragraph_offset": 12, - "sentence_offset": 967, - "paragraph_num": 37 - }, - { - "key": "98b80ee2b196c5dcb9e09e6893f64165", - "offset": 4720, - "new_text": "①路曼曼其修远兮,吾将上下而求索(《离骚》)\u000b②佩缤纷其繁饰兮,芳菲菲其弥章(《离骚》)【何其】译为“多么”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 45, - "end": 47, - "id": 187213, - "idx": 222, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①路曼曼其修远兮,吾将上下而求索(《离骚》) \u000b②佩缤纷其繁饰兮,芳菲菲其弥章(《离骚》) \u000b【何其】译为“多么”。", - "insert_len": 58, - "paragraph_offset": 12, - "sentence_offset": 998, - "paragraph_num": 37 - }, - { - "key": "ccb15a86ef0fb4177b586f305f708a10", - "offset": 4780, - "new_text": "①至于誓天断发,泣下沾襟,何其衰也!(《伶官传序》)\u000b\u000b6.【且】\u000b(一)用作连词。", - "diffs": [ - { - "tag": "r", - "origin": "!", - "text": "!", - "start": 17, - "end": 18, - "id": 187214, - "idx": 223, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①至于誓天断发,泣下沾襟,何其衰也!(《伶官传序》) \u000b\u000b6.【且】 \u000b(一)用作连词。", - "insert_len": 44, - "paragraph_offset": 12, - "sentence_offset": 1056, - "paragraph_num": 37 - }, - { - "key": "3f12a34fff6ed2bccb88ad609820c82a", - "offset": 4826, - "new_text": "1.递进关系,而且,并且。", - "insert": "1.递进关系,而且,并且。", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 1100, - "paragraph_num": 37 - }, - { - "key": "42372156bc6a217a58214280e8641292", - "offset": 4841, - "new_text": "例:\u000b①且立石于其墓之门(《五人墓碑记》)②肃宣权旨,论天下事势,致殷勤之意,且问备曰。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 22, - "end": 24, - "id": 187215, - "idx": 227, - "isAccept": 0, - "type": 2 - } - ], - "insert": "例: \u000b①且立石于其墓之门(《五人墓碑记》) \u000b②肃宣权旨,论天下事势,致殷勤之意,且问备曰。", - "insert_len": 47, - "paragraph_offset": 12, - "sentence_offset": 1113, - "paragraph_num": 37 - }, - { - "key": "600307755d234b870bd72be88d22afac", - "offset": 4888, - "new_text": "(《赤壁之战》)\u000b③彼所将中国人不过十五六万,且己久疲。", - "insert": "(《赤壁之战》) \u000b③彼所将中国人不过十五六万,且己久疲。", - "insert_len": 29, - "paragraph_offset": 12, - "sentence_offset": 1160, - "paragraph_num": 37 - }, - { - "key": "a75aeea9050c51c8cc9509dad565fd35", - "offset": 4917, - "new_text": "(《赤壁之战》)\u000b2.递进关系,况且,再说。", - "insert": "(《赤壁之战》) \u000b2.递进关系,况且,再说。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 1189, - "paragraph_num": 37 - }, - { - "key": "f3a097399507be8754d033136e88d48e", - "offset": 4940, - "new_text": "①且壮士不死即已,死即举大名耳。", - "insert": "①且壮士不死即已,死即举大名耳。", - "insert_len": 16, - "paragraph_offset": 12, - "sentence_offset": 1212, - "paragraph_num": 37 - }, - { - "key": "5de235c7e8f50926a35dc6ee32408500", - "offset": 4958, - "new_text": "(《陈涉世家》)\u000b②且将军大势可以拒操者,长江也。", - "insert": "(《陈涉世家》) \u000b②且将军大势可以拒操者,长江也。", - "insert_len": 26, - "paragraph_offset": 12, - "sentence_offset": 1228, - "paragraph_num": 37 - }, - { - "key": "9c78c4d77d6a0e219dcf20637a488394", - "offset": 4984, - "new_text": "(《赤壁之战》)\u000b③且燕赵处秦革灭殆尽之际。", - "insert": "(《赤壁之战》) \u000b③且燕赵处秦革灭殆尽之际。", - "insert_len": 23, - "paragraph_offset": 12, - "sentence_offset": 1254, - "paragraph_num": 37 - }, - { - "key": "803af0b2951b2c87fa453519930b7b8b", - "offset": 5007, - "new_text": "(《六国论》)\u000b3.让步关系,尚且,还。", - "insert": "(《六国论》) \u000b3.让步关系,尚且,还。", - "insert_len": 21, - "paragraph_offset": 12, - "sentence_offset": 1277, - "paragraph_num": 37 - }, - { - "key": "5c94def154d88084b97e4a1edc632235", - "offset": 5028, - "new_text": "①臣死且不避,卮酒安足辞!", - "insert": "①臣死且不避,卮酒安足辞!", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 1298, - "paragraph_num": 37 - }, - { - "key": "9e82607eb4e3a1eee507b8bc44552299", - "offset": 5043, - "new_text": "(《鸿门宴》)\u000b②故之圣人,其出人也远矣,犹且从师而问焉(《师说》)4.并列关系:又,又……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 35, - "end": 37, - "id": 187216, - "idx": 234, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b②故之圣人,其出人也远矣,犹且从师而问焉(《师说》) \u000b4.并列关系:又,又……", - "insert_len": 49, - "paragraph_offset": 12, - "sentence_offset": 1311, - "paragraph_num": 37 - }, - { - "key": "ca4491da4c337c8f6982a2befaf1e683", - "offset": 5092, - "new_text": "又……", - "insert": "又……", - "insert_len": 3, - "paragraph_offset": 12, - "sentence_offset": 1360, - "paragraph_num": 37 - }, - { - "key": "bd1ec35d58ff005cd704c04933e4de5b", - "offset": 5095, - "new_text": ",一面……", - "insert": ",一面……", - "insert_len": 5, - "paragraph_offset": 12, - "sentence_offset": 1363, - "paragraph_num": 37 - }, - { - "key": "bd1ec35d58ff005cd704c04933e4de5b", - "offset": 5100, - "new_text": ",一面……", - "insert": ",一面……", - "insert_len": 5, - "paragraph_offset": 12, - "sentence_offset": 1368, - "paragraph_num": 37 - }, - { - "key": "5cdb90fe2f6ca0e52dd6b705f047ad43", - "offset": 5105, - "new_text": "①示赵弱且怯也。", - "insert": "①示赵弱且怯也。", - "insert_len": 8, - "paragraph_offset": 12, - "sentence_offset": 1373, - "paragraph_num": 37 - }, - { - "key": "6392c794dd8a03626a9dc6cc12baa2a8", - "offset": 5115, - "new_text": "(《廉颇蔺相如列传》)\u000b②命如南山石,四体康且直(《孔雀东南飞》)③又有若老人咳且笑于山谷中者(《石钟山记》)\u000b④凡四方之士无有不过而拜且泣者。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 34, - "end": 36, - "id": 187217, - "idx": 236, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b②命如南山石,四体康且直(《孔雀东南飞》) \u000b③又有若老人咳且笑于山谷中者(《石钟山记》) \u000b④凡四方之士无有不过而拜且泣者。", - "insert_len": 76, - "paragraph_offset": 12, - "sentence_offset": 1381, - "paragraph_num": 37 - }, - { - "key": "8d42f73bcb6da819882957091dcc041d", - "offset": 5191, - "new_text": "(《五人墓碑记》)\u000b(二)用作副词。", - "insert": "(《五人墓碑记》) \u000b(二)用作副词。", - "insert_len": 19, - "paragraph_offset": 12, - "sentence_offset": 1457, - "paragraph_num": 37 - }, - { - "key": "df8208a915eeb5ad6399b4809b7a4946", - "offset": 5210, - "new_text": "1.将,将要。", - "insert": "1.将,将要。", - "insert_len": 7, - "paragraph_offset": 12, - "sentence_offset": 1476, - "paragraph_num": 37 - }, - { - "key": "d16adacaa3c8b5771c68becf210402f0", - "offset": 5219, - "new_text": "①有怠而欲出者,曰:“不出,火且尽”(《游褒禅山记》)\u000b②且为之奈何(《鸿门宴》)③若属皆且为所虏(《鸿门宴》)\u000b④卿但暂还家,吾今且报府。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 42, - "end": 44, - "id": 187218, - "idx": 240, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①有怠而欲出者,曰:“不出,火且尽”(《游褒禅山记》) \u000b②且为之奈何(《鸿门宴》) \u000b③若属皆且为所虏(《鸿门宴》) \u000b④卿但暂还家,吾今且报府。", - "insert_len": 74, - "paragraph_offset": 12, - "sentence_offset": 1483, - "paragraph_num": 37 - }, - { - "key": "85d1c43731773f62d422a49e5c926bae", - "offset": 5295, - "new_text": "(《孔雀东南飞》)\u000b2.暂且,姑且。", - "insert": "(《孔雀东南飞》) \u000b2.暂且,姑且。", - "insert_len": 19, - "paragraph_offset": 12, - "sentence_offset": 1557, - "paragraph_num": 37 - }, - { - "key": "36eb2688bfc8571c0202d51e83c8142f", - "offset": 5314, - "new_text": "①存者且偷生,死者长已矣!", - "insert": "①存者且偷生,死者长已矣!", - "insert_len": 13, - "paragraph_offset": 12, - "sentence_offset": 1576, - "paragraph_num": 37 - }, - { - "key": "d3b8363f4ae8e0ec9d65a7ddce348c7f", - "offset": 5329, - "new_text": "(《石壕吏》)\u000b②誓不相隔卿,且暂还家去。", - "insert": "(《石壕吏》) \u000b②誓不相隔卿,且暂还家去。", - "insert_len": 22, - "paragraph_offset": 12, - "sentence_offset": 1589, - "paragraph_num": 37 - }, - { - "key": "4c03da222e225fbadec45352ac521c12", - "offset": 5351, - "new_text": "(《孔雀东南飞》)\u000b【且夫】句首助词,表示下文是更进一步的议论,“况且”,“再说”。", - "insert": "(《孔雀东南飞》) \u000b【且夫】句首助词,表示下文是更进一步的议论,“况且”,“再说”。", - "insert_len": 43, - "paragraph_offset": 12, - "sentence_offset": 1611, - "paragraph_num": 37 - }, - { - "key": "670f008a708e6674f827d45da94e9933", - "offset": 5394, - "new_text": "例:\u000b①且夫天下非小弱也,雍州之地,殽函之固,自若也(《过秦论》)②且夫天地之间,物各有主(《赤壁赋》)\u000b③且夫臧获婢妾,犹能引决,况仆之不得已乎(《报任安书》)【且如】就像。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 34, - "end": 36, - "id": 187219, - "idx": 246, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 85, - "end": 87, - "id": 187220, - "idx": 248, - "isAccept": 0, - "type": 2 - } - ], - "insert": "例: \u000b①且夫天下非小弱也,雍州之地,殽函之固,自若也(《过秦论》) \u000b②且夫天地之间,物各有主(《赤壁赋》) \u000b③且夫臧获婢妾,犹能引决,况仆之不得已乎(《报任安书》) \u000b【且如】就像。", - "insert_len": 94, - "paragraph_offset": 12, - "sentence_offset": 1654, - "paragraph_num": 37 - }, - { - "key": "6daed6cf7af7fd6214fdb38e46d85de6", - "offset": 5488, - "new_text": "①且如今年冬,未休关西卒(《兵车行》)", - "insert": "①且如今年冬,未休关西卒(《兵车行》)\n", - "insert_len": 20, - "paragraph_offset": 12, - "sentence_offset": 1748, - "paragraph_num": 37 - }, - { - "key": "189e386ff5fc184122fd0da26fb16df8", - "offset": 5513, - "new_text": "7.【若】\u000b(一)动词,像,好像。", - "insert": "7.【若】 \u000b(一)动词,像,好像。", - "insert_len": 18, - "paragraph_offset": 13, - "sentence_offset": 0, - "paragraph_num": 46 - }, - { - "key": "82e54c980685d7e533eac9373d65d35e", - "offset": 5531, - "new_text": "①视之,形若土狗,梅花翅,方首,长胫,意似良(《促织》)\u000b②吾不忍其觳觫,若无罪而就死地(《齐桓晋文之事》)③其若是,孰有御之。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 55, - "end": 57, - "id": 187221, - "idx": 251, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①视之,形若土狗,梅花翅,方首,长胫,意似良(《促织》) \u000b②吾不忍其觳觫,若无罪而就死地(《齐桓晋文之事》) \u000b③其若是,孰有御之。", - "insert_len": 67, - "paragraph_offset": 13, - "sentence_offset": 18, - "paragraph_num": 46 - }, - { - "key": "8c1c5270467c0b8f58afaf7f0d1e5354", - "offset": 5600, - "new_text": "(《孟子见梁襄王》)\u000b(二)用作代词。", - "insert": "(《孟子见梁襄王》) \u000b(二)用作代词。", - "insert_len": 20, - "paragraph_offset": 13, - "sentence_offset": 85, - "paragraph_num": 46 - }, - { - "key": "b303f5bb363f25ddb1753198364406bb", - "offset": 5620, - "new_text": "1. 表对称,相当于“你”“你们”;做定语时则译为“你的”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 10, - "end": 11, - "id": 187222, - "idx": 253, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 12, - "end": 14, - "id": 187223, - "idx": 254, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 16, - "end": 17, - "id": 187224, - "idx": 255, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "作", - "text": "做", - "start": 18, - "end": 19, - "id": 187225, - "idx": 256, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 25, - "end": 26, - "id": 187226, - "idx": 257, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 28, - "end": 29, - "id": 187227, - "idx": 258, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1. 表对称,相当于\"你\"\"你们\";作定语时则译为\"你的\"。", - "insert_len": 30, - "paragraph_offset": 13, - "sentence_offset": 105, - "paragraph_num": 46 - }, - { - "key": "24f9fb7f89bef27f75419c3804f41c70", - "offset": 5652, - "new_text": "①若入前为寿 ,寿毕 ,请以剑舞(《鸿门宴》)\u000b②不者,若属皆且为所虏(《鸿门宴》若属:你们这些)③更若役,复若赋……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 50, - "end": 52, - "id": 187228, - "idx": 260, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①若入前为寿 ,寿毕 ,请以剑舞(《鸿门宴》) \u000b②不者,若属皆且为所虏(《鸿门宴》若属:你们这些) \u000b③更若役,复若赋……", - "insert_len": 62, - "paragraph_offset": 13, - "sentence_offset": 135, - "paragraph_num": 46 - }, - { - "key": "99d71a44c7bcf3808326465df7c247bc", - "offset": 5716, - "new_text": "(《捕蛇者说》你的)\u000b2.表近指,相当于“这”“这样”“如此”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 21, - "end": 22, - "id": 187229, - "idx": 262, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 23, - "end": 25, - "id": 187230, - "idx": 263, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 27, - "end": 29, - "id": 187231, - "idx": 264, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 31, - "end": 32, - "id": 187232, - "idx": 265, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《捕蛇者说》你的) \u000b2.表近指,相当于\"这\"\"这样\"\"如此\"。", - "insert_len": 33, - "paragraph_offset": 13, - "sentence_offset": 197, - "paragraph_num": 46 - }, - { - "key": "81b56d41a41c127b386fd90cf48aeaf1", - "offset": 5749, - "new_text": "①以若所为求若所欲,犹缘木而求鱼也(《齐桓晋文之事》)\u000b(三)用作连词。", - "insert": "①以若所为求若所欲,犹缘木而求鱼也(《齐桓晋文之事》) \u000b(三)用作连词。", - "insert_len": 37, - "paragraph_offset": 13, - "sentence_offset": 230, - "paragraph_num": 46 - }, - { - "key": "2b913baeee762e04dbcd1cd0903a8807", - "offset": 5788, - "new_text": "1.表假设,相当于“如果”“假设”等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 9, - "end": 10, - "id": 187233, - "idx": 267, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 12, - "end": 14, - "id": 187234, - "idx": 268, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 16, - "end": 17, - "id": 187235, - "idx": 269, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.表假设,相当于\"如果\"\"假设\"等。", - "insert_len": 19, - "paragraph_offset": 13, - "sentence_offset": 267, - "paragraph_num": 46 - }, - { - "key": "3fe210a218eb26972168aaabcd9b8c07", - "offset": 5809, - "new_text": "①若据而有之,此帝王之资也。", - "insert": "①若据而有之,此帝王之资也。", - "insert_len": 14, - "paragraph_offset": 13, - "sentence_offset": 286, - "paragraph_num": 46 - }, - { - "key": "204e4299e7a99636f72f38d2c6b14ecd", - "offset": 5825, - "new_text": "(《赤壁之战》)\u000b②若备与彼协心,上下齐同,则宜抚安,与结盟好。", - "insert": "(《赤壁之战》) \u000b②若备与彼协心,上下齐同,则宜抚安,与结盟好。", - "insert_len": 33, - "paragraph_offset": 13, - "sentence_offset": 300, - "paragraph_num": 46 - }, - { - "key": "4b8e263051bad7a30bcb52e1d8e0dab0", - "offset": 5858, - "new_text": "(《赤壁之战》)\u000b③若不能,何不按兵束甲,北面而事之!", - "insert": "(《赤壁之战》) \u000b③若不能,何不按兵束甲,北面而事之!", - "insert_len": 28, - "paragraph_offset": 13, - "sentence_offset": 333, - "paragraph_num": 46 - }, - { - "key": "ed29167b9557e4d72af7e3dbebd832ce", - "offset": 5886, - "new_text": "(《赤壁之战》)\u000b2.表选择,相当于“或”“或者”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 19, - "end": 20, - "id": 187236, - "idx": 273, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 21, - "end": 23, - "id": 187237, - "idx": 274, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 25, - "end": 26, - "id": 187238, - "idx": 275, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《赤壁之战》) \u000b2.表选择,相当于\"或\"\"或者\"。", - "insert_len": 27, - "paragraph_offset": 13, - "sentence_offset": 361, - "paragraph_num": 46 - }, - { - "key": "c0330c9701bb6f4323d3c26f45e66006", - "offset": 5913, - "new_text": "①以万人若一郡降者,封万户。", - "insert": "①以万人若一郡降者,封万户。", - "insert_len": 14, - "paragraph_offset": 13, - "sentence_offset": 388, - "paragraph_num": 46 - }, - { - "key": "5dba86cb4528ecab16a68fc66ac34814", - "offset": 5929, - "new_text": "(《汉书·高帝纪》)\u000b3.至,至于。", - "insert": "(《汉书·高帝纪》) \u000b3.至,至于。", - "insert_len": 19, - "paragraph_offset": 13, - "sentence_offset": 402, - "paragraph_num": 46 - }, - { - "key": "be5ec43493e4e55296f503544b5c18a2", - "offset": 5948, - "new_text": "①若民,则无恒产,因无恒心。", - "insert": "①若民,则无恒产,因无恒心。", - "insert_len": 14, - "paragraph_offset": 13, - "sentence_offset": 421, - "paragraph_num": 46 - }, - { - "key": "eff4486f8b0687219c3fd02000f51a00", - "offset": 5964, - "new_text": "(《齐桓晋文之事》)\u000b【若夫】是用在一段话的开头、引起论述的词。", - "insert": "(《齐桓晋文之事》) \u000b【若夫】是用在一段话的开头、引起论述的词。", - "insert_len": 33, - "paragraph_offset": 13, - "sentence_offset": 435, - "paragraph_num": 46 - }, - { - "key": "42a1387775087941a5aaf65d7db6dc2a", - "offset": 5997, - "new_text": "近似“要说那”、“像那”的意思。", - "insert": "近似“要说那”、“像那”的意思。", - "insert_len": 16, - "paragraph_offset": 13, - "sentence_offset": 468, - "paragraph_num": 46 - }, - { - "key": "53e4171cf5a24f7cd6ce873343f33166", - "offset": 6013, - "new_text": "①若夫淫雨霏霏,连月不开。", - "diffs": [ - { - "tag": "r", - "origin": "霪", - "text": "淫", - "start": 3, - "end": 4, - "id": 187239, - "idx": 278, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①若夫霪雨霏霏,连月不开。", - "insert_len": 13, - "paragraph_offset": 13, - "sentence_offset": 484, - "paragraph_num": 46 - }, - { - "key": "2dd2069cb509198330189b43821206fe", - "offset": 6028, - "new_text": "(《岳阳楼记》)\u000b②若夫乘天地之正,而御六气之辩,以游无穷者,彼且恶乎待哉(《逍遥游》)【若定】心中有数,从容不迫。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 45, - "end": 47, - "id": 187240, - "idx": 280, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《岳阳楼记》) \u000b②若夫乘天地之正,而御六气之辩,以游无穷者,彼且恶乎待哉(《逍遥游》) \u000b【若定】心中有数,从容不迫。", - "insert_len": 61, - "paragraph_offset": 13, - "sentence_offset": 497, - "paragraph_num": 46 - }, - { - "key": "a70f53ccdf14c440fa63509c848bf244", - "offset": 6089, - "new_text": "①指挥若定。", - "insert": "①指挥若定。", - "insert_len": 6, - "paragraph_offset": 13, - "sentence_offset": 558, - "paragraph_num": 46 - }, - { - "key": "566462e786a64d6d4d42d63a0a832599", - "offset": 6097, - "new_text": "(《赤壁之战》)\u000b【若何】怎么样?", - "diffs": [ - { - "tag": "r", - "origin": "。", - "text": "?", - "start": 17, - "end": 18, - "id": 187241, - "idx": 282, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《赤壁之战》) \u000b【若何】怎么样。", - "insert_len": 18, - "paragraph_offset": 13, - "sentence_offset": 564, - "paragraph_num": 46 - }, - { - "key": "0c3da54abbe6d166c5d621770cdf9d25", - "offset": 6115, - "new_text": "①以闲敝邑,若何?", - "insert": "①以闲敝邑,若何?", - "insert_len": 9, - "paragraph_offset": 13, - "sentence_offset": 582, - "paragraph_num": 46 - }, - { - "key": "9a06850342d2ce7bb246bdd17917fd58", - "offset": 6126, - "new_text": "(《崤之战》)\u000b【若干】约计之词,相当于“几许”、“多少”。", - "insert": "(《崤之战》) \u000b【若干】约计之词,相当于“几许”、“多少”。", - "insert_len": 31, - "paragraph_offset": 13, - "sentence_offset": 591, - "paragraph_num": 46 - }, - { - "key": "9114c9c456368c6c57acc313b838c335", - "offset": 6157, - "new_text": "①车后若干递送夫。", - "insert": "①车后若干递送夫。\n", - "insert_len": 10, - "paragraph_offset": 13, - "sentence_offset": 622, - "paragraph_num": 46 - }, - { - "key": "34762a41145fd421081e168969cf5be1", - "offset": 6172, - "new_text": "8.【所】\u000b(一)名词,处所,地方。", - "insert": "8.【所】 \u000b(一)名词,处所,地方。", - "insert_len": 19, - "paragraph_offset": 14, - "sentence_offset": 0, - "paragraph_num": 59 - }, - { - "key": "42cc3239f8479660043397c4ff7d7e0b", - "offset": 6191, - "new_text": "①又间令吴广之次所旁丛祠中。", - "insert": "①又间令吴广之次所旁丛祠中。", - "insert_len": 14, - "paragraph_offset": 14, - "sentence_offset": 19, - "paragraph_num": 59 - }, - { - "key": "742e854bb96b311656cc2945c8c25f24", - "offset": 6207, - "new_text": "(《陈涉世家》)\u000b②成反复自念,得无教我猎虫所耶?", - "insert": "(《陈涉世家》) \u000b②成反复自念,得无教我猎虫所耶?", - "insert_len": 26, - "paragraph_offset": 14, - "sentence_offset": 33, - "paragraph_num": 59 - }, - { - "key": "e1662b84d3bfff53f520db80e0937ced", - "offset": 6233, - "new_text": "(《促织》)\u000b③某所,而母立于兹。", - "insert": "(《促织》) \u000b③某所,而母立于兹。", - "insert_len": 18, - "paragraph_offset": 14, - "sentence_offset": 59, - "paragraph_num": 59 - }, - { - "key": "5c8f6f450af5f121fb00692d6978171c", - "offset": 6251, - "new_text": "(《项脊轩志》)\u000b(二)助词1.放在动词前同动词组成“所”字结构,表示“所……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 15, - "end": 17, - "id": 187242, - "idx": 288, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 29, - "end": 30, - "id": 187243, - "idx": 289, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 31, - "end": 32, - "id": 187244, - "idx": 290, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 38, - "end": 39, - "id": 187245, - "idx": 291, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《项脊轩志》) \u000b(二)助词 \u000b1.放在动词前同动词组成\"所\"字结构,表示\"所……", - "insert_len": 42, - "paragraph_offset": 14, - "sentence_offset": 77, - "paragraph_num": 59 - }, - { - "key": "cf937ec2f6a035a883cb1312851a6cc0", - "offset": 6293, - "new_text": "的人“、”所……", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 2, - "end": 3, - "id": 187246, - "idx": 292, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 4, - "end": 5, - "id": 187247, - "idx": 293, - "isAccept": 0, - "type": 2 - } - ], - "insert": "的人\"、\"所……", - "insert_len": 8, - "paragraph_offset": 14, - "sentence_offset": 119, - "paragraph_num": 59 - }, - { - "key": "aa234aa5614d194370a73f415c40df3c", - "offset": 6301, - "new_text": "的事物“、”所……", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187248, - "idx": 294, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 5, - "end": 6, - "id": 187249, - "idx": 295, - "isAccept": 0, - "type": 2 - } - ], - "insert": "的事物\"、\"所……", - "insert_len": 9, - "paragraph_offset": 14, - "sentence_offset": 127, - "paragraph_num": 59 - }, - { - "key": "27f8596fe59ee854d49b9639181afa96", - "offset": 6310, - "new_text": "的情况“等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187250, - "idx": 296, - "isAccept": 0, - "type": 2 - } - ], - "insert": "的情况\"等。", - "insert_len": 6, - "paragraph_offset": 14, - "sentence_offset": 136, - "paragraph_num": 59 - }, - { - "key": "9f0af333b1b7eeb6c1bdc9e78d68c365", - "offset": 6316, - "new_text": "①会征促织,成不敢敛户口,而又无所赔偿(《促织》)\u000b②道之所存,师之所存也。", - "insert": "①会征促织,成不敢敛户口,而又无所赔偿(《促织》) \u000b②道之所存,师之所存也。", - "insert_len": 39, - "paragraph_offset": 14, - "sentence_offset": 142, - "paragraph_num": 59 - }, - { - "key": "4728e92fd6059276d22ae30c94bdc71a", - "offset": 6357, - "new_text": "(《师说》)\u000b③过蒙拔擢,宠命优渥,岂敢盘桓,有所希冀(《陈情表》)2.“所”和动词结合,后面再有名词性结构,则所字结构起定语的作用。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 35, - "end": 37, - "id": 187251, - "idx": 299, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《师说》) \u000b③过蒙拔擢,宠命优渥,岂敢盘桓,有所希冀(《陈情表》) \u000b2.“所”和动词结合,后面再有名词性结构,则所字结构起定语的作用。", - "insert_len": 70, - "paragraph_offset": 14, - "sentence_offset": 181, - "paragraph_num": 59 - }, - { - "key": "db1535e87c259edcec7f80fb2705a08d", - "offset": 6427, - "new_text": "①夜则以兵围所寓舍。", - "insert": "①夜则以兵围所寓舍。", - "insert_len": 10, - "paragraph_offset": 14, - "sentence_offset": 251, - "paragraph_num": 59 - }, - { - "key": "028666309ebf0911937b74cd60273372", - "offset": 6439, - "new_text": "(《〈指南录〉后序》)\u000b②臣所过屠者朱亥(《信陵君窃符救赵》)【为……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 32, - "end": 34, - "id": 187252, - "idx": 301, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《〈指南录〉后序》) \u000b②臣所过屠者朱亥(《信陵君窃符救赵》) \u000b【为……", - "insert_len": 38, - "paragraph_offset": 14, - "sentence_offset": 261, - "paragraph_num": 59 - }, - { - "key": "93861fa889b91ad43aaf3a5ea3fe51f2", - "offset": 6477, - "new_text": "所】“为”和“所”呼应,组成“为……", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 14, - "end": 15, - "id": 187253, - "idx": 302, - "isAccept": 0, - "type": 2 - } - ], - "insert": "所】“为”和“所”呼应,组成\"为……", - "insert_len": 18, - "paragraph_offset": 14, - "sentence_offset": 299, - "paragraph_num": 59 - }, - { - "key": "890518a506028bb956b544738a8d7448", - "offset": 6495, - "new_text": "所……", - "insert": "所……", - "insert_len": 3, - "paragraph_offset": 14, - "sentence_offset": 317, - "paragraph_num": 59 - }, - { - "key": "41e23450bdd518197a73ad97bee26144", - "offset": 6498, - "new_text": "“的格式,表示被动。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 0, - "end": 1, - "id": 187254, - "idx": 303, - "isAccept": 0, - "type": 2 - } - ], - "insert": "\"的格式,表示被动。", - "insert_len": 10, - "paragraph_offset": 14, - "sentence_offset": 320, - "paragraph_num": 59 - }, - { - "key": "5ace7550ed6c4d2178e1bb1678c14d50", - "offset": 6508, - "new_text": "①嬴闻如姬父为人所杀。", - "insert": "①嬴闻如姬父为人所杀。", - "insert_len": 11, - "paragraph_offset": 14, - "sentence_offset": 330, - "paragraph_num": 59 - }, - { - "key": "0ac5cb75afd49339b6d9447e450581ce", - "offset": 6521, - "new_text": "(《信陵君窃符救赵》)\u000b②仆以口语遇遭此祸,重为乡党所笑,以污辱先人(《报任安书》)【所以】1.表示行为所凭借的方式、方法或依据,相当于“用来……的方法”“是用来……的”“等。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 43, - "end": 45, - "id": 187255, - "idx": 305, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 49, - "end": 51, - "id": 187256, - "idx": 306, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " ", - "text": "", - "start": 82, - "end": 83, - "id": 187257, - "idx": 307, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 91, - "end": 92, - "id": 187258, - "idx": 308, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《信陵君窃符救赵》) \u000b②仆以口语遇遭此祸,重为乡党所笑,以污辱先人(《报任安书》) \u000b【所以】 \u000b1.表示行为所凭借的方式、方法或依据,相当于“用来……的方法” “是用来……的”\"等。", - "insert_len": 94, - "paragraph_offset": 14, - "sentence_offset": 341, - "paragraph_num": 59 - }, - { - "key": "0432500acbdf9399d89b99764e55fa07", - "offset": 6615, - "new_text": "①吾所以待侯生者备矣,天下莫不闻(《信陵君窃符救赵》)\u000b②师者,所以传道受业解惑也。", - "insert": "①吾所以待侯生者备矣,天下莫不闻(《信陵君窃符救赵》) \u000b②师者,所以传道受业解惑也。", - "insert_len": 43, - "paragraph_offset": 14, - "sentence_offset": 435, - "paragraph_num": 59 - }, - { - "key": "28850752c660c8bcdb6f2aca38302428", - "offset": 6660, - "new_text": "(《师说》)\u000b2.表示原因。", - "insert": "(《师说》) \u000b2.表示原因。", - "insert_len": 15, - "paragraph_offset": 14, - "sentence_offset": 478, - "paragraph_num": 59 - }, - { - "key": "a81ec02659cf7765e46cf2f2a8ac09fc", - "offset": 6675, - "new_text": "相当于“……的原因(缘故)”。", - "insert": "相当于“……的原因(缘故)”。", - "insert_len": 15, - "paragraph_offset": 14, - "sentence_offset": 493, - "paragraph_num": 59 - }, - { - "key": "4f242fb7e1a568bbfa0f52c6db0599a6", - "offset": 6690, - "new_text": "①臣所以去亲戚而事君者,徒慕君之高义也。", - "insert": "①臣所以去亲戚而事君者,徒慕君之高义也。", - "insert_len": 20, - "paragraph_offset": 14, - "sentence_offset": 508, - "paragraph_num": 59 - }, - { - "key": "52bc7c467c020708a5d1f1014e453809", - "offset": 6712, - "new_text": "(《廉颇蔺相如列传》)\u000b②吾所以为此者,以先国家之急而后私仇也。", - "insert": "(《廉颇蔺相如列传》) \u000b②吾所以为此者,以先国家之急而后私仇也。", - "insert_len": 33, - "paragraph_offset": 14, - "sentence_offset": 528, - "paragraph_num": 59 - }, - { - "key": "b77bf1d6c5830061921114eb5e826fe6", - "offset": 6745, - "new_text": "(《廉颇蔺相如列传》)\u000b③所以遣将守关者,备他盗之出入与非常也。", - "insert": "(《廉颇蔺相如列传》) \u000b③所以遣将守关者,备他盗之出入与非常也。", - "insert_len": 33, - "paragraph_offset": 14, - "sentence_offset": 561, - "paragraph_num": 59 - }, - { - "key": "dcc3fc4a3d52cff2fcf9324618d928bc", - "offset": 6778, - "new_text": "(《鸿门宴》)\u000b【所谓】所说的。", - "insert": "(《鸿门宴》) \u000b【所谓】所说的。", - "insert_len": 17, - "paragraph_offset": 14, - "sentence_offset": 594, - "paragraph_num": 59 - }, - { - "key": "2faeb66b1b347f36a27f01c4a819ed47", - "offset": 6795, - "new_text": "①此所谓战胜于朝廷。", - "insert": "①此所谓战胜于朝廷。", - "insert_len": 10, - "paragraph_offset": 14, - "sentence_offset": 611, - "paragraph_num": 59 - }, - { - "key": "d83b96293b4b0adf2fdd78d78ed6c300", - "offset": 6807, - "new_text": "(《邹忌讽齐王纳谏》)\u000b②非吾所谓传其道解其惑者也。", - "insert": "(《邹忌讽齐王纳谏》) \u000b②非吾所谓传其道解其惑者也。", - "insert_len": 27, - "paragraph_offset": 14, - "sentence_offset": 621, - "paragraph_num": 59 - }, - { - "key": "3a0d09f418b129e51421503c22a1050f", - "offset": 6834, - "new_text": "(《师说》)\u000b【所在】\u000b1.到处。", - "insert": "(《师说》) \u000b【所在】 \u000b1.到处。", - "insert_len": 19, - "paragraph_offset": 14, - "sentence_offset": 648, - "paragraph_num": 59 - }, - { - "key": "99ede80b1c2563220e1beab3ed8bbdf2", - "offset": 6853, - "new_text": "①石之铿然有声音者,所在皆是也。", - "insert": "①石之铿然有声音者,所在皆是也。", - "insert_len": 16, - "paragraph_offset": 14, - "sentence_offset": 667, - "paragraph_num": 59 - }, - { - "key": "43f3c24c06cf54018df08880213d5c50", - "offset": 6871, - "new_text": "(《石钟山记》)\u000b2.所在之处,处所。", - "insert": "(《石钟山记》) \u000b2.所在之处,处所。", - "insert_len": 20, - "paragraph_offset": 14, - "sentence_offset": 683, - "paragraph_num": 59 - }, - { - "key": "f36abb51d9eb7449a379ba6885449b9b", - "offset": 6891, - "new_text": "①原来有这等一个所在,且回衙去(《闺塾》)\u000b②急趋之,折过墙隅,迷其所在。", - "insert": "①原来有这等一个所在,且回衙去(《闺塾》) \u000b②急趋之,折过墙隅,迷其所在。", - "insert_len": 38, - "paragraph_offset": 14, - "sentence_offset": 703, - "paragraph_num": 59 - }, - { - "key": "a854058a381419336a448f97b341e764", - "offset": 6931, - "new_text": "(《促织》)", - "insert": "(《促织》)\n", - "insert_len": 7, - "paragraph_offset": 14, - "sentence_offset": 741, - "paragraph_num": 59 - }, - { - "key": "8f0eb510026cbe2ab0839972c346a56b", - "offset": 6941, - "new_text": "9.【为】 \u000b(一)动词。", - "insert": "9.【为】  \u000b(一)动词。", - "insert_len": 14, - "paragraph_offset": 15, - "sentence_offset": 0, - "paragraph_num": 69 - }, - { - "key": "290b3647c6216c02afac92dd432d5e9a", - "offset": 6955, - "new_text": "1.有“做”“作为”“充当”“变成”“成为”等义,翻译比较灵活。", - "insert": "1.有“做”“作为”“充当”“变成”“成为”等义,翻译比较灵活。", - "insert_len": 32, - "paragraph_offset": 15, - "sentence_offset": 14, - "paragraph_num": 69 - }, - { - "key": "eaded8b1ba053830b0b5feb3502c7de4", - "offset": 6989, - "new_text": "①斩木为兵,揭竿为旗。", - "insert": "①斩木为兵,揭竿为旗。", - "insert_len": 11, - "paragraph_offset": 15, - "sentence_offset": 46, - "paragraph_num": 69 - }, - { - "key": "6e8dd39038e06d276f9b76ef5aab8bc8", - "offset": 7002, - "new_text": "(《过秦论》)\u000b②然后以六合为家,崤函为宫。", - "insert": "(《过秦论》) \u000b②然后以六合为家,崤函为宫。", - "insert_len": 23, - "paragraph_offset": 15, - "sentence_offset": 57, - "paragraph_num": 69 - }, - { - "key": "e8d45f9b9efcb9d54514f484e6c4c8e1", - "offset": 7025, - "new_text": "(《过秦论》)\u000b③卒相与欢,为刎颈之交。", - "insert": "(《过秦论》) \u000b③卒相与欢,为刎颈之交。", - "insert_len": 21, - "paragraph_offset": 15, - "sentence_offset": 80, - "paragraph_num": 69 - }, - { - "key": "af99d3605fce881482b7ede76797e9ef", - "offset": 7046, - "new_text": "(《廉颇蔺相如列传》)\u000b④冰,水为之,而寒于水。", - "insert": "(《廉颇蔺相如列传》) \u000b④冰,水为之,而寒于水。", - "insert_len": 25, - "paragraph_offset": 15, - "sentence_offset": 101, - "paragraph_num": 69 - }, - { - "key": "aa14675a8d2f933e9398865f2ea94a6f", - "offset": 7071, - "new_text": "(《劝学》)\u000b⑤赵王窃闻秦王善为(演奏)秦声。", - "insert": "(《劝学》) \u000b⑤赵王窃闻秦王善为(演奏)秦声。", - "insert_len": 24, - "paragraph_offset": 15, - "sentence_offset": 126, - "paragraph_num": 69 - }, - { - "key": "d23edc0f806653f7febe97733f09ed11", - "offset": 7095, - "new_text": "(《廉颇蔺相如列传》)\u000b⑥今日嬴之为(帮助)公子亦足矣(《信陵君窃符救赵》)⑦南取百越之地,以为(划为)桂林、象郡。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 39, - "end": 41, - "id": 187259, - "idx": 325, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b⑥今日嬴之为(帮助)公子亦足矣(《信陵君窃符救赵》) \u000b⑦南取百越之地,以为(划为)桂林、象郡。", - "insert_len": 61, - "paragraph_offset": 15, - "sentence_offset": 150, - "paragraph_num": 69 - }, - { - "key": "f4e43c6a7ac038a9cf342c9b5312b550", - "offset": 7156, - "new_text": "(《过秦论》)\u000b⑧为(治理)国以礼,其言不让,是故晒之。", - "insert": "(《过秦论》) \u000b⑧为(治理)国以礼,其言不让,是故晒之。", - "insert_len": 29, - "paragraph_offset": 15, - "sentence_offset": 211, - "paragraph_num": 69 - }, - { - "key": "5a4340408ddd61e5e1ff1b46dc7d0478", - "offset": 7185, - "new_text": "(《论语》)\u000b2.以为,认为。", - "insert": "(《论语》) \u000b2.以为,认为。", - "insert_len": 16, - "paragraph_offset": 15, - "sentence_offset": 240, - "paragraph_num": 69 - }, - { - "key": "0490a9dfa49152be781e6501308fba47", - "offset": 7201, - "new_text": "①此亡秦之续耳。", - "insert": "①此亡秦之续耳。", - "insert_len": 8, - "paragraph_offset": 15, - "sentence_offset": 256, - "paragraph_num": 69 - }, - { - "key": "206ec1841586c017d99645aec8a49bd9", - "offset": 7211, - "new_text": "窃为大王不取也(《鸿门宴》)\u000b②两小儿笑曰:“孰为汝多知乎!”", - "insert": "窃为大王不取也(《鸿门宴》) \u000b②两小儿笑曰:“孰为汝多知乎!”", - "insert_len": 32, - "paragraph_offset": 15, - "sentence_offset": 264, - "paragraph_num": 69 - }, - { - "key": "925a47ea5d065cf70e6069e7c7090dd1", - "offset": 7243, - "new_text": "(《两小儿辩日》) \u000b3.判断词,是。", - "insert": "(《两小儿辩日》)  \u000b3.判断词,是。", - "insert_len": 20, - "paragraph_offset": 15, - "sentence_offset": 296, - "paragraph_num": 69 - }, - { - "key": "94e543da26fd0390550d93ff44c23d3c", - "offset": 7263, - "new_text": "①如今人方为刀俎,我为鱼肉。", - "insert": "①如今人方为刀俎,我为鱼肉。", - "insert_len": 14, - "paragraph_offset": 15, - "sentence_offset": 316, - "paragraph_num": 69 - }, - { - "key": "23fb76842cbd572cdb3ee928699b6d9b", - "offset": 7279, - "new_text": "(《廉颇蔺相如列传》)\u000b②非为织作迟,群家妇难为。", - "insert": "(《廉颇蔺相如列传》) \u000b②非为织作迟,群家妇难为。", - "insert_len": 26, - "paragraph_offset": 15, - "sentence_offset": 330, - "paragraph_num": 69 - }, - { - "key": "ea04339dcaad421bb7f770d5de5654f1", - "offset": 7305, - "new_text": "(《孔雀东南飞》)\u000b(二)介词。", - "insert": "(《孔雀东南飞》) \u000b(二)介词。", - "insert_len": 17, - "paragraph_offset": 15, - "sentence_offset": 356, - "paragraph_num": 69 - }, - { - "key": "544a6defe4ca7716e217dc1efe3a0aa4", - "offset": 7322, - "new_text": "1.表被动,有时跟“所“结合,构成”为所“或”为……", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 9, - "end": 10, - "id": 187260, - "idx": 332, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 11, - "end": 12, - "id": 187261, - "idx": 333, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 17, - "end": 18, - "id": 187262, - "idx": 334, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 20, - "end": 21, - "id": 187263, - "idx": 335, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 22, - "end": 23, - "id": 187264, - "idx": 336, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.表被动,有时跟\"所\"结合,构成\"为所\"或\"为……", - "insert_len": 26, - "paragraph_offset": 15, - "sentence_offset": 373, - "paragraph_num": 69 - }, - { - "key": "121eb3e897032e48a8482b95a90715c5", - "offset": 7350, - "new_text": "所“,译为“被”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 1, - "end": 2, - "id": 187265, - "idx": 337, - "isAccept": 0, - "type": 2 - } - ], - "insert": "所\",译为“被”。", - "insert_len": 9, - "paragraph_offset": 15, - "sentence_offset": 399, - "paragraph_num": 69 - }, - { - "key": "f7a30f452baf88cd5ff933803c600c4b", - "offset": 7359, - "new_text": "①吾属今为之虏矣。", - "insert": "①吾属今为之虏矣。", - "insert_len": 9, - "paragraph_offset": 15, - "sentence_offset": 408, - "paragraph_num": 69 - }, - { - "key": "80d5c323b4ef79484e774d7cbcf3d8a9", - "offset": 7370, - "new_text": "(《鸿门宴》)\u000b②遂为猾胥报充里正役。", - "insert": "(《鸿门宴》) \u000b②遂为猾胥报充里正役。", - "insert_len": 20, - "paragraph_offset": 15, - "sentence_offset": 417, - "paragraph_num": 69 - }, - { - "key": "d0dbeab0faa8e53d5279b8fd060a0985", - "offset": 7390, - "new_text": "(《促织》)\u000b③身死国灭,为天下笑,(《过秦论》)④不者,若属皆且为所虏。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 26, - "end": 28, - "id": 187266, - "idx": 340, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《促织》) \u000b③身死国灭,为天下笑,(《过秦论》) \u000b④不者,若属皆且为所虏。", - "insert_len": 40, - "paragraph_offset": 15, - "sentence_offset": 437, - "paragraph_num": 69 - }, - { - "key": "77a3bf87d3c23da50294e4bac7c18211", - "offset": 7430, - "new_text": "(《鸿门宴》)\u000b⑤羸兵为人马所蹈藉,陷泥中死者甚众。", - "insert": "(《鸿门宴》) \u000b⑤羸兵为人马所蹈藉,陷泥中死者甚众。", - "insert_len": 27, - "paragraph_offset": 15, - "sentence_offset": 477, - "paragraph_num": 69 - }, - { - "key": "5dfd4691acc1d10e8825c9e1adb8bbfb", - "offset": 7457, - "new_text": "(《赤壁之战》)\u000b2.介绍原因或目的。", - "insert": "(《赤壁之战》) \u000b2.介绍原因或目的。", - "insert_len": 20, - "paragraph_offset": 15, - "sentence_offset": 504, - "paragraph_num": 69 - }, - { - "key": "9f5239684033cab63879e30d88863295", - "offset": 7477, - "new_text": "为了,因为。", - "insert": "为了,因为。", - "insert_len": 6, - "paragraph_offset": 15, - "sentence_offset": 524, - "paragraph_num": 69 - }, - { - "key": "24ed23057c6e4858c74977583271bcd1", - "offset": 7483, - "new_text": "①慎勿为归死,贵贱轻何薄(《孔雀东南飞》)\u000b②为宫室之美,妻妾之奉,所识穷乏者得我欤(《庄暴见孟子》)③今为宫室之美为之。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 52, - "end": 54, - "id": 187267, - "idx": 344, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①慎勿为归死,贵贱轻何薄(《孔雀东南飞》) \u000b②为宫室之美,妻妾之奉,所识穷乏者得我欤(《庄暴见孟子》) \u000b③今为宫室之美为之。", - "insert_len": 64, - "paragraph_offset": 15, - "sentence_offset": 530, - "paragraph_num": 69 - }, - { - "key": "e427e10158a824be8c4cb493d556cef7", - "offset": 7549, - "new_text": "(《庄暴见孟子》)\u000b3.介绍涉及的对象。", - "insert": "(《庄暴见孟子》) \u000b3.介绍涉及的对象。", - "insert_len": 21, - "paragraph_offset": 15, - "sentence_offset": 594, - "paragraph_num": 69 - }, - { - "key": "2999e4ac7d43b7b201540600f42b428a", - "offset": 7570, - "new_text": "给,替。", - "insert": "给,替。", - "insert_len": 4, - "paragraph_offset": 15, - "sentence_offset": 615, - "paragraph_num": 69 - }, - { - "key": "da516b3773ba652b0665bbf54a17fb78", - "offset": 7574, - "new_text": "①于是秦王不怿,为一击缶。", - "insert": "①于是秦王不怿,为一击缶。", - "insert_len": 13, - "paragraph_offset": 15, - "sentence_offset": 619, - "paragraph_num": 69 - }, - { - "key": "164743253bdc5fc0d4595f8eb597239f", - "offset": 7589, - "new_text": "(《廉颇蔺相如列传》)\u000b②请以赵十五城为秦王寿。", - "insert": "(《廉颇蔺相如列传》) \u000b②请以赵十五城为秦王寿。", - "insert_len": 25, - "paragraph_offset": 15, - "sentence_offset": 632, - "paragraph_num": 69 - }, - { - "key": "d224cc2c20f09c18c289ba9d7c4d6f49", - "offset": 7614, - "new_text": "(《廉颇蔺相如列传》)\u000b③臣请为王言乐。", - "insert": "(《廉颇蔺相如列传》) \u000b③臣请为王言乐。", - "insert_len": 21, - "paragraph_offset": 15, - "sentence_offset": 657, - "paragraph_num": 69 - }, - { - "key": "b8c7b81754840cc6d75d792e7c6668a2", - "offset": 7635, - "new_text": "(《庄暴见孟子》)\u000b4.对,向。", - "insert": "(《庄暴见孟子》) \u000b4.对,向。", - "insert_len": 17, - "paragraph_offset": 15, - "sentence_offset": 678, - "paragraph_num": 69 - }, - { - "key": "b43fe927333157cef8acbcb3f7db5c6e", - "offset": 7652, - "new_text": "①为之奈何?", - "insert": "①为之奈何?", - "insert_len": 6, - "paragraph_offset": 15, - "sentence_offset": 695, - "paragraph_num": 69 - }, - { - "key": "2abbfafe3a42b129f20792895a9e3bfa", - "offset": 7660, - "new_text": "(《鸿门宴》)\u000b②如姬为公子泣(《信陵君窃符救赵》)5.表示动作、行为的时间。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 27, - "end": 29, - "id": 187268, - "idx": 350, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b②如姬为公子泣(《信陵君窃符救赵》) \u000b5.表示动作、行为的时间。", - "insert_len": 42, - "paragraph_offset": 15, - "sentence_offset": 701, - "paragraph_num": 69 - }, - { - "key": "87ea009b185f8ae11e4e1f56f9c63469", - "offset": 7702, - "new_text": "可译为“当”“等到”等。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187269, - "idx": 351, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 5, - "end": 7, - "id": 187270, - "idx": 352, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 9, - "end": 10, - "id": 187271, - "idx": 353, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"当\"\"等到\"等。", - "insert_len": 12, - "paragraph_offset": 15, - "sentence_offset": 743, - "paragraph_num": 69 - }, - { - "key": "a554a0b04edc414a9caf3fd3886b2b1f", - "offset": 7714, - "new_text": "①为其来也,臣请缚一人过王而行。", - "insert": "①为其来也,臣请缚一人过王而行。", - "insert_len": 16, - "paragraph_offset": 15, - "sentence_offset": 755, - "paragraph_num": 69 - }, - { - "key": "90710b5f48a4c8917f520080f37db266", - "offset": 7732, - "new_text": "(《晏子使楚》)\u000b(三)句末语气词,表示反诘或疑问。", - "diffs": [ - { - "tag": "i", - "origin": "", - "text": "反诘或", - "start": 21, - "end": 21, - "id": 187272, - "idx": 355, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": "或反诘", - "text": "", - "start": 23, - "end": 26, - "id": 187273, - "idx": 356, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《晏子使楚》) \u000b(三)句末语气词,表示疑问或反诘。", - "insert_len": 27, - "paragraph_offset": 15, - "sentence_offset": 771, - "paragraph_num": 69 - }, - { - "key": "f2b106f55f37180ee31ad45a8d8a863f", - "offset": 7759, - "new_text": "呢。", - "insert": "呢。", - "insert_len": 2, - "paragraph_offset": 15, - "sentence_offset": 798, - "paragraph_num": 69 - }, - { - "key": "eae67bc27c011baeff8b8bf0b965387e", - "offset": 7761, - "new_text": "①如今人方为刀俎,我为鱼肉,何辞为(《鸿门宴》)\u000b②是社稷之臣也。", - "insert": "①如今人方为刀俎,我为鱼肉,何辞为(《鸿门宴》) \u000b②是社稷之臣也。", - "insert_len": 34, - "paragraph_offset": 15, - "sentence_offset": 800, - "paragraph_num": 69 - }, - { - "key": "6de5b30221f43d01e3e813e7f26ce9a6", - "offset": 7797, - "new_text": "何以伐为?", - "insert": "何以伐为?", - "insert_len": 5, - "paragraph_offset": 15, - "sentence_offset": 834, - "paragraph_num": 69 - }, - { - "key": "f1c1b8467b0681948e3833c67a135332", - "offset": 7802, - "new_text": "(《季氏将伐颛臾》)\u000b③何故怀瑾握瑜而自令见放为?", - "insert": "(《季氏将伐颛臾》) \u000b③何故怀瑾握瑜而自令见放为?", - "insert_len": 26, - "paragraph_offset": 15, - "sentence_offset": 839, - "paragraph_num": 69 - }, - { - "key": "20609325e9d81e88b9fa243289eea03c", - "offset": 7828, - "new_text": "(《屈原列传》)", - "insert": "(《屈原列传》)\n", - "insert_len": 9, - "paragraph_offset": 15, - "sentence_offset": 865, - "paragraph_num": 69 - }, - { - "key": "b9303972f216577f85f4c54716422c9d", - "offset": 7840, - "new_text": "10.【焉】\u000b(一)兼词。", - "insert": "10.【焉】 \u000b(一)兼词。", - "insert_len": 14, - "paragraph_offset": 16, - "sentence_offset": 0, - "paragraph_num": 71 - }, - { - "key": "d52d3796ec719373c683c1f197918e68", - "offset": 7854, - "new_text": "1.相当于“于之”、“于此”、“于彼”。", - "insert": "1.相当于“于之”、“于此”、“于彼”。", - "insert_len": 20, - "paragraph_offset": 16, - "sentence_offset": 14, - "paragraph_num": 71 - }, - { - "key": "54e582e5a498124b92ee47fb6222ee1c", - "offset": 7876, - "new_text": "①三人行,必有我师焉(在其中)。", - "insert": "①三人行,必有我师焉(在其中)。", - "insert_len": 16, - "paragraph_offset": 16, - "sentence_offset": 34, - "paragraph_num": 71 - }, - { - "key": "5d6a067ca990294f2c8a93336345f254", - "offset": 7895, - "new_text": "(《论语》)\u000b②积土成山,风雨兴焉(从这里)。", - "insert": "(《论语》) \u000b②积土成山,风雨兴焉(从这里)。", - "insert_len": 24, - "paragraph_offset": 16, - "sentence_offset": 50, - "paragraph_num": 71 - }, - { - "key": "5be792950a5efcb4206da572a454dd63", - "offset": 7919, - "new_text": "(《劝学》)\u000b③五人者,盖当蓼洲周公子被逮,激于义而死焉(在这件事情上)者也。", - "insert": "(《劝学》) \u000b③五人者,盖当蓼洲周公子被逮,激于义而死焉(在这件事情上)者也。", - "insert_len": 40, - "paragraph_offset": 16, - "sentence_offset": 74, - "paragraph_num": 71 - }, - { - "key": "12cc304893c019f4dcda19f5c33d35bd", - "offset": 7959, - "new_text": "(《五人墓碑记》)\u000b2.相当于“于何”。", - "insert": "(《五人墓碑记》) \u000b2.相当于“于何”。", - "insert_len": 21, - "paragraph_offset": 16, - "sentence_offset": 114, - "paragraph_num": 71 - }, - { - "key": "e577cc8141e0c383362b8070ac2ed3b9", - "offset": 7980, - "new_text": "译为“在哪里”“从哪里”等。", - "insert": "译为“在哪里”“从哪里”等。", - "insert_len": 14, - "paragraph_offset": 16, - "sentence_offset": 135, - "paragraph_num": 71 - }, - { - "key": "ba6cbe43db2dcc31511680ce276eef8c", - "offset": 7994, - "new_text": "①且焉置土石?", - "insert": "①且焉置土石?", - "insert_len": 7, - "paragraph_offset": 16, - "sentence_offset": 149, - "paragraph_num": 71 - }, - { - "key": "2dc7527a3df158cfece57b4479244385", - "offset": 8003, - "new_text": "(《愚公移山》)\u000b②非再至,焉知其若此?", - "insert": "(《愚公移山》) \u000b②非再至,焉知其若此?", - "insert_len": 21, - "paragraph_offset": 16, - "sentence_offset": 156, - "paragraph_num": 71 - }, - { - "key": "d1ec976725447e382507fcf1bfccb14a", - "offset": 8024, - "new_text": "③焉有仁人在位,罔民而可为也?", - "insert": "③焉有仁人在位,罔民而可为也?", - "insert_len": 15, - "paragraph_offset": 16, - "sentence_offset": 177, - "paragraph_num": 71 - }, - { - "key": "874ccaad39b22c02c7530ba5bbf74158", - "offset": 8041, - "new_text": "(《齐桓晋文之事》)\u000b(二)代词。", - "insert": "(《齐桓晋文之事》) \u000b(二)代词。", - "insert_len": 18, - "paragraph_offset": 16, - "sentence_offset": 192, - "paragraph_num": 71 - }, - { - "key": "8a06b480d0264995ec11fa93c299a435", - "offset": 8059, - "new_text": "1.相当于“之”。", - "insert": "1.相当于“之”。", - "insert_len": 9, - "paragraph_offset": 16, - "sentence_offset": 210, - "paragraph_num": 71 - }, - { - "key": "ac721914414f6eb9dbe522604d2902e6", - "offset": 8070, - "new_text": "①唯俟夫观人风者得焉。", - "diffs": [ - { - "tag": "r", - "origin": "惟", - "text": "唯", - "start": 1, - "end": 2, - "id": 187274, - "idx": 365, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①惟俟夫观人风者得焉。", - "insert_len": 11, - "paragraph_offset": 16, - "sentence_offset": 219, - "paragraph_num": 71 - }, - { - "key": "823277374652bc17403cde7afa940d36", - "offset": 8084, - "new_text": "(《捕蛇者说》)\u000b②犹且从师而问焉。", - "insert": "(《捕蛇者说》) \u000b②犹且从师而问焉。", - "insert_len": 19, - "paragraph_offset": 16, - "sentence_offset": 230, - "paragraph_num": 71 - }, - { - "key": "fa16627f51c10013d7fb61fd0e365b3d", - "offset": 8103, - "new_text": "(《师说》)\u000b③去今之墓而葬焉,其为时止十有一月耳。", - "insert": "(《师说》) \u000b③去今之墓而葬焉,其为时止十有一月耳。", - "insert_len": 27, - "paragraph_offset": 16, - "sentence_offset": 249, - "paragraph_num": 71 - }, - { - "key": "b91deda3d0ca328cf711337de830ecad", - "offset": 8130, - "new_text": "(《五人墓碑记》)\u000b2.哪里,怎么。", - "insert": "(《五人墓碑记》) \u000b2.哪里,怎么。", - "insert_len": 19, - "paragraph_offset": 16, - "sentence_offset": 276, - "paragraph_num": 71 - }, - { - "key": "c5f9c323a97c544be78eeb237a419e56", - "offset": 8149, - "new_text": "①未知生,焉知死(《论语》)\u000b②割鸡焉用牛刀(《论语》)(三)语气词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 29, - "end": 31, - "id": 187275, - "idx": 370, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①未知生,焉知死(《论语》) \u000b②割鸡焉用牛刀(《论语》) \u000b(三)语气词。", - "insert_len": 38, - "paragraph_offset": 16, - "sentence_offset": 295, - "paragraph_num": 71 - }, - { - "key": "e9e4b640b0aa1c4e087732b950b91426", - "offset": 8189, - "new_text": "1。", - "insert": "1。", - "insert_len": 2, - "paragraph_offset": 16, - "sentence_offset": 333, - "paragraph_num": 71 - }, - { - "key": "2447095b5a88fef41d102ba453ceede8", - "offset": 8193, - "new_text": "句末语气词,了,啊,呢。", - "insert": "句末语气词,了,啊,呢。", - "insert_len": 12, - "paragraph_offset": 16, - "sentence_offset": 335, - "paragraph_num": 71 - }, - { - "key": "c78a03b69b88763bb2de2149fb6e638b", - "offset": 8205, - "new_text": "①至丹以荆卿为计,始速祸焉。", - "insert": "①至丹以荆卿为计,始速祸焉。", - "insert_len": 14, - "paragraph_offset": 16, - "sentence_offset": 347, - "paragraph_num": 71 - }, - { - "key": "0db39b70e828b49109299d17d6744dab", - "offset": 8221, - "new_text": "(《六国论》)\u000b②一羽之不举,谓不用力焉。", - "diffs": [ - { - "tag": "r", - "origin": "为", - "text": "谓", - "start": 16, - "end": 17, - "id": 187276, - "idx": 372, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《六国论》) \u000b②一羽之不举,为不用力焉。", - "insert_len": 22, - "paragraph_offset": 16, - "sentence_offset": 361, - "paragraph_num": 71 - }, - { - "key": "5a03ac686f0877774f9cf29335938778", - "offset": 8243, - "new_text": "(《齐桓晋文之事》)\u000b③则牛羊何择焉?", - "insert": "(《齐桓晋文之事》) \u000b③则牛羊何择焉?", - "insert_len": 20, - "paragraph_offset": 16, - "sentence_offset": 383, - "paragraph_num": 71 - }, - { - "key": "1f030e0eb29d2c574e98a917fa710095", - "offset": 8263, - "new_text": "(《齐桓晋文之事》)\u000b2.作句中语气词,表示停顿,相当于“也”。", - "insert": "(《齐桓晋文之事》) \u000b2.作句中语气词,表示停顿,相当于“也”。", - "insert_len": 33, - "paragraph_offset": 16, - "sentence_offset": 403, - "paragraph_num": 71 - }, - { - "key": "045cc304dfc756dd78d06ccf7fc16657", - "offset": 8296, - "new_text": "①句读之不知,惑之不解,或师焉,或否焉,小学而大遗(《师说》)\u000b②少焉,月出于东山之上,徘徊于斗牛之间(《赤壁赋》)3.作词尾,相当于“然”,译为“……的样子”“……地”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 59, - "end": 61, - "id": 187277, - "idx": 376, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①句读之不知,惑之不解,或师焉,或否焉,小学而大遗(《师说》) \u000b②少焉,月出于东山之上,徘徊于斗牛之间(《赤壁赋》) \u000b3.作词尾,相当于“然”,译为“……的样子”“……地”。", - "insert_len": 89, - "paragraph_offset": 16, - "sentence_offset": 436, - "paragraph_num": 71 - }, - { - "key": "e68ae24d729ca2865a28d548d692e84a", - "offset": 8387, - "new_text": "①盘盘焉,囷囷焉,蜂房水涡,矗不知乎几千万落(《阿房宫赋》)\u000b②于乱石间择其一二扣之,硿硿焉(《石钟山记》)", - "insert": "①盘盘焉,囷囷焉,蜂房水涡,矗不知乎几千万落(《阿房宫赋》) \u000b②于乱石间择其一二扣之,硿硿焉(《石钟山记》)\n", - "insert_len": 56, - "paragraph_offset": 16, - "sentence_offset": 525, - "paragraph_num": 71 - }, - { - "key": "5a17e0eecf4172408625965a3c7ab301", - "offset": 8448, - "new_text": "11.【也】\u000b(一)句末语气词,\u000b1.表示判断语气。", - "insert": "11.【也】 \u000b(一)句末语气词, \u000b1.表示判断语气。", - "insert_len": 28, - "paragraph_offset": 17, - "sentence_offset": 0, - "paragraph_num": 86 - }, - { - "key": "f3896fe0e1d636db50d01107ae2627af", - "offset": 8476, - "new_text": "①城北徐公,齐国之美丽者也(《邹忌讽齐王纳谏》)\u000b②张良曰:“沛公之参乘樊哙者也”(《鸿门宴》)2.句末语气词,表示陈述或解释语气。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 49, - "end": 51, - "id": 187278, - "idx": 381, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①城北徐公,齐国之美丽者也(《邹忌讽齐王纳谏》) \u000b②张良曰:“沛公之参乘樊哙者也”(《鸿门宴》) \u000b2.句末语气词,表示陈述或解释语气。", - "insert_len": 69, - "paragraph_offset": 17, - "sentence_offset": 28, - "paragraph_num": 86 - }, - { - "key": "7e334722e38212b1149a08b23ae4e55e", - "offset": 8547, - "new_text": "例:\u000b①即不忍其觳觫,若无罪而就死地,故以羊易之也(《齐桓晋文之事》)②雷霆乍惊,宫车过也。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 36, - "end": 38, - "id": 187279, - "idx": 383, - "isAccept": 0, - "type": 2 - } - ], - "insert": "例: \u000b①即不忍其觳觫,若无罪而就死地,故以羊易之也(《齐桓晋文之事》) \u000b②雷霆乍惊,宫车过也。", - "insert_len": 49, - "paragraph_offset": 17, - "sentence_offset": 97, - "paragraph_num": 86 - }, - { - "key": "0bd9ca6b8e9faad14be19713ee6749f5", - "offset": 8596, - "new_text": "(《阿房宫赋》)\u000b3.用在句中或句末,表示肯定、感叹的语气。", - "insert": "(《阿房宫赋》) \u000b3.用在句中或句末,表示肯定、感叹的语气。", - "insert_len": 31, - "paragraph_offset": 17, - "sentence_offset": 146, - "paragraph_num": 86 - }, - { - "key": "d10317a858fbd71ca6298b531bce8115", - "offset": 8627, - "new_text": "①呜呼!", - "diffs": [ - { - "tag": "r", - "origin": "鸣", - "text": "呜", - "start": 1, - "end": 2, - "id": 187280, - "idx": 385, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①鸣呼!", - "insert_len": 4, - "paragraph_offset": 17, - "sentence_offset": 177, - "paragraph_num": 86 - }, - { - "key": "dabd6a50356c3b7366b0a4a56ce6f0e3", - "offset": 8633, - "new_text": "灭六国者六国也,非秦也。", - "insert": "灭六国者六国也,非秦也。", - "insert_len": 12, - "paragraph_offset": 17, - "sentence_offset": 181, - "paragraph_num": 86 - }, - { - "key": "d2eaa53e33b6413f4283aff177a32fdd", - "offset": 8645, - "new_text": "族秦者秦也,非天下也。", - "insert": "族秦者秦也,非天下也。", - "insert_len": 11, - "paragraph_offset": 17, - "sentence_offset": 193, - "paragraph_num": 86 - }, - { - "key": "13ab2a4841059d9371e3d02ded9f05e2", - "offset": 8656, - "new_text": "(《过秦论》)\u000b②至于誓天断发,泣下沾襟,何其衰也!(《伶官传序》)③古之人不余欺也(《石钟山记》)\u000b4.用在句末,表示疑问或反诘语气。", - "diffs": [ - { - "tag": "r", - "origin": "!", - "text": "!", - "start": 26, - "end": 27, - "id": 187281, - "idx": 387, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 35, - "end": 37, - "id": 187282, - "idx": 388, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《过秦论》) \u000b②至于誓天断发,泣下沾襟,何其衰也!(《伶官传序》) \u000b③古之人不余欺也(《石钟山记》) \u000b4.用在句末,表示疑问或反诘语气。", - "insert_len": 72, - "paragraph_offset": 17, - "sentence_offset": 204, - "paragraph_num": 86 - }, - { - "key": "78f9d884e580a8e204ea45cdc5e275c8", - "offset": 8728, - "new_text": "①公子畏死邪?", - "insert": "①公子畏死邪?", - "insert_len": 7, - "paragraph_offset": 17, - "sentence_offset": 276, - "paragraph_num": 86 - }, - { - "key": "05aed2f4dea47def1e86b4109c000239", - "offset": 8737, - "new_text": "何泣也?", - "insert": "何泣也?", - "insert_len": 4, - "paragraph_offset": 17, - "sentence_offset": 283, - "paragraph_num": 86 - }, - { - "key": "50c02d8607b882c1f60c58d6142b9ffe", - "offset": 8741, - "new_text": "(《信陵君窃符救赵》)\u000b②吾王庶几无疾病与,何以能鼓乐也?", - "insert": "(《信陵君窃符救赵》) \u000b②吾王庶几无疾病与,何以能鼓乐也?", - "insert_len": 30, - "paragraph_offset": 17, - "sentence_offset": 287, - "paragraph_num": 86 - }, - { - "key": "fad9108e5714df55c08802028ccee5f8", - "offset": 8771, - "new_text": "(《庄暴见孟子》)\u000b③使秦复爱六国之人,则递三世可至万世而为君,谁得而族灭也?", - "insert": "(《庄暴见孟子》) \u000b③使秦复爱六国之人,则递三世可至万世而为君,谁得而族灭也?", - "insert_len": 40, - "paragraph_offset": 17, - "sentence_offset": 317, - "paragraph_num": 86 - }, - { - "key": "de67d9a4e79c34a01a1a71e1f9c8f864", - "offset": 8811, - "new_text": "5.用在句末,表示祈使语气。", - "insert": "5.用在句末,表示祈使语气。", - "insert_len": 14, - "paragraph_offset": 17, - "sentence_offset": 357, - "paragraph_num": 86 - }, - { - "key": "47eba635bb84462cc99ca6b272c5dc62", - "offset": 8827, - "new_text": "①攻之不克,围之不济,吾其还也。", - "diffs": [ - { - "tag": "r", - "origin": "继", - "text": "济", - "start": 9, - "end": 10, - "id": 187283, - "idx": 392, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①攻之不克,围之不继,吾其还也。", - "insert_len": 16, - "paragraph_offset": 17, - "sentence_offset": 371, - "paragraph_num": 86 - }, - { - "key": "d316a654bb3d329ab1258967f7f747fb", - "offset": 8845, - "new_text": "(《崤之战》)\u000b②当相与共谋之,勿令姊有穷途之虑也(《杜十娘怒沉百宝箱》)(二)句中语气词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 38, - "end": 40, - "id": 187284, - "idx": 394, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《崤之战》) \u000b②当相与共谋之,勿令姊有穷途之虑也(《杜十娘怒沉百宝箱》) \u000b(二)句中语气词。", - "insert_len": 49, - "paragraph_offset": 17, - "sentence_offset": 387, - "paragraph_num": 86 - }, - { - "key": "9ecff6f3c4937a5279618ba6c43d98d3", - "offset": 8894, - "new_text": "用在句中,表示语气停顿。", - "insert": "用在句中,表示语气停顿。", - "insert_len": 12, - "paragraph_offset": 17, - "sentence_offset": 436, - "paragraph_num": 86 - }, - { - "key": "432518a859201ebb7152dc6f6696af44", - "offset": 8906, - "new_text": "①是说也,人常疑之。", - "insert": "①是说也,人常疑之。", - "insert_len": 10, - "paragraph_offset": 17, - "sentence_offset": 448, - "paragraph_num": 86 - }, - { - "key": "c23cbde5bc385ff2947111f15c331466", - "offset": 8918, - "new_text": "(《石钟山记》)\u000b②其闻道也亦先乎吾。", - "insert": "(《石钟山记》) \u000b②其闻道也亦先乎吾。", - "insert_len": 20, - "paragraph_offset": 17, - "sentence_offset": 458, - "paragraph_num": 86 - }, - { - "key": "0fd87b2616f9c245a2d8b4aca89d5fba", - "offset": 8938, - "new_text": "(《师说》)\u000b【……", - "insert": "(《师说》) \u000b【……", - "insert_len": 11, - "paragraph_offset": 17, - "sentence_offset": 478, - "paragraph_num": 86 - }, - { - "key": "c6f901813318aad3f71c1506b6ec52dc", - "offset": 8949, - "new_text": "之谓也】【其……", - "insert": "之谓也】【其……", - "insert_len": 8, - "paragraph_offset": 17, - "sentence_offset": 489, - "paragraph_num": 86 - }, - { - "key": "c6f901813318aad3f71c1506b6ec52dc", - "offset": 8957, - "new_text": "之谓也】【其……", - "insert": "之谓也】【其……", - "insert_len": 8, - "paragraph_offset": 17, - "sentence_offset": 497, - "paragraph_num": 86 - }, - { - "key": "3c54c61e1b9190a80860be66b2be551a", - "offset": 8965, - "new_text": "之谓乎】意思是“说的就是……啊”\u000b①诗云:“他人有心,予忖度之。”", - "insert": "之谓乎】意思是“说的就是……啊” \u000b①诗云:“他人有心,予忖度之。”", - "insert_len": 34, - "paragraph_offset": 17, - "sentence_offset": 505, - "paragraph_num": 86 - }, - { - "key": "4730c9af29ff6d9750c1b8a5b5b48d56", - "offset": 8999, - "new_text": "——夫子之谓也(《齐桓晋文之事》)\u000b【也哉】语气助词连用,为加强语气,多有感叹或反诘之意。", - "insert": "——夫子之谓也(《齐桓晋文之事》) \u000b【也哉】语气助词连用,为加强语气,多有感叹或反诘之意。", - "insert_len": 46, - "paragraph_offset": 17, - "sentence_offset": 539, - "paragraph_num": 86 - }, - { - "key": "f1e16ddd4a042fd2304af28b3a75ed36", - "offset": 9045, - "new_text": "例:\u000b①岂非计久长,有子孙相继为王也哉?", - "insert": "例: \u000b①岂非计久长,有子孙相继为王也哉?", - "insert_len": 21, - "paragraph_offset": 17, - "sentence_offset": 585, - "paragraph_num": 86 - }, - { - "key": "7b814adc189b4a11dfa90c6b5c3b7b00", - "offset": 9066, - "new_text": "(《触龙说赵太后》)\u000b②穷予生之光阴以疗梅也哉!", - "insert": "(《触龙说赵太后》) \u000b②穷予生之光阴以疗梅也哉!", - "insert_len": 25, - "paragraph_offset": 17, - "sentence_offset": 606, - "paragraph_num": 86 - }, - { - "key": "a4339715b7c3a5f07f0b974550552bdf", - "offset": 9091, - "new_text": "(《病梅馆记》)\u000b③岂独伶人也哉!", - "insert": "(《病梅馆记》) \u000b③岂独伶人也哉!", - "insert_len": 18, - "paragraph_offset": 17, - "sentence_offset": 631, - "paragraph_num": 86 - }, - { - "key": "ac3f036d0e7d4a01a1e8e48008d64615", - "offset": 9109, - "new_text": "(《伶官传序》)\u000b\u000b12.【以】\u000b(一)介词\u000b1.表示工具。", - "insert": "(《伶官传序》) \u000b\u000b12.【以】 \u000b(一)介词 \u000b1.表示工具。", - "insert_len": 33, - "paragraph_offset": 17, - "sentence_offset": 649, - "paragraph_num": 86 - }, - { - "key": "bf4f9fdec7ce7538081d1c4e8d163613", - "offset": 9142, - "new_text": "译为:拿,用,凭着。", - "insert": "译为:拿,用,凭着。\n", - "insert_len": 11, - "paragraph_offset": 17, - "sentence_offset": 682, - "paragraph_num": 86 - }, - { - "key": "e8c6debceb0826b5b65b96d1cfa4994e", - "offset": 9154, - "new_text": "愿以十五城请易璧。", - "insert": "愿以十五城请易璧。", - "insert_len": 9, - "paragraph_offset": 18, - "sentence_offset": 0, - "paragraph_num": 87 - }, - { - "key": "f8262d2b57d3485b223470c4966a67b9", - "offset": 9163, - "new_text": "(《廉颇蔺相如列传》)②士大夫终不肯以小舟夜泊绝壁之下。", - "diffs": [ - { - "tag": "r", - "origin": "璧", - "text": "壁", - "start": 25, - "end": 26, - "id": 187285, - "idx": 406, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) ②士大夫终不肯以小舟夜泊绝璧之下。", - "insert_len": 29, - "paragraph_offset": 18, - "sentence_offset": 9, - "paragraph_num": 87 - }, - { - "key": "871bc08c1d43e6afd7b0560e6584d932", - "offset": 9192, - "new_text": "(《石钟山记》)", - "insert": "(《石钟山记》)\n", - "insert_len": 9, - "paragraph_offset": 18, - "sentence_offset": 38, - "paragraph_num": 87 - }, - { - "key": "5191abb3c8cd4d33cda88bbc91688d8b", - "offset": 9202, - "new_text": "2.表示凭借。", - "insert": "2.表示凭借。", - "insert_len": 7, - "paragraph_offset": 19, - "sentence_offset": 0, - "paragraph_num": 88 - }, - { - "key": "02301b875df70b928f643352e5332b9a", - "offset": 9209, - "new_text": "译为:凭,靠。", - "insert": "译为:凭,靠。", - "insert_len": 7, - "paragraph_offset": 19, - "sentence_offset": 7, - "paragraph_num": 88 - }, - { - "key": "cbd6a200bdc33ca011708f3b4cd17efe", - "offset": 9216, - "new_text": "①以勇气闻于诸侯。", - "insert": "①以勇气闻于诸侯。", - "insert_len": 9, - "paragraph_offset": 19, - "sentence_offset": 14, - "paragraph_num": 88 - }, - { - "key": "d1b71782777bd852d9ed2f3966c26c77", - "offset": 9227, - "new_text": "(《廉颇蔺相如列传》)②久之,能以足音辨人。", - "insert": "(《廉颇蔺相如列传》) ②久之,能以足音辨人。", - "insert_len": 23, - "paragraph_offset": 19, - "sentence_offset": 23, - "paragraph_num": 88 - }, - { - "key": "12ec5b10d1c0506f8f0a1ae87c858fff", - "offset": 9250, - "new_text": "(《项脊轩志》)", - "insert": "(《项脊轩志》)\n", - "insert_len": 9, - "paragraph_offset": 19, - "sentence_offset": 46, - "paragraph_num": 88 - }, - { - "key": "f054a637e56271716145ea50da186a4c", - "offset": 9260, - "new_text": "皆好辞而以赋见称。", - "insert": "皆好辞而以赋见称。", - "insert_len": 9, - "paragraph_offset": 20, - "sentence_offset": 0, - "paragraph_num": 89 - }, - { - "key": "20609325e9d81e88b9fa243289eea03c", - "offset": 9269, - "new_text": "(《屈原列传》)", - "insert": "(《屈原列传》)\n", - "insert_len": 9, - "paragraph_offset": 20, - "sentence_offset": 9, - "paragraph_num": 89 - }, - { - "key": "734f21056103b405b86bf3672c49a735", - "offset": 9279, - "new_text": "3.表示所处置的对 象。", - "insert": "3.表示所处置的对 象。", - "insert_len": 12, - "paragraph_offset": 21, - "sentence_offset": 0, - "paragraph_num": 90 - }, - { - "key": "158f6b0a535ee6d08a26df50bea5ec53", - "offset": 9291, - "new_text": "译为:把。", - "insert": "译为:把。", - "insert_len": 5, - "paragraph_offset": 21, - "sentence_offset": 12, - "paragraph_num": 90 - }, - { - "key": "29438ceefd7cc3b68a9f2310361e0f46", - "offset": 9296, - "new_text": "①操当以肃还付乡党。", - "insert": "①操当以肃还付乡党。", - "insert_len": 10, - "paragraph_offset": 21, - "sentence_offset": 17, - "paragraph_num": 90 - }, - { - "key": "16cb55a6c9216d3fb091ef51e4c5f692", - "offset": 9307, - "new_text": "(《赤壁之战》)", - "insert": "(《赤壁之战》)\n", - "insert_len": 9, - "paragraph_offset": 21, - "sentence_offset": 27, - "paragraph_num": 90 - }, - { - "key": "d47114f9bdce1833b6f4b4d9c7222833", - "offset": 9317, - "new_text": "4.表示时间、 处所。", - "insert": "4.表示时间、 处所。", - "insert_len": 11, - "paragraph_offset": 22, - "sentence_offset": 0, - "paragraph_num": 91 - }, - { - "key": "9cc4d14123969ea5cab59a3e5c3d5fe1", - "offset": 9328, - "new_text": "译为:于,在,从。", - "insert": "译为:于,在,从。", - "insert_len": 9, - "paragraph_offset": 22, - "sentence_offset": 11, - "paragraph_num": 91 - }, - { - "key": "d76bf8306ca971c7919dc02e16ebb249", - "offset": 9337, - "new_text": "①以八月十三斩于市。", - "insert": "①以八月十三斩于市。", - "insert_len": 10, - "paragraph_offset": 22, - "sentence_offset": 20, - "paragraph_num": 91 - }, - { - "key": "45b92308c3f2315ad0f3e4f6b1cf82f2", - "offset": 9349, - "new_text": "②以崇祯十七年夏,自京师徒步入华山为黄冠。", - "insert": "②以崇祯十七年夏,自京师徒步入华山为黄冠。\n", - "insert_len": 22, - "paragraph_offset": 22, - "sentence_offset": 30, - "paragraph_num": 91 - }, - { - "key": "7dd20b1737b3e9e2e1d970ec8872283d", - "offset": 9373, - "new_text": "果予以未时还家,而汝以辰时气绝。", - "insert": "果予以未时还家,而汝以辰时气绝。\n", - "insert_len": 17, - "paragraph_offset": 23, - "sentence_offset": 0, - "paragraph_num": 92 - }, - { - "key": "eae78da4d959c11d3b5403e61f6dc8c1", - "offset": 9391, - "new_text": "5.表示原因。", - "insert": "5.表示原因。", - "insert_len": 7, - "paragraph_offset": 24, - "sentence_offset": 0, - "paragraph_num": 93 - }, - { - "key": "4c7c8df6917385168d11699b73fe4b2b", - "offset": 9398, - "new_text": "译为:因为,由于。", - "insert": "译为:因为,由于。\n", - "insert_len": 10, - "paragraph_offset": 24, - "sentence_offset": 7, - "paragraph_num": 93 - }, - { - "key": "7b16dc78ceb390015df8e15ee055d41d", - "offset": 9409, - "new_text": "赵王岂以一璧之故欺秦邪?", - "insert": "赵王岂以一璧之故欺秦邪?", - "insert_len": 12, - "paragraph_offset": 25, - "sentence_offset": 0, - "paragraph_num": 94 - }, - { - "key": "eda8a2936841bd2ab6102b46c8332d94", - "offset": 9421, - "new_text": "(《廉颇蔺相如列传》)", - "insert": "(《廉颇蔺相如列传》)\n", - "insert_len": 12, - "paragraph_offset": 25, - "sentence_offset": 12, - "paragraph_num": 94 - }, - { - "key": "1461f84b5518217ac46b0cb1c4aece72", - "offset": 9434, - "new_text": "卒以吾郡这发愤一击,不敢复有株治。", - "insert": "卒以吾郡这发愤一击,不敢复有株治。", - "insert_len": 17, - "paragraph_offset": 26, - "sentence_offset": 0, - "paragraph_num": 95 - }, - { - "key": "5fecc561c9ebea145fdea8fa99d4060a", - "offset": 9451, - "new_text": "(《五人墓碑记》)", - "insert": "(《五人墓碑记》)\n", - "insert_len": 10, - "paragraph_offset": 26, - "sentence_offset": 17, - "paragraph_num": 95 - }, - { - "key": "2851719faba58cb7f236288474b40b4e", - "offset": 9462, - "new_text": "怀王以不知忠臣之分,故内惑于郑袖,外欺于张仪。", - "insert": "怀王以不知忠臣之分,故内惑于郑袖,外欺于张仪。", - "insert_len": 23, - "paragraph_offset": 27, - "sentence_offset": 0, - "paragraph_num": 96 - }, - { - "key": "20609325e9d81e88b9fa243289eea03c", - "offset": 9485, - "new_text": "(《屈原列传》)", - "insert": "(《屈原列传》)\n", - "insert_len": 9, - "paragraph_offset": 27, - "sentence_offset": 23, - "paragraph_num": 96 - }, - { - "key": "ea84fc3a3f7ff004270ae21e98b81d1f", - "offset": 9495, - "new_text": "6.表示依据。", - "insert": "6.表示依据。", - "insert_len": 7, - "paragraph_offset": 28, - "sentence_offset": 0, - "paragraph_num": 97 - }, - { - "key": "537e559936e75ec5e545b876f1206471", - "offset": 9502, - "new_text": "译为:按照、依照、根据。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 5, - "end": 6, - "id": 187286, - "idx": 408, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 8, - "end": 9, - "id": 187287, - "idx": 409, - "isAccept": 0, - "type": 2 - } - ], - "insert": "译为:按照,依照,根据。", - "insert_len": 12, - "paragraph_offset": 28, - "sentence_offset": 7, - "paragraph_num": 97 - }, - { - "key": "8befbab4ef06bc8ce8c4c688327767ad", - "offset": 9514, - "new_text": "①今以实校之。", - "insert": "①今以实校之。", - "insert_len": 7, - "paragraph_offset": 28, - "sentence_offset": 19, - "paragraph_num": 97 - }, - { - "key": "16cb55a6c9216d3fb091ef51e4c5f692", - "offset": 9522, - "new_text": "(《赤壁之战》)", - "insert": "(《赤壁之战》)\n", - "insert_len": 9, - "paragraph_offset": 28, - "sentence_offset": 26, - "paragraph_num": 97 - }, - { - "key": "518d01abad42ba95b27084048d845621", - "offset": 9532, - "new_text": "②余船以次俱进。", - "insert": "②余船以次俱进。", - "insert_len": 8, - "paragraph_offset": 29, - "sentence_offset": 0, - "paragraph_num": 98 - }, - { - "key": "6f31aab50cae07e4368e75ffe5cc323c", - "offset": 9540, - "new_text": "(《赤壁之战》)\u000b说明:“以”字的宾语有时可以前置,有时可以省略。", - "insert": "(《赤壁之战》) \u000b说明:“以”字的宾语有时可以前置,有时可以省略。", - "insert_len": 34, - "paragraph_offset": 29, - "sentence_offset": 8, - "paragraph_num": 98 - }, - { - "key": "2f66ed10e0d9aa5327ae568da3824e20", - "offset": 9574, - "new_text": "①以一当十(成语)②夜以继日(成语)③秋以为期(《诗经·氓》)\u000b(二)连词。", - "insert": "①以一当十(成语) ②夜以继日(成语) ③秋以为期(《诗经·氓》) \u000b(二)连词。", - "insert_len": 41, - "paragraph_offset": 29, - "sentence_offset": 42, - "paragraph_num": 98 - }, - { - "key": "86f4c619d7733077ddae13743809dd44", - "offset": 9617, - "new_text": "1.表示并列或递进关系。", - "insert": "1.表示并列或递进关系。", - "insert_len": 12, - "paragraph_offset": 29, - "sentence_offset": 83, - "paragraph_num": 98 - }, - { - "key": "6b9a04d6694cfb6bd87f7678f86506fb", - "offset": 9631, - "new_text": "可译为“而”“又”“而且”“并且”等,或者省去。", - "insert": "可译为“而”“又”“而且”“并且”等,或者省去。", - "insert_len": 24, - "paragraph_offset": 29, - "sentence_offset": 95, - "paragraph_num": 98 - }, - { - "key": "4a1d2fd56f59d917fb85753653fc487a", - "offset": 9655, - "new_text": "①夫夷以近,则游者众。", - "insert": "①夫夷以近,则游者众。", - "insert_len": 11, - "paragraph_offset": 29, - "sentence_offset": 119, - "paragraph_num": 98 - }, - { - "key": "df83e1233830561c846c0dc3ff725142", - "offset": 9668, - "new_text": "(《游褒禅山记》)②忽魂悸以魄动。", - "insert": "(《游褒禅山记》) ②忽魂悸以魄动。", - "insert_len": 18, - "paragraph_offset": 29, - "sentence_offset": 130, - "paragraph_num": 98 - }, - { - "key": "4c7da9577cb88aabd946eb9bcf857fce", - "offset": 9686, - "new_text": "(《梦游天姥吟留别》)\u000b2.表示承接关系,前一动作行为往往是后一动作行为的手段或方式。", - "insert": "(《梦游天姥吟留别》) \u000b2.表示承接关系,前一动作行为往往是后一动作行为的手段或方式。", - "insert_len": 44, - "paragraph_offset": 29, - "sentence_offset": 148, - "paragraph_num": 98 - }, - { - "key": "bc7e42bde744c4c13ed211442e51dd40", - "offset": 9730, - "new_text": "可译为“而”或省去。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187288, - "idx": 416, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 5, - "end": 6, - "id": 187289, - "idx": 417, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"而\"或省去。", - "insert_len": 10, - "paragraph_offset": 29, - "sentence_offset": 192, - "paragraph_num": 98 - }, - { - "key": "9245d6a3bc2d04153689bc6387197449", - "offset": 9740, - "new_text": "①余与四人拥火以入。", - "insert": "①余与四人拥火以入。", - "insert_len": 10, - "paragraph_offset": 29, - "sentence_offset": 202, - "paragraph_num": 98 - }, - { - "key": "17a633394b3054650d707a28e9d4437b", - "offset": 9752, - "new_text": "(《石钟山记》)②樊哙侧其盾以撞。", - "insert": "(《石钟山记》) ②樊哙侧其盾以撞。", - "insert_len": 18, - "paragraph_offset": 29, - "sentence_offset": 212, - "paragraph_num": 98 - }, - { - "key": "fb067d6d9e0a48a3e3289b0a04ee57d5", - "offset": 9770, - "new_text": "(《鸿门宴》)③各各竦立以听。", - "insert": "(《鸿门宴》) ③各各竦立以听。", - "insert_len": 16, - "paragraph_offset": 29, - "sentence_offset": 230, - "paragraph_num": 98 - }, - { - "key": "bb71d32f66cf45ca30154a3632d70e4e", - "offset": 9786, - "new_text": "(《促织》)\u000b3.表示目的关系,后一动作行为往往是前一动作行为的目的或结果。", - "insert": "(《促织》) \u000b3.表示目的关系,后一动作行为往往是前一动作行为的目的或结果。", - "insert_len": 39, - "paragraph_offset": 29, - "sentence_offset": 246, - "paragraph_num": 98 - }, - { - "key": "79449c845e9175fb8cca5636b26aabdf", - "offset": 9825, - "new_text": "可译“而”“来”“用来”“以致”等。", - "insert": "可译“而”“来”“用来”“以致”等。", - "insert_len": 18, - "paragraph_offset": 29, - "sentence_offset": 285, - "paragraph_num": 98 - }, - { - "key": "692e1d2bce9bfdfb36c57358ea2e2418", - "offset": 9843, - "new_text": "①请立太子为王,以绝秦望。", - "insert": "①请立太子为王,以绝秦望。", - "insert_len": 13, - "paragraph_offset": 29, - "sentence_offset": 303, - "paragraph_num": 98 - }, - { - "key": "97d825ed44d4a5e4fd8bba28a53437fb", - "offset": 9858, - "new_text": "(《廉颇蔺相如列传》)\u000b②当求数顷之田,于伊、颍之上,以待余年,教吾子与汝子(《祭十二郎文》)③为秦人积威之所劫,日削月割,以趋于亡(《六国论》)\u000b4.表示因果关系,常用在表原因的分句前,可译为“因为”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 48, - "end": 50, - "id": 187290, - "idx": 422, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 101, - "end": 102, - "id": 187291, - "idx": 424, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 104, - "end": 105, - "id": 187292, - "idx": 425, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b②当求数顷之田,于伊、颍之上,以待余年,教吾子与汝子(《祭十二郎文》) \u000b③为秦人积威之所劫,日削月割,以趋于亡(《六国论》) \u000b4.表示因果关系,常用在表原因的分句前,可译为\"因为\"。", - "insert_len": 106, - "paragraph_offset": 29, - "sentence_offset": 316, - "paragraph_num": 98 - }, - { - "key": "a2228c8115461caaf2cd83c8f82e7b4e", - "offset": 9964, - "new_text": "例如:\u000b①不赂者以赂者丧(《六国论》)②所谓华山洞者,以其乃华山之阳名之也(《游褒禅山记》)\u000b③诸侯以公子贤,多客,不敢加兵谋魏十余年。", - "insert": "例如: \u000b①不赂者以赂者丧(《六国论》) ②所谓华山洞者,以其乃华山之阳名之也(《游褒禅山记》) \u000b③诸侯以公子贤,多客,不敢加兵谋魏十余年。", - "insert_len": 71, - "paragraph_offset": 29, - "sentence_offset": 422, - "paragraph_num": 98 - }, - { - "key": "1d58a8a5b30a3054e39abf5770c13dba", - "offset": 10035, - "new_text": "(《信陵君窃符救赵》)\u000b5.表示修饰关系,连接状语和中心语,可译为“而”,或省去。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 34, - "end": 35, - "id": 187293, - "idx": 430, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 36, - "end": 37, - "id": 187294, - "idx": 431, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《信陵君窃符救赵》) \u000b5.表示修饰关系,连接状语和中心语,可译为\"而\",或省去。", - "insert_len": 42, - "paragraph_offset": 29, - "sentence_offset": 493, - "paragraph_num": 98 - }, - { - "key": "ce453b988f9e65596c4a792e2a2f9b15", - "offset": 10077, - "new_text": "例如:\u000b①木欣欣以向荣,泉涓涓而始流。", - "insert": "例如: \u000b①木欣欣以向荣,泉涓涓而始流。", - "insert_len": 20, - "paragraph_offset": 29, - "sentence_offset": 535, - "paragraph_num": 98 - }, - { - "key": "bd069d8e776510a039aa497003ad6698", - "offset": 10097, - "new_text": "(陶渊明《归去来辞》)\u000b(三)助词1.作语助,表示时间、方位和范围。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 18, - "end": 20, - "id": 187295, - "idx": 434, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(陶渊明《归去来辞》) \u000b(三)助词 \u000b1.作语助,表示时间、方位和范围。", - "insert_len": 37, - "paragraph_offset": 29, - "sentence_offset": 555, - "paragraph_num": 98 - }, - { - "key": "46cd3fc89db7d9553f39965ae0148da8", - "offset": 10134, - "new_text": "例:\u000b①受命以来,夙夜忧叹。", - "insert": "例: \u000b①受命以来,夙夜忧叹。", - "insert_len": 15, - "paragraph_offset": 29, - "sentence_offset": 592, - "paragraph_num": 98 - }, - { - "key": "df4d195a3ec9ad466149fc7995357529", - "offset": 10149, - "new_text": "(以:表时间)(《出师表》)\u000b②指从此以往十五都予赵。", - "insert": "(以:表时间)(《出师表》) \u000b②指从此以往十五都予赵。", - "insert_len": 28, - "paragraph_offset": 29, - "sentence_offset": 607, - "paragraph_num": 98 - }, - { - "key": "4c1edb573274d590fc2d4b5b12e2b05f", - "offset": 10177, - "new_text": "(以:方位)(《廉颇蔺相如列传》)③自王侯以下莫不逾侈。", - "insert": "(以:方位)(《廉颇蔺相如列传》) ③自王侯以下莫不逾侈。", - "insert_len": 29, - "paragraph_offset": 29, - "sentence_offset": 635, - "paragraph_num": 98 - }, - { - "key": "73a3ce9e68f1ef94d0fa7524f12dc98b", - "offset": 10206, - "new_text": "(以:表范围)\u000b2.作语助,起调整音节作用。", - "insert": "(以:表范围) \u000b2.作语助,起调整音节作用。", - "insert_len": 23, - "paragraph_offset": 29, - "sentence_offset": 664, - "paragraph_num": 98 - }, - { - "key": "9b939cb9885e4a9374e8880a9fbbb394", - "offset": 10229, - "new_text": "例:①逆以煎我怀。", - "insert": "例: ①逆以煎我怀。", - "insert_len": 10, - "paragraph_offset": 29, - "sentence_offset": 687, - "paragraph_num": 98 - }, - { - "key": "9f155e400dc58bcfca9d974b9af8b9d7", - "offset": 10239, - "new_text": "(《孔雀东南飞》)\u000b(四)动词\u000b1.以为,认为。", - "insert": "(《孔雀东南飞》) \u000b(四)动词 \u000b1.以为,认为。", - "insert_len": 26, - "paragraph_offset": 29, - "sentence_offset": 697, - "paragraph_num": 98 - }, - { - "key": "5abfe8d5d8906cff55b0062c688a393f", - "offset": 10265, - "new_text": "①老臣以媪为长安君计短也。", - "insert": "①老臣以媪为长安君计短也。", - "insert_len": 13, - "paragraph_offset": 29, - "sentence_offset": 723, - "paragraph_num": 98 - }, - { - "key": "e4680ded8a201fe6c73809ae4f31c831", - "offset": 10279, - "new_text": "(《触龙说赵太后》)②皆以美于徐公。", - "insert": "(《触龙说赵太后》) ②皆以美于徐公。", - "insert_len": 19, - "paragraph_offset": 29, - "sentence_offset": 736, - "paragraph_num": 98 - }, - { - "key": "1661a002108130c8760175e07a96d080", - "offset": 10298, - "new_text": "(《邹忌讽齐王纳谏》)\u000b2.用,任用。", - "insert": "(《邹忌讽齐王纳谏》) \u000b2.用,任用。", - "insert_len": 20, - "paragraph_offset": 29, - "sentence_offset": 755, - "paragraph_num": 98 - }, - { - "key": "2d9316e8f059ecec6c574373e229460a", - "offset": 10318, - "new_text": "①忠不必用兮,贤不必以。", - "insert": "①忠不必用兮,贤不必以。", - "insert_len": 12, - "paragraph_offset": 29, - "sentence_offset": 775, - "paragraph_num": 98 - }, - { - "key": "21a117cfb5a3bae38658ee934c6a546a", - "offset": 10331, - "new_text": "(《涉江》)\u000b(五)名词。", - "insert": "(《涉江》) \u000b(五)名词。", - "insert_len": 14, - "paragraph_offset": 29, - "sentence_offset": 787, - "paragraph_num": 98 - }, - { - "key": "5a7d9fa859ec581b7e96269b9b35e31e", - "offset": 10345, - "new_text": "译为:缘由、原因。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 5, - "end": 6, - "id": 187296, - "idx": 445, - "isAccept": 0, - "type": 2 - } - ], - "insert": "译为:缘由,原因。", - "insert_len": 9, - "paragraph_offset": 29, - "sentence_offset": 801, - "paragraph_num": 98 - }, - { - "key": "1c30854fc1c98534fd7a38ab13f6d4fb", - "offset": 10354, - "new_text": "①古人秉烛游,良有以也(李白《春夜宴桃李园序》)\u000b(六)通假\u000b1.通“已”,", - "diffs": [ - { - "tag": "d", - "origin": "已经。", - "text": "", - "start": 40, - "end": 43, - "id": 187297, - "idx": 448, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①古人秉烛游,良有以也(李白《春夜宴桃李园序》) \u000b(六)通假 \u000b1.通“已”,已经。", - "insert_len": 43, - "paragraph_offset": 29, - "sentence_offset": 810, - "paragraph_num": 98 - }, - { - "key": "30727e96a2c749ba4135518f230ecda6", - "offset": 10398, - "new_text": "①固以怪之矣。", - "insert": "①固以怪之矣。", - "insert_len": 7, - "paragraph_offset": 29, - "sentence_offset": 853, - "paragraph_num": 98 - }, - { - "key": "dabe7a85b762324c6b932f3edc31024d", - "offset": 10406, - "new_text": "②日已尽矣。", - "diffs": [ - { - "tag": "r", - "origin": "以", - "text": "已", - "start": 2, - "end": 3, - "id": 187298, - "idx": 449, - "isAccept": 0, - "type": 2 - } - ], - "insert": "②日以尽矣。", - "insert_len": 6, - "paragraph_offset": 29, - "sentence_offset": 860, - "paragraph_num": 98 - }, - { - "key": "6359c62cbe3b65bb3a534b309d33f239", - "offset": 10413, - "new_text": "2.通“已”,止。", - "insert": "2.通“已”,止。", - "insert_len": 9, - "paragraph_offset": 29, - "sentence_offset": 866, - "paragraph_num": 98 - }, - { - "key": "636bed833f1b665b03cdd5a6115742dd", - "offset": 10424, - "new_text": "①无以,则王乎?", - "insert": "①无以,则王乎?", - "insert_len": 8, - "paragraph_offset": 29, - "sentence_offset": 875, - "paragraph_num": 98 - }, - { - "key": "fd41de5555517dde6cd20dbb1ab59e95", - "offset": 10433, - "new_text": "【以为】\u000b1.认为,把……", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": ",", - "start": 10, - "end": 11, - "id": 187299, - "idx": 451, - "isAccept": 0, - "type": 2 - } - ], - "insert": "【以为】 \u000b1.认为,把……", - "insert_len": 14, - "paragraph_offset": 29, - "sentence_offset": 883, - "paragraph_num": 98 - }, - { - "key": "3f20d3f698023b61cc57326844d45697", - "offset": 10449, - "new_text": "当作或看作。", - "insert": "当作或看作。", - "insert_len": 6, - "paragraph_offset": 29, - "sentence_offset": 897, - "paragraph_num": 98 - }, - { - "key": "122f73f09fa94315c8e9d0b5ab840cf9", - "offset": 10455, - "new_text": "①虎视之,庞然大物也,以为神。", - "insert": "①虎视之,庞然大物也,以为神。", - "insert_len": 15, - "paragraph_offset": 29, - "sentence_offset": 903, - "paragraph_num": 98 - }, - { - "key": "2b43c9a89a9c4f0a8ebea05c06b643dd", - "offset": 10471, - "new_text": "②医之好治不病以为功!", - "insert": "②医之好治不病以为功!", - "insert_len": 11, - "paragraph_offset": 29, - "sentence_offset": 918, - "paragraph_num": 98 - }, - { - "key": "3f6e51601560ee794c4814306e5a70ba", - "offset": 10483, - "new_text": "⑵把……", - "insert": "⑵把……", - "insert_len": 4, - "paragraph_offset": 29, - "sentence_offset": 929, - "paragraph_num": 98 - }, - { - "key": "7e9c62b38e4f1e994b8a52e0745747c7", - "offset": 10489, - "new_text": "作为或制成。", - "insert": "作为或制成。\n", - "insert_len": 7, - "paragraph_offset": 29, - "sentence_offset": 933, - "paragraph_num": 98 - }, - { - "key": "2795fb8973753d1f2fdc5824add4dffd", - "offset": 10497, - "new_text": "①南取百越之地,以为桂林、象郡。", - "insert": "①南取百越之地,以为桂林、象郡。", - "insert_len": 16, - "paragraph_offset": 30, - "sentence_offset": 0, - "paragraph_num": 99 - }, - { - "key": "4dae704680627f676aad88aacffa7a80", - "offset": 10513, - "new_text": "(以为:把它设为。)", - "insert": "(以为:把它设为。)", - "insert_len": 10, - "paragraph_offset": 30, - "sentence_offset": 16, - "paragraph_num": 99 - }, - { - "key": "d88756ecf9981f8b80a76cdcf7f8188c", - "offset": 10523, - "new_text": "②铸以为金人十二。", - "insert": "②铸以为金人十二。", - "insert_len": 9, - "paragraph_offset": 30, - "sentence_offset": 26, - "paragraph_num": 99 - }, - { - "key": "3e272981778bc28a16b93428745a68c4", - "offset": 10534, - "new_text": "【以是】【是以】相当“因此”,引出事理发展或推断的结果。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 10, - "end": 11, - "id": 187300, - "idx": 452, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 13, - "end": 14, - "id": 187301, - "idx": 453, - "isAccept": 0, - "type": 2 - } - ], - "insert": "【以是】【是以】相当\"因此\",引出事理发展或推断的结果。", - "insert_len": 28, - "paragraph_offset": 30, - "sentence_offset": 35, - "paragraph_num": 99 - }, - { - "key": "6af9efd91d60fd24bf2888dd394c8634", - "offset": 10564, - "new_text": "①余是以记之,盖叹郦元之简,而笑李渤之陋也。", - "insert": "①余是以记之,盖叹郦元之简,而笑李渤之陋也。", - "insert_len": 22, - "paragraph_offset": 30, - "sentence_offset": 63, - "paragraph_num": 99 - }, - { - "key": "931c1a569554571cd4610ad1910d5178", - "offset": 10588, - "new_text": "(《石钟山记》)\u000b②公子往而臣不送,以是知公子恨之复返也(《信陵君窃符救赵》)【有以】【无以】意思分别是“有什么办法用来……”", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 40, - "end": 42, - "id": 187302, - "idx": 455, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《石钟山记》) \u000b②公子往而臣不送,以是知公子恨之复返也(《信陵君窃符救赵》) \u000b【有以】【无以】意思分别是“有什么办法用来……”", - "insert_len": 66, - "paragraph_offset": 30, - "sentence_offset": 85, - "paragraph_num": 99 - }, - { - "key": "e281780231f64b0b49d026dc4cc4c623", - "offset": 10654, - "new_text": "“没有什么办法……”", - "diffs": [ - { - "tag": "d", - "origin": "用来", - "text": "", - "start": 7, - "end": 9, - "id": 187303, - "idx": 456, - "isAccept": 0, - "type": 2 - } - ], - "insert": "“没有什么办法用来……”", - "insert_len": 12, - "paragraph_offset": 30, - "sentence_offset": 151, - "paragraph_num": 99 - }, - { - "key": "85667e91771f7e13f79cf674336f38da", - "offset": 10666, - "new_text": "①项王未有以应,曰:“坐。”", - "insert": "①项王未有以应,曰:“坐。”", - "insert_len": 14, - "paragraph_offset": 30, - "sentence_offset": 163, - "paragraph_num": 99 - }, - { - "key": "9ad11769c5f8b99172949cb94f183123", - "offset": 10682, - "new_text": "(《鸿门宴》)\u000b②王语暴以好乐,暴未有以对也(《庄暴见孟子》)③故不积跬步,无以至千里;不积小流,无以成江(《劝学》)\u000b④臣无祖母,无以至今日,祖母无臣,无以终余年(《陈情表》)\u000b13.【因】(一)介词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 32, - "end": 34, - "id": 187304, - "idx": 458, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 93, - "end": 95, - "id": 187305, - "idx": 460, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 102, - "end": 104, - "id": 187306, - "idx": 461, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b②王语暴以好乐,暴未有以对也(《庄暴见孟子》) \u000b③故不积跬步,无以至千里;不积小流,无以成江(《劝学》) \u000b④臣无祖母,无以至今日,祖母无臣,无以终余年(《陈情表》) \u000b\u000b13.【因】 \u000b(一)介词。", - "insert_len": 110, - "paragraph_offset": 30, - "sentence_offset": 177, - "paragraph_num": 99 - }, - { - "key": "22ada119324d102e276a05a519c866f4", - "offset": 10792, - "new_text": "1.依照,根据。", - "insert": "1.依照,根据。", - "insert_len": 8, - "paragraph_offset": 30, - "sentence_offset": 287, - "paragraph_num": 99 - }, - { - "key": "59c7fd178f8badce825b8da76ed7acee", - "offset": 10802, - "new_text": "①罔不因势象形。", - "insert": "①罔不因势象形。", - "insert_len": 8, - "paragraph_offset": 30, - "sentence_offset": 295, - "paragraph_num": 99 - }, - { - "key": "426d75ea4aa4749b649cc44a1a2c240b", - "offset": 10812, - "new_text": "(《核舟记》)\u000b②变法者因时而化。", - "insert": "(《核舟记》) \u000b②变法者因时而化。", - "insert_len": 18, - "paragraph_offset": 30, - "sentence_offset": 303, - "paragraph_num": 99 - }, - { - "key": "8f5db6d657ee9035a68bb806557ba161", - "offset": 10830, - "new_text": "③善战者因其势而利导之。", - "insert": "③善战者因其势而利导之。", - "insert_len": 12, - "paragraph_offset": 30, - "sentence_offset": 321, - "paragraph_num": 99 - }, - { - "key": "9b9ab8e25cee516e89ecd983d18a22a1", - "offset": 10844, - "new_text": "2.依靠,凭借。", - "insert": "2.依靠,凭借。", - "insert_len": 8, - "paragraph_offset": 30, - "sentence_offset": 333, - "paragraph_num": 99 - }, - { - "key": "eb4a7e6689edd23b62249be3db8729aa", - "offset": 10854, - "new_text": "①因利乘便,宰割天下,分裂山河(《过秦论》)\u000b②因人之力而敝之,不仁(《烛之武退秦师》)③又因厚币用事者臣靳尚。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 45, - "end": 47, - "id": 187307, - "idx": 464, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①因利乘便,宰割天下,分裂山河(《过秦论》) \u000b②因人之力而敝之,不仁(《烛之武退秦师》) \u000b③又因厚币用事者臣靳尚。", - "insert_len": 59, - "paragraph_offset": 30, - "sentence_offset": 341, - "paragraph_num": 99 - }, - { - "key": "45f04b56430cb6ab32e9ff6c1baa23c7", - "offset": 10915, - "new_text": "(《屈原列传》)\u000b3.趁着,趁此。", - "insert": "(《屈原列传》) \u000b3.趁着,趁此。", - "insert_len": 18, - "paragraph_offset": 30, - "sentence_offset": 400, - "paragraph_num": 99 - }, - { - "key": "7a2d4fe6e8104e95e0f814c920c11eee", - "offset": 10933, - "new_text": "①不如因而厚遇之。", - "insert": "①不如因而厚遇之。", - "insert_len": 9, - "paragraph_offset": 30, - "sentence_offset": 418, - "paragraph_num": 99 - }, - { - "key": "3b4c444d1caaf9b211f1ef4d7841a9ba", - "offset": 10944, - "new_text": "(《鸿门宴》)\u000b②因击沛公于坐。", - "insert": "(《鸿门宴》) \u000b②因击沛公于坐。", - "insert_len": 17, - "paragraph_offset": 30, - "sentence_offset": 427, - "paragraph_num": 99 - }, - { - "key": "d39d2bcf2b4c257ab0eadb85a0217bf1", - "offset": 10961, - "new_text": "(《鸿门宴》)\u000b4.通过,经由。", - "insert": "(《鸿门宴》) \u000b4.通过,经由。", - "insert_len": 17, - "paragraph_offset": 30, - "sentence_offset": 444, - "paragraph_num": 99 - }, - { - "key": "f2468b451d6db0bf8a1943a1d0ac4dac", - "offset": 10978, - "new_text": "①因宾客至蔺相如门谢罪。", - "insert": "①因宾客至蔺相如门谢罪。", - "insert_len": 12, - "paragraph_offset": 30, - "sentence_offset": 461, - "paragraph_num": 99 - }, - { - "key": "3ae4a115beb7669c441260c2559bda50", - "offset": 10992, - "new_text": "(《鸿门宴》)\u000b5.因为,由于。", - "insert": "(《鸿门宴》) \u000b5.因为,由于。", - "insert_len": 17, - "paragraph_offset": 30, - "sentence_offset": 473, - "paragraph_num": 99 - }, - { - "key": "e5fa6a46b91c4e9b4b3b55dee023f588", - "offset": 11009, - "new_text": "①因造玉清宫,伐山取材,方有人见之。", - "insert": "①因造玉清宫,伐山取材,方有人见之。", - "insert_len": 18, - "paragraph_offset": 30, - "sentence_offset": 490, - "paragraph_num": 99 - }, - { - "key": "2f7c058c878ab6325c0b1bbb2817bf57", - "offset": 11029, - "new_text": "②恩所加则思无因喜以谬赏。", - "insert": "②恩所加则思无因喜以谬赏。", - "insert_len": 13, - "paragraph_offset": 30, - "sentence_offset": 508, - "paragraph_num": 99 - }, - { - "key": "810de978c42598971a33038649ee038b", - "offset": 11044, - "new_text": "(《谏太宗十思书》)\u000b(二)副词。", - "insert": "(《谏太宗十思书》) \u000b(二)副词。", - "insert_len": 18, - "paragraph_offset": 30, - "sentence_offset": 521, - "paragraph_num": 99 - }, - { - "key": "0a6928cd49c0a7fb1d44656e22661c8b", - "offset": 11062, - "new_text": "1.于是,就;因而。", - "insert": "1.于是,就;因而。", - "insert_len": 10, - "paragraph_offset": 30, - "sentence_offset": 539, - "paragraph_num": 99 - }, - { - "key": "7d99312c3e1aa1f66785cdc5c0744871", - "offset": 11074, - "new_text": "①因拔刀斫前奏案。", - "insert": "①因拔刀斫前奏案。", - "insert_len": 9, - "paragraph_offset": 30, - "sentence_offset": 549, - "paragraph_num": 99 - }, - { - "key": "da17a9047b4bd854e7c5942c6058441a", - "offset": 11085, - "new_text": "(《赤壁之战》)\u000b②相如因持璧却立……", - "insert": "(《赤壁之战》) \u000b②相如因持璧却立……", - "insert_len": 20, - "paragraph_offset": 30, - "sentence_offset": 558, - "paragraph_num": 99 - }, - { - "key": "77ded4a1cf1bf6c46e9e586a0ca8bcf8", - "offset": 11105, - "new_text": "(《廉颇蔺相如列传》)\u000b2.原因、缘由、机缘。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 17, - "end": 18, - "id": 187308, - "idx": 472, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 20, - "end": 21, - "id": 187309, - "idx": 473, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b2.原因,缘由,机缘。", - "insert_len": 24, - "paragraph_offset": 30, - "sentence_offset": 578, - "paragraph_num": 99 - }, - { - "key": "98858aad672c3a708d60c9eeaad45db7", - "offset": 11129, - "new_text": "①于今无会因。", - "insert": "①于今无会因。", - "insert_len": 7, - "paragraph_offset": 30, - "sentence_offset": 602, - "paragraph_num": 99 - }, - { - "key": "4bd245ab20c9d61616c97812458acd16", - "offset": 11138, - "new_text": "(《孔雀东南飞》)\u000b(三)动词1.根据①故事因于世,而备适于事(《五蠹》)2.沿袭,继续。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 16, - "end": 18, - "id": 187310, - "idx": 475, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 22, - "end": 24, - "id": 187311, - "idx": 476, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 42, - "end": 44, - "id": 187312, - "idx": 477, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《孔雀东南飞》) \u000b(三)动词 \u000b1.根据 \u000b①故事因于世,而备适于事(《五蠹》) \u000b2.沿袭,继续。", - "insert_len": 52, - "paragraph_offset": 30, - "sentence_offset": 609, - "paragraph_num": 99 - }, - { - "key": "ec322a72c65953ecf691a6b28cde7b5f", - "offset": 11190, - "new_text": "①蒙故业,因遗策。", - "insert": "①蒙故业,因遗策。", - "insert_len": 9, - "paragraph_offset": 30, - "sentence_offset": 661, - "paragraph_num": 99 - }, - { - "key": "78efb17ff5f70be4f7c5a9664f744ccf", - "offset": 11201, - "new_text": "(《过秦论》)\u000b②加之以师旅,因之以饥馑。", - "insert": "(《过秦论》) \u000b②加之以师旅,因之以饥馑。\n", - "insert_len": 23, - "paragraph_offset": 30, - "sentence_offset": 670, - "paragraph_num": 99 - }, - { - "key": "58dc42124df4b4ce775d1efd649f4614", - "offset": 11227, - "new_text": "14.【于】\u000b(一)介词。", - "insert": "14.【于】 \u000b(一)介词。", - "insert_len": 14, - "paragraph_offset": 31, - "sentence_offset": 0, - "paragraph_num": 112 - }, - { - "key": "5d1b65917a6d8d69b2503ceef19c84a1", - "offset": 11241, - "new_text": "1.在、从、到\u000b①乃设九宾礼于庭。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 3, - "end": 4, - "id": 187313, - "idx": 480, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 5, - "end": 6, - "id": 187314, - "idx": 481, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.在,从,到 \u000b①乃设九宾礼于庭。", - "insert_len": 18, - "paragraph_offset": 31, - "sentence_offset": 14, - "paragraph_num": 112 - }, - { - "key": "074d7556944460f0f4e7ebbbd136a77a", - "offset": 11261, - "new_text": "(在)《廉颇蔺相如列传》\u000b②缙绅、大夫、士萃于左丞相府,莫知计所出。", - "insert": "(在)《廉颇蔺相如列传》 \u000b②缙绅、大夫、士萃于左丞相府,莫知计所出。", - "insert_len": 35, - "paragraph_offset": 31, - "sentence_offset": 32, - "paragraph_num": 112 - }, - { - "key": "a7962cbd11b25ff86de0f15fcae785f6", - "offset": 11296, - "new_text": "③青,取之于蓝,而青于蓝。", - "insert": "③青,取之于蓝,而青于蓝。", - "insert_len": 13, - "paragraph_offset": 31, - "sentence_offset": 67, - "paragraph_num": 112 - }, - { - "key": "e0de4d380e7c978c3038fba986792768", - "offset": 11311, - "new_text": "(前一个“于”:从)(《劝学》)\u000b④从径道亡,归璧于赵。", - "insert": "(前一个“于”:从)(《劝学》) \u000b④从径道亡,归璧于赵。", - "insert_len": 29, - "paragraph_offset": 31, - "sentence_offset": 80, - "paragraph_num": 112 - }, - { - "key": "c248486714dba8950646b4fc05853f6d", - "offset": 11340, - "new_text": "(到)《廉颇蔺相如列传》\u000b2.“在……方面”“从……中”①荆国有余地而不足于民。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 29, - "end": 31, - "id": 187315, - "idx": 486, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(到)《廉颇蔺相如列传》 \u000b2.“在……方面”“从……中” \u000b①荆国有余地而不足于民。", - "insert_len": 43, - "paragraph_offset": 31, - "sentence_offset": 109, - "paragraph_num": 112 - }, - { - "key": "de3b279ec57ed664751bb8fdd1aa4729", - "offset": 11383, - "new_text": "②于人为可讥,而在己为悔。", - "insert": "②于人为可讥,而在己为悔。", - "insert_len": 13, - "paragraph_offset": 31, - "sentence_offset": 152, - "paragraph_num": 112 - }, - { - "key": "e2bb8ca5b560ab9c1d781ce7782d4366", - "offset": 11398, - "new_text": "(《游褒禅山记》)\u000b3.由于①业精于勤、荒于嬉(《进学解》)\u000b4.向,对,对于。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 15, - "end": 17, - "id": 187316, - "idx": 488, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《游褒禅山记》) \u000b3.由于 \u000b①业精于勤、荒于嬉(《进学解》) \u000b4.向,对,对于。", - "insert_len": 44, - "paragraph_offset": 31, - "sentence_offset": 165, - "paragraph_num": 112 - }, - { - "key": "06c036f9542d3cb1e7fb6e6ba73118d1", - "offset": 11442, - "new_text": "①请奉命求救于孙将军(《赤壁之战》)\u000b②鲁肃闻刘表卒,言于孙权曰……", - "insert": "①请奉命求救于孙将军(《赤壁之战》) \u000b②鲁肃闻刘表卒,言于孙权曰……", - "insert_len": 35, - "paragraph_offset": 31, - "sentence_offset": 209, - "paragraph_num": 112 - }, - { - "key": "875d3ba5d3a6f07ead6540724f5cdd48", - "offset": 11479, - "new_text": "(《赤壁之战》)\u000b③爱其子,择师而教之,于其身也,则耻师焉。", - "insert": "(《赤壁之战》) \u000b③爱其子,择师而教之,于其身也,则耻师焉。", - "insert_len": 31, - "paragraph_offset": 31, - "sentence_offset": 244, - "paragraph_num": 112 - }, - { - "key": "a30fe637b109cc2d0e511a36568ee538", - "offset": 11510, - "new_text": "(《师说》)\u000b5.被。", - "insert": "(《师说》) \u000b5.被。", - "insert_len": 12, - "paragraph_offset": 31, - "sentence_offset": 275, - "paragraph_num": 112 - }, - { - "key": "07b6f101a4e5c16cbbd5df943ad81916", - "offset": 11522, - "new_text": "①君幸于赵王。", - "insert": "①君幸于赵王。", - "insert_len": 7, - "paragraph_offset": 31, - "sentence_offset": 287, - "paragraph_num": 112 - }, - { - "key": "c6503cbdf763c4737404cd9506abb4ca", - "offset": 11531, - "new_text": "《廉颇蔺相如列传》\u000b②故内惑于郑袖,外欺于张仪。", - "insert": "《廉颇蔺相如列传》 \u000b②故内惑于郑袖,外欺于张仪。", - "insert_len": 25, - "paragraph_offset": 31, - "sentence_offset": 294, - "paragraph_num": 112 - }, - { - "key": "d35ef9ade1bb3abd28c5e59759b2c7a7", - "offset": 11556, - "new_text": "(《屈原列传》)\u000b6.与,跟,同。", - "insert": "(《屈原列传》) \u000b6.与,跟,同。", - "insert_len": 18, - "paragraph_offset": 31, - "sentence_offset": 319, - "paragraph_num": 112 - }, - { - "key": "c4cc78e34273f05fabc9f4c3644782d3", - "offset": 11574, - "new_text": "①身长八尺,每自比于管仲、乐毅。", - "insert": "①身长八尺,每自比于管仲、乐毅。", - "insert_len": 16, - "paragraph_offset": 31, - "sentence_offset": 337, - "paragraph_num": 112 - }, - { - "key": "2c93c458f1c30bbf7b1678862b6a0aa4", - "offset": 11592, - "new_text": "②燕王欲结于君。", - "insert": "②燕王欲结于君。", - "insert_len": 8, - "paragraph_offset": 31, - "sentence_offset": 353, - "paragraph_num": 112 - }, - { - "key": "d6d60f18cad794b248294f7ee97d2c2c", - "offset": 11602, - "new_text": "《廉颇蔺相如列传》\u000b③莫若遣腹心自结于东,以共济世业。", - "insert": "《廉颇蔺相如列传》 \u000b③莫若遣腹心自结于东,以共济世业。", - "insert_len": 28, - "paragraph_offset": 31, - "sentence_offset": 361, - "paragraph_num": 112 - }, - { - "key": "4c20bf4dbbfaaceda721f59ccd86e749", - "offset": 11630, - "new_text": "《赤壁之战》\u000b7.比。", - "insert": "《赤壁之战》 \u000b7.比。", - "insert_len": 12, - "paragraph_offset": 31, - "sentence_offset": 389, - "paragraph_num": 112 - }, - { - "key": "904c3116df6f4b556011ae7ee2998f5b", - "offset": 11642, - "new_text": "①孔子曰:“苛政猛于虎也。”", - "insert": "①孔子曰:“苛政猛于虎也。”", - "insert_len": 14, - "paragraph_offset": 31, - "sentence_offset": 401, - "paragraph_num": 112 - }, - { - "key": "f2e512d2de2c1b2ec3eb281740ceca5a", - "offset": 11658, - "new_text": "②青,取之于蓝,而青于蓝。", - "insert": "②青,取之于蓝,而青于蓝。", - "insert_len": 13, - "paragraph_offset": 31, - "sentence_offset": 415, - "paragraph_num": 112 - }, - { - "key": "18bae56acc64c9cab38a7ac44c7291e0", - "offset": 11673, - "new_text": "(后一个“于”:比)(《劝学》)\u000b【于是】\u000b1.相当于“于+此”,在这时,在这种情况下,对此、从此、因此。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 48, - "end": 49, - "id": 187317, - "idx": 499, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 51, - "end": 52, - "id": 187318, - "idx": 500, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(后一个“于”:比)(《劝学》) \u000b【于是】 \u000b1.相当于“于+此”,在这时,在这种情况下,对此,从此,因此。", - "insert_len": 55, - "paragraph_offset": 31, - "sentence_offset": 428, - "paragraph_num": 112 - }, - { - "key": "2a1c72665cc6059233bc685160c3ed2c", - "offset": 11728, - "new_text": "例:\u000b①于是宾客无不变色离席。", - "insert": "例: \u000b①于是宾客无不变色离席。", - "insert_len": 16, - "paragraph_offset": 31, - "sentence_offset": 483, - "paragraph_num": 112 - }, - { - "key": "839bdb69543dff29eb427acdeae28dd7", - "offset": 11744, - "new_text": "(在这时)\u000b②吾祖死于是,吾父死于是。", - "insert": "(在这时) \u000b②吾祖死于是,吾父死于是。", - "insert_len": 20, - "paragraph_offset": 31, - "sentence_offset": 499, - "paragraph_num": 112 - }, - { - "key": "99474eac08f78d325723a241adbf1448", - "offset": 11764, - "new_text": "(在这种情况下)(《捕蛇者说》)\u000b③于是秦王不怿,为一击罅。", - "insert": "(在这种情况下)(《捕蛇者说》) \u000b③于是秦王不怿,为一击罅。", - "insert_len": 31, - "paragraph_offset": 31, - "sentence_offset": 519, - "paragraph_num": 112 - }, - { - "key": "c332731176b481b5c4364a4a8a73fecc", - "offset": 11795, - "new_text": "(对此)《廉颇蔺相如列传》\u000b④于是余有叹焉。", - "insert": "(对此)《廉颇蔺相如列传》 \u000b④于是余有叹焉。", - "insert_len": 23, - "paragraph_offset": 31, - "sentence_offset": 550, - "paragraph_num": 112 - }, - { - "key": "4ce96937e644a325fef93f3aad3b1b84", - "offset": 11818, - "new_text": "(因此)(《游褒禅山记》)\u000b⑤遂墨以葬文公,晋于是始墨。", - "insert": "(因此)(《游褒禅山记》) \u000b⑤遂墨以葬文公,晋于是始墨。", - "insert_len": 29, - "paragraph_offset": 31, - "sentence_offset": 573, - "paragraph_num": 112 - }, - { - "key": "668278039bec6d75335d2515d219be6e", - "offset": 11847, - "new_text": "(从此)\u000b2.连词,表前后句的承接或因果关系,与现代汉语“于是”相同。", - "insert": "(从此) \u000b2.连词,表前后句的承接或因果关系,与现代汉语“于是”相同。", - "insert_len": 36, - "paragraph_offset": 31, - "sentence_offset": 602, - "paragraph_num": 112 - }, - { - "key": "bb63efd3b5dc20210f541e13763eebb6", - "offset": 11883, - "new_text": "例:\u000b①于是秦王不怿,为一击缻。", - "insert": "例: \u000b①于是秦王不怿,为一击缻。", - "insert_len": 17, - "paragraph_offset": 31, - "sentence_offset": 638, - "paragraph_num": 112 - }, - { - "key": "9ce2101bf2ed31999e5df0950d47e840", - "offset": 11900, - "new_text": "(《廉颇蔺相如列传》)\u000b②吴之民方痛心焉,于是乘其厉声以呵,则噪而相逐。", - "insert": "(《廉颇蔺相如列传》) \u000b②吴之民方痛心焉,于是乘其厉声以呵,则噪而相逐。", - "insert_len": 37, - "paragraph_offset": 31, - "sentence_offset": 655, - "paragraph_num": 112 - }, - { - "key": "7c5f992f403b278401e3c90833ff53a9", - "offset": 11937, - "new_text": "(《五人墓碑记》)\u000b③于是为长安君约车百乘,质于齐。", - "insert": "(《五人墓碑记》) \u000b③于是为长安君约车百乘,质于齐。", - "insert_len": 27, - "paragraph_offset": 31, - "sentence_offset": 692, - "paragraph_num": 112 - }, - { - "key": "1941988f1a604765228699a9fd246890", - "offset": 11964, - "new_text": "(《触龙说赵太后》)\u000b【见……", - "insert": "(《触龙说赵太后》) \u000b【见……", - "insert_len": 16, - "paragraph_offset": 31, - "sentence_offset": 719, - "paragraph_num": 112 - }, - { - "key": "e5f503a3d2427c6e887d08f19cfa6075", - "offset": 11980, - "new_text": "于】表示被动。", - "insert": "于】表示被动。", - "insert_len": 7, - "paragraph_offset": 31, - "sentence_offset": 735, - "paragraph_num": 112 - }, - { - "key": "25ddf373f4e646d83246349fd4169d4a", - "offset": 11987, - "new_text": "①吾长见笑于大方之家(《秋水》)\u000b②今是溪独见辱于愚,何哉(《愚溪诗序》)", - "insert": "①吾长见笑于大方之家(《秋水》) \u000b②今是溪独见辱于愚,何哉(《愚溪诗序》)\n", - "insert_len": 39, - "paragraph_offset": 31, - "sentence_offset": 742, - "paragraph_num": 112 - }, - { - "key": "427f28e05aab7384a36d5c91cc2d4e1c", - "offset": 12031, - "new_text": "15.【与】\u000b(一)介词。", - "insert": "15.【与】 \u000b(一)介词。", - "insert_len": 14, - "paragraph_offset": 32, - "sentence_offset": 0, - "paragraph_num": 115 - }, - { - "key": "77cb1eb5150420faa1c37645211da2f4", - "offset": 12045, - "new_text": "1.介词。", - "insert": "1.介词。", - "insert_len": 5, - "paragraph_offset": 32, - "sentence_offset": 14, - "paragraph_num": 115 - }, - { - "key": "a165e54789a938408be717c0134d38aa", - "offset": 12052, - "new_text": "和,跟,同。", - "insert": "和,跟,同。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 19, - "paragraph_num": 115 - }, - { - "key": "d17793ea9389eabab4b4304985b44d40", - "offset": 12058, - "new_text": "①沛公军霸上,未得与项羽相见(《鸿门宴》)\u000b②而翁归,自与汝复算耳(《促织》)\u000b2。", - "insert": "①沛公军霸上,未得与项羽相见(《鸿门宴》) \u000b②而翁归,自与汝复算耳(《促织》) \u000b2。", - "insert_len": 44, - "paragraph_offset": 32, - "sentence_offset": 25, - "paragraph_num": 115 - }, - { - "key": "2999e4ac7d43b7b201540600f42b428a", - "offset": 12104, - "new_text": "给,替。", - "insert": "给,替。", - "insert_len": 4, - "paragraph_offset": 32, - "sentence_offset": 69, - "paragraph_num": 115 - }, - { - "key": "78760936332fb43028e5b7a3e15fd861", - "offset": 12108, - "new_text": "①陈涉少时,尝与人佣耕。", - "insert": "①陈涉少时,尝与人佣耕。", - "insert_len": 12, - "paragraph_offset": 32, - "sentence_offset": 73, - "paragraph_num": 115 - }, - { - "key": "6b5cd0f2b5d3e445cfe60019b2449e35", - "offset": 12122, - "new_text": "(《陈涉世家》)\u000b②与尔三矢,尔其无忘乃父之志!(《伶官传序》)3.比,和……", - "diffs": [ - { - "tag": "r", - "origin": "!", - "text": "!", - "start": 24, - "end": 25, - "id": 187319, - "idx": 516, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 33, - "end": 35, - "id": 187320, - "idx": 517, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《陈涉世家》) \u000b②与尔三矢,尔其无忘乃父之志!(《伶官传序》) \u000b3.比,和……", - "insert_len": 42, - "paragraph_offset": 32, - "sentence_offset": 85, - "paragraph_num": 115 - }, - { - "key": "3b88682131e33dcf3f1c6d03cd9bdf8a", - "offset": 12164, - "new_text": "比较。", - "insert": "比较。", - "insert_len": 3, - "paragraph_offset": 32, - "sentence_offset": 127, - "paragraph_num": 115 - }, - { - "key": "e418798d71d9ef802f470bc6d163ae3e", - "offset": 12167, - "new_text": "①吾孰与徐公美(《邹忌讽齐王纳谏》)\u000b②较秦之所得,与战胜而得者,其实百倍(《六国论》)(二)连词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 45, - "end": 47, - "id": 187321, - "idx": 519, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①吾孰与徐公美(《邹忌讽齐王纳谏》) \u000b②较秦之所得,与战胜而得者,其实百倍(《六国论》) \u000b(二)连词。", - "insert_len": 53, - "paragraph_offset": 32, - "sentence_offset": 130, - "paragraph_num": 115 - }, - { - "key": "b2845c5ffc1a7fde0807a5a1eaae9c00", - "offset": 12222, - "new_text": "1.连词。", - "insert": "1.连词。", - "insert_len": 5, - "paragraph_offset": 32, - "sentence_offset": 183, - "paragraph_num": 115 - }, - { - "key": "a165e54789a938408be717c0134d38aa", - "offset": 12229, - "new_text": "和,跟,同。", - "insert": "和,跟,同。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 188, - "paragraph_num": 115 - }, - { - "key": "66261577d49458c8451d1010a9be3241", - "offset": 12235, - "new_text": "①然谋臣与爪牙之士,不可不养而择也(《勾践灭吴》)\u000b②勾践载稻与脂于舟以行。", - "insert": "①然谋臣与爪牙之士,不可不养而择也(《勾践灭吴》) \u000b②勾践载稻与脂于舟以行。", - "insert_len": 39, - "paragraph_offset": 32, - "sentence_offset": 194, - "paragraph_num": 115 - }, - { - "key": "16c0fdd724183d009281eb9ee8f76ddd", - "offset": 12276, - "new_text": "(《勾践灭吴》)\u000b(三)动词。", - "insert": "(《勾践灭吴》) \u000b(三)动词。", - "insert_len": 16, - "paragraph_offset": 32, - "sentence_offset": 233, - "paragraph_num": 115 - }, - { - "key": "cd1c56430b2a38d1b6e756a7205774bc", - "offset": 12292, - "new_text": "1.给予,授予。", - "insert": "1.给予,授予。", - "insert_len": 8, - "paragraph_offset": 32, - "sentence_offset": 249, - "paragraph_num": 115 - }, - { - "key": "14a586885a100e3211320a7c11fe59f0", - "offset": 12302, - "new_text": "①生三人,公与之母;生二子,公与之饩。", - "insert": "①生三人,公与之母;生二子,公与之饩。", - "insert_len": 19, - "paragraph_offset": 32, - "sentence_offset": 257, - "paragraph_num": 115 - }, - { - "key": "27f2e608a818482187149132b5f81011", - "offset": 12323, - "new_text": "(《勾践灭吴》)\u000b②则与一生彘肩(《鸿门宴》)③与尔三矢,尔其无忘乃父之志。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 24, - "end": 26, - "id": 187322, - "idx": 523, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《勾践灭吴》) \u000b②则与一生彘肩(《鸿门宴》) \u000b③与尔三矢,尔其无忘乃父之志。", - "insert_len": 41, - "paragraph_offset": 32, - "sentence_offset": 276, - "paragraph_num": 115 - }, - { - "key": "d7c80840c59bb042963c599c81eead37", - "offset": 12364, - "new_text": "(《伶官传序》)\u000b2.结交、亲附。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 14, - "end": 15, - "id": 187323, - "idx": 525, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《伶官传序》) \u000b2.结交,亲附。", - "insert_len": 18, - "paragraph_offset": 32, - "sentence_offset": 317, - "paragraph_num": 115 - }, - { - "key": "c3f2c7f95509d6758db5b3dfdc85fa1a", - "offset": 12382, - "new_text": "①因人之力而敝之,不仁;失其所与,不知(《烛之武退秦师》)\u000b②合从缔交,相与为一(《过秦论》)③与嬴而不助五国也(《《六国论》》)\u000b3.对付。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 48, - "end": 50, - "id": 187324, - "idx": 527, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①因人之力而敝之,不仁;失其所与,不知(《烛之武退秦师》) \u000b②合从缔交,相与为一(《过秦论》) \u000b③与嬴而不助五国也(《《六国论》》) \u000b3.对付。", - "insert_len": 75, - "paragraph_offset": 32, - "sentence_offset": 335, - "paragraph_num": 115 - }, - { - "key": "718e4e5c6b08ab8525cf218163e90d7b", - "offset": 12459, - "new_text": "①庞煖易与耳。", - "insert": "①庞煖易与耳。", - "insert_len": 7, - "paragraph_offset": 32, - "sentence_offset": 410, - "paragraph_num": 115 - }, - { - "key": "55450fd42d382c26d743d33b34bbd0b8", - "offset": 12468, - "new_text": "4.参加,参与。", - "insert": "4.参加,参与。", - "insert_len": 8, - "paragraph_offset": 32, - "sentence_offset": 417, - "paragraph_num": 115 - }, - { - "key": "da46ffc6704bc57f57329aa34e1be250", - "offset": 12478, - "new_text": "①骞叔之子于师。", - "diffs": [ - { - "tag": "r", - "origin": "与", - "text": "于", - "start": 5, - "end": 6, - "id": 187325, - "idx": 529, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①骞叔之子与师。", - "insert_len": 8, - "paragraph_offset": 32, - "sentence_offset": 425, - "paragraph_num": 115 - }, - { - "key": "0b00188f4ff0de2b725ebc06efa7f6e0", - "offset": 12488, - "new_text": "(《骞叔哭师》)\u000b5.赞许,同意。", - "insert": "(《骞叔哭师》) \u000b5.赞许,同意。", - "insert_len": 18, - "paragraph_offset": 32, - "sentence_offset": 433, - "paragraph_num": 115 - }, - { - "key": "cc6f78badeb3b1e7426428b350419149", - "offset": 12506, - "new_text": "①吾与点也。", - "insert": "①吾与点也。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 451, - "paragraph_num": 115 - }, - { - "key": "37c403d0958be5cd28f965737b299fa0", - "offset": 12514, - "new_text": "②朝过夕改,君子与之。", - "insert": "②朝过夕改,君子与之。", - "insert_len": 11, - "paragraph_offset": 32, - "sentence_offset": 457, - "paragraph_num": 115 - }, - { - "key": "ccfc51d0c03a117726f63ef48a3330bb", - "offset": 12527, - "new_text": "(四)通假。", - "insert": "(四)通假。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 468, - "paragraph_num": 115 - }, - { - "key": "8d7ed6e3c71c97c6d4b0834af7acc029", - "offset": 12535, - "new_text": "通“欤”。", - "insert": "通“欤”。", - "insert_len": 5, - "paragraph_offset": 32, - "sentence_offset": 474, - "paragraph_num": 115 - }, - { - "key": "fd013d4ec528f58bde69c878ee4a9876", - "offset": 12540, - "new_text": "句末语气词,表示感叹或疑问。", - "insert": "句末语气词,表示感叹或疑问。", - "insert_len": 14, - "paragraph_offset": 32, - "sentence_offset": 479, - "paragraph_num": 115 - }, - { - "key": "feb872b4bb4c0d16d7509c1998afb6d7", - "offset": 12554, - "new_text": "①无乃尔是过与(《《季氏将伐颛臾》》)\u000b②虎兕出于柙,龟玉毁于椟中,是谁之过与(《《季氏将伐颛臾》》)③然则废衅钟与(《齐桓晋文之事》)\u000b【孰与】【与……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 52, - "end": 54, - "id": 187326, - "idx": 532, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①无乃尔是过与(《《季氏将伐颛臾》》) \u000b②虎兕出于柙,龟玉毁于椟中,是谁之过与(《《季氏将伐颛臾》》) \u000b③然则废衅钟与(《齐桓晋文之事》) \u000b【孰与】【与……", - "insert_len": 81, - "paragraph_offset": 32, - "sentence_offset": 493, - "paragraph_num": 115 - }, - { - "key": "883c2aa81d1552e74646ff9151b1e049", - "offset": 12637, - "new_text": "孰】表示比较与选择,译为:“跟……比较,哪一个……”", - "insert": "孰】表示比较与选择,译为:“跟……比较,哪一个……”", - "insert_len": 26, - "paragraph_offset": 32, - "sentence_offset": 574, - "paragraph_num": 115 - }, - { - "key": "6cdb86618703ab3d03195a3d40bfe7ce", - "offset": 12663, - "new_text": "①谓其妻曰:“我孰与城北徐公美(《邹忌讽齐王纳谏》)\u000b②沛公曰:“孰与君少长?”", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 6, - "end": 7, - "id": 187327, - "idx": 534, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①谓其妻曰:\"我孰与城北徐公美(《邹忌讽齐王纳谏》) \u000b②沛公曰:“孰与君少长?”", - "insert_len": 41, - "paragraph_offset": 32, - "sentence_offset": 600, - "paragraph_num": 115 - }, - { - "key": "c2a8fc43dd1e866cf2cb3201f086c341", - "offset": 12706, - "new_text": "(《鸿门宴》)\u000b③公之视廉将军孰与秦王(《廉颇蔺相如列传》)④吾与徐公孰美(《邹忌讽齐王纳谏》)\u000b【孰若】【与其……", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 31, - "end": 33, - "id": 187328, - "idx": 537, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《鸿门宴》) \u000b③公之视廉将军孰与秦王(《廉颇蔺相如列传》) \u000b④吾与徐公孰美(《邹忌讽齐王纳谏》) \u000b【孰若】【与其……", - "insert_len": 62, - "paragraph_offset": 32, - "sentence_offset": 641, - "paragraph_num": 115 - }, - { - "key": "ea5f61e92720a29e11ffdef2b90d5448", - "offset": 12768, - "new_text": "孰若】表示选择(舍前取后),译为:“哪如”“与其……哪如……”", - "insert": "孰若】表示选择(舍前取后),译为:“哪如”“与其……哪如……”", - "insert_len": 31, - "paragraph_offset": 32, - "sentence_offset": 703, - "paragraph_num": 115 - }, - { - "key": "ab2fee7ebf9cee718aa352dba21fb556", - "offset": 12799, - "new_text": "①与其坐而待亡,孰若起而拯之(《冯婉贞》)\u000b②与其杀是童,孰若卖之(《童区寄传》)\u000b\u000b16.【则】(一)连词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 51, - "end": 53, - "id": 187329, - "idx": 541, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①与其坐而待亡,孰若起而拯之(《冯婉贞》) \u000b②与其杀是童,孰若卖之(《童区寄传》) \u000b\u000b16.【则】 \u000b(一)连词。", - "insert_len": 59, - "paragraph_offset": 32, - "sentence_offset": 734, - "paragraph_num": 115 - }, - { - "key": "6d953d4f03afd887d22278d409185352", - "offset": 12860, - "new_text": "1.表示承接关系。", - "insert": "1.表示承接关系。", - "insert_len": 9, - "paragraph_offset": 32, - "sentence_offset": 793, - "paragraph_num": 115 - }, - { - "key": "59cebed6c76400470892a66a90932513", - "offset": 12871, - "new_text": "译为“就”“便”,或译为“原来是”“已经是”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 2, - "end": 3, - "id": 187330, - "idx": 542, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 4, - "end": 6, - "id": 187331, - "idx": 543, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 7, - "end": 8, - "id": 187332, - "idx": 544, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 12, - "end": 13, - "id": 187333, - "idx": 545, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 16, - "end": 18, - "id": 187334, - "idx": 546, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 21, - "end": 22, - "id": 187335, - "idx": 547, - "isAccept": 0, - "type": 2 - } - ], - "insert": "译为\"就\"\"便\",或译为\"原来是\"\"已经是\"。", - "insert_len": 23, - "paragraph_offset": 32, - "sentence_offset": 802, - "paragraph_num": 115 - }, - { - "key": "92929d7e3adf05845f04c3b294f7323f", - "offset": 12894, - "new_text": "例如:\u000b①项王曰:\"壮士!", - "insert": "例如: \u000b①项王曰:\"壮士!", - "insert_len": 14, - "paragraph_offset": 32, - "sentence_offset": 825, - "paragraph_num": 115 - }, - { - "key": "b4c68caf4c73904583c217ba80b3f5e3", - "offset": 12908, - "new_text": "赐之卮酒。", - "insert": "赐之卮酒。", - "insert_len": 5, - "paragraph_offset": 32, - "sentence_offset": 839, - "paragraph_num": 115 - }, - { - "key": "da3aa86915489b64f7d34fcb8dc11a1f", - "offset": 12913, - "new_text": "“则与斗卮酒。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 0, - "end": 1, - "id": 187336, - "idx": 549, - "isAccept": 0, - "type": 2 - } - ], - "insert": "\"则与斗卮酒。", - "insert_len": 7, - "paragraph_offset": 32, - "sentence_offset": 844, - "paragraph_num": 115 - }, - { - "key": "24f150e65f184af0aebea62eab041027", - "offset": 12920, - "new_text": "(《鸿门宴》)\u000b②故木受绳则直,金就砺则利。", - "insert": "(《鸿门宴》) \u000b②故木受绳则直,金就砺则利。", - "insert_len": 23, - "paragraph_offset": 32, - "sentence_offset": 851, - "paragraph_num": 115 - }, - { - "key": "a38524eee4128594639728005bdb1ca1", - "offset": 12943, - "new_text": "(《劝学》)\u000b③徐而察之,则山下皆石穴罅。", - "insert": "(《劝学》) \u000b③徐而察之,则山下皆石穴罅。", - "insert_len": 22, - "paragraph_offset": 32, - "sentence_offset": 874, - "paragraph_num": 115 - }, - { - "key": "d4af608f3d354a916aec7166defd5c5b", - "offset": 12965, - "new_text": "(《石钟山记》)\u000b④临视,则虫集冠上(《促织》)\u000b2.表示条件、假设关系。", - "insert": "(《石钟山记》) \u000b④临视,则虫集冠上(《促织》) \u000b2.表示条件、假设关系。", - "insert_len": 39, - "paragraph_offset": 32, - "sentence_offset": 896, - "paragraph_num": 115 - }, - { - "key": "6cb1d80917ddac0f3f9dca147cbb0bb8", - "offset": 13004, - "new_text": "译为“假使”“如果”“要是……就”“那么”“就”“便”。", - "insert": "译为“假使”“如果”“要是……就”“那么”“就”“便”。", - "insert_len": 28, - "paragraph_offset": 32, - "sentence_offset": 935, - "paragraph_num": 115 - }, - { - "key": "e501c39e50d33fc2cbdddfe5525b9ef4", - "offset": 13032, - "new_text": "①入则无法家拂士,出则无敌国外患者,国恒亡。", - "insert": "①入则无法家拂士,出则无敌国外患者,国恒亡。", - "insert_len": 22, - "paragraph_offset": 32, - "sentence_offset": 963, - "paragraph_num": 115 - }, - { - "key": "8587b36309c32718394a47e9aaf179e5", - "offset": 13056, - "new_text": "(《生于忧患,死于安乐》)\u000b②向吾不为斯役,则久已病矣。", - "insert": "(《生于忧患,死于安乐》) \u000b②向吾不为斯役,则久已病矣。", - "insert_len": 29, - "paragraph_offset": 32, - "sentence_offset": 985, - "paragraph_num": 115 - }, - { - "key": "aff67bf16792b19c7e2c4db345f14067", - "offset": 13085, - "new_text": "(《捕蛇者说》)\u000b3.表示并列关系。", - "insert": "(《捕蛇者说》) \u000b3.表示并列关系。", - "insert_len": 19, - "paragraph_offset": 32, - "sentence_offset": 1014, - "paragraph_num": 115 - }, - { - "key": "abd1ce19225528717d402e927a1fe332", - "offset": 13104, - "new_text": "这种用法都是两个或两个以上的“则”连用,每个“则”字都用在意思相对、结构相似的一个分句里,表示分句之间是并列关系。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 14, - "end": 15, - "id": 187337, - "idx": 556, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 16, - "end": 17, - "id": 187338, - "idx": 557, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 22, - "end": 23, - "id": 187339, - "idx": 558, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 24, - "end": 25, - "id": 187340, - "idx": 559, - "isAccept": 0, - "type": 2 - } - ], - "insert": "这种用法都是两个或两个以上的\"则\"连用,每个\"则\"字都用在意思相对、结构相似的一个分句里,表示分句之间是并列关系。", - "insert_len": 57, - "paragraph_offset": 32, - "sentence_offset": 1033, - "paragraph_num": 115 - }, - { - "key": "c52efa4edd1e97f41419a17185eeb5e3", - "offset": 13161, - "new_text": "可译为“就”,或不译。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 3, - "end": 4, - "id": 187341, - "idx": 560, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 5, - "end": 6, - "id": 187342, - "idx": 561, - "isAccept": 0, - "type": 2 - } - ], - "insert": "可译为\"就\",或不译。", - "insert_len": 11, - "paragraph_offset": 32, - "sentence_offset": 1090, - "paragraph_num": 115 - }, - { - "key": "7bc9cf1c173a34614245ee9199681d00", - "offset": 13172, - "new_text": "①位卑则足羞,官盛则近谀。", - "insert": "①位卑则足羞,官盛则近谀。", - "insert_len": 13, - "paragraph_offset": 32, - "sentence_offset": 1101, - "paragraph_num": 115 - }, - { - "key": "89214395a868e1bcbdc046a14d85bae8", - "offset": 13187, - "new_text": "(《师说》)\u000b②入则孝,出则弟。", - "insert": "(《师说》) \u000b②入则孝,出则弟。", - "insert_len": 17, - "paragraph_offset": 32, - "sentence_offset": 1114, - "paragraph_num": 115 - }, - { - "key": "fc87c7c03097d5d31199cf0a98225bf0", - "offset": 13204, - "new_text": "(《论语·学而》)\u000b③小则获邑,大则得城。", - "insert": "(《论语·学而》) \u000b③小则获邑,大则得城。", - "insert_len": 22, - "paragraph_offset": 32, - "sentence_offset": 1131, - "paragraph_num": 115 - }, - { - "key": "b521567a8af4dbbd08b55b7947be659f", - "offset": 13226, - "new_text": "④位卑则足羞,官盛则近谀。", - "insert": "④位卑则足羞,官盛则近谀。", - "insert_len": 13, - "paragraph_offset": 32, - "sentence_offset": 1153, - "paragraph_num": 115 - }, - { - "key": "11243fe7ecbcda12e848467f8624c058", - "offset": 13241, - "new_text": "4.表示转折、让步关系。", - "insert": "4.表示转折、让步关系。", - "insert_len": 12, - "paragraph_offset": 32, - "sentence_offset": 1166, - "paragraph_num": 115 - }, - { - "key": "590f294a81fd06e8898721b201d8ed5c", - "offset": 13255, - "new_text": "表示转折时,用在后一分句,译为“可是”“却”;表示让步时,用在前一分句,译为“虽然”“倒是”。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 15, - "end": 16, - "id": 187343, - "idx": 564, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 18, - "end": 20, - "id": 187344, - "idx": 565, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 21, - "end": 22, - "id": 187345, - "idx": 566, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 38, - "end": 39, - "id": 187346, - "idx": 567, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "”“", - "start": 41, - "end": 43, - "id": 187347, - "idx": 568, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "”", - "start": 45, - "end": 46, - "id": 187348, - "idx": 569, - "isAccept": 0, - "type": 2 - } - ], - "insert": "表示转折时,用在后一分句,译为\"可是\"\"却\";表示让步时,用在前一分句,译为\"虽然\"\"倒是\"。", - "insert_len": 47, - "paragraph_offset": 32, - "sentence_offset": 1178, - "paragraph_num": 115 - }, - { - "key": "22d86eef2472b7c546998d214e4bce1a", - "offset": 13302, - "new_text": "①于其身也,则耻师焉,惑矣。", - "insert": "①于其身也,则耻师焉,惑矣。", - "insert_len": 14, - "paragraph_offset": 32, - "sentence_offset": 1225, - "paragraph_num": 115 - }, - { - "key": "0a581dfb2bc43ca458a37f4317c6c502", - "offset": 13318, - "new_text": "(《师说》)\u000b②手裁举,则双超忽而跃(《促织》)③其室则迩,其人甚远。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 25, - "end": 27, - "id": 187349, - "idx": 571, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《师说》) \u000b②手裁举,则双超忽而跃(《促织》) \u000b③其室则迩,其人甚远。", - "insert_len": 38, - "paragraph_offset": 32, - "sentence_offset": 1239, - "paragraph_num": 115 - }, - { - "key": "ec40fe266aba79acae825603b0d7dd5f", - "offset": 13356, - "new_text": "(《诗经》)\u000b5.表示选择关系。", - "insert": "(《诗经》) \u000b5.表示选择关系。", - "insert_len": 17, - "paragraph_offset": 32, - "sentence_offset": 1277, - "paragraph_num": 115 - }, - { - "key": "beef9517834bd59660e5248c459efd99", - "offset": 13373, - "new_text": "常和“非”“不”呼应着用,译为“就是”“不是……就是”。", - "insert": "常和“非”“不”呼应着用,译为“就是”“不是……就是”。", - "insert_len": 28, - "paragraph_offset": 32, - "sentence_offset": 1294, - "paragraph_num": 115 - }, - { - "key": "e3ac0a07eb175f78d1618674d14f9230", - "offset": 13401, - "new_text": "①非死则徙尔(《捕蛇者说》)\u000b②非其身之所种则不食(《勾践灭吴》)(二)副词。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 34, - "end": 36, - "id": 187350, - "idx": 574, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①非死则徙尔(《捕蛇者说》) \u000b②非其身之所种则不食(《勾践灭吴》) \u000b(二)副词。", - "insert_len": 42, - "paragraph_offset": 32, - "sentence_offset": 1322, - "paragraph_num": 115 - }, - { - "key": "c2074adc770b552aef3f31b3141e059a", - "offset": 13445, - "new_text": "1.用在判断句中,起强调和确认作用,可译作“是“”就是“。", - "diffs": [ - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 21, - "end": 22, - "id": 187351, - "idx": 575, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"\"", - "text": "“”", - "start": 23, - "end": 25, - "id": 187352, - "idx": 576, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "\"", - "text": "“", - "start": 27, - "end": 28, - "id": 187353, - "idx": 577, - "isAccept": 0, - "type": 2 - } - ], - "insert": "1.用在判断句中,起强调和确认作用,可译作\"是\"\"就是\"。", - "insert_len": 29, - "paragraph_offset": 32, - "sentence_offset": 1364, - "paragraph_num": 115 - }, - { - "key": "e402473ff3ac460b9478c7a5d243e90b", - "offset": 13476, - "new_text": "例如:\u000b①此则岳阳楼之大观也。", - "insert": "例如: \u000b①此则岳阳楼之大观也。", - "insert_len": 16, - "paragraph_offset": 32, - "sentence_offset": 1393, - "paragraph_num": 115 - }, - { - "key": "f4292e64f041da438d97e7bffe9f06e6", - "offset": 13492, - "new_text": "(《岳阳楼记》)\u000b2.表对已然或发现的强调。", - "insert": "(《岳阳楼记》) \u000b2.表对已然或发现的强调。", - "insert_len": 23, - "paragraph_offset": 32, - "sentence_offset": 1409, - "paragraph_num": 115 - }, - { - "key": "5a9540ccb32f7729909b1174603f08d5", - "offset": 13515, - "new_text": "可译为“已经”“原来”“原来已经”。", - "insert": "可译为“已经”“原来”“原来已经”。", - "insert_len": 18, - "paragraph_offset": 32, - "sentence_offset": 1432, - "paragraph_num": 115 - }, - { - "key": "0d51bc2fb3c666419422820f9aa58e76", - "offset": 13533, - "new_text": "①及诸河,则在舟中矣。", - "insert": "①及诸河,则在舟中矣。", - "insert_len": 11, - "paragraph_offset": 32, - "sentence_offset": 1450, - "paragraph_num": 115 - }, - { - "key": "5f8ae3f8b62267fc13e561e2444a1010", - "offset": 13546, - "new_text": "(《殽之战》\u000b(三)名词。", - "insert": "(《殽之战》 \u000b(三)名词。", - "insert_len": 14, - "paragraph_offset": 32, - "sentence_offset": 1461, - "paragraph_num": 115 - }, - { - "key": "df7cc8c15f559a4f22c458acd1d65233", - "offset": 13560, - "new_text": "1.指分项或自成段落的文字的条数。", - "insert": "1.指分项或自成段落的文字的条数。", - "insert_len": 17, - "paragraph_offset": 32, - "sentence_offset": 1475, - "paragraph_num": 115 - }, - { - "key": "fbe49a65750c5a3a7082db5b6102b05b", - "offset": 13579, - "new_text": "①《论语》六则。", - "insert": "①《论语》六则。", - "insert_len": 8, - "paragraph_offset": 32, - "sentence_offset": 1492, - "paragraph_num": 115 - }, - { - "key": "a7a4bcc5b332dbaa8299935d587230ee", - "offset": 13589, - "new_text": "2。", - "insert": "2。", - "insert_len": 2, - "paragraph_offset": 32, - "sentence_offset": 1500, - "paragraph_num": 115 - }, - { - "key": "7ddd6681dfdea3e6723cadf9773dae54", - "offset": 13593, - "new_text": "准则,法则。", - "insert": "准则,法则。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 1502, - "paragraph_num": 115 - }, - { - "key": "9aaa722d02a2e5dfac35a33f44e5de9b", - "offset": 13599, - "new_text": "①以身作则。", - "insert": "①以身作则。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 1508, - "paragraph_num": 115 - }, - { - "key": "bf8b9385d26fbf1623135b6853efe7c1", - "offset": 13607, - "new_text": "(四)动词。", - "insert": "(四)动词。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 1514, - "paragraph_num": 115 - }, - { - "key": "37e9bc7b4bf5295ae8d72a51110103e5", - "offset": 13615, - "new_text": "效法。", - "insert": "效法。", - "insert_len": 3, - "paragraph_offset": 32, - "sentence_offset": 1520, - "paragraph_num": 115 - }, - { - "key": "52f60102f770a1e805ad6e247299ed2a", - "offset": 13618, - "new_text": "①遵后稷、公刘之业,则古公、公季之法。", - "insert": "①遵后稷、公刘之业,则古公、公季之法。", - "insert_len": 19, - "paragraph_offset": 32, - "sentence_offset": 1523, - "paragraph_num": 115 - }, - { - "key": "c30cce769bdb3f47d94ba79c3490b24f", - "offset": 13639, - "new_text": "(五)通假。", - "insert": "(五)通假。", - "insert_len": 6, - "paragraph_offset": 32, - "sentence_offset": 1542, - "paragraph_num": 115 - }, - { - "key": "c884e89e7b8fcd7eb5450cd9b836507c", - "offset": 13647, - "new_text": "同“辄”,总是、常常。", - "diffs": [ - { - "tag": "r", - "origin": ",", - "text": "、", - "start": 7, - "end": 8, - "id": 187354, - "idx": 581, - "isAccept": 0, - "type": 2 - } - ], - "insert": "同“辄”,总是,常常。", - "insert_len": 11, - "paragraph_offset": 32, - "sentence_offset": 1548, - "paragraph_num": 115 - }, - { - "key": "81b146bb4cc9d1a1bab407541b755f1e", - "offset": 13658, - "new_text": "①居则曰:“不吾知也!”", - "insert": "①居则曰:“不吾知也!”", - "insert_len": 12, - "paragraph_offset": 32, - "sentence_offset": 1559, - "paragraph_num": 115 - }, - { - "key": "7860307dc0795f8dedd099fa95cfd859", - "offset": 13672, - "new_text": "【则是】只当是。", - "insert": "【则是】只当是。", - "insert_len": 8, - "paragraph_offset": 32, - "sentence_offset": 1571, - "paragraph_num": 115 - }, - { - "key": "f286785ef58043d68072403605ae19f3", - "offset": 13683, - "new_text": "①与窦娥烧一陌儿,则是看你死的孩儿面上。", - "insert": "①与窦娥烧一陌儿,则是看你死的孩儿面上。", - "insert_len": 20, - "paragraph_offset": 32, - "sentence_offset": 1579, - "paragraph_num": 115 - }, - { - "key": "9a119d91a793d91978eb885f02befb95", - "offset": 13705, - "new_text": "(《窦娥冤》)\u000b【则则】赞叹的声音。", - "insert": "(《窦娥冤》) \u000b【则则】赞叹的声音。", - "insert_len": 19, - "paragraph_offset": 32, - "sentence_offset": 1599, - "paragraph_num": 115 - }, - { - "key": "01c7118d91a35e01c19427515ef81c13", - "offset": 13724, - "new_text": "①连呼则则。", - "insert": "①连呼则则。\n", - "insert_len": 7, - "paragraph_offset": 32, - "sentence_offset": 1618, - "paragraph_num": 115 - }, - { - "key": "8da62649fcbf79c3b1b251688bb8b9ac", - "offset": 13736, - "new_text": "17.【者】\u000b(一)助词。", - "insert": "17.【者】 \u000b(一)助词。", - "insert_len": 14, - "paragraph_offset": 33, - "sentence_offset": 0, - "paragraph_num": 116 - }, - { - "key": "c74a14080bd5390f4ff6456662f19613", - "offset": 13750, - "new_text": "1.指人、物、事、时、地等。", - "insert": "1.指人、物、事、时、地等。", - "insert_len": 14, - "paragraph_offset": 33, - "sentence_offset": 14, - "paragraph_num": 116 - }, - { - "key": "6bf22fb30a6162752b747963fd660c83", - "offset": 13766, - "new_text": "“……的”,“……的(人、东西、事情)”。", - "insert": "“……的”,“……的(人、东西、事情)”。", - "insert_len": 21, - "paragraph_offset": 33, - "sentence_offset": 28, - "paragraph_num": 116 - }, - { - "key": "c474176a8676102f7d466da06069f679", - "offset": 13787, - "new_text": "①有复言令长安君为质者,老妇必唾其面!", - "insert": "①有复言令长安君为质者,老妇必唾其面!", - "insert_len": 19, - "paragraph_offset": 33, - "sentence_offset": 49, - "paragraph_num": 116 - }, - { - "key": "8e30e7ba2b0894dc3a1139a6a6513a77", - "offset": 13808, - "new_text": "(《触龙说赵太后》)\u000b②秦自缪公以来二十余君,未尝有坚明约束者也(《廉颇蔺相如列传》)2.用在数词后面,译为“……个方面”“……样东西”“……件事情”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 44, - "end": 46, - "id": 187355, - "idx": 585, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《触龙说赵太后》) \u000b②秦自缪公以来二十余君,未尝有坚明约束者也(《廉颇蔺相如列传》) \u000b2.用在数词后面,译为“……个方面”“……样东西”“……件事情”。", - "insert_len": 79, - "paragraph_offset": 33, - "sentence_offset": 68, - "paragraph_num": 116 - }, - { - "key": "e45d77021883e6f14e353e786ff657a8", - "offset": 13887, - "new_text": "①此数者,用兵之患也。", - "insert": "①此数者,用兵之患也。", - "insert_len": 11, - "paragraph_offset": 33, - "sentence_offset": 147, - "paragraph_num": 116 - }, - { - "key": "4b7fcb0a86cdf07e1176871045b97cad", - "offset": 13900, - "new_text": "(《赤壁之战》)\u000b②或异于二者之为,何哉?", - "insert": "(《赤壁之战》) \u000b②或异于二者之为,何哉?", - "insert_len": 22, - "paragraph_offset": 33, - "sentence_offset": 158, - "paragraph_num": 116 - }, - { - "key": "71ee918ce1bd45394f825efcd0217ece", - "offset": 13922, - "new_text": "(《岳阳楼记》)\u000b3.用作“若”“似”“如”的宾语,译为“……的样子”。", - "insert": "(《岳阳楼记》) \u000b3.用作“若”“似”“如”的宾语,译为“……的样子”。", - "insert_len": 37, - "paragraph_offset": 33, - "sentence_offset": 180, - "paragraph_num": 116 - }, - { - "key": "0e255b8a8d01d7cf313bb6886283656a", - "offset": 13959, - "new_text": "①言之,貌若甚戚者(《捕蛇者说》)\u000b②然往来视之,觉无异能者(《黔之驴》)4.放在后置的定语后面,相当于“的”。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 38, - "end": 40, - "id": 187356, - "idx": 589, - "isAccept": 0, - "type": 2 - } - ], - "insert": "①言之,貌若甚戚者(《捕蛇者说》) \u000b②然往来视之,觉无异能者(《黔之驴》) \u000b4.放在后置的定语后面,相当于“的”。", - "insert_len": 59, - "paragraph_offset": 33, - "sentence_offset": 217, - "paragraph_num": 116 - }, - { - "key": "8158eb68988cb3f71d58583e46755c0b", - "offset": 14020, - "new_text": "①求人可使报秦者,未得。", - "insert": "①求人可使报秦者,未得。", - "insert_len": 12, - "paragraph_offset": 33, - "sentence_offset": 276, - "paragraph_num": 116 - }, - { - "key": "6e02136194f72d9b0455d47c29397975", - "offset": 14034, - "new_text": "(《廉颇蔺相如列传》)\u000b②顷之,烟炎张天,人马烧溺死者甚众(《赤壁之战》)5.放在主语后面,引出判断,不必译出。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 38, - "end": 40, - "id": 187357, - "idx": 591, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《廉颇蔺相如列传》) \u000b②顷之,烟炎张天,人马烧溺死者甚众(《赤壁之战》) \u000b5.放在主语后面,引出判断,不必译出。", - "insert_len": 59, - "paragraph_offset": 33, - "sentence_offset": 288, - "paragraph_num": 116 - }, - { - "key": "8da713db61279343e48222b8a7108a97", - "offset": 14093, - "new_text": "①廉颇者,赵之良将也。", - "insert": "①廉颇者,赵之良将也。", - "insert_len": 11, - "paragraph_offset": 33, - "sentence_offset": 347, - "paragraph_num": 116 - }, - { - "key": "f289b17a2f1a78ef8dc5906f5de4df81", - "offset": 14106, - "new_text": "(《廉颇蔺相如列传》)\u000b②师者,所以传道受业解惑也。", - "insert": "(《廉颇蔺相如列传》) \u000b②师者,所以传道受业解惑也。", - "insert_len": 27, - "paragraph_offset": 33, - "sentence_offset": 358, - "paragraph_num": 116 - }, - { - "key": "6be95202cfc9c59ff6a9d53fb735562f", - "offset": 14133, - "new_text": "(《师说》)\u000b6.用在“今”“昔”等时间词后面,不必译出。", - "insert": "(《师说》) \u000b6.用在“今”“昔”等时间词后面,不必译出。", - "insert_len": 30, - "paragraph_offset": 33, - "sentence_offset": 385, - "paragraph_num": 116 - }, - { - "key": "b68521a721da5e39e1ec199c243a1f33", - "offset": 14163, - "new_text": "①近者奉辞伐罪。", - "insert": "①近者奉辞伐罪。", - "insert_len": 8, - "paragraph_offset": 33, - "sentence_offset": 415, - "paragraph_num": 116 - }, - { - "key": "861c1e4a0055bc563e13fb8d817be550", - "offset": 14173, - "new_text": "(《赤壁之战》)\u000b②古者以天下为主,君为客。", - "insert": "(《赤壁之战》) \u000b②古者以天下为主,君为客。", - "insert_len": 23, - "paragraph_offset": 33, - "sentence_offset": 423, - "paragraph_num": 116 - }, - { - "key": "a4fd763efc804848d173e8c5f4b0c47d", - "offset": 14196, - "new_text": "③远者数世,近者及身。", - "insert": "③远者数世,近者及身。", - "insert_len": 11, - "paragraph_offset": 33, - "sentence_offset": 446, - "paragraph_num": 116 - }, - { - "key": "0ec3bbaf6b23ab13613c75a01ccadc11", - "offset": 14209, - "new_text": "7.放在分句的句末,引出原因。", - "insert": "7.放在分句的句末,引出原因。", - "insert_len": 15, - "paragraph_offset": 33, - "sentence_offset": 457, - "paragraph_num": 116 - }, - { - "key": "cd65870179317979e59b5241eb7c0e79", - "offset": 14226, - "new_text": "①然操遂能克绍,以弱为强者,非惟天时,抑亦人谋也。", - "insert": "①然操遂能克绍,以弱为强者,非惟天时,抑亦人谋也。", - "insert_len": 25, - "paragraph_offset": 33, - "sentence_offset": 472, - "paragraph_num": 116 - }, - { - "key": "37d5d77ac5cfe63bf1807a1bff9183cf", - "offset": 14253, - "new_text": "(《赤壁之战》)\u000b②臣所以去亲戚而事君者,徒慕君之高义也。", - "insert": "(《赤壁之战》) \u000b②臣所以去亲戚而事君者,徒慕君之高义也。", - "insert_len": 30, - "paragraph_offset": 33, - "sentence_offset": 497, - "paragraph_num": 116 - }, - { - "key": "54c21b068584c58da1bda05b665c6aff", - "offset": 14283, - "new_text": "(《廉颇蔺相如列传》)\u000b③吾妻之美我者,私我也。", - "insert": "(《廉颇蔺相如列传》) \u000b③吾妻之美我者,私我也。", - "insert_len": 25, - "paragraph_offset": 33, - "sentence_offset": 527, - "paragraph_num": 116 - }, - { - "key": "71b42c4828ab76c69c242c774805bf4a", - "offset": 14308, - "new_text": "(《邹忌讽齐王纳谏》)\u000b(二)语气词。", - "insert": "(《邹忌讽齐王纳谏》) \u000b(二)语气词。", - "insert_len": 20, - "paragraph_offset": 33, - "sentence_offset": 552, - "paragraph_num": 116 - }, - { - "key": "29340745b4eee75ec80c69379d6a11d2", - "offset": 14328, - "new_text": "1.放在疑问句的句末,表示疑问语气等。", - "insert": "1.放在疑问句的句末,表示疑问语气等。", - "insert_len": 19, - "paragraph_offset": 33, - "sentence_offset": 572, - "paragraph_num": 116 - }, - { - "key": "41f713bc0096dc3a459f164a96af8d30", - "offset": 14349, - "new_text": "①何者?", - "insert": "①何者?", - "insert_len": 4, - "paragraph_offset": 33, - "sentence_offset": 591, - "paragraph_num": 116 - }, - { - "key": "2cda9018ec16e117540b77ae95a53a69", - "offset": 14355, - "new_text": "严大国之威以修敬也(《廉颇蔺相如列传》)\u000b②谁为大王为此计者?", - "insert": "严大国之威以修敬也(《廉颇蔺相如列传》) \u000b②谁为大王为此计者?", - "insert_len": 32, - "paragraph_offset": 33, - "sentence_offset": 595, - "paragraph_num": 116 - }, - { - "key": "092e3d909e434853744005b117f2abce", - "offset": 14387, - "new_text": "(《鸿门宴》)", - "insert": "(《鸿门宴》)\n", - "insert_len": 8, - "paragraph_offset": 33, - "sentence_offset": 627, - "paragraph_num": 116 - }, - { - "key": "078d4df6de28e152268cb89aba1eb1e1", - "offset": 14398, - "new_text": "18.【之】\u000b(一)代词。", - "insert": "18.【之】 \u000b(一)代词。", - "insert_len": 14, - "paragraph_offset": 34, - "sentence_offset": 0, - "paragraph_num": 130 - }, - { - "key": "97a1d2cff3db34247487a458462c395d", - "offset": 14412, - "new_text": "1.第三人称代词,他、她、它(们)。", - "insert": "1.第三人称代词,他、她、它(们)。", - "insert_len": 18, - "paragraph_offset": 34, - "sentence_offset": 14, - "paragraph_num": 130 - }, - { - "key": "06099e634d9efe9e697c610b578c4bb2", - "offset": 14432, - "new_text": "有时灵活运用于第一人称或第二人称。", - "insert": "有时灵活运用于第一人称或第二人称。", - "insert_len": 17, - "paragraph_offset": 34, - "sentence_offset": 32, - "paragraph_num": 130 - }, - { - "key": "edc1118f777ed89fe8ab2ec62baa5288", - "offset": 14449, - "new_text": "①太后盛气而揖之。", - "insert": "①太后盛气而揖之。", - "insert_len": 9, - "paragraph_offset": 34, - "sentence_offset": 49, - "paragraph_num": 130 - }, - { - "key": "a55c5fa922b394b610912f8dc9ac0f28", - "offset": 14460, - "new_text": "(《触龙说赵太后》)\u000b②不知将军宽之至此也。", - "insert": "(《触龙说赵太后》) \u000b②不知将军宽之至此也。", - "insert_len": 23, - "paragraph_offset": 34, - "sentence_offset": 58, - "paragraph_num": 130 - }, - { - "key": "ca434573b6049738d3ff81148bc58261", - "offset": 14483, - "new_text": "(之:我)(《廉颇蔺相如列传》)\u000b③臣乃市井鼓刀屠者,而公子数存之。", - "insert": "(之:我)(《廉颇蔺相如列传》) \u000b③臣乃市井鼓刀屠者,而公子数存之。", - "insert_len": 35, - "paragraph_offset": 34, - "sentence_offset": 81, - "paragraph_num": 130 - }, - { - "key": "a81a88893e79fac3decbf813dc865348", - "offset": 14518, - "new_text": "(之:我)(《信陵君窃符救赵》)\u000b④且公子纵轻胜,弃之降秦,独不怜公子姊邪?", - "insert": "(之:我)(《信陵君窃符救赵》) \u000b④且公子纵轻胜,弃之降秦,独不怜公子姊邪?", - "insert_len": 39, - "paragraph_offset": 34, - "sentence_offset": 116, - "paragraph_num": 130 - }, - { - "key": "3e227a39a3b81ab50064ca415f95e5a0", - "offset": 14557, - "new_text": "(之:我)(《信陵君窃符救赵》)\u000b⑤然语之,又恐汝日日为吾担忧。", - "insert": "(之:我)(《信陵君窃符救赵》) \u000b⑤然语之,又恐汝日日为吾担忧。", - "insert_len": 33, - "paragraph_offset": 34, - "sentence_offset": 155, - "paragraph_num": 130 - }, - { - "key": "a0f8a502668de730f43d56264dd872a3", - "offset": 14590, - "new_text": "(之:你)(《与妻书》)\u000b2.指示代词,这,此。", - "insert": "(之:你)(《与妻书》) \u000b2.指示代词,这,此。", - "insert_len": 25, - "paragraph_offset": 34, - "sentence_offset": 188, - "paragraph_num": 130 - }, - { - "key": "749d4d60728a7eb1c34c8c32bb34a342", - "offset": 14615, - "new_text": "①夫子欲之,吾二臣者皆不欲也。", - "insert": "①夫子欲之,吾二臣者皆不欲也。", - "insert_len": 15, - "paragraph_offset": 34, - "sentence_offset": 213, - "paragraph_num": 130 - }, - { - "key": "43349abeafdee4db48bdba0e3d7fceec", - "offset": 14632, - "new_text": "(《季氏将伐颛臾》)\u000b②君子疾夫舍曰欲之而必为之辞(前一个“之”,这样。后一个“之”,它。)", - "insert": "(《季氏将伐颛臾》) \u000b②君子疾夫舍曰欲之而必为之辞(前一个“之”,这样。后一个“之”,它。)", - "insert_len": 47, - "paragraph_offset": 34, - "sentence_offset": 228, - "paragraph_num": 130 - }, - { - "key": "043ac5f49ae6ec52a8bcea31db422acc", - "offset": 14679, - "new_text": "(《季氏将伐颛臾》)\u000b③之二虫又何知。", - "insert": "(《季氏将伐颛臾》) \u000b③之二虫又何知。", - "insert_len": 20, - "paragraph_offset": 34, - "sentence_offset": 275, - "paragraph_num": 130 - }, - { - "key": "5291efbe5635eb2cbca2573264746497", - "offset": 14699, - "new_text": "(《逍遥游》)\u000b④均之二策,宁许之以负秦曲。", - "insert": "(《逍遥游》) \u000b④均之二策,宁许之以负秦曲。", - "insert_len": 23, - "paragraph_offset": 34, - "sentence_offset": 295, - "paragraph_num": 130 - }, - { - "key": "4ee36409478e627f87fdc39ee8907db0", - "offset": 14722, - "new_text": "(《廉颇蔺相如列传》)\u000b(二)助词。", - "insert": "(《廉颇蔺相如列传》) \u000b(二)助词。", - "insert_len": 19, - "paragraph_offset": 34, - "sentence_offset": 318, - "paragraph_num": 130 - }, - { - "key": "ce6f94998834aeb061b37dfb881b8aed", - "offset": 14741, - "new_text": "1.相当于现代汉语的“的”,放在定语和中心语之间。", - "insert": "1.相当于现代汉语的“的”,放在定语和中心语之间。", - "insert_len": 25, - "paragraph_offset": 34, - "sentence_offset": 337, - "paragraph_num": 130 - }, - { - "key": "c381322b3076e9cc8b69b9018c4179d3", - "offset": 14768, - "new_text": "①虎兕出于柙,龟玉毁于椟中,是谁之过与?", - "insert": "①虎兕出于柙,龟玉毁于椟中,是谁之过与?", - "insert_len": 20, - "paragraph_offset": 34, - "sentence_offset": 362, - "paragraph_num": 130 - }, - { - "key": "adf47fee4ad3ef8c32e5ff934d2ec1c5", - "offset": 14790, - "new_text": "(《季氏将伐颛臾》)\u000b②子而思报父母之仇,臣而思报君之仇。", - "insert": "(《季氏将伐颛臾》) \u000b②子而思报父母之仇,臣而思报君之仇。", - "insert_len": 30, - "paragraph_offset": 34, - "sentence_offset": 382, - "paragraph_num": 130 - }, - { - "key": "aafa33d6a1595c0dcded54dc1ad822cf", - "offset": 14820, - "new_text": "(《勾践灭吴》)\u000b2.放在主语和谓语之间,取消句子的独立性。", - "insert": "(《勾践灭吴》) \u000b2.放在主语和谓语之间,取消句子的独立性。", - "insert_len": 31, - "paragraph_offset": 34, - "sentence_offset": 412, - "paragraph_num": 130 - }, - { - "key": "3db1f9fef5fce122d70a58ad6369ba2e", - "offset": 14851, - "new_text": "①臣之壮也,犹不如人;今老矣,无能为也已。", - "insert": "①臣之壮也,犹不如人;今老矣,无能为也已。", - "insert_len": 21, - "paragraph_offset": 34, - "sentence_offset": 443, - "paragraph_num": 130 - }, - { - "key": "5a6ffc2c4b23c94305eaadc71f4c3a41", - "offset": 14874, - "new_text": "(《烛之武退秦师》)\u000b②客之美我者,欲有求于我也。", - "insert": "(《烛之武退秦师》) \u000b②客之美我者,欲有求于我也。", - "insert_len": 26, - "paragraph_offset": 34, - "sentence_offset": 464, - "paragraph_num": 130 - }, - { - "key": "bfcbedb2535d13c70b64ab8718cda6bc", - "offset": 14900, - "new_text": "(《邹忌讽齐王纳谏》)\u000b③不患其众之不足也,而患其志行之少耻也。", - "insert": "(《邹忌讽齐王纳谏》) \u000b③不患其众之不足也,而患其志行之少耻也。", - "insert_len": 33, - "paragraph_offset": 34, - "sentence_offset": 490, - "paragraph_num": 130 - }, - { - "key": "8e30e8cd1cbe931945b393606ba64821", - "offset": 14933, - "new_text": "(《勾践灭吴》)\u000b④王无异于百姓之以王为爱也。", - "insert": "(《勾践灭吴》) \u000b④王无异于百姓之以王为爱也。", - "insert_len": 24, - "paragraph_offset": 34, - "sentence_offset": 523, - "paragraph_num": 130 - }, - { - "key": "38f155ab8f133b245f3fde43b4c8eb9c", - "offset": 14957, - "new_text": "3.放在倒置的动(介)宾短语之间,作为宾语提前的标志。", - "insert": "3.放在倒置的动(介)宾短语之间,作为宾语提前的标志。", - "insert_len": 27, - "paragraph_offset": 34, - "sentence_offset": 547, - "paragraph_num": 130 - }, - { - "key": "79bc708fab53e2a4de5c34438c38bf23", - "offset": 14986, - "new_text": "①句读之不知,惑之不解,或师焉,或不焉。", - "insert": "①句读之不知,惑之不解,或师焉,或不焉。", - "insert_len": 20, - "paragraph_offset": 34, - "sentence_offset": 574, - "paragraph_num": 130 - }, - { - "key": "5af96859867f22ae7f5bfa1d49867fa0", - "offset": 15008, - "new_text": "(《师说》)\u000b②譬若以肉投馁虎,何功之有哉?", - "insert": "(《师说》) \u000b②譬若以肉投馁虎,何功之有哉?", - "insert_len": 23, - "paragraph_offset": 34, - "sentence_offset": 594, - "paragraph_num": 130 - }, - { - "key": "8c7e9c2e2ade85d50f9fb43aa466365f", - "offset": 15031, - "new_text": "(《信陵君窃符救赵》)\u000b③诗云:“他人有心,予忖度之。”", - "insert": "(《信陵君窃符救赵》) \u000b③诗云:“他人有心,予忖度之。”", - "insert_len": 29, - "paragraph_offset": 34, - "sentence_offset": 617, - "paragraph_num": 130 - }, - { - "key": "35ea34290f14983312108adec23d20eb", - "offset": 15060, - "new_text": "——夫子之谓也。", - "insert": "——夫子之谓也。", - "insert_len": 8, - "paragraph_offset": 34, - "sentence_offset": 646, - "paragraph_num": 130 - }, - { - "key": "7f965e4e0e716e9f87acde37854764ba", - "offset": 15068, - "new_text": "(《齐桓晋文之事》)\u000b4.放在倒置的定语与中心语之间,作为定语后置的标志。", - "insert": "(《齐桓晋文之事》) \u000b4.放在倒置的定语与中心语之间,作为定语后置的标志。", - "insert_len": 38, - "paragraph_offset": 34, - "sentence_offset": 654, - "paragraph_num": 130 - }, - { - "key": "835800c170960f34eb9df25e1aa68ede", - "offset": 15106, - "new_text": "①蚓无爪牙之利,筋骨之强。", - "insert": "①蚓无爪牙之利,筋骨之强。", - "insert_len": 13, - "paragraph_offset": 34, - "sentence_offset": 692, - "paragraph_num": 130 - }, - { - "key": "d774be7bf8fe7e66ced0169daead8f5c", - "offset": 15121, - "new_text": "(《劝学》)\u000b②人又谁能以身之察察,受物之汶汶者乎(《屈原列传》)5.用在时间词或动词(多为不及物动词)后面,凑足音节,没有实在意义。", - "diffs": [ - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 34, - "end": 36, - "id": 187358, - "idx": 618, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《劝学》) \u000b②人又谁能以身之察察,受物之汶汶者乎(《屈原列传》) \u000b5.用在时间词或动词(多为不及物动词)后面,凑足音节,没有实在意义。", - "insert_len": 70, - "paragraph_offset": 34, - "sentence_offset": 705, - "paragraph_num": 130 - }, - { - "key": "e9b608c3d4b345ff7e2ed49cb3d1c625", - "offset": 15191, - "new_text": "①填然鼓之,兵刃既接,弃甲曳兵而走。", - "insert": "①填然鼓之,兵刃既接,弃甲曳兵而走。", - "insert_len": 18, - "paragraph_offset": 34, - "sentence_offset": 775, - "paragraph_num": 130 - }, - { - "key": "6c459325f56812eabf0aaf4ee18ff5da", - "offset": 15211, - "new_text": "(《寡人之于国也》)\u000b②余扃牖而居,久之,能以足音辨人。", - "insert": "(《寡人之于国也》) \u000b②余扃牖而居,久之,能以足音辨人。", - "insert_len": 29, - "paragraph_offset": 34, - "sentence_offset": 793, - "paragraph_num": 130 - }, - { - "key": "afae7e8fef27cacdfcda04cb9f4edb4c", - "offset": 15240, - "new_text": "(《项脊轩志》)\u000b③顷之,烟炎张天。", - "insert": "(《项脊轩志》) \u000b③顷之,烟炎张天。", - "insert_len": 19, - "paragraph_offset": 34, - "sentence_offset": 822, - "paragraph_num": 130 - }, - { - "key": "d3298288bff3177edf686e84e0fa5a93", - "offset": 15259, - "new_text": "(《赤壁之战》)\u000b(三)动词,到……", - "insert": "(《赤壁之战》) \u000b(三)动词,到……", - "insert_len": 19, - "paragraph_offset": 34, - "sentence_offset": 841, - "paragraph_num": 130 - }, - { - "key": "d4d49a4795c18b8ebfd8ac469dae5751", - "offset": 15278, - "new_text": "去。", - "insert": "去。", - "insert_len": 2, - "paragraph_offset": 34, - "sentence_offset": 860, - "paragraph_num": 130 - }, - { - "key": "bb6c405403e34e1e56a38d4ccb617b0f", - "offset": 15280, - "new_text": "①胡为乎遑遑欲何之?", - "insert": "①胡为乎遑遑欲何之?", - "insert_len": 10, - "paragraph_offset": 34, - "sentence_offset": 862, - "paragraph_num": 130 - }, - { - "key": "148412ab5222f501fe8ca6d4fe685f6d", - "offset": 15292, - "new_text": "(《归去来兮辞》)\u000b②奚以之九万里而南为?", - "insert": "(《归去来兮辞》) \u000b②奚以之九万里而南为?", - "insert_len": 22, - "paragraph_offset": 34, - "sentence_offset": 872, - "paragraph_num": 130 - }, - { - "key": "cada7b737d3655450e1223e0fee19767", - "offset": 15314, - "new_text": "(《逍遥游》)\u000b③有牵牛而过堂下者,王见之,曰:“牛何之?”(《齐桓晋文之事》)④卒之东郭墦间,之祭者,乞其余;不足,又顾而之他。", - "diffs": [ - { - "tag": "r", - "origin": "?", - "text": "?", - "start": 29, - "end": 30, - "id": 187359, - "idx": 624, - "isAccept": 0, - "type": 2 - }, - { - "tag": "d", - "origin": " \u000b", - "text": "", - "start": 41, - "end": 43, - "id": 187360, - "idx": 625, - "isAccept": 0, - "type": 2 - } - ], - "insert": "(《逍遥游》) \u000b③有牵牛而过堂下者,王见之,曰:“牛何之?”(《齐桓晋文之事》) \u000b④卒之东郭墦间,之祭者,乞其余;不足,又顾而之他。", - "insert_len": 68, - "paragraph_offset": 34, - "sentence_offset": 894, - "paragraph_num": 130 - }, - { - "key": "80d983255171ae29f9080693adea4dd8", - "offset": 15382, - "new_text": "(《齐人有一妻一妾章》)", - "insert": "(《齐人有一妻一妾章》)\n", - "insert_len": 13, - "paragraph_offset": 34, - "sentence_offset": 962, - "paragraph_num": 130 - } - ], - "id": 2374, - "isBlackWord": false, - "isWhiteWord": false, - "name": "文言文指导资料.doc", - "status": 3 -} \ No newline at end of file diff --git a/src/service/fake/document.ts b/src/service/fake/document.ts deleted file mode 100644 index 0a14eca..0000000 --- a/src/service/fake/document.ts +++ /dev/null @@ -1,231 +0,0 @@ -export const FakeDocument = { - "abnormalCount": { - "blackWord": 0, - "characterError": 4, - "wordError": 0, - "numberError": 0, - "unitsError": 0, - "punctuationError": 0, - "grammarError": 0, - "knowledgeableError": 0, - "tendentiousError": 0, - "inconsistentError": 0, - "formatError": 0, - "total": 0, - "untreated": 1, - "sensitive": 0 - }, - "correctedSet": [ - { - "key": "4c0b624cddaba8c939a188f984131415", - "offset": 0, - "new_text": "新花社北京5月12日电文", - "insert": "新华社北京5月12日的电文\n", - "diffs": [ - { - "tag": "r", - "origin": "新花社", - "text": "新华社", - "start": 0, - "end": 3, - "id": 1, - "idx": 1, - "isAccept": 0, - "type": 2 - }, - { - "tag": "i", - "origin": "", - "text": "的", - "start": 10, - "end": 10, - "id": 2, - "idx": 2, - "isAccept": 0, - "type": 2 - } - ], - "insert_len": 13 - }, - { - "key": "dd8ab8b907177039e7720a88a2449e85", - "offset": 13, - "new_text": "我们要注意一些影响.", - "diffs": [ - { - "tag": "r", - "origin": "门", - "text": "们", - "start": 1, - "end": 2, - "id": 10, - "idx": 10, - "isAccept": 0, - "type": 2 - } - ], - "insert": "我门要注意一些影响.\n", - "insert_len": 11 - }, - { - "key": "", - "offset": 24, - "insert": "\n", - "insert_len": 1 - } - ], - "id": 1816, - "isBlackWord": false, - "isWhiteWord": false, - "name": "测试基本操作.docx", - "status": 3 -} - -let id = 1000; -export const FakeDocument1862 = ()=>{ - return { - "abnormalCount": { - "blackWord": 3, - "characterError": 1, - "wordError": 0, - "numberError": 0, - "unitsError": 0, - "punctuationError": 0, - "grammarError": 0, - "knowledgeableError": 0, - "tendentiousError": 0, - "inconsistentError": 0, - "formatError": 0, - "total": 4, - "untreated": 4, - "sensitive": 0 - }, - "correctedSet": [ - { - "key": "1de515eb4e4a6efa126045f624ac9640", - "offset": 0, - "new_text": "按揭购房的人都知道,贷款方式主要分为等额本金和等额本息两种。", - "insert": "按揭购房的人都知道,贷款方式主要分为等额本金和等额本息两种。\n", - "insert_len": 31, - "paragraph_offset": 0, - "sentence_offset": 0, - "paragraph_num": 1 - }, - { - "key": "2490aaf36637a82a3957fd6f59f14826", - "offset": 31, - "new_text": "这两者之间的差异,直接关系到贷款人每个月的还款金额以及整个贷款期间的利息支付。", - "insert": "这两者之间的差异,直接关系到贷款人每个月的还款金额以及整个贷款期间的利息支付。\n", - "insert_len": 40, - "paragraph_offset": 1, - "sentence_offset": 0, - "paragraph_num": 2 - }, - { - "key": "95033f395d89983519503dc8191200d1", - "offset": 71, - "new_text": "近期,浙江男子刘某的遭遇,就为我们提供了一个生动的案例。", - "insert": "近期,浙江男子刘某的遭遇,就为我们提供了一个生动的案例。", - "insert_len": 28, - "paragraph_offset": 2, - "sentence_offset": 0, - "paragraph_num": 3 - }, - { - "key": "c8488c81829e9e46cade2f17dcecdbf2", - "offset": 99, - "new_text": "刘某买房按揭后,按时还款,9年后,却因为看到房贷余额而在银行大厅崩溃大哭。", - "insert": "刘某买房按揭后,按时还款,9年后,却因为看到房贷余额而在银行大厅崩溃大哭。\n", - "insert_len": 38, - "paragraph_offset": 2, - "sentence_offset": 28, - "paragraph_num": 3 - }, - { - "key": "3c82748a3baa729a7126f66035117c07", - "offset": 137, - "new_text": "这种情况我们罕少遇到。", - "diffs": [ - { - "tag": "r", - "origin": "罕少", - "text": "**", - "start": 6, - "end": 8, - "id": 143453, - "idx": 1, - "isAccept": 0, - "type": 1 - } - ], - "insert": "这种情况我们罕少遇到。", - "insert_len": 11, - "paragraph_offset": 3, - "sentence_offset": 0, - "paragraph_num": 27 - }, - { - "key": "1a184ba7b055f6bc4ce2b25de7e227b6", - "offset": 148, - "new_text": "当然也有可能是一昧追求节省费用!", - "diffs": [ - { - "tag": "r", - "origin": "时", - "text": "是", - "start": 6, - "end": 7, - "id": 143454, - "idx": 2, - "isAccept": 0, - "type": 2 - }, - { - "tag": "r", - "origin": "一昧追求", - "text": "一味追求", - "start": 7, - "end": 11, - "id": 143455, - "idx": 3, - "isAccept": 0, - "type": 1 - } - ], - "insert": "当然也有可能时一昧追求节省费用!\n", - "insert_len": 17, - "paragraph_offset": 3, - "sentence_offset": 11, - "paragraph_num": 27 - }, - { - "key": "17088a97f3ed2e40e50481941da1173c", - "offset": 165, - "new_text": "呵呵呵123123不错吧!", - "diffs": [ - { - "tag": "r", - "origin": "123123", - "text": "******", - "start": 3, - "end": 9, - "id": 143456, - "idx": 5, - "isAccept": 0, - "type": 1 - } - ], - "insert": "呵呵呵123123 不错吧!\n", - "insert_len": 15, - "paragraph_offset": 4, - "sentence_offset": 0, - "paragraph_num": 28 - } - ], - "id": 2183, - "isBlackWord": false, - "isWhiteWord": false, - "name": "女友从不知道什么是边界感.docx", - "status": 3 - } -} \ No newline at end of file diff --git a/src/service/request.ts b/src/service/request.ts deleted file mode 100644 index ca274da..0000000 --- a/src/service/request.ts +++ /dev/null @@ -1,193 +0,0 @@ -import axios, {AxiosHeaders} from 'axios'; -import {stringify} from 'qs' -import {BizError} from "./types.ts"; -import {useUserinfoStore} from "./userinfoStore"; -import Storage from './../utils/storage' -import {TUploadParam} from "./types/base.ts"; -import {ApplicationInfo} from "@/core/config.ts"; -import { getDeviceId } from '@/core/device-id.ts'; - -export interface APIResponse { - /** - * 错误码,0:成功,其他失败 - */ - code: number; - data?: T; - /** - * 非0情况下,提示信息 - */ - msg: string; -} - -const JSON_FORMAT: string = 'application/json'; -export type RequestMethod = 'get' | 'post' | 'put' | 'delete' -const REQUEST_TIMEOUT = 300000; // 超时时长5min - -const Axios = axios.create({ - baseURL: APP_CONFIG.API_PREFIX, - headers: { - 'Content-Type': JSON_FORMAT - } -}) - -// 请求前拦截 -Axios.interceptors.request.use(config => { - const token = Storage.get(APP_CONFIG.LOGIN_TOKEN_KEY) - // const {token} = useUserinfoStore() - if (token) { - config.headers['Authorization'] = `Bearer ${token}`; - } - if (config.data && config.data instanceof FormData) { - config.headers['Content-Type'] = 'multipart/form-data'; - } - config.headers['x-version'] = ApplicationInfo.version; - config.headers['deviceid'] = ApplicationInfo.deviceId || getDeviceId(); - config.headers['source'] = `plugin-${ApplicationInfo.platform}`; - - return config -}, err => { - return Promise.reject(err) -}) -let isRefreshing = false; -type EmptyFunction = () => void; -const refreshSubscribers: EmptyFunction[] = []; -// -// // 返回后拦截 -Axios.interceptors.response.use(res => { - const data = res.data as APIResponse; - if (data.code === 403) { - // 需要刷新token - if (!isRefreshing) { - //没有刷新 开始吧 - isRefreshing = true; - return new Promise((resolve,reject) => { - axios.get('/api/v1/refresh',{ - headers: { - 'x-version':ApplicationInfo.version, - 'deviceid':ApplicationInfo.deviceId || getDeviceId(), - 'source':`plugin-${ApplicationInfo.platform}` - } - }).then((ret) => { - //没有刷新 开始吧 - isRefreshing = false; - if(ret.status == 200){ - if(ret.data.code == 0){ - refreshSubscribers.forEach((subscriber) => subscriber()); - refreshSubscribers.length = 0 - isRefreshing = false; - resolve(Axios.request(res.config)) - }else{ - reject(new BizError(ret.data?.msg || '服务异常,请稍后再试',ret.data.code)); - } - }else{ - reject(new Error(ret.data?.msg || '服务异常,请稍后再试')); - } - }) - }); - } else { - return new Promise((resolve) => { - refreshSubscribers.push(() => { - resolve(Axios.request(res.config)) - }) - }) - } - } - return res -}, err => { - err.message = '服务异常,请稍后再试'; - if (err.message === 'Network Error') { - err.message = '网络连接异常!'; - } else if (err.code === 'ECONNABORTED') { - err.message = '请求超时,请稍后再试'; - } - - return Promise.reject(err) -}) - -export function request(url: string, method: RequestMethod, data:object|null|string|number = null, getOriginResult = false, showlogin = true) { - return new Promise((resolve, reject) => { - let timeout = REQUEST_TIMEOUT; - let headers: AxiosHeaders | undefined = undefined; - if(data && data['_request_timeout']){ - timeout = data['_request_timeout']; - delete data['_request_timeout']; - } - if(data && data['_header_config']){ - headers = data['_header_config']; - delete data['_header_config']; - } - Axios.request>({ - url, - method, - timeout, - data, - headers - }).then(res => { - if (res.status != 200) { - reject(new BizError("服务异常,请稍后再试", res.status)) - return; - } - // const contentType = ((typeof (res.headers.getContentType) == "function") - // ? (res.headers.getContentType()) : JSON_FORMAT)?.toString(); - // if (!contentType?.toLowerCase().includes(JSON_FORMAT)) { - // resolve(res.data as any) - // return; - // } - // const - const {code, msg, data} = res.data - if (code == 0) { - if (getOriginResult) { - resolve(res.data as T) - return; - } - resolve(data as unknown as T) - } else { - if (code == 401 && showlogin) { - // 自动刷新 token - const state = useUserinfoStore.getState() - state.update() - return; - } - reject(new BizError(msg, code, data)) - } - }).catch(e => { - reject(new BizError(e.message, e.code || 500)) - }) - }) -} - -export function uploadFile(url: string, params: TUploadParam, returnOrigin = false) { - const formData = new FormData(); - formData.append(params.fileName || 'file', params.file); - if (params.data) { - for (const key in params.data) { - formData.append(key, params.data[key]) - } - } - return request(url, 'post', formData, returnOrigin) -} - -export function post(url: string, data: object = {}, returnOrigin = false) { - return request(url, 'post', data, returnOrigin) -} - -export function get(url: string, data: object|null = null, returnOrigin = false) { - if (data) { - const params = {...data}; - if( params['_header_config']) delete params['_header_config']; - url += (url.indexOf('?') === -1 ? '?' : '&') + stringify(params) - } - return request(url, 'get', data, returnOrigin) -} - -export function put(url: string, data: object = {}) { - return request(url, 'put', data) -} - -export function getFileBlob(url: string) { - return new Promise((resolve, reject) => { - fetch(url).then(res => res.blob()).then(res => { - resolve(res) - }).catch(reject); - }); -} diff --git a/src/service/types.ts b/src/service/types.ts deleted file mode 100644 index 73f9786..0000000 --- a/src/service/types.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {TProofreadItem} from "./types/document.ts"; - -export type PanelStateEnum = 'normal' | 'process' | 'perfect' | 'blank' -// editor replace attribute -export type ReplaceItemAttribute = { - processed?: 'check' | 'cancel'; - origin: string; - text?: string; - /** - * 地名纠错 成语纠错 - */ - type: 'words' | 'address' | 'delete' | string; - id?: number; -} -export type EditorOperationItem = { - insert: string; - processed?: 'check' | 'cancel'; - attributes?: { - [key: string]: any; - replace?: TProofreadItem; - }; -} -export type EditorContentData = { - ops: EditorOperationItem[] -} - -// api data models -export type CorrectContent = { - end: number; - start: number; - origin: string; - /** - * d 删除 i 删除 r替换 e等于 - */ - tag: 'd'|'r'|'i' | string; - text: string; -} -export type CorrectItem = { - corrected_content: CorrectContent[], - key: string; - new_text: string; - offset: number; - text: string; - type: "words" | string; -} -export type CheckResult = { - /** - * 有修改的句子及对应修改内容的列表 - */ - corrected: CorrectItem[]; - job_id: string; - /** - * 原文 - */ - text: string; - remain_char: number; -} - -export class BizError extends Error { - /** - * 错误码 - */ - code = 1; - data:any; - - constructor(message: string, code = 1,data?:any) { - super(message); - this.code = code; - this.data = data; - } -} - -// 登录结果 -export type LoginResult = { - message: string; - token: string; - phone: string -} diff --git a/src/service/types/base.ts b/src/service/types/base.ts deleted file mode 100644 index 7f79828..0000000 --- a/src/service/types/base.ts +++ /dev/null @@ -1,61 +0,0 @@ -export type TPageParam = { - currentPage?: number; - pageSize?: number; -} - -export type TPaginationResult = { - /** - * 当前页 - */ - current: number; - /** - * 一页显示大小 - */ - pageSize: number; - /** - * 总数 - */ - total: number; - /** - * 排序 - */ - sort?: string; -} - -export type int = number; -export type bool = boolean; - -export type TUploadParam = { - file: File; - fileName?: string; - data?: Record; -} - -export type BaseTime = { - /** - * 创建时间戳 - */ - ctime: int; - /** - * 修改时间 - */ - utime: int; - /** - * 删除时间 - */ - dtime: int; -} - -/** - * 数据状态 - */ -export enum StatusEnum { - /** - * 启用 - */ - ENABLE = 1, - /** - * 禁用 - */ - DISABLED = 2 -} diff --git a/src/service/types/document.ts b/src/service/types/document.ts deleted file mode 100644 index 9a13496..0000000 --- a/src/service/types/document.ts +++ /dev/null @@ -1,359 +0,0 @@ -// 整数 -import {TPageParam, TPaginationResult, int, bool} from "./base.ts"; -import {IProofreadTypeData} from "../../types/proofread.ts"; - -type ProofreadAction = 'replace' | 'delete' | 'insert'; - -// 0未知 1草稿 2AI分析中 3校对中 4校对完成 -export enum DocumentStatus { - unknown, - draft, - analyzing, - proofreading, - finish, - analyzing2 = 10, -} - -export type TProofreadData = { - remainingTime: number; - status: DocumentStatus; -} - -//校验内容 -export type TCorrectedContent = { - id: number; - /** - * 'd' | 'i' | 'r' - */ - tag: 'd' | 'i' | 'r' | string; - //原内容 - origin: string; - //替换内容 - text: string; - //开始位置 - start: int; - //结束位置 - end: int; - // 校对记录id - idx: number; - // 分组id - groupId?: number | string; - isAccept: ProofreadStateEnum; - // 类别 - type: int; - typeData?: IProofreadTypeData; - action?: string; - // 颜色 - color?: string; - ignoreProcess?: boolean; - fid?: number; -} - -export type TDocumentCorrectItem = { - diffs?: TCorrectedContent[]; - key: string; - insert: string; - insert_len: number; - new_text?: string; - offset: number; - paragraph_offset: number; - paragraph_num: number; - sentence_offset: number; -} - -export type TCorrectData = { - abnormalCount: TProofreadCountResult; - list: TCorrectedContent[]; -} - - -// 文档信息 -export type TDocumentContentDetail = { - correctedSet: TDocumentCorrectItem[]; - abnormalCount: TProofreadCountResult; - id?: number; - status?: DocumentStatus; - name?: string; - isBlackWord?: boolean; - isWhiteWord?: boolean; -} - -// 校对 -export type TProofreadResultParam = { - /** - * 当前文档ID - */ - fid: int; -} & TPageParam - -/** - * 0未知 1个人黑名单 2字错 3词错 4数字错 5标点错 6计量单位错 7语法错误 8知识性差错 9倾向性差错 10不一致 11格式错 12 敏感词 13 核验 - */ -export enum ProofreadTypeEnum { - unknown, - blackWord, - /** - * 字错 - */ - characterError, - /** - * 词错 - */ - wordError, - /** - * 数字错 - */ - numberError, - /** - * 计量单位错 - */ - unitsError, - /** - * 标点错 - */ - punctuationError, - /** - * 语法错 - */ - grammarError, - /** - * 知识性差错 - */ - knowledgeableError, - /** - * 倾向性差错 - */ - tendentiousError, - /** - * 不⼀致 - */ - inconsistentError, - /** - * 格式错 - */ - formatError, - /** - * 敏感词 - */ - sensitive, - /** - * 核验 - */ - verify, - - /** - * 黑名单-替换 - */ - blackWordReplace=14, - /** - * 黑名单-拦截 - */ - blackWordBlock = 15, - -} - -export type TProofreadCountResult = { - /** - * 个人黑名单 - */ - blackWord?: int; - /** - * 字错 - */ - characterError?: int; - /** - * 词错 - */ - wordError?: int; - /** - * 数字错 - */ - numberError?: int; - /** - * 计量单位错 - */ - unitsError?: int; - /** - * 标点错 - */ - punctuationError?: int; - /** - * 语法错 - */ - grammarError?: int; - /** - * 知识性差错 - */ - knowledgeableError?: int; - /** - * 倾向性差错 - */ - tendentiousError?: int; - /** - * 不⼀致 - */ - inconsistentError?: int; - /** - * 格式错 - */ - formatError?: int; - /** - * 敏感词 - */ - sensitive?: int; - - verify?: int; - /** - * 总数量 - */ - total: int; - /** - * 未处理数量 - */ - untreated?: int; -} - - -export type AcceptParam = { - ids?: number[]; - type?: ProofreadTypeEnum; - //是否采纳 - action: ProofreadStateEnum - //1 全部 - isAll?: 1 | number; -} - -// 0默认 1未动 2采纳 3忽略 -export enum ProofreadStateEnum { - Default, - // 目前没有实际意义 - NotAdopted, - Accept, - Ignore, - Review, -} - -export type TProofreadItem = { - /** - * id - */ - id: int; - /** - * 用户ID - */ - uid: string; - /** - * 文稿ID - */ - fid: int; - //md5加密字段(原始内容加密字段) - key: string; - /** - * 原始内容 - */ - text: string; - /** - * 校验后的文本 - */ - newText: string; - correctedContent: TCorrectedContent; - /** - * 检验时间 - */ - checkTime: int; - offset: int; - /** - * 是否采纳 0默认 1忽略 2采纳 3未采纳 - */ - isAccept: ProofreadStateEnum; - /** - * 异常类型 0未知 1个人黑名单 2字错 3词错 4数字错 5标点错 6计量单位错 7语法错误 8知识性差错 9倾向性差错 10不一致 11格式错 - */ - type: ProofreadTypeEnum; - /** - * 创建时间 - */ - ctime: int; - action?: ProofreadAction -} - -export type TProofreadResult = { - countResp: TProofreadCountResult; - list: TProofreadItem[]; - pagination: TPaginationResult; -} - - -export type TCheckResult = { - corrected_content: TCorrectedContent[] | null; - insert: string; - insert_len: number; - new_text: string; - text: string; - text_len: number; - offset: number; -} -export type TProofreadResultV1 = { - check_result: TCheckResult[]; -} -//采纳校对结果参数 -export type TAcceptParam = { - /** - * 当id大于0,更改的是单条校对结果 - */ - id?: number; - /** - * 当id参数不传时,更改的是 当前文档校对结果未处理的结果 - */ - fid: number; - /** - * 当type 不传时,默认为全部类型 - * 异常类型 0未知 1个人黑名单 2字错 3词错 4数字错 5标点错 6计量单位错 7语法错误 8知识性差错 9倾向性差错 10不一致 11格式错 - */ - type?: number; - /** - * 是否采纳 0默认 1未动 2采纳 3未采纳 - */ - isAccept?: 0 | 1 | 2 | 3; - /** - * true 采纳/忽略相同结果 - * false 单个采纳/忽略结果 - */ - acceptSame?: boolean; -} - -interface OSSDataType { - dir: string; - expire: string; - host: string; - accessId: string; - policy: string; - signature: string; -} - -export type TOSSPolicy = { - //Oss access id - access_id: string; - //上传 host - host: string; - //Oss 上传 policy - policy: string; - //Oss 上传的鉴权签名 - signature: string; - //该签名和policy有效期截至时间 - expire: int; - //上传的 路径,在最后的 / 后面接上文件名称 文件名称 处理成 K8efE3imYn.docx,文件名长度16 - dir: string; - //允许上传的文件最大大小,单位字节 - max_size: int; - //允许上传的文件最大大小,单位字节 - allow: string; -} -export type TProcessDocumentParam = { - //上传文档到oss时用的 dir+filename 拼接的字符串 - key: string; - //原始的文档名称 不带文件名称后缀 - filename: string; - isBlackWord?: bool; - isWhiteWord?: bool; -} diff --git a/src/service/types/lexicon.ts b/src/service/types/lexicon.ts deleted file mode 100644 index de7410b..0000000 --- a/src/service/types/lexicon.ts +++ /dev/null @@ -1,138 +0,0 @@ -// 整数 -import {TPageParam, TPaginationResult, int, bool, BaseTime, StatusEnum} from "./base.ts"; - -export type TListParam = { - word?: string; - /** - * 开始日期(时间戳) - */ - startTime?: int; - /** - * 结束日期(时间戳) - */ - endTime?: int; -} & TPageParam - -export enum BlackCreateActionType { - Delete = 1, - Replace = 2, -} - -export const LexiconActionTypeList: { - [key in BlackCreateActionType]: string -} = { - 1: '删除', - 2: '替换', -} - -export type TBlackLexicon = { - /** - * 拦截词 - */ - word: string; - /** - * 领域类型 第一期没有类型 (默认值为0) - */ - type?: number; - /** - * 操作类型 1删除 2替换 - */ - actionType: BlackCreateActionType; - /** - * 替换词 - */ - replaceWord: string; -} -export type TBlackLexiconItem = { - /** - * id - */ - id: int; - /** - * 用户ID - */ - uid: string; - /** - * 黑名单状态 1启用 2禁用 - */ - wordStatus: StatusEnum; -} & TBlackLexicon & BaseTime; - -/** - * 黑名单导入结果 - */ -export type TImportBlackResult = { - /** - * 总拦截词 - */ - totalWords: string[]; - /** - * 有效拦截词 - */ - words: string[]; - /** - * 重复拦截词 - */ - repeatWords: string[]; - /** - * 错误格式拦截词 - */ - formatErrorWords: string[]; -} - -/** - * - */ -export type TWhiteLexicon = { - /** - * 放行词 - */ - word: string; - /** - * 领域类型 第一期没有类型 (默认值为0) - */ - type?: int; -} -export type TWhitelistItem = { - id: int; - uid: string; - actionType?: BlackCreateActionType; - /** - * 替换词 - */ - replaceWord?: string; - /** - * 白名单状态 - */ - wordStatus: int; -} & TWhiteLexicon & BaseTime; - -export type TCreateBatch = { - /** - * 拦截词 (数组) - */ - words: string[]; - /** - * 操作类型 1删除 2替换 (数组) - */ - actionTypes: BlackCreateActionType[]; - /** - * 替换词 (数组) - */ - replaceWords: string[]; -} - -export type TBatchCreateError = { - /** - * 消息提示 - */ - msg:string; - /** - * 数组索引值 - */ - index:int; - /** - * 1为放行词 - */ - type:int; -} diff --git a/src/service/types/notice.ts b/src/service/types/notice.ts deleted file mode 100644 index 90e9c15..0000000 --- a/src/service/types/notice.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {BaseTime, bool, int} from "./base.ts"; - -/** - * 公告类型 1:链接公告 2:普通公告 3:弹窗公告 - */ -export enum NoticeTypeEnum { - Link = 1, - Normal, - Popup -} - -/** - * 状态 1:上架中 2:已下架 - */ -export enum NoticeStatusEnum { - Online = 1, - Offline -} - -export interface INotice extends BaseTime { - // id - id: int - // 公告文案 - title: string - // - type: NoticeTypeEnum - // 跳转链接 - url: string - // 弹窗文案 - describe: string - // 是否为强弹框 0:否 1:是 - coerce_show: bool - // - status: NoticeStatusEnum - // - sort: int -} diff --git a/src/service/types/settings.ts b/src/service/types/settings.ts deleted file mode 100644 index d535201..0000000 --- a/src/service/types/settings.ts +++ /dev/null @@ -1,31 +0,0 @@ -export type Settings = { - - // 出版社 1未设置 2设置 - industry_publish: string|number; - word_black: string|number; - word_white: string|number; - fallen_officers: string|number; - leader_quotes: string|number; - leader_info: string|number; - [key:string]:string|number; -} -export interface UpgradeInfo { - id: number; - app_name: string; - client_type: number; - publish_type: number; - version: string; - download_url: string; - // 升级类型 1强制升级 2强制提示 3弱提示 - upgrade_type: number; - publish_time: number; - message: string; - compatible_version_id: number; - // 是否显示弹框 1:显示2:不显示 - is_show_pop: number; -} -export interface AppUpgradeInfo { - upgradeInfo?: UpgradeInfo; - upgradeAvailable?: boolean; - currentVersion?: string; -} \ No newline at end of file diff --git a/src/service/types/user.ts b/src/service/types/user.ts deleted file mode 100644 index cf0a0b8..0000000 --- a/src/service/types/user.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {int} from "./base.ts"; - -export type TUserInfo = { - /** - * 用户ID - */ - uid: int; - /** - * 用户手机号 - */ - phone: string; - /** - * 用户昵称 - */ - nickname: string; - career?: number; - company?: string; - /** - * 状态 - */ - status: int; - /** - * 用户创建时间戳 - */ - ctime: int; - /** - * 用户头像 - */ - avatar: string; - is_bind_wechat?: boolean; - wechat_nickname?: string; -} diff --git a/src/service/use-proofread.ts b/src/service/use-proofread.ts deleted file mode 100644 index 82beb7c..0000000 --- a/src/service/use-proofread.ts +++ /dev/null @@ -1,201 +0,0 @@ -import mqtt from "mqtt"; -import {useEffect, useState} from "react"; -import {getDeviceId} from "@/core/device-id.ts"; -import {proofread, save} from "@/service/api/document.ts"; -import {getSettings} from "@/service/api/settings.ts"; -import {Settings} from "@/service/types/settings.ts"; -import {QoS} from "mqtt-packet"; - -type ProofreadContent = { - insert: string; - insert_len: number; - paragraph_num: number; - ext: string; -} -type MQTT_CONNECTION_OPTIONS = { - connectUrl?: string; - clientId?: string; - username?: string; - password?: string; -} -type SubscribeOption = { - topic: string; - clientId: string; - path: string; - qos?: QoS; -} - -export const proofreadCacheData: { - count: number; - settings?: Settings - client?:mqtt.MqttClient | null -} = { - count: 0, - -} - -const PROOFREAD_CONFIG = { - URL: 'ws://192.168.0.231:8083/mqtt', // 'ws://43.136.175.109:8083/mqtt' 192.168.0.231 - username: undefined, - password: undefined, -} - -export function useProofread(opts?: MQTT_CONNECTION_OPTIONS) { - const [isConnected, setIsConnected] = useState(false) - //const [_client, setClient] = useState() - const [currentMessage, setData] = useState<{ topic: string, message: string }>() - const [subscribeTopics, setSubscribeTopics] = useState<{ - [key: string]: (message: any) => void - }>({}) - - const createClient = (_opts:SubscribeOption)=>{ - if(proofreadCacheData.client && proofreadCacheData.client.connected){ - proofreadCacheData.client.end(); - } - const options = { - clean: true, // true: 清除会话, false: 保留会话 - connectTimeout: 4000, // 超时时间 - keepalive: 60, - // 手动连接 - manualConnect: true, - // 认证信息 - clientId: _opts.clientId || opts?.clientId || getDeviceId(), - qos:1, - ...PROOFREAD_CONFIG, - } - const client= proofreadCacheData.client = mqtt.connect(_opts.path || opts?.connectUrl || PROOFREAD_CONFIG.URL, options) - client.on('connect', () => { - console.log('连接成功',_opts) - // client.subscribe('StreamProcessing001', (err) => { - // if (err) { - // console.log('订阅失败:', err) - // } - // }) - setIsConnected(true) - }) - client.on('reconnect', () => { - console.log('正在重连:') - }) - - client.on('error', (error) => { - console.log('连接失败:', error) - setIsConnected(false) - }) - client.on('close', () => { - console.log('连接已关闭') - setIsConnected(false) - }) - - - client.on('message', (topic, ret) => { - const message = ret.toString(); - setData({ - topic, - message - }) - const result = JSON.parse(message) - // console.log('收到消息:', topic, result) - // if (SubscribedTopics.has(topic)) { - // SubscribedTopics.get(topic)?.forEach((callback: VoidCallback) => callback(message)) - // } - subscribeTopics[topic]?.(result); - }) - console.log('init mqtt client ==> ', proofreadCacheData.count++, client) - return proofreadCacheData.client; - } - useEffect(() => { - // if(proofreadCacheData.client && proofreadCacheData.client.connected){ - // proofreadCacheData.client.end() - // } - // - // 绑定当前组件的连接 - // setClient(client) - // 但组件销毁时,断开连接 - return () => { - if (proofreadCacheData.client && proofreadCacheData.client.connected) { - proofreadCacheData.client.end() - proofreadCacheData.client = null - } - } - }, []) - const send = (topic: string, message: string) => { - proofreadCacheData.client?.publish(topic, message) - } - - /** - * 订阅指定的主题 - * - * 该函数尝试使客户端订阅一个MQTT主题如果客户端尚未连接,则尝试连接 - * 一旦连接成功(或已经处于连接状态),客户端将订阅指定的主题 - * - * @param topic 要订阅的主题字符串 - * @param callback 订阅成功后,客户端将调用此回调函数,并将接收到的消息作为参数传递 - */ - function subscribe(opts:SubscribeOption, callback?: (message: T) => void, subscribeCallback?: (err: Error | null) => void) { - // const opts = typeof topic == 'string' ? {topic} : topic; - console.log('subscribe use',opts) - const client = createClient(opts); - if (!client) return; - client.connect() - client.subscribe(opts.topic, { - qos: opts.qos || 1 - } ,(err, granted, packet) => { - console.log('subscribe callback', err, granted, packet) - subscribeCallback?.(err) - if (!err) { - if (callback) { - subscribeTopics[opts.topic] = callback; - setSubscribeTopics(() => subscribeTopics) - // const callbackArray = SubscribedTopics.has(topic) ? (SubscribedTopics.get(topic) || []) : []; - // callbackArray.push(callback) - // SubscribedTopics.set(topic, callbackArray) - } - } - }) - } - - return { - isConnected, - currentMessage, - client:proofreadCacheData.client, - connect: () => proofreadCacheData.client?.connect(), - endSubscribe: () => { - proofreadCacheData.client?.end(); - proofreadCacheData.client = null; - }, - send, - subscribe - } -} - -async function currentProofreadSetting() { - // 如果没有校对设置数据 则获取并缓存 - if (!proofreadCacheData.settings) { - // 获取当前校对设置 - const settings = await getSettings(); - // fixed server bug at 240416 (cannot unmarshal string into Go struct field ProofreadReq.industry_publish of type int64) - // 如果是数字类型,则转换为数字类型 - Object.keys(settings).forEach(key => { - if (/^\d+$/.test(String(settings[key]))) { - settings[key] = Number(settings[key]) - } - }) - proofreadCacheData.settings = settings; - } - - return proofreadCacheData.settings; -} - -/** - * 保存文档并进行校对 - * @param documentId - * @param content - */ -export async function saveAndProofread(documentId: number, content: ProofreadContent[]) { - // 保存文档 - await save(documentId, content); - // 获取当前校对设置 - const settings = await currentProofreadSetting() - // 进行校对 - await proofread(documentId, 1, settings) -} \ No newline at end of file diff --git a/src/service/userinfoStore.ts b/src/service/userinfoStore.ts deleted file mode 100644 index b986d58..0000000 --- a/src/service/userinfoStore.ts +++ /dev/null @@ -1,89 +0,0 @@ -import {create} from "zustand"; -import {user} from "./api/index.ts"; - -type VoidFunction = () => void; -type AfterLoginSuccessTarget = string | null | VoidFunction - -export const useUserinfoStore = create<{ - /** - * 用户信息 - */ - userinfo?: Account; - /** - * 用户登录凭证 - */ - token?: string; - loginTarget?: AfterLoginSuccessTarget; - loginModalVisible?: boolean; - /** - * 登录 - * @param phone 手机号 - * @param code 验证码 - */ - login: (data:{phone?: string, code?: string}) => Promise; - confirmLogin: (data:{phone?: string, code?: string,confirm_login_key: string}) => Promise; - /** - * 注销用户登录信息 - */ - logout: () => Promise; - /** - * 初始化用户数据,当已经登录则返回true - */ - init: () => Promise; - initialized: boolean; - update: (userinfo?: Account) => void -}>((set) => { - return { - userinfo: undefined, - loginModalVisible: false, - initialized: false, - update: (userinfo) => { - set({ - userinfo - }) - }, - init: () => { - return new Promise((resolve) => { - user.info().then(userinfo => { - set({userinfo}) - resolve(userinfo); - }).catch(e => { - resolve(undefined) - console.log('init error', e) - }).finally(() => { - set({initialized: true}) - }) - }); - }, - logout: () => { - return new Promise((resolve, reject) => { - user.logout().then(() => { - set({ - userinfo: undefined - }) - resolve() - }).catch((e)=>{ - console.log('logout error', e) - reject(e) - }) - }); - }, - login: (data) => { - return new Promise((resolve, reject) => { - user.login(data).then(userinfo => { - set({userinfo}) - resolve(userinfo) - }).catch(reject) - }) - }, - - confirmLogin: (data:{phone?: string, code?: string,confirm_login_key: string}) => { - return new Promise((resolve, reject) => { - user.confirmLogin(data).then(userinfo => { - set({userinfo}) - resolve(userinfo) - }).catch(reject) - }) - }, - } -}) diff --git a/src/types/account.ts b/src/types/account.ts deleted file mode 100644 index eacef3d..0000000 --- a/src/types/account.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {TPageParam} from "./base"; - -export interface Area { - city_code: number | string; - district_code: number | string; - province_code: number | string; -} - -export enum UserRole { - ROOT, - ADMIN, - EDITOR -} - -export interface AccountSearchParams extends TPageParam{ - phone?: string; -} - -export enum AccountStatus { - /** - * 正常 - */ - NORMAL = 1, - /** - * 禁用 - */ - LOCKED = 2 -} diff --git a/src/types/auth.ts b/src/types/auth.ts deleted file mode 100644 index 2d6d7d0..0000000 --- a/src/types/auth.ts +++ /dev/null @@ -1,74 +0,0 @@ -import {ReactElement} from 'react'; -import {UserRole} from "./account.ts"; - -export {UserRole}; -// ==============================|| AUTH TYPES ||============================== // - -export type GuardProps = { - children: ReactElement | null; -}; - - -export type UserProfile = { - /** - * 用户ID - */ - uid: number; - /** - * 用户手机号 - */ - phone: string; - /** - * 用户昵称 - */ - nickname: string; - /** - * 状态 - */ - status: number; - /** - * 用户创建时间戳 - */ - ctime: number; - /** - * 用户头像 - */ - avatar: string; - /** - * 用户角色 - */ - role?: UserRole; -}; - -export interface AuthProps { - isLoggedIn: boolean; - isInitialized?: boolean; - user?: UserProfile | null; - token?: string | null; -} - -export interface AuthActionProps { - type: string; - payload?: AuthProps; -} - -export interface InitialLoginContextProps { - isLoggedIn: boolean; - isInitialized?: boolean; - user?: UserProfile | null | undefined; -} - -export interface JWTDataProps { - userId: string; -} - -export type JWTContextType = { - isLoggedIn: boolean; - isInitialized?: boolean; - user?: UserProfile | null | undefined; - logout: () => Promise; - login: (email: string, password: string,type:'code'|'password') => Promise; - register: (email: string, password: string, firstName: string, lastName: string) => Promise; - resetPassword: (email: string) => Promise; - updateProfile: VoidFunction; -}; diff --git a/src/types/base.ts b/src/types/base.ts deleted file mode 100644 index 1fd6147..0000000 --- a/src/types/base.ts +++ /dev/null @@ -1,61 +0,0 @@ -export type TPageParam = { - currentPage?: number; - pageSize?: number; -}; - -export type TPaginationResult = { - /** - * 当前页 - */ - current: number; - /** - * 一页显示大小 - */ - pageSize: number; - /** - * 总数 - */ - total: number; - /** - * 排序 - */ - sort?: string; -}; - -export type int = number; -export type bool = boolean; - -export type TUploadParam = { - file: File; - fileName?: string; - data?: Record; -}; - -export type BaseTime = { - /** - * 创建时间戳 - */ - ctime: int; - /** - * 修改时间 - */ - utime: int; - /** - * 删除时间 - */ - dtime: int; -}; - -/** - * 数据状态 - */ -export enum StatusEnum { - /** - * 启用 - */ - ENABLE = 1, - /** - * 禁用 - */ - DISABLED = 2 -} diff --git a/src/types/detection.d.ts b/src/types/detection.d.ts deleted file mode 100644 index f000629..0000000 --- a/src/types/detection.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -declare namespace Detection { - type DetectionInfo = { - id: number; - type: number; - summary?: string; - location?: string; - result_content: string; - } - - type CheckResult = { - isChecking: boolean; - checkingKey: string; - checkingSummary: string; - checkingLocation: string; - } -} \ No newline at end of file diff --git a/src/types/document.ts b/src/types/document.ts deleted file mode 100644 index 82e7dcc..0000000 --- a/src/types/document.ts +++ /dev/null @@ -1,79 +0,0 @@ -export enum DocumentProofreadStatus { - NOT_START, - IN_PROGRESS, - FINISHED -} - -export interface IAbnormalCount { - blackWord: number; - characterError: number; - wordError: number; - numberError: number; - unitsError: number; - punctuationError: number; - grammarError: number; - knowledgeableError: number; - tendentiousError: number; - inconsistentError: number; - formatError: number; - total: number; - untreated: number; - sensitive: number; -} - -export interface IDocumentProofread { - tag: string; - old: string; - new: string; - start: number; - end: number; - id: number; - idx: number; - index?: number; - suggest: number; - mid: number; - type: number; -} - -export interface IQuotation { - category: string; - content: string; - document_name: string; - hypelink: string; - id: string; -} - -export interface ILeader { - correct_name: string; - positions: string[]; - sort_error?: any; -} - -export interface IPosition { - leaders: string[]; - position: string; -} - -export interface IDocumentCorrect { - key: string; - offset: number; - new_text?: string; - ranges?: IDocumentProofread[]; - original: string; - original_len: number; -} - -export interface IDocumentDetail { - id: number; - isBlackWord: boolean; - isOrigin: number; - isWhiteWord: boolean; - name: string; - status: number; - abnormalCount?: IAbnormalCount; - correctedSet: IDocumentCorrect[]; - leaders: ILeader[]; - quotations: IQuotation[]; - positions: IPosition[]; -} - diff --git a/src/types/proofread-state.ts b/src/types/proofread-state.ts deleted file mode 100644 index 87703c4..0000000 --- a/src/types/proofread-state.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type ProofreadState = 'finish' | 'proofreading' | 'analyzing' | 'draft' | string; - -export const ProofreadStateConfig: { - [key in ProofreadState]: string; -} = { - finish: '校对完成', - proofreading: '校对中', - analyzing: 'AI分析中', - draft: '草稿', -} diff --git a/src/types/proofread.ts b/src/types/proofread.ts deleted file mode 100644 index 1f0a6a8..0000000 --- a/src/types/proofread.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {ProofreadTypeEnum, TProofreadCountResult} from "@/service/types/document.ts"; - -export type ProofreadType = - 'black' - | 'char' - | 'word' - | 'number' - | 'symbol' - | 'unit' - | 'syntax' - | 'info' - | 'tendency' - | 'inconsistent' - | 'format' - | 'sensitive' - -export type ProofreadDataKey =keyof TProofreadCountResult - -export const ProofreadTypeList: ProofreadType[] = [ - 'black', 'char', 'word', 'number', 'symbol', 'unit', - 'syntax', 'info', 'tendency', 'inconsistent', 'format', 'sensitive', -] - -export type IProofreadTypeData = { - type: ProofreadType, - color: string; - text: string; - count?: number; - key: ProofreadDataKey; - id: ProofreadTypeEnum|ProofreadTypeEnum[]; - // 采纳全部时要提交的类型 - acceptAll?:ProofreadTypeEnum[]; - // 忽略全部时要提交的类型 - ignoreAll?:ProofreadTypeEnum[]; -} - -export const ProofreadTypeData: IProofreadTypeData[] = [ - {id:ProofreadTypeEnum.characterError,type: 'char', count: 0, text: '提示', color: '#D6AA69',key:'characterError'}, - {id:ProofreadTypeEnum.sensitive,type: 'sensitive', count: 0, text: '敏感词', color: '#D6AA69',key:'sensitive'}, - {id:[ProofreadTypeEnum.blackWord,ProofreadTypeEnum.blackWordBlock,ProofreadTypeEnum.blackWordReplace], type: 'black', - acceptAll:[ProofreadTypeEnum.blackWordReplace],ignoreAll:[ProofreadTypeEnum.blackWordBlock,ProofreadTypeEnum.blackWordReplace], - count: 0, text: '黑名单', color: '#2A2A2A',key:'blackWord'}, - {id:ProofreadTypeEnum.wordError,type: 'word', count: 0, text: '词错', color: '#D6AA69',key:'wordError'}, - {id:ProofreadTypeEnum.numberError,type: 'number', count: 0, text: '数字错', color: '#D6AA69',key:'numberError'}, - {id:ProofreadTypeEnum.punctuationError,type: 'symbol', count: 0, text: '标点错', color: '#D6AA69',key:'punctuationError'}, - {id:ProofreadTypeEnum.unitsError,type: 'unit', count: 0, text: '计量单位错', color: '#D6AA69',key:'unitsError'}, - {id:ProofreadTypeEnum.grammarError,type: 'syntax', count: 0, text: '语法错误', color: '#D6AA69',key:'grammarError'}, - {id:ProofreadTypeEnum.knowledgeableError,type: 'info', count: 0, text: '知识性错误', color: '#D6AA69',key:'knowledgeableError'}, - {id:ProofreadTypeEnum.tendentiousError,type: 'tendency', count: 0, text: '倾向性错误', color: '#D6AA69',key:'tendentiousError'}, - {id:ProofreadTypeEnum.inconsistentError,type: 'inconsistent', count: 0, text: '不一致错误', color: '#D6AA69',key:'inconsistentError'}, - {id:ProofreadTypeEnum.formatError,type: 'format', count: 0, text: '格式错误', color: '#D6AA69',key:'formatError'}, -] - -export const ProofreadTypeKeys:{ - [key:number]: string -} = { - [ProofreadTypeEnum.characterError]: 'characterError', - [ProofreadTypeEnum.sensitive]: 'sensitive', - [ProofreadTypeEnum.blackWord]: 'blackWord', - [ProofreadTypeEnum.wordError]: 'wordError', - [ProofreadTypeEnum.numberError]: 'numberError', - [ProofreadTypeEnum.punctuationError]: 'punctuationError', - [ProofreadTypeEnum.unitsError]: 'unitsError', - [ProofreadTypeEnum.grammarError]: 'grammarError', - [ProofreadTypeEnum.knowledgeableError]: 'knowledgeableError', - [ProofreadTypeEnum.tendentiousError]: 'tendentiousError', - [ProofreadTypeEnum.inconsistentError]: 'inconsistentError', - [ProofreadTypeEnum.formatError]: 'formatError', -} - -export type ProofreadItemAction = 'replace' | 'delete' - -export type ProofreadItemState = 'unprocessed' | 'accept' | 'ignore' - -export type IProofreadItem = { - id: number; - type: ProofreadType; - action: ProofreadItemAction - origin: string; - replace: string; - state: ProofreadItemState -} diff --git a/src/types/type-proofread.d.ts b/src/types/type-proofread.d.ts deleted file mode 100644 index be033b5..0000000 --- a/src/types/type-proofread.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -declare type ProofreadData_bak = { - tag: string; - origin: string; - text:string; - start: number; - end: number; - id: number; - idx: number; - isAccept: number; - type: number; -} -declare type ProofreadSentence_bak = { - diffs: ProofreadData[]; - new_text: string; - insert: string; - insert_len: number; - // paragraph_offset: number; - sentence_offset: number; - paragraph_num: number; -} \ No newline at end of file diff --git a/src/types/v3/enums.ts b/src/types/v3/enums.ts deleted file mode 100644 index 5cde703..0000000 --- a/src/types/v3/enums.ts +++ /dev/null @@ -1,110 +0,0 @@ - -/* -confusion = "confusion" # 易错词 -whitelist = "whitelist" # 白名单 -quotation = "quotation" # 语录 -leader = "leader" # 领导人 -position = "position" # 职位 -blacklist = "blacklist" # 黑名单 -blacklist_mask = "blacklist_mask" # 黑名单 -blacklist_replace = "blacklist_replace" # 黑名单 -sensitive = "sensitive" # 敏感词 -punctuation = "punctuation" # 标点符号 -model = "model" # 模型检测 -now_called = "now_called" # 现称 -quoting_legal = "quoting_legal" # 法规 -serial_number = "serial_number" # 序号 -coinage = "coinage" # 造字 -first_choice = "first_choice" # 首选 -alien = "alien" # 异形词 -incorrect_expression = "incorrect_expression" # 表述有误 -after_a_certain_year = "after_a_certain_year" # xx年以后 -word = "word" # 词类型错误 -char = "char" # 字类型错误 -proper = "proper" # 专名纠错,包括成语纠错、人名纠错等 - */ -export const V3Enums = { - ProofreadType : { - quotation: {key: 'quotation', value: 203, name: '引用领导人讲话', color: 'hsla(179, 100%, 70%, 1)'}, - leader: {key: 'leader', value: 201, name: '政要人物', color: 'hsla(179, 100%, 70%, 1)'}, - position: {key: 'position', value: 202, name: '领导人职位', color: 'hsla(179, 100%, 70%, 1)'}, - fallen_officers: {key: 'fallen_officers', value: 202, name: '落马官员', color: 'hsla(179, 100%, 70%, 1)'}, - confusion: {key: 'confusion', value: -1, name: '易错词', color: '#fd6643'}, - sensitive: {key: 'sensitive', value: 101, name: '敏感词', color: '#2A2A2A'}, - blacklist: {key: 'blacklist', value: 102, name: '黑名单', color: '#fd6643'}, - whitelist: {key: 'whitelist', value: -1, name: '白名单', color: '#fd6643'}, - punctuation: {key: 'punctuation', value: 103, name: '标点', color: '#fd6643'}, - model: {key: 'model', value: -1, name: '', color: '#fd6643'}, - nowCalled: {key: 'now_called', value: -1, name: '现称', color: '#fd6643'}, - quotingLegal: {key: 'quoting_legal', value: -1, name: '法规', color: '#fd6643'}, - serialNumber: {key: 'serial_number', value: -1, name: '序号', color: '#fd6643'}, - incorrectExpression: {key: 'incorrect_expression', value: -1, name: '表述有误', color: '#fd6643'}, - after_a_certain_year: {key: 'after_a_certain_year', value: -1, name: '现称', color: '#fd6643'}, - first_choice: {key: 'first_choice', value: -1, name: '首选', color: '#fd6643'}, - coinage: {key: 'coinage', value: -1, name: '造字', color: '#fd6643'}, - coinage_first_choice: {key: 'coinage_first_choice', value: -1, name: '造字 首选', color: '#fd6643'}, - term: {key: 'term', value: -1, name: '规范术语', color: '#fd6643'}, - alien: {key: 'alien', value: -1, name: '异形词', color: '#fd6643'}, - word: {key: 'word', value: -1, name: '词类型错误', color: '#fd6643'}, - char: {key: 'char', value: -1, name: '字类型错误', color: '#fd6643'}, - proper: {key: 'proper', value: -1, name: '专名纠错', color: '#fd6643'}, - other: {key: 'other', value: -1, name: '', color: '#fd6643'}, - // getTitle: (type: string) => { - // return _typeConfig[type]?.name || '其他'; - // }, - // getType - }, - ProofreadTypeList: [ - 'quotation', - 'leader', - 'position', - 'confusion', - 'sensitive', - 'blacklist', - 'whitelist', - 'punctuation', - 'model', - 'nowCalled', - 'quotingLegal', - 'serialNumber', - 'incorrectExpression', - 'afterCertainYear', - 'other', - ], -} - -// export const ProofreadType = { -// quotation: {key: 'quotation', value: 203, name: '语录', color: '#ff0'}, -// leader: {key: 'leader', value: 201, name: '领导人', color: '#ff0'}, -// position: {key: 'position', value: 202, name: '领导人职位', color: '#ff0'}, -// confusion: {key: 'confusion', value: -1, name: '易错词', color: '#ff0'}, -// sensitive: {key: 'sensitive', value: 101, name: '敏感词', color: '#ff0'}, -// blacklist: {key: 'blacklist', value: 102, name: '黑名单', color: '#ff0'}, -// whitelist: {key: 'whitelist', value: -1, name: '白名单', color: '#ff0'}, -// punctuation: {key: 'punctuation', value: 103, name: '标点', color: '#ff0'}, -// model: {key: 'model', value: -1, name: '模型', color: '#ff0'}, -// nowCalled: {key: 'now_called', value: -1, name: '现称', color: '#ff0'}, -// quotingLegal: {key: 'quoting_legal', value: -1, name: '法规', color: '#ff0'}, -// serialNumber: {key: 'serial_number', value: -1, name: '序号', color: '#ff0'}, -// incorrectExpression: {key: 'incorrect_expression', value: -1, name: '表述有误', color: '#ff0'}, -// afterCertainYear: {key: 'after_a_certain_year', value: -1, name: 'xx年以后', color: '#ff0'}, -// other: {key: 'other', value: -1, name: '提示', color: '#ff0'}, -// // getTitle: (type: string) => { -// // return _typeConfig[type]?.name || '其他'; -// // }, -// // getType -// } - - - - - - - - - - - - - - diff --git a/src/types/v3/proofread.d.ts b/src/types/v3/proofread.d.ts deleted file mode 100644 index b3f3584..0000000 --- a/src/types/v3/proofread.d.ts +++ /dev/null @@ -1,172 +0,0 @@ -type int = number; - -declare namespace V3 { - declare type ProofreadDocumentData = { - /** - * 原始句子 - */ - insert: string; - /** - * 原始句子字符数 - */ - insert_len: number; - /** - * 段落序号(透传字段 ext 中需要含该选项) - */ - paragraph_num: number; - /** - * 透传字段,会在 detail v3接口和 mqtt broker 队列中原样返回 - * 需要对该字段进行 base64 化处理 - */ - ext: string; - } - declare type GovInfo = { - type: 'position' | 'quotation' | 'source' | 'job' | 'leader' | string; - content: string; - data?: { - source?: string; - from: string; - origin: string; - link: string; - } - } - declare type ProofreadCorrect = { - tag: string; - origin: string; - text: string; - index: string; - start: number; - end: number; - id: number; - idx?: number; - isAccept: number; - color?: string; - type: 'quotation' | 'position' | 'leader' | string; - typeName?:string; - addition?: string; - gov?: GovInfo[] - } - declare type SentenceExt = { - index:number - } - declare type SentenceOriginInfo = { - insert_len: number; - paragraph_num: number; - origin_text: string; - hash: string; - parseData:string; - } - declare type ProofreadStatus = { - is_finish: boolean; - paragraph_num: number; - paragraph_total: number; - } - - declare type OriginDataInfo = { - insert_len: number; - index?: number; - paragraph_num: number; - origin_text: string; - hash: string | null; - parseData: { - newStr: string; - invisibleChars: { pos: number, char: string }[] - } - } - declare type ProofreadSentence = { - diffs: ProofreadCorrect[]; - code: number; - new_text: string; - insert: string; - ext: string; - insert_len?: number; - paragraph_offset?: number; - sentence_offset?: number; - start_num: number; - - /** - * 段落数 - */ - paragraph_num: number; - /** - * 段落数 - */ - sentence_num: number; - } - - declare type ProofreadItem = { - // paragraph_offset: number; - sentence_offset: number; - paragraph_num: number; - } & ProofreadCorrect - - declare type ProofreadCount = { - total: number; - [key: string]: number; - } - - declare type ProofreadTypeConfig = { - key: string; - value: number; - name: string; - color: string; - } - - declare type ParsedProofreadResult = { - list: ProofreadCorrect[]; - count: ProofreadCount - } - - declare type ProcessAction = { - id: number; - correctId: number; - } - - type CacheData = { - // 当前文档id - documentId: number; - // 所有校对结果 - sentences: ProofreadSentence[]; - // 当前选中校对项下表 - activeItemId: number; - // 校对模式(优先查全、查准) - proofreadMode?: string; - // 选中的tab - activeAcceptState: 1|2|3; - // 禁用的校对项的id - disabled: number[]; - addition?: any; - originData: any; - } - - type ProofreadResultCount = { - all:number; - // 数据量 - not_adopted: number; - // 已复核 - adopted: number; - total:number; - // 错误总数 - error: number; - // 敏感总数 - sensitive: number; - // 黑名单总数 - blacklist: number; - // 政务校对总数 - govCheck: number; - } - - type DetectionResult = { - ID: number | string; - // 错误内容 - source: string; - // 错误原因 - reason: string; - } - type DetectionContent = { - message: string; - result: string; - status: number; - } - -} \ No newline at end of file diff --git a/src/utils/base64.ts b/src/utils/base64.ts deleted file mode 100644 index fd87138..0000000 --- a/src/utils/base64.ts +++ /dev/null @@ -1,23 +0,0 @@ -export function base64ToBuffer(data: string) { - //去掉url的头,并转换为byte - const split = data.split(','); - const bytes = window.atob(split[1]); - //处理异常,将ascii码小于0的转换为大于0 - const ab = new ArrayBuffer(bytes.length); - const ia = new Uint8Array(ab); - for (let i = 0; i < bytes.length; i++) { - ia[i] = bytes.charCodeAt(i); - } - const match = split[0].match(/^data:(.*);base64/) - const contentType = match && match.length == 2 ? match[1] : '' - //return new Blob([ab], {type: split[0]}); - return { - buffer: [ab], - contentType - } -} - -export function base64ToFile(data: string, fileName: string) { - const _data = base64ToBuffer(data); - return new File(_data.buffer, fileName, {type:_data.contentType}) -} diff --git a/src/utils/cloneDeep.ts b/src/utils/cloneDeep.ts deleted file mode 100644 index 8dff4cb..0000000 --- a/src/utils/cloneDeep.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {cloneDeep as clone} from 'lodash' - -export function cloneDeep(obj: T) { - return clone(obj); - // return JSON.parse(JSON.stringify(obj)) as T; - // if(typeof obj !=="object" || obj == null){ - // return obj - // } - // const res : object | any[] = obj instanceof Array ? [] : {}; - // for(const key in obj){ - // if(obj.hasOwnProperty(key)){ - // res[key] = cloneDeep(obj[key]) - // } - // } - // return res -} diff --git a/src/utils/element-util.ts b/src/utils/element-util.ts deleted file mode 100644 index bc51e1e..0000000 --- a/src/utils/element-util.ts +++ /dev/null @@ -1,22 +0,0 @@ - -export function elementInView(elementNode: HTMLElement, containerNode: HTMLElement) { - const elementRect = elementNode.getBoundingClientRect(); - const elementTop = elementRect.top; - const elementBottom = elementRect.bottom; - const containerRect = containerNode.getBoundingClientRect(); - const containerTop = containerRect.top; - const containerBottom = containerRect.bottom; - return elementTop >= containerTop && elementBottom <= containerBottom; -} - -// 获取波浪线背景svg -export const getWaveBackground = (color: string = 'red', width = 2) => { - const svg = `` - return `url(data:image/svg+xml;base64,${btoa(svg)})` -} - - -export const getInsertBackground = (color: string = 'red', width = 2) =>{ - const svg = ``; - return `url(data:image/svg+xml;base64,${btoa(svg)})` -} diff --git a/src/utils/sleep.ts b/src/utils/sleep.ts deleted file mode 100644 index 4715ca5..0000000 --- a/src/utils/sleep.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * - * @param seconds 注意注意单位是秒 - */ -export function sleep(seconds: number) { - return new Promise((resolve) => { - setTimeout(resolve, seconds * 1000) - }); -} diff --git a/src/utils/storage.ts b/src/utils/storage.ts deleted file mode 100644 index ac13ecb..0000000 --- a/src/utils/storage.ts +++ /dev/null @@ -1,45 +0,0 @@ -const _store = window.localStorage -const Storage = { - /** - * 设置缓存 - * @param key - * @param value - * @param expire 过期时间,单位秒,-1表示不过期 - */ - put(key: string, value: any, expire = -1) { - expire = expire == -1 ? -1 : Date.now() + expire * 1000; - _store.setItem(key, JSON.stringify({ - value, - expire - })) - }, - /** - * 获取缓存 - * @param key - * @param defaultValue 默认值,当不存在时返回 - */ - get(key: string, defaultValue: null | T = null) { - const data = _store.getItem(key); - if (data == null) { - return defaultValue; - } - try { - const _data = JSON.parse(data); - if (_data.expire) { - if (_data.expire != -1 && _data.expire < Date.now()) { - Storage.remove(key); - return defaultValue; - } - return _data.value as T; - } - return _data as T; - } catch (_) { - console.log(_) - } - return data as T; - }, - remove(key: string) { - _store.removeItem(key); - } -} -export default Storage diff --git a/src/utils/strings.ts b/src/utils/strings.ts deleted file mode 100644 index 0acbdd0..0000000 --- a/src/utils/strings.ts +++ /dev/null @@ -1,89 +0,0 @@ -import dayjs from "dayjs"; -import relativeTime from "dayjs/plugin/relativeTime" - - -dayjs.extend(relativeTime) - -export function countString(str: string) { - str = str.replace(/\n/, '') - const chinese = Array.from(str) - .filter(ch => /[\u4e00-\u9fa5]/.test(ch)) - .length - const english = Array.from(str) - .map(ch => /[a-zA-Z0-9\s]/.test(ch) ? ch : '') - .join('').length//.split(/\s+/).filter(s => s) - - return chinese + english -} - -export function formatFileSize(bytes: number) { - if (bytes <= 0) return '0KB'; - const units = ['KB', 'MB', 'GB', 'TB']; - let i = 0; - while (bytes >= 1024 && i < units.length - 1) { - bytes /= 1024; - i++; - } - return bytes.toFixed(2) + units[i]; -} - -export function formatWordCount(count: number) { - if (count < 10000) { - return count; - } - return (count / 10000).toFixed(2).replace(/.[0]+$/g,'') + '万' -} - -const REGEX = { - phone: /^(\d{3})\d{4}(\d{4})$/ -} - -export function hidePhone(phone?: string | null) { - if (!phone || !REGEX.phone.test(phone)) return phone; - return phone.replace(REGEX.phone, '$1****$2') -} - -export function isPhone(phone?: string) { - return phone && REGEX.phone.test(phone) -} -function getDayjs(time:any){ - const str = time.toString(); - if(str.length == 10){ - time *= 1000; - } - return dayjs(time); -} - -export function formatTime(time:any,template = 'YYYY-MM-DD HH:mm:ss') { - if(!time) return '-'; - return getDayjs(time).format(template) -} - -export function timeFromNow(time: any) { - return getDayjs(time).fromNow(); -} - -export function calcContentLengthLikeWord(str:string) { - try { - //先将回车换行符做特殊处理 - // eslint-disable-next-line no-irregular-whitespace - str = str.replace(/(\r\n+|\s+| +)/g, "龘"); - // eslint-disable-next-line no-control-regex - str = str.replace(/[\x00-\xff]/g, "m"); - //合并字符m,连续字母、数字、英文符号视为一个单词 - str = str.replace(/m+/g, "*"); - //去掉回车换行符 - str = str.replace(/龘+/g, ""); - //返回字数 - return str.length; - } catch (e) { - return str.length - } -} - -export function cutSummary(str?:string,length = 30,subfix = '...'){ - if(str && str.length > length){ - return str.slice(0,length) + subfix - } - return str -} \ No newline at end of file diff --git a/src/utils/vars.ts b/src/utils/vars.ts deleted file mode 100644 index bfdd822..0000000 --- a/src/utils/vars.ts +++ /dev/null @@ -1,12 +0,0 @@ -const mode = import.meta?.env?.MODE || 'development'; -const isMobile = /(ipod|ipad|ios|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i.test(navigator.userAgent); - -export const env = { - isDev: mode == 'development', - isTest: mode == 'test', - isProduction: mode == 'production', - device: { - isPC: !isMobile, - isMobile - } -} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts deleted file mode 100644 index 44119ee..0000000 --- a/src/vite-env.d.ts +++ /dev/null @@ -1,279 +0,0 @@ -/// - -type ApplicationConfig = { - PROOFREAD_URL: string; - /** - * 接口前缀 - */ - API_PREFIX: string; - /** - * 资源路径 - */ - PUBLIC_PATH: string; - /** - * 默认首页 - */ - HOME_PAGE_PATH: string; - /** - * 编辑器最大数量 - */ - ALLOW_MAX_COUNT: number; - /** - * 同步校对最大字数 - */ - SYNC_CHECK_MAX_WORD_COUNT: number; - /** - * 路由模式 - */ - ROUTER_MODE: 'hash' | 'browser'; - ENV_MODE: 'development' | 'test' | 'production'; - APP_NAME?: string; - APP_SHORT_NAME?: string; - WEB_PATH?: string; - /** - * 用户登录token key - */ - LOGIN_TOKEN_KEY: string; - /** - * 二维码过期时间 - */ - QR_EXPIRE_TIME?: number; -} - -declare const buildVersion: string; -declare const AppVersion: { - version: string; - buildVersion: string; - platform: string; - environment: 'Dev' | 'Test' | 'Prod' | string; - platformVersion: string; -} - -declare const APP_CONFIG: ApplicationConfig; -declare type LoginModel = { - phone: string; - code: string; -} - -declare type WebMessage = { - Message: string; - Data: T -} - -declare class BizError extends Error { - /** - * 错误码 - */ - code = 1; - data: string | object; - - constructor(message: string, code = 1, data?: string | object) { - super(message); - this.code = code; - this.data = data; - } -} - -declare type Account = { - /** - * 用户ID - */ - uid: number; - /** - * 用户手机号 - */ - phone: string; - /** - * 用户昵称 - */ - nickname: string; - /** - * 状态 - */ - status: number; - /** - * 用户创建时间戳 - */ - createdAt: number; - /** - * 用户头像 - */ - avatar: string; - /** - * 过期时间 - */ - expiration: string; - /** - * 是否绑定微信 false 否,true是 - */ - is_bind_wechat: boolean; -} - -declare type DocumentText = { - Text: string; - ParagraphNumber: number; - Hash: string; -} -declare type DocumentContent = { - list: DocumentText[]; - text: string; -} -declare type DocumentData = { - /** - * 错误信息 - */ - message: string; - /** - * 错误码,非0表示有错误 详细错误读取 message - */ - code: number; - content: DocumentContent; - name: string; - fullName: string; - documentId: number; - wordsCount: number; - charactersCount: number; - -} -type AppPluginInfo = { - version: string; - platform: string; - environment: string; - deviceId: string; -} -type BridgeResult = { - code: number; - message: string; - data: T -} -type HostBridge = { - ShowMessageForm: () => void | Promise; - ShowLexiconForm: () => void; - GetAppVersion: () => Promise; - /** - * 显示升级信息 - * @param data 必须是UpgradeInfo类型 - */ - ShowUpgrade: (data: string, force?: boolean) => Promise | void; - /** - * 关闭窗体 - * @constructor - * @deprecated - */ - Close: () => Promise | void; - MoveCursor: (pos: number) => Promise | void; - // 显示登录窗体 - ShowLoginForm: (action: string | null) => Promise | void; - ShowSettingForm: () => Promise | void; - Logout: (action: 'async-info' | string) => Promise | void; - loginSuccess: (userinfo: string | Account) => void; - StartProofread: () => Promise | void; - OpenUrlWithOsBrowser: (url: string) => void; - ShowDialog: (message: string, confirmText?: string, confirmAction?: string) => void; - ShowCurrentPane: () => void; - SetBtnStatus: (key: 'proofread-status' | 'view-panel', status: boolean) => void; - HideCurrentPane: () => void; - noticeOtherWeb: (data: string, target: string | null) => Promise | void; - getAllText: () => Promise; - getDocumentData: (documentId?: number) => Promise; - GetDocumentInfo: (documentId?: number) => Promise; - SetCurrentDocumentId: (id: number) => void | Promise; - GetCurrentDocumentId: () => Promise; - // GetCurrentDocumentSaveId: () => Promise; - /** - * 清楚所有标签 - */ - clearAllProofreadMarkById: (document: number) => void; - ClearCurrentDocumentMarks: () => void; - /** - * 删除标签 - * @param markId 要删除的标签id - */ - removeBookmark: (markId: string | null) => void; - /** - * 添加标签 - * @param data 必须是TCorrectedContent类型 - */ - addBookmark: (data: string) => void; - /** - * 选中标签 - * @param data 必须是TCorrectedContent类型 - */ - selectMark: (data: string) => void; - SelectMarkById: (proofreadId: number, documentId: number) => void; - //处理标签 - processMark: (id: number, status: number) => void; - /** - * 完全将校对内容传递给插件处理,避免定位不准确. - * @param data 必须是 TDocumentCorrectItem[] 数组 - */ - InitContent: (data: string, documentId: number) => Promise<'true' | 'false'>; - GetParagraph: (index: number) => Promise; - /** - * 获取段落文本 - * @param start 段落开始位置 - * @param end 段落结束位置 - */ - getParagraphTextByRange: (start: number, end: number) => Promise; - GetTextByRange: (start: number, end: number) => Promise; - GetDocumentAllText: () => Promise; - getAllParagraphs: () => Promise; - // 获取当前文档段落总数 - getTotalParagraphNumber: () => Promise; - Focus: () => void; - - MarkSentence: (sentence: string, documentId: number) => Promise<'true' | 'false'> - ShowDialogMessage: (message: string) => Promise<'retry' | 'ok'> - ShowConfirmMessage: (message: string, confirmText: string, confirmAction: string) => void; - ShowMessage: (message: string, delay = 1000, showCloseBtn = true) => void; - ReadText: (path: string) => Promise | string> - WriteText: (content: string, path: string) => Promise | string> - SaveCache: (documentId: number, cache: string, silent: boolean) => Promise | string> - LoadCache: () => Promise - GetProofreadOriginData: () => Promise - CacheExists: () => Promise - DeleteCache: () => Promise | void - InitProofreadCacheList: (content: string,originData: string) => Promise - ExportProofreadResult: (modelType: string) => Promise - ShowConfirm: (message: string, caption: string, yesButtonText: string, noButtonText: string) => Promise<'yes' | 'no'> | void - Saved: (document: number) => Promise; - SetCurrentDocumentProofreadStatus(documentId: number, proofread: boolean, proofreading: boolean, checkCurrent: boolean): void; - ShowWebView: (url: string, width: number, height: number, dialog: boolean) => void; - ShowLog: (log: string) => void; - - // - SendNoticeToCheckAll: ()=>void; - SendNoticeToCheckRange: (start:number,end:number)=>void; - SendNoticeToShowCheckHistory: ()=>void; -} -type HostObjects = { - bridge: HostBridge; - event: { - // 触发可拖动事件 - MouseDownDrag: (e?: MouseEvent) => void; - Close: () => Promise | void; - }; - host: { - // 触发可拖动事件 - Download: (url:string) => Promise | void; - Download: (url:string,fileName:string) => Promise | void; - }; - detection: { - WebInitializationCompleted: () => void; - GetHistory: () => Promise; - SetHistory: (result: string) => void; - GetCheckStatus: () => Promise; - SetCheckingData: (isChecking: boolean, checkingKey: string, checkingSummary: string,location:string) => void; - Close: () => void; - } -} -declare type ChromeType = { - webview: { - removeEventListener(arg0: string, onBridgeMessage: (e: MessageEvent) => void): unknown; - addEventListener(arg0: string, onBridgeMessage: (e: MessageEvent) => void): unknown; - hostObjects: HostObjects & { - sync: HostObjects; - }; - } -} -declare const chrome: ChromeType; \ No newline at end of file