From 9d92f86f0889ee3bf572309e612e85f761cc4e37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A7=8B=E4=BA=8E=E5=88=9D=E8=A7=81?= <752204717@qq.com>
Date: Fri, 31 Jul 2026 15:07:12 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=93=E5=88=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
scripts/_figure-extract-debug.html | 1 +
scripts/_out.html | 1 +
scripts/alias-hooks.mjs | 15 +
scripts/alias-loader.mjs | 19 +
scripts/alias-register.mjs | 5 +
scripts/inspect-word-fig-pairing.mjs | 45 +
scripts/inspect-word-figures.mjs | 82 +
scripts/test-extract-figures.mjs | 29 +
scripts/test-fig-match.mjs | 35 +
src/api/index.js | 4 +-
src/common/js/commonJS.js | 37 +-
src/components/common/Sidebar.vue | 4 +
src/components/common/common.vue | 16 +-
src/components/common/langs/en.js | 181 +-
src/components/common/langs/zh.js | 181 +-
src/components/page/GenerateCharts.vue | 499 +++-
.../JournalManagement/common.vue | 27 +
.../JournalManagement/SpecialList/index.vue | 2364 +++++++++++++++++
src/components/page/OnlineProofreading.vue | 593 ++++-
src/components/page/articleAdd.vue | 473 ++--
src/components/page/articleDetailEditor.vue | 830 +++++-
src/components/page/articleListEditor_B1.vue | 203 +-
.../page/components/article/Related.vue | 549 +++-
.../page/components/table/DynamicTable.vue | 16 +
.../page/components/table/content.vue | 1 +
src/components/page/components/table/word.vue | 238 +-
.../components/table/wordHtmlTypesetting.vue | 249 +-
src/components/page/editPublicRefRdit.vue | 946 +++++--
src/components/page/journalFeeApproval.vue | 258 +-
src/router/index.js | 9 +
src/utils/convertNumericSuperscriptsToBlue.js | 6 +-
src/utils/exportFigureWord.js | 1219 ++++++++-
src/utils/exportManuscriptAuthor.js | 217 +-
src/utils/exportManuscriptWord.js | 1112 ++++++--
src/utils/exportManuscriptWordFooter.js | 86 +-
src/utils/exportManuscriptWordHeader.js | 46 +-
src/utils/exportMathWord.js | 317 +++
src/utils/exportTableWord.js | 922 ++++++-
src/utils/exportWordLayout.js | 12 +-
src/utils/manuscriptMediaReferences.js | 133 +-
src/utils/manuscriptReferenceHtml.js | 103 +-
src/utils/manuscriptReferenceWordComments.js | 55 +-
src/utils/moveBlueCitationsBeforePeriod.js | 114 +-
src/utils/parseReferenceFields.js | 249 +-
src/utils/productionSubmissionImport.js | 161 ++
src/utils/wordFigureImport.js | 381 +++
src/utils/wordMathImport.js | 1487 ++++++++++-
src/utils/wordReferenceBatchImport.js | 51 +-
src/utils/wordReferenceStatistics.js | 517 ++++
49 files changed, 13833 insertions(+), 1265 deletions(-)
create mode 100644 scripts/_figure-extract-debug.html
create mode 100644 scripts/_out.html
create mode 100644 scripts/alias-hooks.mjs
create mode 100644 scripts/alias-loader.mjs
create mode 100644 scripts/alias-register.mjs
create mode 100644 scripts/inspect-word-fig-pairing.mjs
create mode 100644 scripts/inspect-word-figures.mjs
create mode 100644 scripts/test-extract-figures.mjs
create mode 100644 scripts/test-fig-match.mjs
create mode 100644 src/components/page/JournalManagement/SpecialList/index.vue
create mode 100644 src/utils/exportMathWord.js
create mode 100644 src/utils/wordFigureImport.js
create mode 100644 src/utils/wordReferenceStatistics.js
diff --git a/scripts/_figure-extract-debug.html b/scripts/_figure-extract-debug.html
new file mode 100644
index 0000000..d181732
--- /dev/null
+++ b/scripts/_figure-extract-debug.html
@@ -0,0 +1 @@
+
Visual analysis of the current status and hotspots of quality of life research in patients with chronic heart failure based on CiteSpace
Qi Zhang1#, Nan Gan1#, Pei-Pei Zou2, De-Jing Yuan3*
, Qing Wu3*
1School of Nursing, Suzhou Medical College, Soochow University, Suzhou 215006, China.
2Department of Nursing, Yangcheng Lake Street Community Health Service Center, Suzhou 215006, China.
3Department of Cardiology, First Affiliated Hospital of Soochow University, Suzhou 215006, China.
#These authors contributed equally to this work and are co-first authors for this paper.
*Correspondence to: De-Jing Yuan, Qing Wu. Department of Cardiology, The First Affiliated Hospital of Soochow University, No. 899, Pinghai Road, Gusu District, Suzhou 215006, China. E-mail: ydjyzu@126.com; qwu@suda.edu.cn.
Author contributions Zhang Q and Zou PP were responsible for the study conception and design, literature search, data retrieval from the Web of Science Core Collection, and software operation using CiteSpace. They also drafted the initial manuscript and prepared all figures and tables. Gan N participated in the data screening, extraction, and cross-checking of the included literature, assisted in the interpretation of co-occurrence and burst detection analyses, and contributed to the revision of the methodology section. Yuan DJ and Wu Q supervised the entire research process, validated the visual analysis results, provided critical revisions to the manuscript for important intellectual content, and secured funding for the project. All authors read and approved the final manuscript. Competing interests The authors declare no conflicts of interest. Acknowledgments This research was supported by Research Project of Suzhou Nursing Society in 2024 (SZHL-A-202407) and Nursing Research Project of the First Affiliated Hospital of Soochow University in 2026 (HLYJ-2026-09). We are deeply grateful to our supervisor, colleagues, and participants for their invaluable support and assistance in completing this project. Abbreviations HF, heart failure; CHD, coronary heart disease; CHF, chronic heart failure; CNKI, China National Knowledge Infrastructure; WOS, Web of Science; COVID-19, coronavirus disease 2019; NYHA, New York Heart Association; TCM, traditional Chinese medicine. Citation Zhang Q, Gan N, Zou PP, Yuan DJ, Wu Q. Visual analysis of the current status and hotspots of quality of life research in patients with chronic heart failure based on CiteSpace. Nurs Commun. 2026;10:12. doi: 10.53388/IN2026012. Peer review information Nursing Communications thanks all anonymous reviewers for their contribution to the peer review of this paper. Editorial Advisory Board: Jie Li. Production editor: Jian Jia. Received: 18 April 2026; Revised: 09 June 2026; Accepted: 15 July 2026; Available online: 16 July 2026. © 2026 By Author(s). Published by TMR Publishing Group Limited. This is an open access article under the CC-BY license. (https://creativecommons.org/licenses/by/4.0/) | Abstract Background: Heart failure poses a growing global burden with rising prevalence and poor quality of life, especially in the elderly. This study explores the research hotspots and evolution in the quality of life in patients with chronic heart failure. Methods: The CiteSpace 6.4.R1 was used to conduct a visual analysis of the literature related to the quality of life in patients with chronic heart failure published in CNKI and Web of Science Core Collection from the establishment of the databases to November 1, 2024. Results: A total of 4,743 publications were included, comprising 4,185 Chinese-language publications and 558 English-language publications. The overall number of publications showed an upward trend. The institution and author with the largest number of published documents in China were Guangzhou University of Chinese Medicine and the team led by Zhang Yan, respectively. The research hotspots mainly focused on quality of life, chronic heart failure, cardiac function, elderly patients, nursing interventions, etc. The institution and author with the largest number of published publications in English were the Berlin Institute of Health and the team led by Stefan D. Anker, respectively. The research hotspots focused on chronic heart failure, quality of life, outcome, management, exercise tolerance, etc. Conclusion: Bibliometric analysis reveals the research patterns and trends in the field of the quality of life in patients with chronic heart failure, and can provide new research perspectives for researchers. Keywords: chronic heart failure; quality of life; visualization; CiteSpace; research hotspots |
Background
Heart failure (HF) is a severe manifestation or end-stage consequence of various heart diseases, with high mortality and rehospitalization rates. The prevalence of HF in adults in developed countries is 1.0%–2.0% [1]. The prevalence of HF in China is increasing due to the aging population, the increasing incidence of chronic diseases such as coronary heart disease (CHD), hypertension, and diabetes, and the improvement of medical standards that prolong the survival of patients with cardiovascular disease. Wang reported that the agestandardized prevalence of HF among urban patients in China was 0.57% for those aged 25–64 years, 3.86% for those aged 65–79 years, and 7.55% for those aged ≥ 80 years [2]. Cardiovascular diseases remain the leading cause of death globally, accounting for approximately 32% of all deaths worldwide [3], which brings a heavy burden to society and families.
Although great progress has been made in the clinical diagnosis and treatment of HF, the quality of life in elderly patients with HF is significantly lower than that in other elderly patients with chronic diseases due to the long course of treatment, many complications, and frequent acute exacerbations [4]. Quality of life is one of the important indicators to evaluate the health outcomes of patients with HF [5]. Chinese scholars began to study the relationship between HF and quality of life in the 1990s. Studies have found that the quality of life in patients with HF outside the hospital is poor, and more than 50% of patients with HF have serious complications within 30 days of discharge, leading to a decline in quality of life [6]. There have been many reviews on the quality of life of patients with CHD, and the specific methods to improve the quality of life of patients with HF have been systematically summarized, such as drug management, exercise management, psychological intervention, remote monitoring, and so on. However, such reviews mainly rely on the induction and integration of existing interventions, making it difficult to systematically identify research hotspots, thematic evolution rules, cooperation networks, and frontier trends in this field.
CiteSpace (6.4.R1) is a data analysis tool for bibliometric analysis and visualization, widely used to summarize hotspots and trends across various research directions in the medical field. However, there are no reports on the quality of life in HF. Thus, this study visually analyzed literature in the field of quality of life in chronic heart failure (CHF) in China National Knowledge Infrastructure (CNKI) and Web of Science (core collection) databases, aiming to explore the research status, hotspots, and development trends in this field so as to provide a basis for formulating targeted interventions, prevent adverse events and improve the prognosis of patients with HF, and finally reduce the social and economic burden.
Methods
Data collection and search strategy
We searched the China National Knowledge Infrastructure (CNKI) AND Web of Science (WOS) Core Collection database by computer. The Chinese search format was (chronic heart failure) AND (quality of life), and the language was Chinese; and the English search formula was: TI=chronic heart failure, TS= “quality of life” OR “life quality”, and the language was English. The search time limit was from the establishment of the database to November 1, 2024. Two researchers independently searched and screened the literature. The inclusion criteria were: 1) published literature related to the quality of life of patients with CHF; 2) the source of literature was journal articles or dissertations. The exclusion criteria were as follows: 1) conference papers, newspapers, and other non-academic reports, and reports of other disciplines that were obviously inconsistent with the content of this study; 2) literature with incomplete information, repeated publication of the same research content, and obvious errors. According to the inclusion and exclusion criteria of the literature, 4,743 pieces of literature were finally included, including 4,185 pieces of Chinese literature and 558 pieces of English literature.
Analysis tool
We used CiteSpace6.4.R1 software to visually analyze the literature related to the quality of life in patients with CHF. Firstly, we imported the retrieved files into NoteExpress software for deduplication and screening. The processed data were imported into CiteSpace. Then we set the relevant parameters: the time span was from January 1996 to November 2024, and the time slice was set to 1 year. After that, we set the selection criteria to a TOPN threshold of 50, selected the Pathfinder method as the shearing method, and set the rest as default. Finally, the knowledge map of the quality of life in patients with CHF was drawn and analyzed.
Results
Analysis of publication characteristics
The results show that the focus and research on the quality of life in patients with CHF began in 1996. The number of Chinese literature published increased from 2 in 1996 to 435 in 2020, showing a gradual upward trend. The number of English-language articles published had a relatively stable change, both below 50, and the highest point was in 2020 (46) (Figure 1).
Figure 1 The number of articles published in English and Chinese on quality of life in patients with chronic heart failure from 1996 to 2024.
This figure illustrates the linear trend of the number of published articles in the field of chronic heart failure quality of life in both Chinese and English from 1996 to 2024. The blue solid line is the linear change trend of the number of publications in the CNKI database, and the yellow solid line is the linear change trend of the number of publications in the Web of Science database.
Analysis of authors
The number of authors’ publications is represented by the size of nodes; the larger the node, the more publications. The line between nodes represents the cooperative relationship between authors; the line width indicates the cooperation strength, and the color represents the cooperation time. The results of Chinese literature analysis are shown in Figure 2A, which shows that there are 201 nodes and 148 lines in the author’s research map, with a density of 0.0074. The top three authors with the highest number of publications are Zhang Yan (15 ), Wang Ying (7), and Xu Hong (6). The analysis results of English literature are shown in Figure 2B, which shows that there are 298 nodes and 343 lines in the author’s research map, with a density of 0.0078. The German scholars Anker, Stefan D ranked first in the number of publications, with 11 publications. There is closer collaboration among authors other than those from China.
Analysis of institutions
In CiteSpace software, when “Institutions” is selected as the Node Type, each node represents a research institution, while each line represents a cooperation between the two institutions, and the network density reflects the strength of cooperation between these institutions. The analysis results of Chinese literature are shown in Figure 3A. There are 166 nodes in the institutional research map, 36 lines, and the density is 0.0026. The top three institutions in the number of Chinese literature publications were Guangzhou University of Chinese Medicine (47), Shandong University of Chinese Medicine (44), and Beijing University of Chinese Medicine (37). The results of visual analysis of the publishing institutions of English literature are shown in Figure 3B. There were 236 nodes, 334 lines, and the density was 0.012. Berlin Institute of Health (17), Charite Universitatsmedizin Berlin (16), and Free University of Berlin (15) had more than 15 articles, all of which are German research institutions with very close cooperation between institutions.
Analysis of keywords
Co-occurrence analysis of keywords. The frequency of keywords reflects the hot spots in the research field. In the graph, the more times the keywords appear, the larger the font and node size. To ensure the accuracy of the analysis, we normalized the keywords by incorporating synonyms, acronyms, as well as single or plural forms, and removed meaningless and irrelevant keywords. On this basis, we conducted a keyword co-occurrence analysis and extracted the top 10 keywords with the highest frequency in the co-occurrence analysis of Chinese and English literature, as shown in Table 1. The keyword co-occurrence map of Chinese literature is shown in Figure 4A. The keywords with large size in Figure 4A were “quality of life,” “chronic heart failure,” “cardiac function,” “elderly patients,” and “nursing intervention”. The keyword co-occurrence map of English literature is shown in Figure 4B. The keywords with large size in Figure 4B were “chronic heart failure,” “quality of life,” “outcome,” “management,” and “exercise tolerance”.
Cluster analysis of keywords. Cluster analysis of keywords can effectively grasp the research hotspots in this field and improve the accuracy of summarizing the research field. The research results of Chinese literature are shown in Figure 5A. The cluster module value (Q) is 0.8664, and the average silhouette value (S) is 0.9767. Q > 0.3, S > 0.5, indicating that the clustering effect of this study was significant and reliable. The top 8 clusters of Chinese literature were #0 heart failure, #1 rehabilitation exercise, #2 depression, #3 clinical observation, #4 community, #5 efficacy, #6 health education, and #7 clinical research. The keyword cluster analysis of English literature is shown in Figure 5B. The cluster module value (Q) is 0.7341, and the average contour value (S) is 0.8907. The top 8 clusters of English literature were #0 left ventricular function, #1 education program, #2 support education, #3 placebo-controlled double-blind study, #4 low-volume high-intensity interval training, #5 vagal neuromodulation, #6 resistance training, #7 adaptive servo-ventilation therapy.
Timeline analysis of keywords. We used the results of keyword clustering to make a keyword timeline map. In this map, the horizontal thick line segment indicates the distribution of each cluster along the time axis, and a longer line segment means that the cluster spans a wider time range. The map formed a total of the first 10 clusters numbered #0 to #9, where the smaller the number of clusters contained , the greater the number of literature. In the cluster analysis of keywords in Chinese literature, the top three clusters with timelines extending to the past two years were heart failure, rehabilitation exercise, and depression. In the cluster analysis of keywords in English literature, the top three clusters with timelines extending to the last 2 years were left ventricular function, support education, and low-volume high-intensity interval training. The keyword clustering timelines in the field of quality of life of patients with CHF in Chinese and English literature are shown in Figures 6A and 6B.
Figure 2 Author co-occurrence maps of Chinese- and English-language publications.
(A) Author co-occurrence map of Chinese-language publications. (B) Author co-occurrence map of English-language publications. Each circular node represents an author, and the node size is proportional to the number of publications. The colored rings indicate the publication period, ranging from cool colors for earlier years to warm colors for more recent years. The links between nodes represent collaborative relationships between authors. Link width indicates the strength of collaboration, while link color indicates the time of collaboration.
Figure 3 Co-occurrence map of Chinese- and English-language literature institutions.
(A) Co-occurrence map of Chinese literature institutions. (B) Co-occurrence map of English literature institutions. Each circular node represents an institution; the size of the node is proportional to the published articles, and the colored ring of the node represents the published time, ranging from cool (early) to warm (recent). Each line between nodes represents a cooperation between two institutions.
Figure 4 Co-occurrence map of keywords in Chinese- and English-language literature.
(A) Co-occurrence map of keywords in Chinese literature. (B) Co-occurrence map of keywords in English literature. Each circular node represents a co-occurring keyword, and the size of the node is proportional to the number of keyword appearances. The colored ring of each node represents the publication year, ranging from cold (early) to warm (recent). The lines between nodes represent two keywords that appear in the same article.
Table 1 High-frequency keywords and centrality
No. | CNKI | WOS |
Frequency (times) | Centrality | Keywords | Frequency (times) | Centrality | Keywords |
1 | 1838 | 0.38 | quality of life | 388 | 0.20 | chronic heart failure |
2 | 911 | 0.62 | chronic heart failure | 309 | 0.08 | quality of life |
3 | 815 | 0.20 | cardiac function | 165 | 0.20 | outcome |
4 | 280 | 0.17 | elderly patients | 129 | 0.10 | management |
5 | 203 | 0.10 | nursing intervention | 108 | 0.16 | exercise tolerance |
6 | 131 | 0.10 | coronary heart disease | 104 | 0.09 | trial |
7 | 101 | 0.07 | prognosis | 69 | 0.10 | association |
8 | 87 | 0.14 | clinical efficacy | 52 | 0.08 | depression |
9 | 84 | 0.03 | depression | 48 | 0.12 | disease |
10 | 75 | 0.05 | comfort care | 47 | 0.09 | elderly patients |
CNKI, China National Knowledge Infrastructure; WOS, Web of Science.
Figure 5 Clustering map of keywords in Chinese- and English-language literature.
(A) Clustering map of keywords in Chinese literature. (B) Clustering map of keywords in English literature. Each circular node represents a keyword. Shapes in different colors represent different clusters, and colors indicate publication year, ranging from cold (early) to warm (recent). Cluster numbers indicate how often keywords appear in the literature, with smaller numbers indicating higher frequencies. In order to grasp the research hotspots in this field and improve the accuracy of summary research field.
Figure 6 Clustering time map of keywords in Chinese- and English-language literature.
(A) Clustering time map of keywords in Chinese literature. (B) Clustering time map of keywords in English literature. Thick horizontal segments indicate the distribution of each cluster along the time axis; longer segments mean that the cluster spans a wider time range, and line colors indicate publication years, ranging from cold (early) to warm (recent). Each circular node on the line segment represents a keyword, and the keywords in the same cluster are arranged on the same horizontal line in chronological order. The arc starting from the node represents the span of time and intuitively presents the emergence, persistence, and extinction process of keywords in this cluster.
Emergence analysis of keywords. Based on the knowledge graph of keywords, we further analyzed the emergence of keywords, that is, the change in the frequency of keywords in a specific time period, reflecting the research frontier and development trend in this field. The 20 most emergent ones are shown in Figures 7A and 7B. The emergent words in the field of quality of life in patients with CHF in Chinese literature included “congestive,” “chronic heart failure,” “social support,” “nursing intervention,” “community,” etc. The keyword with the longest duration was “congestive” (2004–2014), and the keyword with the highest emergence intensity was “chronic heart failure” (27.42), followed by nursing intervention (17.69) at present. Keywords such as “cardiac rehabilitation,” “dapagliflozin,” and “compliance behavior” showed a strong emerging trend from around 2020, and are expected to continue to exert an influence on research in this field in the future. We also analyzed the evolution of emergent words in English literature. In the early stage, the main focus was “left ventricular dysfunction,” “congestive heart failure,” and “exercise tolerance”. In recent years, the research content has been enriched, such as “reduced ejection fraction,” “cardiac function,” and “city cardiomyopathy questionnaire”. The analysis of the 20 keywords with the strongest emergence in the English literature can be summarized as the following characteristics: 1) The subjects of the study were mainly elderly patients and european society; 2) The study instrument was the city cardiomyopathy questionnaire; 3) study types were double blind and questionnaire; 4) The research contents involved left ventricular dysfunction, exercise tolerance, cardiac rehabilitation, etc. 5) social support is a positive nursing intervention.
Figure 7 Emergence map of keywords in Chinese- and English-language literature.
(A) Emergence map of keywords in Chinese literature. (B) Emergence map of keywords in English literature. The green line represents the time period from 1996 to 2024, and the red line represents the time span of the keyword burst. It reflects the research frontier and development trend in this field.
Discussion
Analysis of research status of quality of life in patients with CHF
The concept of “quality of life” was first introduced by American economist J.K. Galbraith in 1958. He noted that people’s quality of life is the degree of satisfaction that is derived from both material and spiritual dimensions [7]. The World Health Organization’s Quality of Life Study Group defines quality of life as the subjective experience of individuals in different cultures and value systems with respect to their goals, expectations, standards, and concerns about living conditions [8]. Health-related quality of life is a complex, multidimensional construct that reflects the relationship between an individual’s quality of life and their health or disease status [9].
Analysis of the number of publications. From the analysis of publication data, it is evident that the number of publications in English remains relatively low, with an annual total of less than 50. The overall trend has been generally stable. The number of publications in China shows an upward trend, and the whole process can be divided into three stages. The first stage was from 1996 to 2003, during which a total of 19 pieces of literature were published. This period represents the enlightenment in exploring the quality of life for patients with CHF. Although research production during this time was somewhat fragmented, it still established a foundational basis for subsequent investigations in this field. The second stage was from 2004 to 2020 and was characterized as a period of rapid development in research concerning quality of life in patients with CHF. The number of published studies increased year by year. Notably, there was a significant surge in publications from 2016 to 2020, reaching a peak in 2020 with 435 pieces of literature published. At the same time, English publications also reached their peak at that time with 46 pieces of literature. This increase likely reflects heightened attention and interest, which we speculate may be related to the requirement of the “Healthy China 2030 Plan” to reduce premature mortality caused by chronic diseases and effectively control the burden of chronic diseases [10, 11]. From 2021 to the present, it is the third stage of research development on the quality of life in patients with CHF. The number of publications on the quality of life in patients with CHF worldwide shows a downward trend year by year. This trend may be related to the following factors: the global outbreak of COVID-19 and, after years of development in this field, basic research becoming saturated, shrinking the space for innovation. In addition, research hotspots have gradually differentiated into more subdivided sub-directions such as digital health and palliative care, and some literature no longer uses “quality of life” as the core keyword.
Lack of cooperation between institutions. There is relatively little cooperation among Chinese authors, whereas English-language authors maintain a relatively close cooperative relationship. An analysis of Chinese publishing institutions reveals that Guangzhou University of Traditional Chinese Medicine has the highest publication output. While cooperation within and among affiliated institutions is frequent, each research institution carries out research projects in its own region and has little cooperation with outside institutions. This phenomenon is consistent with the “principle of minimum effort,” which states that people tend to solve problems with minimal input [12]. However, to pursue the principle of saving time and effort, cooperation only within the region will lead to the unbalanced development of each region. In view of the current situation in China, communication and cooperation between scientific research institutions and scientific research teams should be strengthened to promote the comprehensive development of the research field on the quality of life in patients with CHF. The top three English publications are all from Berlin research institutions, and cooperation among institutions is very close.
Research hotspots of quality of life in patients with CHF
Explore the influencing factors of quality of life and provide support for unmet needs. The co-occurrence analysis of our keywords revealed “prognosis,” “clinical efficacy,” and “outcome” as prominent terms, indicating that the research primarily emphasized treatment effects and prognostic outcomes in patients with CHF. The keywords “elderly,” “coronary heart disease,” and “depression” indicate that advanced age, complicated chronic diseases, and negative emotions have become research hotspots regarding the quality of life in patients with CHF. Cardiac function serves as a standard metric for assessing therapeutic efficacy and prognosis in patients with CHF [13], and a study found that NYHA classification is an independent factor affecting the quality of life in patients with CHF [14]. The higher the NYHA classification of patients, the worse the prognosis of the disease and the lower the quality of life score; therefore, researchers pay more attention to the prognosis and treatment effect of the disease. Elderly patients are the main focus group, and Kim found that age is an independent factor affecting the quality of life in patients with CHF [15]. With the increase of age, the cardiovascular structure and function of patients are degraded [16], and the quality of life is gradually reduced. With the aggravation of aging in China [17], it is urgent to improve the quality of life of elderly patients with HF. HF is rarely isolated, and more than 80% of patients have two or more chronic diseases [18]. The course of coronary heart disease combined with chronic heart failure is protracted and challenging to manage; compounded by patients’ poor health awareness and improper behavior, diseases always flare up and worsen, and finally reduce the quality of life of patients [19]. Therefore, in the process of treatment and care, healthcare providers should pay attention to patients with HF and multiple chronic diseases. In addition, researchers have begun to pay attention to the patients’ negative emotions. Due to the prolonged and recurrent nature of the disease, patients with CHF are susceptible to anxiety, depression, and other negative emotions [20]. The level of depression in patients with CHF is strongly correlated with their quality of life [21], while anxiety, depression, and similar negative emotions exert a substantial adverse effect on it [22]. In summary, within the domain of quality of life in patients with CHF, it is of positive clinical significance to study how to improve the clinical efficacy of patients and provide personalized support to elderly patients with other chronic diseases to help them relieve negative emotions and improve their quality of life.
Implement effective intervention measures to improve the quality of life of patients. Among the co-occurrence results, “nursing stem,” “comfort care,” “management,” and “exercise” highlighted a focus on various interventions and management measures. The emergent results showed that the intensity of nursing intervention was 17.69, ranking second only to CHF itself (27.42). Traditional Chinese Medicine (TCM) interventions, including Baduanjin exercises and acupoint application, have maintained their prominence since 2022 and continue to exert a significant influence in research on the quality of life in patients with CHF. Patients with chronic heart failure have low self-care ability and low medication compliance after discharge, which leads to the recurrence of their condition [23]. A systematic review shows that nursing interventions can effectively improve the self-care ability of patients with chronic heart failure. [24]. Currently, intervention research on the quality of life of patients with CHF is still in the exploratory stage, mainly including continuous nursing, exercise or TCM, and various targeted interventions based on theories and Internet technology development. Studies have found that these interventions can not only improve the quality of life of patients but also significantly improve patient compliance, cardiac function, and exercise endurance [25–29]. Most existing studies use a single measure to intervene in patients and test whether it can improve their quality of life and other outcome indicators, while some investigations have begun integrating new information technologies, such as the “Internet Plus” initiative and WeChat platforms, into intervention strategies. In the future, healthcare providers should be committed to the development of high-quality interventions, the combination of multiple interventions, and the promotion of positive and effective interventions in clinical practice to improve the quality of life in patients with CHF and promote their rehabilitation.
Analysis of the differences in research hotspots of quality of life in patients with CHF between Chinese and English literatures
Analysis of the keywords related to research on the quality of life in patients with CHF reveals that current studies primarily focused on elderly patients, negative emotions, comorbidities, disease treatment effects, and prognosis. In terms of intervention and management, research in China has focused on intervention measures led by medical staff. For instance, a randomized controlled study found that the implementation of nursing interventions helped reduce patients’ anxiety and depression [30], and improve their quality of life. In contrast, studies in English have focused more on patients’ self-management abilities. For example, Abbasi [31] used a variety of methods and self-management education programs based on media to improve the quality of life in patients with CHF. There are three reasons for this. The first is the cultural difference. Western countries emphasize personal responsibility and autonomy, and medical staff serve only as guides. Chinese culture emphasizes deference to authority, and patients tend to entrust health management to medical staff [32]. The second is the difference in the medical system. Western countries have universal basic medical care and a family doctor system that supports patients’ self-management. In China, medical resources are concentrated in large hospitals, and primary care services are weak, so it is more feasible to be led by hospital-based medical staff. The third is the difference in patients’ health literacy. Public health education is carried out early in Western countries, and patients’ health literacy is high. Chinese HF patients are mostly aged, with low education level, a lack of health knowledge, and limited self-management ability. Comfort nursing suggests that Chinese researchers pay attention to patients’ treatment experience and feelings, and emphasize the comfort of patients during the treatment. Chen reported that comfort nursing not only greatly promoted the relief of symptoms but also improved the emotional state and quality of life of patients [33]. The prominence of keywords such as “exercise tolerance” and “trial” highlights that researchers of the English literature pay more attention to patients’ exercise capacity and clinical trials. A systematic review has confirmed that exercise training can enhance exercise tolerance, shorten hospital stays, and improve the quality of life of patients [34]. In view of the above findings, the Chinese literature can learn from the experience of patient self-management in the English literature, but it needs to be localized and applied in practice according to the characteristics of culture and the medical system, and evidence-based research, such as exercise rehabilitation, should be strengthened.
Frontier analysis of quality of life in patients with CHF
Insight into and grasp of the research trends and frontiers of a discipline field are helpful in promoting the innovative development of research in this field. Based on the emergent results, keywords such as “social support,” “nursing intervention,” and “community” began to emerge around 2010 and remained prominent through 2016. During this period, researchers conducted surveys using these keywords and obtained a large number of research results. Patients with CHF require long-term treatment. Studies have shown that good social support has a positive effect on individual psychological health and is an important factor affecting the quality of life [35]. Social support can be categorized as either formal or informal. Formal social support includes the government at all levels, institutions, enterprises, communities, and other formal organizations, which mainly provide social security system support [36]. Communities are an important platform for social support, playing a key role in integrating social resources and coordinating social support. As understanding of patients’ conditions deepened, clinical experience accumulated, and medical research progressed, emergent keywords including “comprehensive Nursing,” “psychological Intervention,” and “compliance behavior” began to be taken seriously. Researchers have shifted their focus from paying attention to the intervention of one aspect of the disease in the early stage to the comprehensive management of multidimensional diseases, which means that the health management for patients has become comprehensive and systematic. The shift from a focus on physical interventions to psychological interventions also reflects a shift in the medical model from a biomedical model to a biopsychological model, with a greater emphasis on the mental health and overall well-being of patients. Since 2022, keywords such as “exercise endurance,” “Baduanjin,” “acupoint application,” “self-care ability,” and “sleep quality” have become increasingly prominent, indicating a growing recognition among healthcare workers of the importance of exercise and sleep in quality of life. This trend also highlights the integration of traditional Chinese medicine therapies and the adoption of more comprehensive, multidisciplinary intervention strategies. In the future, we should rely on community and multidimensional social support, integrate psychological interventions, exercise, sleep management, and characteristic treatments in traditional Chinese medicine, and conduct systematic and comprehensive research and practice in the health management of CHF.
Conclusions
This study systematically retrieved literature related to the quality of life in patients with CHF included in the CNKI and WOS databases and used Citespace6.4.R1 software to review the literature published from the establishment of the database to November 1, 2024. The authors, institutions, and keyword co-occurrence, clustering, and emergence were described and visualized. The study found a large difference in the number of articles published in Chinese and English, and that research had entered a period of decline after a period of rapid development. The research also found that cooperation among Chinese literature publishing institutions was weak. In terms of research hotspots, both English and Chinese literature focus on the elderly and patients with HF and chronic diseases, but the Chinese literature focuses on nursing interventions led by medical staff, whereas the English literature focuses on patient self-management. The research frontier showed an evolutionary trend from single-symptom management to multidimensional, comprehensive management. Future research should strengthen cooperation among institutions; personalize research for different patient types; explore multidisciplinary, multidimensional nursing interventions and comprehensive management research and practice, so as to improve patients’ quality of life.
Limitations
However, this study still has the following limitations: CiteSpace software was used to analyze the node type of literature, which was limited to author, author institution, and keyword analysis, and the co-citation and author contribution of the literature were not analyzed. This study included only English and Chinese literature, and the search terms did not cover all subtypes of “heart failure,” such as diastolic heart failure, or all quality-of-life-related expressions, such as “daily activities” and “self-efficacy”. Future research can use a more comprehensive search strategy for analysis.
\ No newline at end of file
diff --git a/scripts/_out.html b/scripts/_out.html
new file mode 100644
index 0000000..541d6b6
--- /dev/null
+++ b/scripts/_out.html
@@ -0,0 +1 @@
+
Visual analysis of the current status and hotspots of quality of life research in patients with chronic heart failure based on CiteSpace
Qi Zhang1#, Nan Gan1#, Pei-Pei Zou2, De-Jing Yuan3*
, Qing Wu3*
1School of Nursing, Suzhou Medical College, Soochow University, Suzhou 215006, China.
2Department of Nursing, Yangcheng Lake Street Community Health Service Center, Suzhou 215006, China.
3Department of Cardiology, First Affiliated Hospital of Soochow University, Suzhou 215006, China.
#These authors contributed equally to this work and are co-first authors for this paper.
*Correspondence to: De-Jing Yuan, Qing Wu. Department of Cardiology, The First Affiliated Hospital of Soochow University, No. 899, Pinghai Road, Gusu District, Suzhou 215006, China. E-mail: ydjyzu@126.com; qwu@suda.edu.cn.
Author contributions Zhang Q and Zou PP were responsible for the study conception and design, literature search, data retrieval from the Web of Science Core Collection, and software operation using CiteSpace. They also drafted the initial manuscript and prepared all figures and tables. Gan N participated in the data screening, extraction, and cross-checking of the included literature, assisted in the interpretation of co-occurrence and burst detection analyses, and contributed to the revision of the methodology section. Yuan DJ and Wu Q supervised the entire research process, validated the visual analysis results, provided critical revisions to the manuscript for important intellectual content, and secured funding for the project. All authors read and approved the final manuscript. Competing interests The authors declare no conflicts of interest. Acknowledgments This research was supported by Research Project of Suzhou Nursing Society in 2024 (SZHL-A-202407) and Nursing Research Project of the First Affiliated Hospital of Soochow University in 2026 (HLYJ-2026-09). We are deeply grateful to our supervisor, colleagues, and participants for their invaluable support and assistance in completing this project. Abbreviations HF, heart failure; CHD, coronary heart disease; CHF, chronic heart failure; CNKI, China National Knowledge Infrastructure; WOS, Web of Science; COVID-19, coronavirus disease 2019; NYHA, New York Heart Association; TCM, traditional Chinese medicine. Citation Zhang Q, Gan N, Zou PP, Yuan DJ, Wu Q. Visual analysis of the current status and hotspots of quality of life research in patients with chronic heart failure based on CiteSpace. Nurs Commun. 2026;10:12. doi: 10.53388/IN2026012. Peer review information Nursing Communications thanks all anonymous reviewers for their contribution to the peer review of this paper. Editorial Advisory Board: Jie Li. Production editor: Jian Jia. Received: 18 April 2026; Revised: 09 June 2026; Accepted: 15 July 2026; Available online: 16 July 2026. © 2026 By Author(s). Published by TMR Publishing Group Limited. This is an open access article under the CC-BY license. (https://creativecommons.org/licenses/by/4.0/) | Abstract Background: Heart failure poses a growing global burden with rising prevalence and poor quality of life, especially in the elderly. This study explores the research hotspots and evolution in the quality of life in patients with chronic heart failure. Methods: The CiteSpace 6.4.R1 was used to conduct a visual analysis of the literature related to the quality of life in patients with chronic heart failure published in CNKI and Web of Science Core Collection from the establishment of the databases to November 1, 2024. Results: A total of 4,743 publications were included, comprising 4,185 Chinese-language publications and 558 English-language publications. The overall number of publications showed an upward trend. The institution and author with the largest number of published documents in China were Guangzhou University of Chinese Medicine and the team led by Zhang Yan, respectively. The research hotspots mainly focused on quality of life, chronic heart failure, cardiac function, elderly patients, nursing interventions, etc. The institution and author with the largest number of published publications in English were the Berlin Institute of Health and the team led by Stefan D. Anker, respectively. The research hotspots focused on chronic heart failure, quality of life, outcome, management, exercise tolerance, etc. Conclusion: Bibliometric analysis reveals the research patterns and trends in the field of the quality of life in patients with chronic heart failure, and can provide new research perspectives for researchers. Keywords: chronic heart failure; quality of life; visualization; CiteSpace; research hotspots |
Background
Heart failure (HF) is a severe manifestation or end-stage consequence of various heart diseases, with high mortality and rehospitalization rates. The prevalence of HF in adults in developed countries is 1.0%–2.0% [1]. The prevalence of HF in China is increasing due to the aging population, the increasing incidence of chronic diseases such as coronary heart disease (CHD), hypertension, and diabetes, and the improvement of medical standards that prolong the survival of patients with cardiovascular disease. Wang reported that the agestandardized prevalence of HF among urban patients in China was 0.57% for those aged 25–64 years, 3.86% for those aged 65–79 years, and 7.55% for those aged ≥ 80 years [2]. Cardiovascular diseases remain the leading cause of death globally, accounting for approximately 32% of all deaths worldwide [3], which brings a heavy burden to society and families.
Although great progress has been made in the clinical diagnosis and treatment of HF, the quality of life in elderly patients with HF is significantly lower than that in other elderly patients with chronic diseases due to the long course of treatment, many complications, and frequent acute exacerbations [4]. Quality of life is one of the important indicators to evaluate the health outcomes of patients with HF [5]. Chinese scholars began to study the relationship between HF and quality of life in the 1990s. Studies have found that the quality of life in patients with HF outside the hospital is poor, and more than 50% of patients with HF have serious complications within 30 days of discharge, leading to a decline in quality of life [6]. There have been many reviews on the quality of life of patients with CHD, and the specific methods to improve the quality of life of patients with HF have been systematically summarized, such as drug management, exercise management, psychological intervention, remote monitoring, and so on. However, such reviews mainly rely on the induction and integration of existing interventions, making it difficult to systematically identify research hotspots, thematic evolution rules, cooperation networks, and frontier trends in this field.
CiteSpace (6.4.R1) is a data analysis tool for bibliometric analysis and visualization, widely used to summarize hotspots and trends across various research directions in the medical field. However, there are no reports on the quality of life in HF. Thus, this study visually analyzed literature in the field of quality of life in chronic heart failure (CHF) in China National Knowledge Infrastructure (CNKI) and Web of Science (core collection) databases, aiming to explore the research status, hotspots, and development trends in this field so as to provide a basis for formulating targeted interventions, prevent adverse events and improve the prognosis of patients with HF, and finally reduce the social and economic burden.
Methods
Data collection and search strategy
We searched the China National Knowledge Infrastructure (CNKI) AND Web of Science (WOS) Core Collection database by computer. The Chinese search format was (chronic heart failure) AND (quality of life), and the language was Chinese; and the English search formula was: TI=chronic heart failure, TS= “quality of life” OR “life quality”, and the language was English. The search time limit was from the establishment of the database to November 1, 2024. Two researchers independently searched and screened the literature. The inclusion criteria were: 1) published literature related to the quality of life of patients with CHF; 2) the source of literature was journal articles or dissertations. The exclusion criteria were as follows: 1) conference papers, newspapers, and other non-academic reports, and reports of other disciplines that were obviously inconsistent with the content of this study; 2) literature with incomplete information, repeated publication of the same research content, and obvious errors. According to the inclusion and exclusion criteria of the literature, 4,743 pieces of literature were finally included, including 4,185 pieces of Chinese literature and 558 pieces of English literature.
Analysis tool
We used CiteSpace6.4.R1 software to visually analyze the literature related to the quality of life in patients with CHF. Firstly, we imported the retrieved files into NoteExpress software for deduplication and screening. The processed data were imported into CiteSpace. Then we set the relevant parameters: the time span was from January 1996 to November 2024, and the time slice was set to 1 year. After that, we set the selection criteria to a TOPN threshold of 50, selected the Pathfinder method as the shearing method, and set the rest as default. Finally, the knowledge map of the quality of life in patients with CHF was drawn and analyzed.
Results
Analysis of publication characteristics
The results show that the focus and research on the quality of life in patients with CHF began in 1996. The number of Chinese literature published increased from 2 in 1996 to 435 in 2020, showing a gradual upward trend. The number of English-language articles published had a relatively stable change, both below 50, and the highest point was in 2020 (46) (Figure 1).
Figure 1 The number of articles published in English and Chinese on quality of life in patients with chronic heart failure from 1996 to 2024.
This figure illustrates the linear trend of the number of published articles in the field of chronic heart failure quality of life in both Chinese and English from 1996 to 2024. The blue solid line is the linear change trend of the number of publications in the CNKI database, and the yellow solid line is the linear change trend of the number of publications in the Web of Science database.
Analysis of authors
The number of authors’ publications is represented by the size of nodes; the larger the node, the more publications. The line between nodes represents the cooperative relationship between authors; the line width indicates the cooperation strength, and the color represents the cooperation time. The results of Chinese literature analysis are shown in Figure 2A, which shows that there are 201 nodes and 148 lines in the author’s research map, with a density of 0.0074. The top three authors with the highest number of publications are Zhang Yan (15 ), Wang Ying (7), and Xu Hong (6). The analysis results of English literature are shown in Figure 2B, which shows that there are 298 nodes and 343 lines in the author’s research map, with a density of 0.0078. The German scholars Anker, Stefan D ranked first in the number of publications, with 11 publications. There is closer collaboration among authors other than those from China.
Analysis of institutions
In CiteSpace software, when “Institutions” is selected as the Node Type, each node represents a research institution, while each line represents a cooperation between the two institutions, and the network density reflects the strength of cooperation between these institutions. The analysis results of Chinese literature are shown in Figure 3A. There are 166 nodes in the institutional research map, 36 lines, and the density is 0.0026. The top three institutions in the number of Chinese literature publications were Guangzhou University of Chinese Medicine (47), Shandong University of Chinese Medicine (44), and Beijing University of Chinese Medicine (37). The results of visual analysis of the publishing institutions of English literature are shown in Figure 3B. There were 236 nodes, 334 lines, and the density was 0.012. Berlin Institute of Health (17), Charite Universitatsmedizin Berlin (16), and Free University of Berlin (15) had more than 15 articles, all of which are German research institutions with very close cooperation between institutions.
Analysis of keywords
Co-occurrence analysis of keywords. The frequency of keywords reflects the hot spots in the research field. In the graph, the more times the keywords appear, the larger the font and node size. To ensure the accuracy of the analysis, we normalized the keywords by incorporating synonyms, acronyms, as well as single or plural forms, and removed meaningless and irrelevant keywords. On this basis, we conducted a keyword co-occurrence analysis and extracted the top 10 keywords with the highest frequency in the co-occurrence analysis of Chinese and English literature, as shown in Table 1. The keyword co-occurrence map of Chinese literature is shown in Figure 4A. The keywords with large size in Figure 4A were “quality of life,” “chronic heart failure,” “cardiac function,” “elderly patients,” and “nursing intervention”. The keyword co-occurrence map of English literature is shown in Figure 4B. The keywords with large size in Figure 4B were “chronic heart failure,” “quality of life,” “outcome,” “management,” and “exercise tolerance”.
Cluster analysis of keywords. Cluster analysis of keywords can effectively grasp the research hotspots in this field and improve the accuracy of summarizing the research field. The research results of Chinese literature are shown in Figure 5A. The cluster module value (Q) is 0.8664, and the average silhouette value (S) is 0.9767. Q > 0.3, S > 0.5, indicating that the clustering effect of this study was significant and reliable. The top 8 clusters of Chinese literature were #0 heart failure, #1 rehabilitation exercise, #2 depression, #3 clinical observation, #4 community, #5 efficacy, #6 health education, and #7 clinical research. The keyword cluster analysis of English literature is shown in Figure 5B. The cluster module value (Q) is 0.7341, and the average contour value (S) is 0.8907. The top 8 clusters of English literature were #0 left ventricular function, #1 education program, #2 support education, #3 placebo-controlled double-blind study, #4 low-volume high-intensity interval training, #5 vagal neuromodulation, #6 resistance training, #7 adaptive servo-ventilation therapy.
Timeline analysis of keywords. We used the results of keyword clustering to make a keyword timeline map. In this map, the horizontal thick line segment indicates the distribution of each cluster along the time axis, and a longer line segment means that the cluster spans a wider time range. The map formed a total of the first 10 clusters numbered #0 to #9, where the smaller the number of clusters contained , the greater the number of literature. In the cluster analysis of keywords in Chinese literature, the top three clusters with timelines extending to the past two years were heart failure, rehabilitation exercise, and depression. In the cluster analysis of keywords in English literature, the top three clusters with timelines extending to the last 2 years were left ventricular function, support education, and low-volume high-intensity interval training. The keyword clustering timelines in the field of quality of life of patients with CHF in Chinese and English literature are shown in Figures 6A and 6B.
Figure 2 Author co-occurrence maps of Chinese- and English-language publications.
(A) Author co-occurrence map of Chinese-language publications. (B) Author co-occurrence map of English-language publications. Each circular node represents an author, and the node size is proportional to the number of publications. The colored rings indicate the publication period, ranging from cool colors for earlier years to warm colors for more recent years. The links between nodes represent collaborative relationships between authors. Link width indicates the strength of collaboration, while link color indicates the time of collaboration.
Figure 3 Co-occurrence map of Chinese- and English-language literature institutions.
(A) Co-occurrence map of Chinese literature institutions. (B) Co-occurrence map of English literature institutions. Each circular node represents an institution; the size of the node is proportional to the published articles, and the colored ring of the node represents the published time, ranging from cool (early) to warm (recent). Each line between nodes represents a cooperation between two institutions.
Figure 4 Co-occurrence map of keywords in Chinese- and English-language literature.
(A) Co-occurrence map of keywords in Chinese literature. (B) Co-occurrence map of keywords in English literature. Each circular node represents a co-occurring keyword, and the size of the node is proportional to the number of keyword appearances. The colored ring of each node represents the publication year, ranging from cold (early) to warm (recent). The lines between nodes represent two keywords that appear in the same article.
Table 1 High-frequency keywords and centrality
No. | CNKI | WOS |
Frequency (times) | Centrality | Keywords | Frequency (times) | Centrality | Keywords |
1 | 1838 | 0.38 | quality of life | 388 | 0.20 | chronic heart failure |
2 | 911 | 0.62 | chronic heart failure | 309 | 0.08 | quality of life |
3 | 815 | 0.20 | cardiac function | 165 | 0.20 | outcome |
4 | 280 | 0.17 | elderly patients | 129 | 0.10 | management |
5 | 203 | 0.10 | nursing intervention | 108 | 0.16 | exercise tolerance |
6 | 131 | 0.10 | coronary heart disease | 104 | 0.09 | trial |
7 | 101 | 0.07 | prognosis | 69 | 0.10 | association |
8 | 87 | 0.14 | clinical efficacy | 52 | 0.08 | depression |
9 | 84 | 0.03 | depression | 48 | 0.12 | disease |
10 | 75 | 0.05 | comfort care | 47 | 0.09 | elderly patients |
CNKI, China National Knowledge Infrastructure; WOS, Web of Science.
Figure 5 Clustering map of keywords in Chinese- and English-language literature.
(A) Clustering map of keywords in Chinese literature. (B) Clustering map of keywords in English literature. Each circular node represents a keyword. Shapes in different colors represent different clusters, and colors indicate publication year, ranging from cold (early) to warm (recent). Cluster numbers indicate how often keywords appear in the literature, with smaller numbers indicating higher frequencies. In order to grasp the research hotspots in this field and improve the accuracy of summary research field.
Figure 6 Clustering time map of keywords in Chinese- and English-language literature.
(A) Clustering time map of keywords in Chinese literature. (B) Clustering time map of keywords in English literature. Thick horizontal segments indicate the distribution of each cluster along the time axis; longer segments mean that the cluster spans a wider time range, and line colors indicate publication years, ranging from cold (early) to warm (recent). Each circular node on the line segment represents a keyword, and the keywords in the same cluster are arranged on the same horizontal line in chronological order. The arc starting from the node represents the span of time and intuitively presents the emergence, persistence, and extinction process of keywords in this cluster.
Emergence analysis of keywords. Based on the knowledge graph of keywords, we further analyzed the emergence of keywords, that is, the change in the frequency of keywords in a specific time period, reflecting the research frontier and development trend in this field. The 20 most emergent ones are shown in Figures 7A and 7B. The emergent words in the field of quality of life in patients with CHF in Chinese literature included “congestive,” “chronic heart failure,” “social support,” “nursing intervention,” “community,” etc. The keyword with the longest duration was “congestive” (2004–2014), and the keyword with the highest emergence intensity was “chronic heart failure” (27.42), followed by nursing intervention (17.69) at present. Keywords such as “cardiac rehabilitation,” “dapagliflozin,” and “compliance behavior” showed a strong emerging trend from around 2020, and are expected to continue to exert an influence on research in this field in the future. We also analyzed the evolution of emergent words in English literature. In the early stage, the main focus was “left ventricular dysfunction,” “congestive heart failure,” and “exercise tolerance”. In recent years, the research content has been enriched, such as “reduced ejection fraction,” “cardiac function,” and “city cardiomyopathy questionnaire”. The analysis of the 20 keywords with the strongest emergence in the English literature can be summarized as the following characteristics: 1) The subjects of the study were mainly elderly patients and european society; 2) The study instrument was the city cardiomyopathy questionnaire; 3) study types were double blind and questionnaire; 4) The research contents involved left ventricular dysfunction, exercise tolerance, cardiac rehabilitation, etc. 5) social support is a positive nursing intervention.
Figure 7 Emergence map of keywords in Chinese- and English-language literature.
(A) Emergence map of keywords in Chinese literature. (B) Emergence map of keywords in English literature. The green line represents the time period from 1996 to 2024, and the red line represents the time span of the keyword burst. It reflects the research frontier and development trend in this field.
Discussion
Analysis of research status of quality of life in patients with CHF
The concept of “quality of life” was first introduced by American economist J.K. Galbraith in 1958. He noted that people’s quality of life is the degree of satisfaction that is derived from both material and spiritual dimensions [7]. The World Health Organization’s Quality of Life Study Group defines quality of life as the subjective experience of individuals in different cultures and value systems with respect to their goals, expectations, standards, and concerns about living conditions [8]. Health-related quality of life is a complex, multidimensional construct that reflects the relationship between an individual’s quality of life and their health or disease status [9].
Analysis of the number of publications. From the analysis of publication data, it is evident that the number of publications in English remains relatively low, with an annual total of less than 50. The overall trend has been generally stable. The number of publications in China shows an upward trend, and the whole process can be divided into three stages. The first stage was from 1996 to 2003, during which a total of 19 pieces of literature were published. This period represents the enlightenment in exploring the quality of life for patients with CHF. Although research production during this time was somewhat fragmented, it still established a foundational basis for subsequent investigations in this field. The second stage was from 2004 to 2020 and was characterized as a period of rapid development in research concerning quality of life in patients with CHF. The number of published studies increased year by year. Notably, there was a significant surge in publications from 2016 to 2020, reaching a peak in 2020 with 435 pieces of literature published. At the same time, English publications also reached their peak at that time with 46 pieces of literature. This increase likely reflects heightened attention and interest, which we speculate may be related to the requirement of the “Healthy China 2030 Plan” to reduce premature mortality caused by chronic diseases and effectively control the burden of chronic diseases [10, 11]. From 2021 to the present, it is the third stage of research development on the quality of life in patients with CHF. The number of publications on the quality of life in patients with CHF worldwide shows a downward trend year by year. This trend may be related to the following factors: the global outbreak of COVID-19 and, after years of development in this field, basic research becoming saturated, shrinking the space for innovation. In addition, research hotspots have gradually differentiated into more subdivided sub-directions such as digital health and palliative care, and some literature no longer uses “quality of life” as the core keyword.
Lack of cooperation between institutions. There is relatively little cooperation among Chinese authors, whereas English-language authors maintain a relatively close cooperative relationship. An analysis of Chinese publishing institutions reveals that Guangzhou University of Traditional Chinese Medicine has the highest publication output. While cooperation within and among affiliated institutions is frequent, each research institution carries out research projects in its own region and has little cooperation with outside institutions. This phenomenon is consistent with the “principle of minimum effort,” which states that people tend to solve problems with minimal input [12]. However, to pursue the principle of saving time and effort, cooperation only within the region will lead to the unbalanced development of each region. In view of the current situation in China, communication and cooperation between scientific research institutions and scientific research teams should be strengthened to promote the comprehensive development of the research field on the quality of life in patients with CHF. The top three English publications are all from Berlin research institutions, and cooperation among institutions is very close.
Research hotspots of quality of life in patients with CHF
Explore the influencing factors of quality of life and provide support for unmet needs. The co-occurrence analysis of our keywords revealed “prognosis,” “clinical efficacy,” and “outcome” as prominent terms, indicating that the research primarily emphasized treatment effects and prognostic outcomes in patients with CHF. The keywords “elderly,” “coronary heart disease,” and “depression” indicate that advanced age, complicated chronic diseases, and negative emotions have become research hotspots regarding the quality of life in patients with CHF. Cardiac function serves as a standard metric for assessing therapeutic efficacy and prognosis in patients with CHF [13], and a study found that NYHA classification is an independent factor affecting the quality of life in patients with CHF [14]. The higher the NYHA classification of patients, the worse the prognosis of the disease and the lower the quality of life score; therefore, researchers pay more attention to the prognosis and treatment effect of the disease. Elderly patients are the main focus group, and Kim found that age is an independent factor affecting the quality of life in patients with CHF [15]. With the increase of age, the cardiovascular structure and function of patients are degraded [16], and the quality of life is gradually reduced. With the aggravation of aging in China [17], it is urgent to improve the quality of life of elderly patients with HF. HF is rarely isolated, and more than 80% of patients have two or more chronic diseases [18]. The course of coronary heart disease combined with chronic heart failure is protracted and challenging to manage; compounded by patients’ poor health awareness and improper behavior, diseases always flare up and worsen, and finally reduce the quality of life of patients [19]. Therefore, in the process of treatment and care, healthcare providers should pay attention to patients with HF and multiple chronic diseases. In addition, researchers have begun to pay attention to the patients’ negative emotions. Due to the prolonged and recurrent nature of the disease, patients with CHF are susceptible to anxiety, depression, and other negative emotions [20]. The level of depression in patients with CHF is strongly correlated with their quality of life [21], while anxiety, depression, and similar negative emotions exert a substantial adverse effect on it [22]. In summary, within the domain of quality of life in patients with CHF, it is of positive clinical significance to study how to improve the clinical efficacy of patients and provide personalized support to elderly patients with other chronic diseases to help them relieve negative emotions and improve their quality of life.
Implement effective intervention measures to improve the quality of life of patients. Among the co-occurrence results, “nursing stem,” “comfort care,” “management,” and “exercise” highlighted a focus on various interventions and management measures. The emergent results showed that the intensity of nursing intervention was 17.69, ranking second only to CHF itself (27.42). Traditional Chinese Medicine (TCM) interventions, including Baduanjin exercises and acupoint application, have maintained their prominence since 2022 and continue to exert a significant influence in research on the quality of life in patients with CHF. Patients with chronic heart failure have low self-care ability and low medication compliance after discharge, which leads to the recurrence of their condition [23]. A systematic review shows that nursing interventions can effectively improve the self-care ability of patients with chronic heart failure. [24]. Currently, intervention research on the quality of life of patients with CHF is still in the exploratory stage, mainly including continuous nursing, exercise or TCM, and various targeted interventions based on theories and Internet technology development. Studies have found that these interventions can not only improve the quality of life of patients but also significantly improve patient compliance, cardiac function, and exercise endurance [25–29]. Most existing studies use a single measure to intervene in patients and test whether it can improve their quality of life and other outcome indicators, while some investigations have begun integrating new information technologies, such as the “Internet Plus” initiative and WeChat platforms, into intervention strategies. In the future, healthcare providers should be committed to the development of high-quality interventions, the combination of multiple interventions, and the promotion of positive and effective interventions in clinical practice to improve the quality of life in patients with CHF and promote their rehabilitation.
Analysis of the differences in research hotspots of quality of life in patients with CHF between Chinese and English literatures
Analysis of the keywords related to research on the quality of life in patients with CHF reveals that current studies primarily focused on elderly patients, negative emotions, comorbidities, disease treatment effects, and prognosis. In terms of intervention and management, research in China has focused on intervention measures led by medical staff. For instance, a randomized controlled study found that the implementation of nursing interventions helped reduce patients’ anxiety and depression [30], and improve their quality of life. In contrast, studies in English have focused more on patients’ self-management abilities. For example, Abbasi [31] used a variety of methods and self-management education programs based on media to improve the quality of life in patients with CHF. There are three reasons for this. The first is the cultural difference. Western countries emphasize personal responsibility and autonomy, and medical staff serve only as guides. Chinese culture emphasizes deference to authority, and patients tend to entrust health management to medical staff [32]. The second is the difference in the medical system. Western countries have universal basic medical care and a family doctor system that supports patients’ self-management. In China, medical resources are concentrated in large hospitals, and primary care services are weak, so it is more feasible to be led by hospital-based medical staff. The third is the difference in patients’ health literacy. Public health education is carried out early in Western countries, and patients’ health literacy is high. Chinese HF patients are mostly aged, with low education level, a lack of health knowledge, and limited self-management ability. Comfort nursing suggests that Chinese researchers pay attention to patients’ treatment experience and feelings, and emphasize the comfort of patients during the treatment. Chen reported that comfort nursing not only greatly promoted the relief of symptoms but also improved the emotional state and quality of life of patients [33]. The prominence of keywords such as “exercise tolerance” and “trial” highlights that researchers of the English literature pay more attention to patients’ exercise capacity and clinical trials. A systematic review has confirmed that exercise training can enhance exercise tolerance, shorten hospital stays, and improve the quality of life of patients [34]. In view of the above findings, the Chinese literature can learn from the experience of patient self-management in the English literature, but it needs to be localized and applied in practice according to the characteristics of culture and the medical system, and evidence-based research, such as exercise rehabilitation, should be strengthened.
Frontier analysis of quality of life in patients with CHF
Insight into and grasp of the research trends and frontiers of a discipline field are helpful in promoting the innovative development of research in this field. Based on the emergent results, keywords such as “social support,” “nursing intervention,” and “community” began to emerge around 2010 and remained prominent through 2016. During this period, researchers conducted surveys using these keywords and obtained a large number of research results. Patients with CHF require long-term treatment. Studies have shown that good social support has a positive effect on individual psychological health and is an important factor affecting the quality of life [35]. Social support can be categorized as either formal or informal. Formal social support includes the government at all levels, institutions, enterprises, communities, and other formal organizations, which mainly provide social security system support [36]. Communities are an important platform for social support, playing a key role in integrating social resources and coordinating social support. As understanding of patients’ conditions deepened, clinical experience accumulated, and medical research progressed, emergent keywords including “comprehensive Nursing,” “psychological Intervention,” and “compliance behavior” began to be taken seriously. Researchers have shifted their focus from paying attention to the intervention of one aspect of the disease in the early stage to the comprehensive management of multidimensional diseases, which means that the health management for patients has become comprehensive and systematic. The shift from a focus on physical interventions to psychological interventions also reflects a shift in the medical model from a biomedical model to a biopsychological model, with a greater emphasis on the mental health and overall well-being of patients. Since 2022, keywords such as “exercise endurance,” “Baduanjin,” “acupoint application,” “self-care ability,” and “sleep quality” have become increasingly prominent, indicating a growing recognition among healthcare workers of the importance of exercise and sleep in quality of life. This trend also highlights the integration of traditional Chinese medicine therapies and the adoption of more comprehensive, multidisciplinary intervention strategies. In the future, we should rely on community and multidimensional social support, integrate psychological interventions, exercise, sleep management, and characteristic treatments in traditional Chinese medicine, and conduct systematic and comprehensive research and practice in the health management of CHF.
Conclusions
This study systematically retrieved literature related to the quality of life in patients with CHF included in the CNKI and WOS databases and used Citespace6.4.R1 software to review the literature published from the establishment of the database to November 1, 2024. The authors, institutions, and keyword co-occurrence, clustering, and emergence were described and visualized. The study found a large difference in the number of articles published in Chinese and English, and that research had entered a period of decline after a period of rapid development. The research also found that cooperation among Chinese literature publishing institutions was weak. In terms of research hotspots, both English and Chinese literature focus on the elderly and patients with HF and chronic diseases, but the Chinese literature focuses on nursing interventions led by medical staff, whereas the English literature focuses on patient self-management. The research frontier showed an evolutionary trend from single-symptom management to multidimensional, comprehensive management. Future research should strengthen cooperation among institutions; personalize research for different patient types; explore multidisciplinary, multidimensional nursing interventions and comprehensive management research and practice, so as to improve patients’ quality of life.
Limitations
However, this study still has the following limitations: CiteSpace software was used to analyze the node type of literature, which was limited to author, author institution, and keyword analysis, and the co-citation and author contribution of the literature were not analyzed. This study included only English and Chinese literature, and the search terms did not cover all subtypes of “heart failure,” such as diastolic heart failure, or all quality-of-life-related expressions, such as “daily activities” and “self-efficacy”. Future research can use a more comprehensive search strategy for analysis.
\ No newline at end of file
diff --git a/scripts/alias-hooks.mjs b/scripts/alias-hooks.mjs
new file mode 100644
index 0000000..223f2a7
--- /dev/null
+++ b/scripts/alias-hooks.mjs
@@ -0,0 +1,15 @@
+import path from 'path';
+import fs from 'fs';
+import { pathToFileURL } from 'url';
+
+export async function resolve(specifier, context, nextResolve) {
+ if (specifier.startsWith('@/')) {
+ let abs = path.join(process.cwd(), 'src', specifier.slice(2));
+ if (!fs.existsSync(abs) && !path.extname(abs)) {
+ if (fs.existsSync(abs + '.js')) abs += '.js';
+ else if (fs.existsSync(path.join(abs, 'index.js'))) abs = path.join(abs, 'index.js');
+ }
+ return { shortCircuit: true, url: pathToFileURL(abs).href };
+ }
+ return nextResolve(specifier, context);
+}
diff --git a/scripts/alias-loader.mjs b/scripts/alias-loader.mjs
new file mode 100644
index 0000000..11f7f54
--- /dev/null
+++ b/scripts/alias-loader.mjs
@@ -0,0 +1,19 @@
+import path from 'path';
+import fs from 'fs';
+import { pathToFileURL } from 'url';
+
+export async function resolve(specifier, context, nextResolve) {
+ if (specifier.startsWith('@/')) {
+ let rel = specifier.slice(2);
+ let abs = path.join(process.cwd(), 'src', rel);
+ if (!fs.existsSync(abs) && !path.extname(abs)) {
+ if (fs.existsSync(abs + '.js')) abs = abs + '.js';
+ else if (fs.existsSync(path.join(abs, 'index.js'))) abs = path.join(abs, 'index.js');
+ }
+ return {
+ shortCircuit: true,
+ url: pathToFileURL(abs).href
+ };
+ }
+ return nextResolve(specifier, context);
+}
diff --git a/scripts/alias-register.mjs b/scripts/alias-register.mjs
new file mode 100644
index 0000000..b890be3
--- /dev/null
+++ b/scripts/alias-register.mjs
@@ -0,0 +1,5 @@
+import { register } from 'node:module';
+import { pathToFileURL } from 'url';
+import path from 'path';
+
+register(pathToFileURL(path.join(process.cwd(), 'scripts/alias-hooks.mjs')).href);
diff --git a/scripts/inspect-word-fig-pairing.mjs b/scripts/inspect-word-fig-pairing.mjs
new file mode 100644
index 0000000..7b8ae87
--- /dev/null
+++ b/scripts/inspect-word-fig-pairing.mjs
@@ -0,0 +1,45 @@
+import FS from 'fs';
+import path from 'path';
+import JSZip from 'jszip';
+
+const file = path.join(
+ 'C:/Users/Administrator/Desktop/IN2026A0418001_final_20260713 1.docx'
+);
+const xml = await (await JSZip.loadAsync(FS.readFileSync(file))).file('word/document.xml').async('string');
+const paras = xml.split(/<\/w:p>/);
+
+function plainOf(p) {
+ return [...p.matchAll(/]*)?>([\s\S]*?)<\/w:t>/g)]
+ .map((x) => x[1])
+ .join('')
+ .replace(/&/g, '&')
+ .replace(/\s+/g, ' ')
+ .trim();
+}
+
+function blipCount(p) {
+ return (p.match(/a:blip/g) || []).length;
+}
+
+function drawingCount(p) {
+ return (p.match(/ b[1] - a[1])
+ .slice(0, 20)
+);
+
+// Extract paragraphs containing "Figure" with nearby text
+const paras = xml.split(/<\/w:p>/);
+let figParaCount = 0;
+for (let i = 0; i < paras.length; i++) {
+ const p = paras[i];
+ const texts = [...p.matchAll(/]*)?>([\s\S]*?)<\/w:t>/g)].map((x) => x[1]);
+ const plain = texts.join('').replace(/&/g, '&').trim();
+ if (!/^Figure\s+\d+/i.test(plain) && !/^Fig\.?\s*\d+/i.test(plain)) continue;
+ figParaCount += 1;
+ const hasDrawing = / x[1]);
+ // next non-empty para
+ let nextPlain = '';
+ for (let j = i + 1; j < Math.min(i + 5, paras.length); j++) {
+ const nt = [...paras[j].matchAll(/]*)?>([\s\S]*?)<\/w:t>/g)]
+ .map((x) => x[1])
+ .join('')
+ .replace(/&/g, '&')
+ .trim();
+ if (nt) {
+ nextPlain = nt.slice(0, 220);
+ break;
+ }
+ }
+ // prev: look back for drawing-only paragraphs
+ let prevHasDrawing = false;
+ for (let j = i - 1; j >= Math.max(0, i - 6); j--) {
+ if (/]*)?>([\s\S]*?)<\/w:t>/g)]
+ .map((x) => x[1])
+ .join('')
+ .trim();
+ if (pt && !/^[AB]$/.test(pt)) break;
+ }
+ console.log('---');
+ console.log('caption:', plain.slice(0, 160));
+ console.log('colors:', [...new Set(colorVals)]);
+ console.log('sameParaDrawing:', hasDrawing, 'prevHasDrawing:', prevHasDrawing);
+ console.log('next:', nextPlain);
+}
+console.log('figParaCount', figParaCount);
+
+// Check standalone A/B label paragraphs near figures
+let abCount = 0;
+for (const p of paras) {
+ const plain = [...p.matchAll(/]*)?>([\s\S]*?)<\/w:t>/g)]
+ .map((x) => x[1])
+ .join('')
+ .trim();
+ if (/^[AB]$/.test(plain)) abCount += 1;
+}
+console.log('standalone A/B paras', abCount);
diff --git a/scripts/test-extract-figures.mjs b/scripts/test-extract-figures.mjs
new file mode 100644
index 0000000..93969cd
--- /dev/null
+++ b/scripts/test-extract-figures.mjs
@@ -0,0 +1,29 @@
+import FS from 'fs';
+import path from 'path';
+import { JSDOM } from 'jsdom';
+
+const { window } = new JSDOM('');
+global.window = window;
+global.document = window.document;
+global.DOMParser = window.DOMParser;
+global.Node = window.Node;
+global.HTMLElement = window.HTMLElement;
+global.FileReader = window.FileReader;
+global.Blob = window.Blob;
+
+const { parseWordFigures } = await import('../src/utils/wordFigureImport.js');
+
+const filePath = path.join(
+ 'C:/Users/Administrator/Desktop/IN2026A0418001_final_20260713 1.docx'
+);
+const buf = FS.readFileSync(filePath);
+const result = await parseWordFigures(buf);
+console.log('parsedCount', result.parsedCount);
+result.figures.forEach((f, idx) => {
+ console.log('----', idx + 1);
+ console.log('num', f.figureNumber);
+ console.log('title', f.title.slice(0, 130));
+ console.log('note', (f.note || '').slice(0, 150));
+ console.log('imgs', f.imageCount);
+ console.log('red', /data-word-caption-color="red"|#d25a5a/i.test(f.titleHtml || ''));
+});
diff --git a/scripts/test-fig-match.mjs b/scripts/test-fig-match.mjs
new file mode 100644
index 0000000..8e015c4
--- /dev/null
+++ b/scripts/test-fig-match.mjs
@@ -0,0 +1,35 @@
+import {
+ extractFigureNumbersFromText,
+ paragraphMentionsFigureNumber,
+ parseFigureNumberFromTitle,
+ findFirstAmIdForFigureNumber
+} from '../src/utils/manuscriptMediaReferences.js';
+
+const samples = [
+ 'Figure 3A and Figure 3B.',
+ 'as shown in Figure 3A and Figure 3B.',
+ 'See Fig. 3 and Fig. 3A',
+ 'as shown in Figure 3A and Figure 3B.'
+];
+for (const s of samples) {
+ console.log(JSON.stringify(s), '=>', extractFigureNumbersFromText(s), 'mentions3', paragraphMentionsFigureNumber(s, 3));
+}
+console.log(
+ 'title',
+ parseFigureNumberFromTitle('Figure 3 Co-occurrence map')
+);
+console.log(
+ 'find',
+ findFirstAmIdForFigureNumber(
+ [
+ { am_id: 1, type: 0, content: 'hello' },
+ {
+ am_id: 146120,
+ type: 0,
+ content: 'as shown in Figure 3A and Figure 3B.'
+ },
+ { am_id: 3, type: 1, content: '', ami_id: 99 }
+ ],
+ 3
+ )
+);
diff --git a/src/api/index.js b/src/api/index.js
index 525753d..487fb66 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -19,8 +19,8 @@ const service = axios.create({
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
- // baseURL: '/api', //本地
- baseURL: '/', //正式
+ baseURL: '/api', //本地
+ // baseURL: '/', //正式
});
diff --git a/src/common/js/commonJS.js b/src/common/js/commonJS.js
index b4c01ba..36c93a9 100644
--- a/src/common/js/commonJS.js
+++ b/src/common/js/commonJS.js
@@ -6,7 +6,7 @@ import mammoth from "mammoth";
import { MathfieldElement } from 'mathlive';
import 'mathlive/dist/mathlive-static.css';
import 'mathlive/dist/mathlive-fonts.css';
-import { importWordDocumentWithMath as parseWordDocumentWithMath, parseHtmlToLatex as convertHtmlToLatex, postProcessImportedWordHtml, parseImportedHtmlToContentRows, mergeAdjacentBlueTags, normalizeSpacesAroundBlueTags } from '@/utils/wordMathImport';
+import { importWordDocumentWithMath as parseWordDocumentWithMath, parseHtmlToLatex as convertHtmlToLatex, postProcessImportedWordHtml, parseImportedHtmlToContentRows, mergeAdjacentBlueTags, normalizeSpacesAroundBlueTags, extractBodyOutlineHeadings, detectBodyHeadingLevelFromHtml } from '@/utils/wordMathImport';
import { wrapReferenceHighlightsInBlueHtml } from '@/utils/manuscriptMediaReferences';
import api from '../../api/index.js';
import Common from '@/components/common/common'
@@ -1489,7 +1489,7 @@ export default {
// 使用正则表达式删除属性(保留 data-latex)
let updatedAttributes = attributes.replace(/\s([a-zA-Z0-9-]+)(="[^"]*")?/g, function (attrMatch, attrName) {
- if (attrName === "data-latex" || attrName === "data-id" || attrName === "data-wrap") {
+ if (attrName === "data-latex" || attrName === "data-id" || attrName === "data-wrap" || attrName === "data-word-align" || attrName === "data-word-heading") {
return attrMatch;
}
if (type == 'table' && tag == 'img' && (attrName === "src" || attrName === "width" || attrName === "height")) {
@@ -1515,9 +1515,7 @@ export default {
inputHtml = inputHtml.replace(/]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
inputHtml = inputHtml.replace(//g, '').replace(/<\/strong>/g, ''); // 将 `strong` 替换成 `b`
inputHtml = inputHtml.replace(//g, '').replace(/<\/em>/g, ''); // 将 `em` 替换成 `i`
- // 4. 合并相同标签
- inputHtml = inputHtml.replace(/(.*?)<\/b>\s*/g, '$1'); // 合并连续的 标签
- inputHtml = inputHtml.replace(/(.*?)<\/i>\s*/g, '$1'); // 合并连续的 标签
+ // 不再合并连续 /:否则会把多个独立标题拼成一行
return inputHtml;
@@ -1534,6 +1532,7 @@ export default {
cleanAndParseWordContent(content) {
const rows = parseImportedHtmlToContentRows(content);
const parsedData = [];
+ const outline = [];
rows.forEach((raw) => {
const rawStr = String(raw || '');
@@ -1546,6 +1545,14 @@ export default {
return;
}
+ // 标题检测须在剥 style/span 之前(红色信息在 span 上)
+ const headingLevel = detectBodyHeadingLevelFromHtml(rawStr);
+ const headingText = String(rawStr || '')
+ .replace(/<[^>]+>/g, '')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+
let text = replaceNegativeSign(rawStr.trim());
text = this.transformHtmlString(text);
text = text.replace(/<\/?o:p[^>]*>/g, '');
@@ -1559,9 +1566,18 @@ export default {
text = mergeAdjacentBlueTags(text);
text = normalizeSpacesAroundBlueTags(text);
text = wrapReferenceHighlightsInBlueHtml(text);
- parsedData.push(text.trim() === '' ? '' : text);
+ const finalText = text.trim() === '' ? '' : text;
+ if (finalText && (headingLevel === 1 || headingLevel === 2) && headingText) {
+ outline.push({
+ level: headingLevel,
+ text: headingText,
+ rowIndex: parsedData.length
+ });
+ }
+ parsedData.push(finalText);
});
+ parsedData.outline = outline;
return parsedData;
},
@@ -2858,6 +2874,15 @@ export default {
setTimeout(() => {
window.renderMathJax(ed.id);
}, 10);
+ try {
+ const outline = extractBodyOutlineHeadings(html);
+ vueInstance.$emit('importedWordOutline', outline);
+ if (typeof vueInstance.handleImportedWordOutline === 'function') {
+ vueInstance.handleImportedWordOutline(outline);
+ }
+ } catch (outlineErr) {
+ console.warn('extractBodyOutlineHeadings failed', outlineErr);
+ }
if (vueInstance.$message) {
vueInstance.$message.success(
vueInstance.$t ? vueInstance.$t('commonTable.importWordMathSuccess') : 'Word imported'
diff --git a/src/components/common/Sidebar.vue b/src/components/common/Sidebar.vue
index d5082e9..8687888 100644
--- a/src/components/common/Sidebar.vue
+++ b/src/components/common/Sidebar.vue
@@ -543,6 +543,10 @@ export default {
{
index: 'Journal_Agreement',
title: this.$t('sidebar.userManSys11')
+ },
+ {
+ index: 'SpecialList',
+ title: this.$t('sidebar.specialList')
}
]
}
diff --git a/src/components/common/common.vue b/src/components/common/common.vue
index 9bac70a..e0f6d02 100644
--- a/src/components/common/common.vue
+++ b/src/components/common/common.vue
@@ -1,15 +1,17 @@
diff --git a/src/components/common/langs/en.js b/src/components/common/langs/en.js
index dcbc657..e390a86 100644
--- a/src/components/common/langs/en.js
+++ b/src/components/common/langs/en.js
@@ -182,6 +182,93 @@ const en = {
totalCites: 'Total citations',
loadFail: 'Failed to load citation analysis',
},
+ specialList: {
+ button: 'Special Issue List',
+ drawerTitle: 'Special Issue',
+ title: 'Title',
+ intro: 'Introduction',
+ abstract: 'Abstract',
+ keywords: 'Keywords',
+ status: 'Status',
+ statusPass: 'Status',
+ statusPassed: 'Passed',
+ statusRejected: 'Rejected',
+ statusPending: 'Pending',
+ statusChangeSuccess: 'Status updated successfully',
+ specialTopicPassedTip: 'Only approved special issues within the validity period are shown above',
+ deadline: 'Submission deadline:',
+ deadlinePlaceholder: 'Select submission deadline',
+ editor: 'Editor',
+ guestEditor: 'Guest Editor',
+ guestEditorYes: 'Yes',
+ guestEditorNo: 'No',
+ guestEditorPlaceholder: 'Email / Account',
+ guestEditorCheck: 'Check',
+ guestEditorNote: 'Note: The Guest Editor must be a registered user.',
+ guestEditorRegisterTip: 'Click',
+ guestEditorRegister: 'register',
+ guestEditorRemove: 'Remove',
+ guestEditorEmpty: 'Email / Account cannot be empty!',
+ guestEditorNeedCheck: 'Please click Check to verify the Guest Editor first.',
+ guestEditorNotFound: 'Verify that the account or mailbox does not exist!',
+ guestEditorNotFoundManual: 'No registered user found. Please complete the Guest Editor profile below.',
+ guestEditorManualTip: 'Unregistered user. Please complete the profile below.',
+ guestEditorNoEmail: 'This user has no email address.',
+ guestEditorExists: 'This Guest Editor has already been added.',
+ guestEditorAdded: 'Guest Editor added. Please complete profile fields.',
+ guestEditorRequired: 'Please add at least one Guest Editor.',
+ guestEditorOnlyOne: 'Only one Guest Editor can be added when creating.',
+ guestEditorAdd: 'Add Guest Editor',
+ guestEditorAddDialogTitle: 'Add Guest Editor',
+ guestEditorConfirmAdd: 'Confirm',
+ guestEditorRecheck: 'Re-check',
+ guestEditorTableEmpty: 'No guest editors',
+ guestEditorClearTitle: 'Notice',
+ guestEditorClearConfirm: 'This will clear all guest editors for this special issue. Continue?',
+ guestEditorSyncFail: 'Failed to sync Guest Editors.',
+ guestEditorCreateUserFail: 'Failed to create Guest Editor user.',
+ guestEditorUpdateUserFail: 'Failed to update Guest Editor user.',
+ submitting: 'Submitting...',
+ guestAvatarUpdated: 'Avatar updated.',
+ guestAccount: 'Account',
+ guestFirstName: 'First name',
+ guestLastName: 'Last name',
+ guestEmail: 'E-mail',
+ guestAddress: 'Address',
+ guestIntroduction: 'Introduction',
+ guestInterests: 'Interests',
+ guestWebsite: 'Website',
+ guestOrcid: 'orcid',
+ guestPhoto: 'Profile Photo',
+ guestPhotoTip: 'Upload',
+ guestName: 'Name',
+ guestColBaseInfo: 'Base Information',
+ guestColOtherInfo: 'Other Information',
+ guestRealname: 'Realname:',
+ guestDetail: 'Detail',
+ guestSource: 'Source',
+ guestSourceLocal: 'Editable',
+ guestSourceGw: 'Official',
+ guestSourceGwReadonly: 'Official guest editor (read-only)',
+ guestEditingN: 'Editing Guest Editor {n}',
+ guestEditorN: 'Guest Editor {n}',
+ guestAccountRequired: 'Please enter Account for {name}.',
+ guestFirstNameRequired: 'Please enter First name for {name}.',
+ guestLastNameRequired: 'Please enter Last name for {name}.',
+ guestEmailRequired: 'Please enter E-mail for {name}.',
+ guestEmailInvalid: 'Please enter a valid E-mail for {name}.',
+ introRequired: 'Please enter Introduction for {name}.',
+ guestAddressRequired: 'Please enter Address for {name}.',
+ icon: 'Cover Image',
+ operate: 'Action',
+ enterTitle: 'Please enter title',
+ enterIntro: 'Please enter intro',
+ enterAbstract: 'Please enter Abstract',
+ enterKeywords: 'Please enter keywords',
+ enterDeadline: 'Please select submission deadline',
+ imageSizeLimit: 'Image size cannot exceed 2M!',
+ uploadFail: 'Image upload failed'
+ },
partyRole: {
identity: 'Identity',
@@ -283,6 +370,7 @@ const en = {
userManSys8: 'Academic Integrity Committee',
userManSys9: 'Editors & Staff',
userManSys11: 'Journal Agreement',
+ specialList: 'Journal Special Issue List',
analyp: 'Manager',
datasis: 'Journal Data Statistics',
analysis: 'Journal Evaluation System',
@@ -1216,7 +1304,7 @@ const en = {
citeRelevanceDownloadHtmlSuccessWithUploaded: 'HTML downloaded (based on {n} uploaded reference(s))',
refAnnotationReportTip: 'Download annotated HTML relevance report (run AI check first)',
refAnnotationReportShort: 'Report',
- exportRelevanceWordTip: 'Export Word with citation relevance comments (requires AI audit; yellow/red items become comments)',
+ exportRelevanceWordTip: 'Export Word with citation relevance comments (score < 0.65 → author_comment; partial AI results OK)',
exportRelevanceWordShort: 'Rel. Word',
exportRelevanceWordSuccess: 'Word with relevance comments downloaded',
exportRelevanceWordFail: 'Failed to export Word with relevance comments',
@@ -1233,6 +1321,47 @@ const en = {
wordRefsPreviewNoManuscript: 'Manuscript Word file not found (gridData / getFilesForArticle)',
wordRefsPreviewEmpty: 'No References section found in the original Word manuscript',
wordRefsPreviewFail: 'Failed to load Word references',
+ wordRefStatsShort: 'Word refs',
+ wordRefStatsTitle: '1. Reference statistics overview',
+ wordRefStatsCategory: 'Category',
+ wordRefStatsResult: 'Count',
+ wordRefStatsPercent: 'Share',
+ wordRefStatsCompliance: 'Compliance',
+ wordRefStatsTotal: 'Total references',
+ wordRefStatsChinese: 'Chinese references',
+ wordRefStatsFiveYear: 'Last 5 years',
+ wordRefStatsThreeYear: 'Last 3 years',
+ wordRefStatsYearRange: '({start}-{end})',
+ wordRefStatsCountUnit: '{count}',
+ wordRefStatsPass: 'Pass',
+ wordRefStatsFail: 'Fail',
+ wordRefStatsGoal: 'target',
+ wordRefStatsChineseGoal: '(≤10%)',
+ wordRefStatsFiveYearGoal: '(≥70%)',
+ wordRefStatsThreeYearGoal: '(≥30%)',
+ wordRefStatsBaselineNote: 'Baseline year: {year} ({source})',
+ wordRefStatsBaselineToday: 'today',
+ wordRefStatsBaselineAi: 'AI review time',
+ wordRefStatsBaselineArticle: 'submission time',
+ wordRefStatsNoYearHint: '{count} reference(s) with no identifiable year (excluded from recent-year counts)',
+ wordRefStatsAiCompareTitle: 'AI assessment (for comparison)',
+ wordRefStatsAiThreeYear: 'AI · last 3 years',
+ wordRefStatsAiFiveYear: 'AI · last 5 years',
+ wordRefStatsDiffNote: 'Word stats use rule-based parsing; AI uses model assessment. Different manuscript versions, year extraction, or counting rules may cause differences.',
+ wordRefStatsIndices: 'Ref. No.',
+ wordRefStatsIndicesEmpty: 'None',
+ wordRefStatsDetailTitle: '2. Reference numbers by category',
+ wordRefStatsNoYearLabel: 'No identifiable year',
+ wordRefStatsItemDetailTitle: '3. Year by reference',
+ wordRefStatsItemIndex: 'No.',
+ wordRefStatsItemYear: 'Year',
+ wordRefStatsItemTags: 'Category',
+ wordRefStatsItemPreview: 'Preview',
+ wordRefStatsTagThreeYear: 'Last 3 yrs',
+ wordRefStatsTagFiveYear: 'Last 5 yrs',
+ wordRefStatsTagChinese: 'Chinese',
+ wordRefStatsTagNoYear: 'No year',
+ wordRefStatsTagOlder: 'Older',
wordRefBatchUploadShort: 'Upload proofread Word',
wordRefBatchUploadTip: 'Upload proofread Word references, map fields by index, and batch save',
wordRefBatchDialogTitle: 'Word references · field mapping',
@@ -1265,6 +1394,21 @@ const en = {
wordRefBatchHideExisting: 'Hide',
wordRefBatchParseFailed: 'Incomplete parsing — please fill in each field',
wordRefBatchWordOriginal: 'Word original',
+ wordRefBatchPasteShort: 'Paste formatted refs',
+ wordRefBatchPasteTip: 'Paste formatted references ([1] / 1. numbering, blank lines, HTML italics). Map fields by index and batch save.',
+ wordRefBatchPasteTitle: 'Paste references',
+ wordRefBatchPasteMappingTitle: 'Pasted references · field mapping',
+ wordRefBatchPasteOriginal: 'Pasted original',
+ wordRefBatchPasteConfirm: 'Parse & map',
+ wordRefBatchFields: 'Mapped fields',
+ wordRefBatchParseFailedCount: '{count} parse error(s)',
+ wordRefBatchParseErrorNav: 'Parse errors',
+ wordRefBatchMissingFields: 'missing {fields}',
+ zyBatchDeleteAuthors: 'Batch delete authors',
+ zyBatchDeleteAffiliations: 'Batch delete affiliations',
+ zyBatchDeleteAuthorsConfirm: 'Delete {count} author(s) and their affiliation links?',
+ zyBatchDeleteAffiliationsConfirm: 'Delete {count} affiliation(s) and their author links?',
+ zyBatchDeleteResult: 'Done: {ok} deleted, {fail} failed',
refAnnotationReportSuccess: 'Annotation report HTML downloaded',
refAnnotationReportFail: 'Failed to download annotation report',
refAnnotationReportNoArticle: 'Missing article ID — cannot load AI check data',
@@ -1368,6 +1512,23 @@ const en = {
removeProofread: 'Are you sure to delete this suggestion?',
removeContent: 'Are you sure you want to delete this content?',
removeimg: 'Are you sure you want to delete this figure?',
+ figureDeleteAll: 'Delete all',
+ figureDeleteAllConfirm: 'Delete all figures?',
+ figureDeleteAllResult: 'Deleted {ok}, failed {fail}',
+ figureAutoPositionTip: 'Jump to first in-text mention by figure number',
+ figureAutoPositionNoNum: 'Cannot parse figure number from title',
+ figureAutoPositionNoHit: 'No in-text reference to Figure {num} found',
+ figureAutoPositionDone: 'Positioned Figure {num}',
+ figureBatchPosition: 'Batch Position',
+ figureBatchPositionEmpty: 'No unpositioned figures',
+ figureBatchPositionDone: 'Batch done: {ok} positioned, {skip} not found, {fail} failed',
+ tableAutoPositionTip: 'Jump to first in-text mention by table number',
+ tableAutoPositionNoNum: 'Cannot parse table number from title',
+ tableAutoPositionNoHit: 'No in-text reference to Table {num} found',
+ tableAutoPositionDone: 'Positioned Table {num}',
+ tableBatchPosition: 'Batch Position',
+ tableBatchPositionEmpty: 'No unpositioned tables',
+ tableBatchPositionDone: 'Batch done: {ok} positioned, {skip} not found, {fail} failed',
removetable: 'Are you sure you want to delete this table?',
reContent: 'Are you sure you want to restore this content?',
uploadImageInfo: 'Figures can only upload files in JPG, JPEG, and PNG formats!',
@@ -1376,8 +1537,14 @@ const en = {
selectWord: 'Please select only a single word!',
importWordMath: 'Word',
importWordMathTip: 'Upload Word and parse math formulas',
+ importWordFiguresTip: 'Upload Word to extract figures and captions',
+ importWordFiguresLoading: 'Importing figures...',
+ importWordFiguresEmpty: 'No figures found in the Word file',
+ importWordFiguresDone: 'Found {parsed}, added {added}, skipped {skipped}, failed {fail}',
+ importWordFiguresFail: 'Failed to import figures from Word',
importWordMathLoading: 'Importing Word...',
importWordMathSuccess: 'Word imported. Formulas converted to LaTeX.',
+ importedWordOutlineTitle: 'Detected body headings (Word centered/red textbox = H1, black bold without period = H2; Peer review etc. are bold-italic back matter)',
importWordMathFail: 'Word import failed. Please check the file format.',
importWordMathNoFormula: 'No math formulas found in the Word file.',
importWordMathNoNew: 'All formulas already exist. No new rows added.',
@@ -1531,6 +1698,18 @@ const en = {
statusPending: 'Pending',
statusOther: 'Other',
viewArticleDetail: 'Click to view article details',
+ articleDetailTitle: 'Article Details',
+ author: 'Author',
+ corrAuthor: 'Corresponding Author',
+ keywords: 'Keywords',
+ abstract: 'Abstract',
+ fund: 'Funding',
+ scoring: 'AI Score',
+ repetition: 'Similarity',
+ manuscriptFile: 'Manuscript',
+ approvalFile: 'Ethics Approval',
+ repeReport: 'Similarity Report',
+ viewFile: 'View File',
notifyTitle: 'Journal Fee Approval',
notifyMessage: 'You have {count} pending price change request(s)',
notifyHint: 'Click to open the approval page',
diff --git a/src/components/common/langs/zh.js b/src/components/common/langs/zh.js
index 4d28526..0c210a9 100644
--- a/src/components/common/langs/zh.js
+++ b/src/components/common/langs/zh.js
@@ -175,6 +175,93 @@ const zh = {
totalCites: '引用总数',
loadFail: '加载期刊引用分析失败',
},
+ specialList: {
+ button: '专刊列表',
+ drawerTitle: '专刊',
+ title: '标题',
+ intro: '简介',
+ abstract: '摘要',
+ keywords: '关键词',
+ status: '状态',
+ statusPass: '是否通过',
+ statusPassed: '通过',
+ statusRejected: '拒绝',
+ statusPending: '待审核',
+ statusChangeSuccess: '更改通过状态成功',
+ specialTopicPassedTip: '以上专刊只展示已通过且有效期内的专刊',
+ deadline: '投稿截止日期:',
+ deadlinePlaceholder: '选择投稿截止日期',
+ editor: '编辑',
+ guestEditor: '客座编辑',
+ guestEditorYes: '是',
+ guestEditorNo: '否',
+ guestEditorPlaceholder: '邮箱 / 账号',
+ guestEditorCheck: '校验',
+ guestEditorNote: '说明:客座编辑必须是已注册用户。',
+ guestEditorRegisterTip: '点击',
+ guestEditorRegister: '注册',
+ guestEditorRemove: '移除',
+ guestEditorEmpty: '邮箱 / 账号不能为空!',
+ guestEditorNeedCheck: '请先点击校验(Check)确认客座编辑。',
+ guestEditorNotFound: '账号或邮箱不存在!',
+ guestEditorNotFoundManual: '未找到注册用户,请手动完善下方客座编辑资料。',
+ guestEditorManualTip: '未注册用户,请完善下方资料。',
+ guestEditorNoEmail: '该用户没有邮箱。',
+ guestEditorExists: '该客座编辑已添加。',
+ guestEditorAdded: '客座编辑已加入,请完善下方资料字段。',
+ guestEditorRequired: '请至少添加一位客座编辑。',
+ guestEditorOnlyOne: '新增专题时只能添加一位客座编辑。',
+ guestEditorAdd: '添加客座编辑',
+ guestEditorAddDialogTitle: '添加客座编辑',
+ guestEditorConfirmAdd: '确认添加',
+ guestEditorRecheck: '重新 Check',
+ guestEditorTableEmpty: '暂无客座编辑',
+ guestEditorClearTitle: '提示',
+ guestEditorClearConfirm: '将会清空该专刊的客座编辑,是否确定?',
+ guestEditorSyncFail: '同步客座编辑失败。',
+ guestEditorCreateUserFail: '创建客座编辑用户失败。',
+ guestEditorUpdateUserFail: '更新客座编辑用户失败。',
+ submitting: '提交中...',
+ guestAvatarUpdated: '头像已更新。',
+ guestAccount: 'Account',
+ guestFirstName: 'First name',
+ guestLastName: 'Last name',
+ guestEmail: 'E-mail',
+ guestAddress: 'Address',
+ guestIntroduction: 'Introduction',
+ guestInterests: 'Interests',
+ guestWebsite: 'Website',
+ guestOrcid: 'orcid',
+ guestPhoto: 'Profile Photo',
+ guestPhotoTip: 'Upload',
+ guestName: '姓名',
+ guestColBaseInfo: '基本信息',
+ guestColOtherInfo: '其他信息',
+ guestRealname: 'Realname:',
+ guestDetail: 'Detail',
+ guestSource: '来源',
+ guestSourceLocal: '可编辑',
+ guestSourceGw: '官网',
+ guestSourceGwReadonly: '官网客座编辑(只读)',
+ guestEditingN: '正在编辑第 {n} 位客座编辑',
+ guestEditorN: '第 {n} 位客座编辑',
+ guestAccountRequired: '请填写 {name} 的 Account。',
+ guestFirstNameRequired: '请填写 {name} 的 First name。',
+ guestLastNameRequired: '请填写 {name} 的 Last name。',
+ guestEmailRequired: '请填写 {name} 的 E-mail。',
+ introRequired: '请填写 {name} 的 Introduction。',
+ guestEmailInvalid: '请填写 {name} 的正确邮箱格式。',
+ guestAddressRequired: '请填写 {name} 的 Address。',
+ icon: '封面图',
+ operate: '操作',
+ enterTitle: '请输入标题',
+ enterIntro: '请输入 intro',
+ enterAbstract: '请输入 Abstract',
+ enterKeywords: '请输入关键词',
+ enterDeadline: '请选择投稿截止日期',
+ imageSizeLimit: '图片大小不能超过 2M!',
+ uploadFail: '图片上传失败'
+ },
paperArticleCount: {
Periodroll: '期卷',
article: '文章',
@@ -271,6 +358,7 @@ const zh = {
userManSys8: '期刊委员会',
userManSys9: '期刊编辑',
userManSys11: '期刊协议',
+ specialList: '期刊专刊列表',
analyp: '管理',
datasis: '数据统计',
analysis: '引用统计',
@@ -1202,7 +1290,7 @@ const zh = {
citeRelevanceDownloadHtmlSuccessWithUploaded: 'HTML 已下载(基于已上传的 {n} 条参考文献)',
refAnnotationReportTip: '下载带批注的 HTML 相关性分析报告(需先完成 AI 检测)',
refAnnotationReportShort: '批注报告',
- exportRelevanceWordTip: '导出带引文相关性批注的 Word(需先完成 AI 检测;黄/红项原因写入批注)',
+ exportRelevanceWordTip: '导出带引文相关性批注的 Word(分数<0.65 写入 author_comment;未完成检测也可导出)',
exportRelevanceWordShort: '相关性Word',
exportRelevanceWordSuccess: '带相关性批注的 Word 已下载',
exportRelevanceWordFail: '带相关性批注的 Word 导出失败',
@@ -1219,6 +1307,47 @@ const zh = {
wordRefsPreviewNoManuscript: '未找到稿件 Word 文件(gridData / getFilesForArticle)',
wordRefsPreviewEmpty: '未在原 Word 稿件中识别到 References / 参考文献 段落',
wordRefsPreviewFail: '读取 Word 参考文献失败',
+ wordRefStatsShort: 'Word 文献统计',
+ wordRefStatsTitle: '1. 统计数据概览',
+ wordRefStatsCategory: '类别',
+ wordRefStatsResult: '统计结果',
+ wordRefStatsPercent: '占比',
+ wordRefStatsCompliance: '达标情况',
+ wordRefStatsTotal: '总文献数',
+ wordRefStatsChinese: '中文文献',
+ wordRefStatsFiveYear: '近五年文献',
+ wordRefStatsThreeYear: '近三年文献',
+ wordRefStatsYearRange: '({start}-{end})',
+ wordRefStatsCountUnit: '{count} 条',
+ wordRefStatsPass: '达标',
+ wordRefStatsFail: '未达标',
+ wordRefStatsGoal: '目标',
+ wordRefStatsChineseGoal: '(≤10%)',
+ wordRefStatsFiveYearGoal: '(≥70%)',
+ wordRefStatsThreeYearGoal: '(≥30%)',
+ wordRefStatsBaselineNote: '统计基准年:{year}({source})',
+ wordRefStatsBaselineToday: '当前日期',
+ wordRefStatsBaselineAi: 'AI 分析时间',
+ wordRefStatsBaselineArticle: '稿件提交时间',
+ wordRefStatsNoYearHint: '另有 {count} 条未识别出版年份,未计入近三/近五年',
+ wordRefStatsAiCompareTitle: 'AI 评估对比(仅供参考)',
+ wordRefStatsAiThreeYear: 'AI 近三年比例',
+ wordRefStatsAiFiveYear: 'AI 近五年比例',
+ wordRefStatsDiffNote: 'Word 统计为规则解析,AI 为模型评估;稿件版本、年份识别与统计口径不同会导致差异。',
+ wordRefStatsIndices: '序号',
+ wordRefStatsIndicesEmpty: '无',
+ wordRefStatsDetailTitle: '2. 分类序号明细',
+ wordRefStatsNoYearLabel: '未识别出版年份',
+ wordRefStatsItemDetailTitle: '3. 逐条年份识别',
+ wordRefStatsItemIndex: '序号',
+ wordRefStatsItemYear: '识别年份',
+ wordRefStatsItemTags: '归属',
+ wordRefStatsItemPreview: '文献摘要',
+ wordRefStatsTagThreeYear: '近三年',
+ wordRefStatsTagFiveYear: '近五年',
+ wordRefStatsTagChinese: '中文',
+ wordRefStatsTagNoYear: '未识别年份',
+ wordRefStatsTagOlder: '更早',
wordRefBatchUploadShort: '上传校对 Word',
wordRefBatchUploadTip: '上传校对改好的 Word 参考文献,按序号拆解字段并批量保存到系统',
wordRefBatchDialogTitle: 'Word 参考文献 · 字段对照',
@@ -1251,6 +1380,21 @@ const zh = {
wordRefBatchHideExisting: '收起',
wordRefBatchParseFailed: '拆解不完整,请逐项填写',
wordRefBatchWordOriginal: 'Word 原文',
+ wordRefBatchPasteShort: '粘贴整理文献',
+ wordRefBatchPasteTip: '粘贴已整理好的参考文献(支持 [1] / 1. 编号、空行分隔及 HTML 斜体),按序号拆解字段并批量保存到系统',
+ wordRefBatchPasteTitle: '粘贴参考文献',
+ wordRefBatchPasteMappingTitle: '粘贴参考文献 · 字段对照',
+ wordRefBatchPasteOriginal: '粘贴原文',
+ wordRefBatchPasteConfirm: '解析并对照',
+ wordRefBatchFields: '字段对照',
+ wordRefBatchParseFailedCount: '解析报错 {count} 条',
+ wordRefBatchParseErrorNav: '解析报错',
+ wordRefBatchMissingFields: '缺 {fields}',
+ zyBatchDeleteAuthors: '批量删除作者',
+ zyBatchDeleteAffiliations: '批量删除机构',
+ zyBatchDeleteAuthorsConfirm: '确定删除 {count} 位作者及其机构关联吗?',
+ zyBatchDeleteAffiliationsConfirm: '确定删除 {count} 个机构及其作者关联吗?',
+ zyBatchDeleteResult: '删除完成:成功 {ok} 条,失败 {fail} 条',
refAnnotationReportSuccess: '批注分析报告 HTML 已下载',
refAnnotationReportFail: '批注分析报告下载失败',
refAnnotationReportNoArticle: '缺少稿件 ID,无法获取 AI 检测数据',
@@ -1354,6 +1498,23 @@ const zh = {
removeProofread: '确定要删除这条建议吗?',
removeContent: '确定要删除这条内容吗?',
removeimg: '确定要删除这张图片吗?',
+ figureDeleteAll: '批量删除',
+ figureDeleteAllConfirm: '确定删除全部图片吗?',
+ figureDeleteAllResult: '已删除 {ok} 张,失败 {fail} 张',
+ figureAutoPositionTip: '按题注编号定位到正文首次出现处',
+ figureAutoPositionNoNum: '无法从题注识别 Figure 编号',
+ figureAutoPositionNoHit: '正文中未找到 Figure {num} 的引用',
+ figureAutoPositionDone: '已定位 Figure {num}',
+ figureBatchPosition: '批量定位',
+ figureBatchPositionEmpty: '没有待定位的图片',
+ figureBatchPositionDone: '批量定位完成:成功 {ok},未匹配 {skip},失败 {fail}',
+ tableAutoPositionTip: '按题注编号定位到正文首次出现处',
+ tableAutoPositionNoNum: '无法从题注识别 Table 编号',
+ tableAutoPositionNoHit: '正文中未找到 Table {num} 的引用',
+ tableAutoPositionDone: '已定位 Table {num}',
+ tableBatchPosition: '批量定位',
+ tableBatchPositionEmpty: '没有待定位的表格',
+ tableBatchPositionDone: '批量定位完成:成功 {ok},未匹配 {skip},失败 {fail}',
removetable: '确定要删除这个表格吗?',
reContent: '确定要恢复这条内容吗?',
uploadImageInfo: 'Figures 只能上传 JPG、JPEG 和 PNG 格式的文件',
@@ -1362,8 +1523,14 @@ const zh = {
selectWord:'请只选中单个单词!',
importWordMath: 'Word',
importWordMathTip: '上传 Word 并解析数学公式',
+ importWordFiguresTip: '上传 Word,识别图与题注并批量新增 Figure',
+ importWordFiguresLoading: '正在导入图片...',
+ importWordFiguresEmpty: '未在 Word 中识别到图片',
+ importWordFiguresDone: '识别 {parsed} 张,新增 {added} 张,跳过 {skipped},失败 {fail}',
+ importWordFiguresFail: 'Word 图片导入失败',
importWordMathLoading: '正在导入 Word...',
importWordMathSuccess: 'Word 导入成功,公式已转为 LaTeX',
+ importedWordOutlineTitle: '正文标题(Word 居中/红粗文本框=一级,黑粗无句号=二级;Peer review 等为文末粗斜体,不列入 H1/H2)',
importWordMathFail: 'Word 导入失败,请检查文件格式',
importWordMathNoFormula: '未在 Word 中识别到数学公式',
importWordMathNoNew: '公式已存在,未新增重复项',
@@ -1515,6 +1682,18 @@ const zh = {
statusPending: '待审批',
statusOther: '其他记录',
viewArticleDetail: '点击查看文章详情',
+ articleDetailTitle: '文章详情',
+ author: '作者',
+ corrAuthor: '通讯作者',
+ keywords: '关键词',
+ abstract: '摘要',
+ fund: '基金',
+ scoring: 'AI 评分',
+ repetition: '重复率',
+ manuscriptFile: '稿件文件',
+ approvalFile: '伦理批件',
+ repeReport: '查重报告',
+ viewFile: '查看文件',
notifyTitle: '期刊收费审批',
notifyMessage: '您有 {count} 条待审批改价申请',
notifyHint: '点击前往审批页面处理',
diff --git a/src/components/page/GenerateCharts.vue b/src/components/page/GenerateCharts.vue
index 71024f6..aef55d0 100644
--- a/src/components/page/GenerateCharts.vue
+++ b/src/components/page/GenerateCharts.vue
@@ -70,6 +70,11 @@
@goToComment="goToComment"
@edit="handleFigureAndTableEdit"
@delete="handleFigureAndTableDelete"
+ @deleteAllImages="handleDeleteAllFigures"
+ @autoPositionImage="handleAutoPositionImage"
+ @autoPositionTable="handleAutoPositionTable"
+ @batchAutoPositionImages="handleBatchAutoPositionImages"
+ @batchAutoPositionTables="handleBatchAutoPositionTables"
@goToListComment="goToListComment"
@mathFormulasChange="onMathFormulasChange"
style="width: 100%; height: 100%; padding: 0 0px; box-sizing: border-box; background-color: #fff"
@@ -106,6 +111,7 @@
@onLinkUnbind="handleUnbindLink"
@onLinkConfirm="handleConfirmLink"
@saveContent="saveContent"
+ @mergeH3IntoNext="mergeH3IntoNext"
@editComment="editComment"
@loaded="loadedWord"
@onEdit="onEdit"
@@ -417,12 +423,41 @@
@getContent="getContent"
type="content"
@openLatexEditor="openLatexEditor"
+ @importedWordOutline="handleImportedWordOutline"
v-if="addContentVisible"
:enable-import-word-math="zyModeEnabled"
:article-id="articleId"
ref="addContent"
style="margin-left: -115px"
>
+
+
+
+
+ {{ $t('commonTable.importedWordOutlineTitle') }}
+ ({{ importedWordOutline.length }})
+
+
+
+ -
+ H{{ item.level }}
+ {{ item.text }}
+
+
+
@@ -466,6 +501,12 @@ import bottomTinymce from '@/components/page/components/Tinymce';
import catalogue from '@/components/page/components/table/catalogue.vue';
import { isZyModeEnabled } from '@/utils/zyMode';
import { collectHeadingNumberStripUpdates } from '@/utils/stripHeadingNumber';
+import {
+ findFirstAmIdForFigureNumber,
+ findFirstAmIdForTableNumber,
+ parseFigureNumberFromTitle,
+ parseTableNumberFromTitle
+} from '@/utils/manuscriptMediaReferences';
export default {
data() {
return {
@@ -576,6 +617,8 @@ export default {
},
txtVisible: false,
addContentVisible: false,
+ importedWordOutline: [],
+ importedWordOutlineExpanded: false,
editProofreadingContentVisible: false,
proofreadingContent: {},
addContent: {},
@@ -780,7 +823,8 @@ export default {
this.saveContent(content, this.currentContent.am_id);
} else if (type == 'addcontent') {
var list = this.$commonJS.cleanAndParseWordContent(content);
-
+ this.importedWordOutline = Array.isArray(list.outline) ? list.outline.slice() : [];
+ this.importedWordOutlineExpanded = false;
this.saveContentList(list, this.currentId);
} else if (type == 'table') {
this.saveTable(content);
@@ -865,6 +909,58 @@ export default {
this.$message.error(err);
});
},
+ /** zy H3:保存下一段合并内容后静默删除本段 */
+ async mergeH3IntoNext({ deleteAmId, nextAmId, nextContent }) {
+ if (!deleteAmId || !nextAmId) {
+ return;
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ try {
+ let str = String(nextContent || '')
+ .replace(/^\s*(.*?)\s*<\/p>$/i, '$1')
+ .trim();
+ str = str.replace(/
/gi, '');
+ str = await this.$commonJS.decodeHtml(str);
+
+ const editRes = await this.$api.post(this.urlList.editContent, {
+ am_id: nextAmId,
+ content: str
+ });
+ if (!editRes || editRes.code != 0) {
+ this.$message.error((editRes && editRes.msg) || '保存失败');
+ return;
+ }
+
+ const delRes = await this.$api.post(this.urlList.delete, {
+ am_id: deleteAmId
+ });
+ if (!delRes || delRes.code != 0) {
+ this.$message.error((delRes && delRes.msg) || '删除失败');
+ this.refreshCurrentContent('content', nextAmId, editRes.data);
+ this.getCommentList();
+ return;
+ }
+
+ this.refreshCurrentContent('content', nextAmId, editRes.data);
+ const delIndex = this.Main_List.findIndex((item) => item.am_id == deleteAmId);
+ if (delIndex !== -1) {
+ this.Main_List.splice(delIndex, 1);
+ }
+ this.editVisible = false;
+ this.clearWordSelectionUI();
+ this.getCommentList();
+ this.$forceUpdate();
+ } catch (err) {
+ this.$message.error(err && err.msg ? err.msg : err);
+ } finally {
+ loading.close();
+ }
+ },
async saveContentList(content, am_id) {
if (content.length == 0) {
this.$message({
@@ -872,6 +968,9 @@ export default {
message: 'Please enter the content!'
});
}
+ const outline = Array.isArray(content.outline)
+ ? content.outline.slice()
+ : this.importedWordOutline.slice();
const loading = this.$loading({
lock: true,
text: 'Loading...',
@@ -894,10 +993,12 @@ export default {
})
.then(async (res) => {
if (res.code == 0) {
- loading.close();
this.addContentVisible = false;
this.refreshCurrentContent('addMoreRow', am_id, res.data);
+ await this.applyImportedWordOutlineLevels(res.data, outline);
+ this.importedWordOutline = [];
this.getCommentList();
+ loading.close();
} else {
loading.close();
this.$message.error(res.msg);
@@ -908,6 +1009,44 @@ export default {
this.$message.error(err);
});
},
+ handleImportedWordOutline(outline) {
+ this.importedWordOutline = Array.isArray(outline) ? outline.slice() : [];
+ this.importedWordOutlineExpanded = false;
+ },
+ async applyImportedWordOutlineLevels(resData, outline) {
+ const rows = Array.isArray(resData) ? resData : resData ? [resData] : [];
+ const marks = Array.isArray(outline) ? outline : [];
+ if (!rows.length || !marks.length) {
+ return;
+ }
+ const plainOf = (html) =>
+ String(html || '')
+ .replace(/<[^>]+>/g, '')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+ for (let i = 0; i < marks.length; i++) {
+ const mark = marks[i];
+ let row = null;
+ if (mark.rowIndex != null && rows[mark.rowIndex] && rows[mark.rowIndex].am_id) {
+ row = rows[mark.rowIndex];
+ }
+ if (!row || plainOf(row.content) !== mark.text) {
+ row = rows.find((item) => plainOf(item && item.content) === mark.text) || row;
+ }
+ if (!row || !row.am_id) continue;
+ const url = mark.level === 1 ? 'api/Preaccept/changeH1' : mark.level === 2 ? 'api/Preaccept/changeH2' : '';
+ if (!url) continue;
+ try {
+ const res = await this.$api.post(url, { am_id: row.am_id });
+ if (res && res.code == 0 && res.data) {
+ await this.refreshCurrentContent('content', row.am_id, res.data);
+ }
+ } catch (e) {
+ // ignore single heading fail
+ }
+ }
+ },
isHeaderRow(rowIndex, table) {
var table = table;
@@ -1778,9 +1917,54 @@ export default {
});
}
})
- .catch((err) => {
- // this.$message.error(err.msg);
+ .catch(() => {});
+ },
+ async handleDeleteAllFigures(list) {
+ const images = Array.isArray(list) ? list.filter((item) => item && item.ami_id) : [];
+ if (!images.length) {
+ return;
+ }
+ try {
+ await this.$confirm(this.$t('commonTable.figureDeleteAllConfirm'), 'Prompt', {
+ confirmButtonText: 'Submit',
+ cancelButtonText: 'Cancel',
+ type: 'warning'
});
+ } catch (e) {
+ return;
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let fail = 0;
+ for (let i = 0; i < images.length; i++) {
+ const item = images[i];
+ try {
+ const res = await this.$api.post(this.urlList.deleteImage, {
+ ami_id: item.ami_id,
+ article_id: this.articleId
+ });
+ if (res && res.status == 1) {
+ ok += 1;
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.replacement('img', item.ami_id);
+ }
+ } else {
+ fail += 1;
+ }
+ } catch (err) {
+ fail += 1;
+ }
+ }
+ loading.close();
+ this.$message.success(this.$t('commonTable.figureDeleteAllResult', { ok: ok, fail: fail }));
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.refresh('img');
+ }
},
handleFigureAndTableEdit(data, type) {
if (type == 'img') {
@@ -1873,10 +2057,251 @@ export default {
onAddContent(dataId) {
this.addContentVisible = true;
this.addContent = {};
+ this.importedWordOutline = [];
this.currentId = dataId;
},
+ resolveMainRowsForMediaPosition() {
+ const lists = [];
+ if (Array.isArray(this.Main_List) && this.Main_List.length) {
+ lists.push(this.Main_List);
+ }
+ if (Array.isArray(this.ManuscirptContent) && this.ManuscirptContent.length) {
+ lists.push(this.ManuscirptContent);
+ }
+ const word = this.$refs.commonWord;
+ if (word && Array.isArray(word.wordList) && word.wordList.length) {
+ lists.push(word.wordList);
+ }
+ if (word && Array.isArray(word.contentList) && word.contentList.length) {
+ lists.push(word.contentList);
+ }
+ return lists;
+ },
+ findAmIdForFigureNumber(figureNumber) {
+ const lists = this.resolveMainRowsForMediaPosition();
+ for (let i = 0; i < lists.length; i++) {
+ const amId = findFirstAmIdForFigureNumber(lists[i], figureNumber);
+ if (amId) return amId;
+ }
+ return null;
+ },
+ findAmIdForTableNumber(tableNumber) {
+ const lists = this.resolveMainRowsForMediaPosition();
+ for (let i = 0; i < lists.length; i++) {
+ const amId = findFirstAmIdForTableNumber(lists[i], tableNumber);
+ if (amId) return amId;
+ }
+ return null;
+ },
+ async handleAutoPositionImage(img) {
+ if (!img || !img.ami_id) return;
+ if (Number(img.has_selected) === 1) return;
+ const result = await this.autoPositionImageCore(img, { silent: false });
+ if (result && result.ok) {
+ this.$message.success(this.$t('commonTable.figureAutoPositionDone', { num: result.num }));
+ }
+ },
+ async handleAutoPositionTable(table) {
+ if (!table || !table.amt_id) return;
+ if (Number(table.has_selected) === 1) return;
+ const result = await this.autoPositionTableCore(table, { silent: false });
+ if (result && result.ok) {
+ this.$message.success(this.$t('commonTable.tableAutoPositionDone', { num: result.num }));
+ }
+ },
+ async autoPositionImageCore(img, options = {}) {
+ const silent = !!options.silent;
+ const figureNumber = parseFigureNumberFromTitle(img.title || '');
+ if (!figureNumber) {
+ if (!silent) this.$message.warning(this.$t('commonTable.figureAutoPositionNoNum'));
+ return { ok: false, reason: 'noNum' };
+ }
+ const amId = this.findAmIdForFigureNumber(figureNumber);
+ if (!amId) {
+ if (!silent) this.$message.warning(this.$t('commonTable.figureAutoPositionNoHit', { num: figureNumber }));
+ return { ok: false, reason: 'noHit', num: figureNumber };
+ }
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (!silent && panel && typeof panel.setPositioningFigureLoading === 'function') {
+ panel.setPositioningFigureLoading(img.ami_id);
+ }
+ let loading = null;
+ if (!silent) {
+ loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ }
+ try {
+ const res = await this.$api.post(this.urlList.setPositioningImage, {
+ am_id: amId,
+ ami_id: img.ami_id
+ });
+ if (res && res.code == 0) {
+ this.refreshCurrentContent('positioningImg', amId, res.data);
+ if (panel) {
+ panel.refresh('positioningImg', res.data);
+ }
+ return { ok: true, num: figureNumber, amId };
+ }
+ if (!silent) this.$message.error((res && res.msg) || 'Error');
+ return { ok: false, reason: 'error', num: figureNumber };
+ } catch (err) {
+ if (!silent) this.$message.error((err && err.msg) || 'Error');
+ return { ok: false, reason: 'error', num: figureNumber };
+ } finally {
+ if (loading) loading.close();
+ if (!silent && panel && typeof panel.setPositioningFigureLoading === 'function') {
+ panel.setPositioningFigureLoading(null);
+ }
+ }
+ },
+ async autoPositionTableCore(table, options = {}) {
+ const silent = !!options.silent;
+ const tableNumber = parseTableNumberFromTitle(table.title || '');
+ if (!tableNumber) {
+ if (!silent) this.$message.warning(this.$t('commonTable.tableAutoPositionNoNum'));
+ return { ok: false, reason: 'noNum' };
+ }
+ const amId = this.findAmIdForTableNumber(tableNumber);
+ if (!amId) {
+ if (!silent) this.$message.warning(this.$t('commonTable.tableAutoPositionNoHit', { num: tableNumber }));
+ return { ok: false, reason: 'noHit', num: tableNumber };
+ }
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (!silent && panel && typeof panel.setPositioningTableLoading === 'function') {
+ panel.setPositioningTableLoading(table.amt_id);
+ }
+ let loading = null;
+ if (!silent) {
+ loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ }
+ try {
+ const res = await this.$api.post(this.urlList.setPositioningTable, {
+ am_id: amId,
+ amt_id: table.amt_id
+ });
+ if (res && res.code == 0) {
+ this.refreshCurrentContent('positioningTable', amId, res.data);
+ if (panel) {
+ panel.refresh('positioningTable', res.data);
+ }
+ return { ok: true, num: tableNumber, amId };
+ }
+ if (!silent) this.$message.error((res && res.msg) || 'Error');
+ return { ok: false, reason: 'error', num: tableNumber };
+ } catch (err) {
+ if (!silent) this.$message.error((err && err.msg) || 'Error');
+ return { ok: false, reason: 'error', num: tableNumber };
+ } finally {
+ if (loading) loading.close();
+ if (!silent && panel && typeof panel.setPositioningTableLoading === 'function') {
+ panel.setPositioningTableLoading(null);
+ }
+ }
+ },
+ async handleBatchAutoPositionImages(list) {
+ const images = (Array.isArray(list) ? list : []).filter(
+ (img) => img && img.ami_id && Number(img.has_selected) !== 1
+ );
+ if (!images.length) {
+ this.$message.info(this.$t('commonTable.figureBatchPositionEmpty'));
+ return;
+ }
+ images.sort((a, b) => {
+ const na = parseFigureNumberFromTitle(a.title || '') || 9999;
+ const nb = parseFigureNumberFromTitle(b.title || '') || 9999;
+ return na - nb;
+ });
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (panel && typeof panel.setBatchPositioningFigures === 'function') {
+ panel.setBatchPositioningFigures(true);
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let skip = 0;
+ let fail = 0;
+ try {
+ for (let i = 0; i < images.length; i++) {
+ const result = await this.autoPositionImageCore(images[i], { silent: true });
+ if (result && result.ok) ok += 1;
+ else if (result && (result.reason === 'noNum' || result.reason === 'noHit')) skip += 1;
+ else fail += 1;
+ }
+ if (panel) {
+ panel.refresh('img');
+ }
+ this.$message.success(
+ this.$t('commonTable.figureBatchPositionDone', { ok: ok, skip: skip, fail: fail })
+ );
+ } finally {
+ loading.close();
+ if (panel && typeof panel.setBatchPositioningFigures === 'function') {
+ panel.setBatchPositioningFigures(false);
+ }
+ }
+ },
+ async handleBatchAutoPositionTables(list) {
+ const tables = (Array.isArray(list) ? list : []).filter(
+ (table) => table && table.amt_id && Number(table.has_selected) !== 1
+ );
+ if (!tables.length) {
+ this.$message.info(this.$t('commonTable.tableBatchPositionEmpty'));
+ return;
+ }
+ tables.sort((a, b) => {
+ const na = parseTableNumberFromTitle(a.title || '') || 9999;
+ const nb = parseTableNumberFromTitle(b.title || '') || 9999;
+ return na - nb;
+ });
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (panel && typeof panel.setBatchPositioningTables === 'function') {
+ panel.setBatchPositioningTables(true);
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let skip = 0;
+ let fail = 0;
+ try {
+ for (let i = 0; i < tables.length; i++) {
+ const result = await this.autoPositionTableCore(tables[i], { silent: true });
+ if (result && result.ok) ok += 1;
+ else if (result && (result.reason === 'noNum' || result.reason === 'noHit')) skip += 1;
+ else fail += 1;
+ }
+ if (panel) {
+ panel.refresh('table');
+ }
+ this.$message.success(
+ this.$t('commonTable.tableBatchPositionDone', { ok: ok, skip: skip, fail: fail })
+ );
+ } finally {
+ loading.close();
+ if (panel && typeof panel.setBatchPositioningTables === 'function') {
+ panel.setBatchPositioningTables(false);
+ }
+ }
+ },
+
async onDrop(event, dataId) {
if (event.dataTransfer.getData('image')) {
const loading = this.$loading({
@@ -2823,4 +3248,70 @@ wmath[data-wrap='inline'] mjx-container {
display: inline-block !important;
margin: 0 2px !important;
}
+.imported-word-outline {
+ margin: 12px 0 0;
+ padding: 12px 14px;
+ background: #f7f9fc;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+}
+.imported-word-outline__title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 13px;
+ font-weight: 600;
+ color: #303133;
+ cursor: pointer;
+ user-select: none;
+}
+.imported-word-outline__title:hover {
+ color: #006699;
+}
+.imported-word-outline__arrow {
+ transition: transform 0.2s ease;
+ color: #909399;
+}
+.imported-word-outline__arrow.is-expanded {
+ transform: rotate(90deg);
+}
+.imported-word-outline__list {
+ list-style: none;
+ margin: 8px 0 0;
+ padding: 0;
+}
+.imported-word-outline__item {
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+ padding: 4px 0;
+ font-size: 13px;
+ line-height: 1.45;
+ color: #303133;
+}
+.imported-word-outline__item.level-1 {
+ font-weight: 600;
+}
+.imported-word-outline__item.level-2 {
+ padding-left: 18px;
+ color: #606266;
+}
+.imported-word-outline__badge {
+ flex: none;
+ min-width: 28px;
+ height: 18px;
+ line-height: 18px;
+ text-align: center;
+ border-radius: 2px;
+ font-size: 11px;
+ color: #fff;
+ background: #006699;
+}
+.imported-word-outline__item.level-2 .imported-word-outline__badge {
+ background: #909399;
+}
+.imported-word-outline__text {
+ flex: 1;
+ word-break: break-word;
+}
diff --git a/src/components/page/JournalManagement/JournalManagement/common.vue b/src/components/page/JournalManagement/JournalManagement/common.vue
index d8242ba..5986c14 100644
--- a/src/components/page/JournalManagement/JournalManagement/common.vue
+++ b/src/components/page/JournalManagement/JournalManagement/common.vue
@@ -123,6 +123,24 @@
>
{{ $t('articleListEditor.JournalInstallment') }}
+
+ {{ $t('specialList.button') }}
+
+
+
+
+
+ {{ $t('specialList.button') }}
+
+ {{ currentJournal.title }}
+
+
+
+
+
+
+
+
+
+ {{ scope.row.title }}
+
+
+ {{ scope.row.intro }}
+
+
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+ changeSpecialState(scope.row, val)"
+ >
+
+ {{ $t('specialList.statusPassed') }}
+
+
+ {{ $t('specialList.statusRejected') }}
+
+
+
+
+ {{ getSpecialStateText(scope.row.state) }}
+
+
+
+
+
+
+
+ {{ $t('articleListEditor.edit') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentJournal.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('specialList.guestEditorYes') }}
+ {{ $t('specialList.guestEditorNo') }}
+
+
+
+
+
+
+ {{ $t('specialList.guestEditorCheck') }}
+
+
+
+
+
+
+ {{ $t('specialList.guestEditorAdd') }}
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+ {{ $t('specialList.guestRealname') }}
+ {{ getGuestEditorDisplayName(scope.row) }}
+
+
+ {{ $t('specialList.guestEmail') }}:
+ {{ scope.row.email || '—' }}
+
+
+ {{ $t('specialList.guestOrcid') }}:
+ {{ scope.row.orcid }}
+ —
+
+
+
+
+
+
+
+
+ {{ $t('specialList.guestIntroduction') }}: {{ scope.row.intro || '—' }}
+
+
+ {{ $t('specialList.guestAddress') }}: {{ scope.row.address || '—' }}
+
+
+ {{ $t('specialList.guestWebsite') }}:
+ {{ scope.row.website }}
+ —
+
+
+ {{ $t('specialList.guestInterests') }}: {{ scope.row.interests || '—' }}
+
+
+
+
+
+
+
+ {{ $t('articleListEditor.edit') }}
+
+
+ {{ $t('specialList.guestEditorRemove') }}
+
+
+
+
+ {{ $t('specialList.guestDetail') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Account : {{ singleGuestEditor.item.account || '—' }}
+
+
+
+ {{ $t('specialList.guestEditorManualTip') }}
+
+
+
+
+ {{ $t('specialList.guestEditorRemove') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://orcid.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
{{ getGuestEditorDisplayName(guestDetailRow) }}
+
+
+
+
+
+ {{ $t('specialList.guestEmail') }}
+ {{ guestDetailRow.email || '—' }}
+
+
+ {{ $t('specialList.guestFirstName') }}
+ {{ guestDetailRow.first_name || '—' }}
+
+
+ {{ $t('specialList.guestLastName') }}
+ {{ guestDetailRow.last_name || '—' }}
+
+
+ {{ $t('specialList.guestIntroduction') }}
+ {{ guestDetailRow.intro || '—' }}
+
+
+ {{ $t('specialList.guestAddress') }}
+ {{ guestDetailRow.address || '—' }}
+
+
+ {{ $t('specialList.guestInterests') }}
+ {{ guestDetailRow.interests || '—' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('specialList.guestEditorCheck') }}
+
+
+ {{ $t('specialList.guestEditorRecheck') }}
+
+
+
+
+
+
+
+
Account : {{ guestAddDraft.account || '—' }}
+
+
+
+ {{ $t('specialList.guestEditorManualTip') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://orcid.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Account : {{ guestEditDraft.account || '—' }}
+
+
+
+ {{ $t('specialList.guestEditorManualTip') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://orcid.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/page/OnlineProofreading.vue b/src/components/page/OnlineProofreading.vue
index 00da340..5a96784 100644
--- a/src/components/page/OnlineProofreading.vue
+++ b/src/components/page/OnlineProofreading.vue
@@ -79,6 +79,12 @@
@addComment="addCommentSetting"
@goToComment="goToComment"
@edit="handleImageEdit"
+ @delete="handleFigureAndTableDelete"
+ @deleteAllImages="handleDeleteAllFigures"
+ @autoPositionImage="handleAutoPositionImage"
+ @autoPositionTable="handleAutoPositionTable"
+ @batchAutoPositionImages="handleBatchAutoPositionImages"
+ @batchAutoPositionTables="handleBatchAutoPositionTables"
@goToListComment="goToListComment"
@mathFormulasChange="onMathFormulasChange"
style="width: 100%; height: 100%; padding: 0 0px; box-sizing: border-box; background-color: #fff"
@@ -111,6 +117,7 @@
:mathFormulasList="mathFormulasList"
@onDrop="onDrop"
@saveContent="saveContent"
+ @mergeH3IntoNext="mergeH3IntoNext"
@editComment="editComment"
@loaded="loadedWord"
@onEdit="onEdit"
@@ -408,11 +415,40 @@
:value="addContent.content"
@getContent="getContent"
@openLatexEditor="openLatexEditor"
+ @importedWordOutline="handleImportedWordOutline"
v-if="addContentVisible"
:enable-import-word-math="true"
ref="addContent"
style="margin-left: -115px"
>
+
+
+
+
+ {{ $t('commonTable.importedWordOutlineTitle') }}
+ ({{ importedWordOutline.length }})
+
+
+
+ -
+ H{{ item.level }}
+ {{ item.text }}
+
+
+
@@ -439,6 +475,12 @@ import Tinymce from '@/components/page/components/Tinymce';
import bottomTinymce from '@/components/page/components/Tinymce';
import catalogue from '@/components/page/components/OnlineProofreading/catalogue.vue';
import reference from '@/components/page/components/OnlineProofreading/reference.vue';
+import {
+ findFirstAmIdForFigureNumber,
+ findFirstAmIdForTableNumber,
+ parseFigureNumberFromTitle,
+ parseTableNumberFromTitle
+} from '@/utils/manuscriptMediaReferences';
export default {
data() {
return {
@@ -482,7 +524,9 @@ export default {
addImage: 'api/Preaccept/addMainImage',
editImage: 'api/Preaccept/editMainImage',
addTable: 'api/Preaccept/addMainTable',
- editTable: 'api/Preaccept/editMainTable'
+ editTable: 'api/Preaccept/editMainTable',
+ deleteImage: 'api/Articlemain/removeMainImage',
+ deleteTable: 'api/Articlemain/removeMainTable'
},
wordStyle: `
// p {
@@ -547,6 +591,8 @@ export default {
},
txtVisible: false,
addContentVisible: false,
+ importedWordOutline: [],
+ importedWordOutlineExpanded: false,
editProofreadingContentVisible: false,
proofreadingContent: {},
addContent: {},
@@ -727,7 +773,8 @@ export default {
this.saveContent(content, this.currentContent.am_id);
} else if (type == 'addcontent') {
var list = this.$commonJS.cleanAndParseWordContent(content);
-
+ this.importedWordOutline = Array.isArray(list.outline) ? list.outline.slice() : [];
+ this.importedWordOutlineExpanded = false;
this.saveContentList(list, this.currentId);
} else if (type == 'table') {
this.saveTable(content);
@@ -755,6 +802,52 @@ export default {
}
});
},
+ /** zy H3:保存下一段合并内容后静默删除本段 */
+ async mergeH3IntoNext({ deleteAmId, nextAmId, nextContent }) {
+ if (!deleteAmId || !nextAmId) {
+ return;
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ try {
+ let str = String(nextContent || '')
+ .replace(/^\s*(.*?)\s*<\/p>$/i, '$1')
+ .trim();
+ str = await this.$commonJS.decodeHtml(str);
+
+ const editRes = await this.$api.post(this.urlList.editContent, {
+ am_id: nextAmId,
+ content: str
+ });
+ if (!editRes || editRes.code != 0) {
+ this.$message.error((editRes && editRes.msg) || '保存失败');
+ return;
+ }
+
+ const delRes = await this.$api.post(this.urlList.delete, {
+ am_id: deleteAmId
+ });
+ if (!delRes || delRes.code != 0) {
+ this.$message.error((delRes && delRes.msg) || '删除失败');
+ this.getDate();
+ this.getCommentList();
+ return;
+ }
+
+ this.editVisible = false;
+ this.clearWordSelectionUI();
+ this.getDate();
+ this.getCommentList();
+ } catch (err) {
+ this.$message.error(err && err.msg ? err.msg : err);
+ } finally {
+ loading.close();
+ }
+ },
async saveContentList(content, am_id) {
if (content.length == 0) {
this.$message({
@@ -762,7 +855,22 @@ export default {
message: 'Please enter the content!'
});
}
+ const outline = Array.isArray(content.outline)
+ ? content.outline.slice()
+ : this.importedWordOutline.slice();
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ content = content.map((str) => {
+ if (str.replace(/
/gi, '').trim() === '') {
+ return '';
+ }
+ return str;
+ });
await this.$api
.post('api/Preaccept/addMoreRow', {
article_id: this.articleId,
@@ -772,11 +880,56 @@ export default {
.then(async (res) => {
if (res.code == 0) {
this.addContentVisible = false;
+ await this.applyImportedWordOutlineLevels(res.data, outline);
+ this.importedWordOutline = [];
this.getDate();
this.getCommentList();
+ loading.close();
+ } else {
+ loading.close();
+ this.$message.error(res.msg);
}
+ })
+ .catch((err) => {
+ loading.close();
+ this.$message.error(err);
});
},
+ handleImportedWordOutline(outline) {
+ this.importedWordOutline = Array.isArray(outline) ? outline.slice() : [];
+ this.importedWordOutlineExpanded = false;
+ },
+ async applyImportedWordOutlineLevels(resData, outline) {
+ const rows = Array.isArray(resData) ? resData : resData ? [resData] : [];
+ const marks = Array.isArray(outline) ? outline : [];
+ if (!rows.length || !marks.length) {
+ return;
+ }
+ const plainOf = (html) =>
+ String(html || '')
+ .replace(/<[^>]+>/g, '')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+ for (let i = 0; i < marks.length; i++) {
+ const mark = marks[i];
+ let row = null;
+ if (mark.rowIndex != null && rows[mark.rowIndex] && rows[mark.rowIndex].am_id) {
+ row = rows[mark.rowIndex];
+ }
+ if (!row || plainOf(row.content) !== mark.text) {
+ row = rows.find((item) => plainOf(item && item.content) === mark.text) || row;
+ }
+ if (!row || !row.am_id) continue;
+ const url = mark.level === 1 ? 'api/Preaccept/changeH1' : mark.level === 2 ? 'api/Preaccept/changeH2' : '';
+ if (!url) continue;
+ try {
+ await this.$api.post(url, { am_id: row.am_id });
+ } catch (e) {
+ // ignore single heading fail
+ }
+ }
+ },
isHeaderRow(rowIndex, table) {
var table = table;
@@ -1355,6 +1508,102 @@ export default {
this.picStyle.visiTitle = 'Add Figure';
this.pictVisible = true;
},
+ async handleFigureAndTableDelete(data, type) {
+ try {
+ await this.$confirm(this.$t('commonTable.remove' + type), 'Prompt', {
+ confirmButtonText: 'Submit',
+ cancelButtonText: 'Cancel',
+ type: 'warning'
+ });
+ } catch (e) {
+ return;
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ try {
+ if (type == 'img') {
+ const res = await this.$api.post(this.urlList.deleteImage, {
+ ami_id: data.ami_id,
+ article_id: this.articleId
+ });
+ if (res.status == 1) {
+ this.$message.success(res.msg);
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.replacement('img', data.ami_id);
+ }
+ } else {
+ this.$message.error(res.msg);
+ }
+ } else if (type == 'table' || type == 'math') {
+ const res = await this.$api.post(this.urlList.deleteTable, {
+ amt_id: data.amt_id,
+ article_id: this.articleId
+ });
+ if (res.status == 1) {
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.replacement(type, data.amt_id);
+ }
+ } else {
+ this.$message.error(res.msg);
+ }
+ }
+ } catch (err) {
+ this.$message.error((err && err.msg) || 'Error');
+ } finally {
+ loading.close();
+ }
+ },
+ async handleDeleteAllFigures(list) {
+ const images = Array.isArray(list) ? list.filter((item) => item && item.ami_id) : [];
+ if (!images.length) {
+ return;
+ }
+ try {
+ await this.$confirm(this.$t('commonTable.figureDeleteAllConfirm'), 'Prompt', {
+ confirmButtonText: 'Submit',
+ cancelButtonText: 'Cancel',
+ type: 'warning'
+ });
+ } catch (e) {
+ return;
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let fail = 0;
+ for (let i = 0; i < images.length; i++) {
+ const item = images[i];
+ try {
+ const res = await this.$api.post(this.urlList.deleteImage, {
+ ami_id: item.ami_id,
+ article_id: this.articleId
+ });
+ if (res && res.status == 1) {
+ ok += 1;
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.replacement('img', item.ami_id);
+ }
+ } else {
+ fail += 1;
+ }
+ } catch (err) {
+ fail += 1;
+ }
+ }
+ loading.close();
+ this.$message.success(this.$t('commonTable.figureDeleteAllResult', { ok: ok, fail: fail }));
+ if (this.$refs.commonWordHtmlTypeSetting) {
+ this.$refs.commonWordHtmlTypeSetting.refresh('img');
+ }
+ },
handleTableAdd(type) {
this.lineStyle = { note: '', table_data: '', html_data: '' };
this.lineStyle.visiTitle = 'Add Table';
@@ -1508,6 +1757,280 @@ export default {
this.currentId = dataId;
},
+
+ resolveMainRowsForMediaPosition() {
+ const lists = [];
+ if (Array.isArray(this.Main_List) && this.Main_List.length) {
+ lists.push(this.Main_List);
+ }
+ if (Array.isArray(this.ManuscirptContent) && this.ManuscirptContent.length) {
+ lists.push(this.ManuscirptContent);
+ }
+ const word = this.$refs.commonWord;
+ if (word && Array.isArray(word.wordList) && word.wordList.length) {
+ lists.push(word.wordList);
+ }
+ if (word && Array.isArray(word.contentList) && word.contentList.length) {
+ lists.push(word.contentList);
+ }
+ return lists;
+ },
+ findAmIdForFigureNumber(figureNumber) {
+ const lists = this.resolveMainRowsForMediaPosition();
+ for (let i = 0; i < lists.length; i++) {
+ const amId = findFirstAmIdForFigureNumber(lists[i], figureNumber);
+ if (amId) return amId;
+ }
+ return null;
+ },
+ findAmIdForTableNumber(tableNumber) {
+ const lists = this.resolveMainRowsForMediaPosition();
+ for (let i = 0; i < lists.length; i++) {
+ const amId = findFirstAmIdForTableNumber(lists[i], tableNumber);
+ if (amId) return amId;
+ }
+ return null;
+ },
+ async handleAutoPositionImage(img) {
+ if (!img || !img.ami_id) return;
+ if (Number(img.has_selected) === 1) return;
+ const result = await this.autoPositionImageCore(img, { silent: false });
+ if (result && result.ok) {
+ this.$message.success(this.$t('commonTable.figureAutoPositionDone', { num: result.num }));
+ }
+ },
+ async handleAutoPositionTable(table) {
+ if (!table || !table.amt_id) return;
+ if (Number(table.has_selected) === 1) return;
+ const result = await this.autoPositionTableCore(table, { silent: false });
+ if (result && result.ok) {
+ this.$message.success(this.$t('commonTable.tableAutoPositionDone', { num: result.num }));
+ }
+ },
+ async autoPositionImageCore(img, options = {}) {
+ const silent = !!options.silent;
+ const figureNumber = parseFigureNumberFromTitle(img.title || '');
+ if (!figureNumber) {
+ if (!silent) this.$message.warning(this.$t('commonTable.figureAutoPositionNoNum'));
+ return { ok: false, reason: 'noNum' };
+ }
+ const amId = this.findAmIdForFigureNumber(figureNumber);
+ if (!amId) {
+ if (!silent) this.$message.warning(this.$t('commonTable.figureAutoPositionNoHit', { num: figureNumber }));
+ return { ok: false, reason: 'noHit', num: figureNumber };
+ }
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (!silent && panel && typeof panel.setPositioningFigureLoading === 'function') {
+ panel.setPositioningFigureLoading(img.ami_id);
+ }
+ let loading = null;
+ if (!silent) {
+ loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ }
+ try {
+ const res = await this.$api.post(this.urlList.setPositioningImage, {
+ am_id: amId,
+ ami_id: img.ami_id
+ });
+ if (res && res.code == 0) {
+ if (!silent) {
+ if (typeof this.getDate === 'function') {
+ await this.getDate();
+ } else if (typeof this.refreshCurrentContent === 'function') {
+ this.refreshCurrentContent('positioningImg', amId, res.data);
+ }
+ this.$nextTick(() => {
+ if (panel) {
+ panel.refresh('img');
+ panel.refresh('positioningImg', res.data);
+ }
+ if (typeof this.goToComment === 'function') {
+ this.goToComment(amId);
+ }
+ });
+ } else if (typeof this.refreshCurrentContent === 'function') {
+ this.refreshCurrentContent('positioningImg', amId, res.data);
+ }
+ return { ok: true, num: figureNumber, amId, data: res.data };
+ }
+ if (!silent) this.$message.error((res && res.msg) || 'Error');
+ return { ok: false, reason: 'error', num: figureNumber };
+ } catch (err) {
+ if (!silent) this.$message.error((err && err.msg) || 'Error');
+ return { ok: false, reason: 'error', num: figureNumber };
+ } finally {
+ if (loading) loading.close();
+ if (!silent && panel && typeof panel.setPositioningFigureLoading === 'function') {
+ panel.setPositioningFigureLoading(null);
+ }
+ }
+ },
+ async autoPositionTableCore(table, options = {}) {
+ const silent = !!options.silent;
+ const tableNumber = parseTableNumberFromTitle(table.title || '');
+ if (!tableNumber) {
+ if (!silent) this.$message.warning(this.$t('commonTable.tableAutoPositionNoNum'));
+ return { ok: false, reason: 'noNum' };
+ }
+ const amId = this.findAmIdForTableNumber(tableNumber);
+ if (!amId) {
+ if (!silent) this.$message.warning(this.$t('commonTable.tableAutoPositionNoHit', { num: tableNumber }));
+ return { ok: false, reason: 'noHit', num: tableNumber };
+ }
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (!silent && panel && typeof panel.setPositioningTableLoading === 'function') {
+ panel.setPositioningTableLoading(table.amt_id);
+ }
+ let loading = null;
+ if (!silent) {
+ loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ }
+ try {
+ const res = await this.$api.post(this.urlList.setPositioningTable, {
+ am_id: amId,
+ amt_id: table.amt_id
+ });
+ if (res && res.code == 0) {
+ if (!silent) {
+ if (typeof this.getDate === 'function') {
+ await this.getDate();
+ } else if (typeof this.refreshCurrentContent === 'function') {
+ this.refreshCurrentContent('positioningTable', amId, res.data);
+ }
+ this.$nextTick(() => {
+ if (panel) {
+ panel.refresh('table');
+ panel.refresh('positioningTable', res.data);
+ }
+ if (typeof this.goToComment === 'function') {
+ this.goToComment(amId);
+ }
+ });
+ } else if (typeof this.refreshCurrentContent === 'function') {
+ this.refreshCurrentContent('positioningTable', amId, res.data);
+ }
+ return { ok: true, num: tableNumber, amId, data: res.data };
+ }
+ if (!silent) this.$message.error((res && res.msg) || 'Error');
+ return { ok: false, reason: 'error', num: tableNumber };
+ } catch (err) {
+ if (!silent) this.$message.error((err && err.msg) || 'Error');
+ return { ok: false, reason: 'error', num: tableNumber };
+ } finally {
+ if (loading) loading.close();
+ if (!silent && panel && typeof panel.setPositioningTableLoading === 'function') {
+ panel.setPositioningTableLoading(null);
+ }
+ }
+ },
+ async handleBatchAutoPositionImages(list) {
+ const images = (Array.isArray(list) ? list : []).filter(
+ (img) => img && img.ami_id && Number(img.has_selected) !== 1
+ );
+ if (!images.length) {
+ this.$message.info(this.$t('commonTable.figureBatchPositionEmpty'));
+ return;
+ }
+ images.sort((a, b) => {
+ const na = parseFigureNumberFromTitle(a.title || '') || 9999;
+ const nb = parseFigureNumberFromTitle(b.title || '') || 9999;
+ return na - nb;
+ });
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (panel && typeof panel.setBatchPositioningFigures === 'function') {
+ panel.setBatchPositioningFigures(true);
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let skip = 0;
+ let fail = 0;
+ try {
+ for (let i = 0; i < images.length; i++) {
+ const result = await this.autoPositionImageCore(images[i], { silent: true });
+ if (result && result.ok) ok += 1;
+ else if (result && (result.reason === 'noNum' || result.reason === 'noHit')) skip += 1;
+ else fail += 1;
+ }
+ if (typeof this.getDate === 'function') {
+ await this.getDate();
+ }
+ if (panel) {
+ panel.refresh('img');
+ }
+ this.$message.success(
+ this.$t('commonTable.figureBatchPositionDone', { ok: ok, skip: skip, fail: fail })
+ );
+ } finally {
+ loading.close();
+ if (panel && typeof panel.setBatchPositioningFigures === 'function') {
+ panel.setBatchPositioningFigures(false);
+ }
+ }
+ },
+ async handleBatchAutoPositionTables(list) {
+ const tables = (Array.isArray(list) ? list : []).filter(
+ (table) => table && table.amt_id && Number(table.has_selected) !== 1
+ );
+ if (!tables.length) {
+ this.$message.info(this.$t('commonTable.tableBatchPositionEmpty'));
+ return;
+ }
+ tables.sort((a, b) => {
+ const na = parseTableNumberFromTitle(a.title || '') || 9999;
+ const nb = parseTableNumberFromTitle(b.title || '') || 9999;
+ return na - nb;
+ });
+ const panel = this.$refs.commonWordHtmlTypeSetting;
+ if (panel && typeof panel.setBatchPositioningTables === 'function') {
+ panel.setBatchPositioningTables(true);
+ }
+ const loading = this.$loading({
+ lock: true,
+ text: 'Loading...',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+ let ok = 0;
+ let skip = 0;
+ let fail = 0;
+ try {
+ for (let i = 0; i < tables.length; i++) {
+ const result = await this.autoPositionTableCore(tables[i], { silent: true });
+ if (result && result.ok) ok += 1;
+ else if (result && (result.reason === 'noNum' || result.reason === 'noHit')) skip += 1;
+ else fail += 1;
+ }
+ if (typeof this.getDate === 'function') {
+ await this.getDate();
+ }
+ if (panel) {
+ panel.refresh('table');
+ }
+ this.$message.success(
+ this.$t('commonTable.tableBatchPositionDone', { ok: ok, skip: skip, fail: fail })
+ );
+ } finally {
+ loading.close();
+ if (panel && typeof panel.setBatchPositioningTables === 'function') {
+ panel.setBatchPositioningTables(false);
+ }
+ }
+ },
async onDrop(event, dataId) {
if (event.dataTransfer.getData('image')) {
@@ -2384,4 +2907,70 @@ export default {
background-color: #0066990d;
/* display: block !important; */
}
+.imported-word-outline {
+ margin: 12px 0 0;
+ padding: 12px 14px;
+ background: #f7f9fc;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+}
+.imported-word-outline__title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 13px;
+ font-weight: 600;
+ color: #303133;
+ cursor: pointer;
+ user-select: none;
+}
+.imported-word-outline__title:hover {
+ color: #006699;
+}
+.imported-word-outline__arrow {
+ transition: transform 0.2s ease;
+ color: #909399;
+}
+.imported-word-outline__arrow.is-expanded {
+ transform: rotate(90deg);
+}
+.imported-word-outline__list {
+ list-style: none;
+ margin: 8px 0 0;
+ padding: 0;
+}
+.imported-word-outline__item {
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+ padding: 4px 0;
+ font-size: 13px;
+ line-height: 1.45;
+ color: #303133;
+}
+.imported-word-outline__item.level-1 {
+ font-weight: 600;
+}
+.imported-word-outline__item.level-2 {
+ padding-left: 18px;
+ color: #606266;
+}
+.imported-word-outline__badge {
+ flex: none;
+ min-width: 28px;
+ height: 18px;
+ line-height: 18px;
+ text-align: center;
+ border-radius: 2px;
+ font-size: 11px;
+ color: #fff;
+ background: #006699;
+}
+.imported-word-outline__item.level-2 .imported-word-outline__badge {
+ background: #909399;
+}
+.imported-word-outline__text {
+ flex: 1;
+ word-break: break-word;
+}
diff --git a/src/components/page/articleAdd.vue b/src/components/page/articleAdd.vue
index 5154e07..ac570e1 100644
--- a/src/components/page/articleAdd.vue
+++ b/src/components/page/articleAdd.vue
@@ -63,6 +63,29 @@
/>
+
+
+
+
+
+
{{ index + 1 }}
-
- *
- Name :
-
+ Name :
- *
+ *
Email :
@@ -723,10 +744,7 @@
-->
-
- *
- Affiliation :
-
+ Affiliation :
@@ -1248,6 +1266,8 @@ export default {
// checkedjours: [],
abstrart: '',
type: '',
+ special_num: '',
+ special_title: '',
approval: '',
// istransfer: false,
// becomeRev: false,
@@ -1270,6 +1290,8 @@ export default {
},
raltiAutList: [],
journal_type: [],
+ specialList: [],
+ showSpecialSelect: false,
reviewerForm: {
username: localStorage.getItem('U_name'),
gender: 1,
@@ -1282,20 +1304,6 @@ export default {
qualifications: ''
},
tuiJianForm: [
- {
- realname: '',
- email: '',
- department: '',
- company: '',
- major_all: ''
- },
- {
- realname: '',
- email: '',
- department: '',
- company: '',
- major_all: ''
- },
{
realname: '',
email: '',
@@ -1311,47 +1319,7 @@ export default {
fileL_manuscirpt: [],
fileL_supplementary: [],
fileL_articleCopyright: [],
- tuiJianRules: {
- realname: [
- {
- required: true,
- message: 'Please enter a realname',
- trigger: 'blur'
- }
- ],
- email: [
- {
- required: true,
- message: 'Please enter a email',
- trigger: 'blur'
- },
- {
- validator: validateNotQQEmail, // 绑定自定义校验
- trigger: 'blur'
- }
- ],
- // department: [
- // {
- // required: true,
- // message: 'Please enter a department',
- // trigger: 'blur'
- // }
- // ],
- company: [
- {
- required: true,
- message: 'Please select a affiliation',
- trigger: 'blur'
- }
- ]
- // major_all: [
- // {
- // required: true,
- // message: 'Please select a Filed',
- // trigger: 'blur'
- // }
- // ]
- },
+ tuiJianRules: {},
rules: {
journal: [
{
@@ -1855,6 +1823,48 @@ export default {
}
});
},
+ // 有选专刊才传 special_num、special_title,没有则不带这两字段
+ onSpecialChange(val) {
+ if (val === undefined || val === null || val === '' || Number(val) === 0) {
+ this.form.special_num = '';
+ this.form.special_title = '';
+ return;
+ }
+ this.form.special_num = val;
+ const matched = (this.specialList || []).find(
+ (item) => String(item.journal_special_id) === String(val)
+ );
+ this.form.special_title = (matched && matched.title) || this.form.special_title || '';
+ },
+ getSelectedSpecialPayload() {
+ const specialId = this.form.special_num;
+ if (specialId === undefined || specialId === null || specialId === '' || Number(specialId) === 0) {
+ return null;
+ }
+ const matched = (this.specialList || []).find(
+ (item) => String(item.journal_special_id) === String(specialId)
+ );
+ // id 始终用表单选中的 journal_special_id;title 优先表单已存值,再回落列表
+ return {
+ special_num: String(specialId),
+ special_title: String(
+ this.form.special_title || (matched && matched.title) || ''
+ )
+ };
+ },
+ withSpecialId(payload) {
+ const data = Object.assign({}, payload || {});
+ delete data.special_id;
+ const special = this.getSelectedSpecialPayload();
+ if (special) {
+ data.special_num = special.special_num;
+ data.special_title = special.special_title;
+ } else {
+ delete data.special_num;
+ delete data.special_title;
+ }
+ return data;
+ },
handleStepClick(e) {
console.log('e at line 1469:', e);
// 通过事件源找到点击的步骤项
@@ -1910,52 +1920,103 @@ export default {
this.$forceUpdate();
},
- // 提交前校验所有评审人表单
- async validateAllReviewers() {
- // 统计「已填写且通过校验」的表单数量
- let validFilledCount = 0;
- // 定义「表单是否为空」的判断逻辑(根据你的实际核心字段调整!)
- // 示例:判断核心字段(如姓名、专业)是否都为空,可根据业务增删字段
- const isFormEmpty = (formData) => {
- // 核心字段列表:请替换为你的实际必填字段(空表单的判断标准)
- const coreFields = ['realname', 'email', 'company']; // 示例字段:姓名、专业
- return coreFields.every((field) => {
- const value = formData[field];
- // 空值判断:包括 undefined、null、''、空数组等
- return value === undefined || value === null || value === '' || (Array.isArray(value) && value.length === 0);
- });
+ // 推荐审稿人:整行是否填写了除邮箱外的任意信息(有则邮箱必填)
+ hasReviewerPartialData(item) {
+ if (!item) {
+ return false;
+ }
+ const name = String(item.realname || '').trim();
+ const company = String(item.company || '').trim();
+ const department = String(item.department || '').trim();
+ const major = item.major_all;
+ const hasMajor = Array.isArray(major) ? major.length > 0 : !!major;
+ return !!(name || company || department || hasMajor);
+ },
+ isReviewerRowEmpty(item) {
+ if (!item) {
+ return true;
+ }
+ const email = String(item.email || '').trim();
+ return !email && !this.hasReviewerPartialData(item);
+ },
+ createEmptyReviewer() {
+ return {
+ realname: '',
+ email: '',
+ department: '',
+ company: '',
+ major_all: []
};
-
- // 遍历所有表单实例
- for (const form of this.$refs.tuiJianForm) {
+ },
+ validateReviewerEmail(rule, value, callback) {
+ const emailReg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+ const qqEmailReg = /@qq\.com$/i;
+ if (!value) {
+ callback();
+ return;
+ }
+ if (!emailReg.test(value)) {
+ callback(new Error('Please enter a valid email address'));
+ return;
+ }
+ if (qqEmailReg.test(value)) {
+ callback(new Error('QQ email is not allowed'));
+ return;
+ }
+ callback();
+ },
+ getTuiJianRules(item) {
+ const needEmail = this.hasReviewerPartialData(item);
+ const emailRules = [];
+ if (needEmail) {
+ emailRules.push({
+ required: true,
+ message: 'Please enter a email',
+ trigger: 'blur'
+ });
+ }
+ emailRules.push({
+ validator: this.validateReviewerEmail,
+ trigger: 'blur'
+ });
+ return {
+ realname: [],
+ company: [],
+ email: emailRules
+ };
+ },
+ // 提交前校验推荐审稿人:非必填;若填了信息则邮箱必填
+ async validateAllReviewers() {
+ const forms = this.$refs.tuiJianForm;
+ if (!forms) {
+ return true;
+ }
+ const formList = Array.isArray(forms) ? forms : [forms];
+ for (let i = 0; i < formList.length; i++) {
+ const item = this.tuiJianForm[i];
+ if (this.isReviewerRowEmpty(item)) {
+ continue;
+ }
+ if (!String((item && item.email) || '').trim()) {
+ return false;
+ }
try {
- // 1. 获取当前表单的绑定数据(根据你的表单组件调整!)
- // 若你的表单用 v-model 绑定在 form.model 上,就取 form.model;若绑定在其他属性,需对应修改
- const formData = form.model || form;
-
- // 2. 判断表单是否「未填写」:未填写则跳过校验
- if (isFormEmpty(formData)) {
- continue;
- }
-
- // 3. 已填写的表单:必须通过校验
- await form.validate();
- // 4. 校验通过,计数+1
- validFilledCount++;
+ await formList[i].validate();
} catch (error) {
- // 已填写的表单校验失败,直接终止并返回false
return false;
}
}
-
- // 5. 最终校验:至少有1条已填写且通过校验
- return validFilledCount >= 1;
+ return true;
},
handleJournalSelected(journal) {
if (journal == '') {
this.check_item = {};
this.ms_alias = '';
this.form.journal = '';
+ this.form.special_num = '';
+ this.form.special_title = '';
+ this.specialList = [];
+ this.showSpecialSelect = false;
this.reviewerof.journal = 1;
if (localStorage.getItem('ms_journal_alias')) {
@@ -2001,21 +2062,15 @@ export default {
// return false;
// }
- // 5. 处理推荐审稿人信息及校验
- const hasReviewerInfo = this.tuiJianForm.some((item) =>
- item.major_all ? item.major_all.length > 0 : '' || item.realname || item.email || item.country
- );
+ // 5. 推荐审稿人非必填;若填写了信息则邮箱必填
if (!(await this.validateAllReviewers())) {
- this.$message.error(
- 'Please recommend at least one reviewer and fill in their complete information. This will help speed up the review process!'
- );
+ this.$message.error('If you fill in reviewer information, please provide a valid email.');
return false;
- } else {
- this.tuiJianForm.forEach((item) => {
- item.major = item.major_all && item.major_all.length > 0 ? item.major_all[item.major_all.length - 1] : '';
- });
- this.form.reviewers = this.tuiJianForm;
}
+ this.tuiJianForm.forEach((item) => {
+ item.major = item.major_all && item.major_all.length > 0 ? item.major_all[item.major_all.length - 1] : '';
+ });
+ this.form.reviewers = this.tuiJianForm.filter((item) => !this.isReviewerRowEmpty(item));
// 6. 所有校验通过,提交 manuscript
this.Submission_of_manuscripts();
@@ -2029,9 +2084,25 @@ export default {
background: 'rgba(0, 0, 0, 0.7)'
});
+ // 用纯对象提交;专刊字段最后强制写入,避免被覆盖或丢失
+ let payload;
+ try {
+ payload = JSON.parse(JSON.stringify(this.form));
+ } catch (e) {
+ payload = Object.assign({}, this.form);
+ }
+ delete payload.special_id;
+ delete payload.special_num;
+ delete payload.special_title;
+ const special = this.getSelectedSpecialPayload();
+ if (special) {
+ payload.special_num = special.special_num;
+ payload.special_title = special.special_title;
+ }
+
this.$api
// api/Article/addArticle
- .post('api/Article/addArticlePart4', this.form)
+ .post('api/Article/addArticlePart4', payload)
.then((res) => {
this.loading = false;
if (res.code == 0) {
@@ -2089,6 +2160,9 @@ export default {
this.jour_form.journal = this.items[i].journal_id;
}
}
+ if (this.form.journal) {
+ this.loadSpecialsByJournal(this.form.journal, true);
+ }
this.$api
.post('api/Reviewer/getAllMajor')
@@ -2582,18 +2656,18 @@ export default {
}
},
- // 添加推荐审稿人
+ // 添加推荐审稿人(最多 3 个)
onAddTuijian() {
- this.tuiJianForm.push({
- realname: '',
- email: '',
- department: '',
- company: '',
- major_all: ''
- });
+ if (this.tuiJianForm.length >= 3) {
+ return;
+ }
+ this.tuiJianForm.push(this.createEmptyReviewer());
},
onDeleteTuijian(item, index) {
+ if (this.tuiJianForm.length <= 1) {
+ return;
+ }
this.tuiJianForm.splice(index, 1);
},
dowloadFileTemplate() {
@@ -3161,6 +3235,9 @@ export default {
this.majors_b = [];
this.majors_c = [];
this.mj_jour = [];
+ this.form.special_num = '';
+ this.form.special_title = '';
+ this.loadSpecialsByJournal(this.form.journal);
this.changeVisible = false;
this.initMajor();
@@ -3188,6 +3265,9 @@ export default {
this.majors_b = [];
this.majors_c = [];
this.mj_jour = [];
+ this.form.special_num = '';
+ this.form.special_title = '';
+ this.loadSpecialsByJournal(e);
if (this.$route.query.id) {
this.saveArticle();
@@ -3195,6 +3275,61 @@ export default {
this.initMajor();
// this.getTopics()
},
+ async loadSpecialsByJournal(journalId, keepSelected) {
+ const jid = journalId || this.form.journal;
+ if (!jid) {
+ this.specialList = [];
+ this.showSpecialSelect = false;
+ if (!keepSelected) {
+ this.form.special_num = '';
+ this.form.special_title = '';
+ }
+ return;
+ }
+ try {
+ const res = await this.$api.post('api/Special/getSpecials', {
+ journal_id: jid
+ });
+ if (res.code != 0) {
+ this.specialList = [];
+ this.showSpecialSelect = false;
+ if (!keepSelected) {
+ this.form.special_num = '';
+ this.form.special_title = '';
+ }
+ return;
+ }
+ const list =
+ (res.data && (res.data.specials || res.data.special)) ||
+ (res.data && res.data.data && (res.data.data.specials || res.data.data.special)) ||
+ [];
+ const isShow = String((res.data && res.data.is_show) || '').toLowerCase() !== 'false';
+ this.specialList = list;
+ this.showSpecialSelect = isShow && list.length > 0;
+ if (!keepSelected) {
+ this.form.special_num = '';
+ this.form.special_title = '';
+ } else if (this.form.special_num) {
+ const matched = list.find(
+ (item) =>
+ String(item.journal_special_id) === String(this.form.special_num) ||
+ String(item.special_num) === String(this.form.special_num)
+ );
+ if (matched) {
+ this.form.special_num = matched.journal_special_id;
+ this.form.special_title = matched.title || this.form.special_title || '';
+ }
+ // 列表中暂时匹配不到时,保留已保存的 special_num / special_title,便于提交
+ }
+ } catch (err) {
+ this.specialList = [];
+ this.showSpecialSelect = false;
+ if (!keepSelected) {
+ this.form.special_num = '';
+ this.form.special_title = '';
+ }
+ }
+ },
saveArticle() {
// api/Article/changeJournal
@@ -3478,21 +3613,23 @@ export default {
return false;
}
this.$api
- .post('api/Article/addArticlePart1', {
- article_id: this.form.article_id,
- journal: this.form.journal,
- title: this.form.title,
- keyWords: this.form.keyWords,
- abstrart: this.form.abstrart,
- type: this.form.type,
- username: this.form.username,
- user_id: this.form.user_id,
- approval: this.form.approval,
- approval_file: this.form.approval_file,
- approval_content: this.form.approval_content,
-
- fund: this.form.fund
- })
+ .post(
+ 'api/Article/addArticlePart1',
+ this.withSpecialId({
+ article_id: this.form.article_id,
+ journal: this.form.journal,
+ title: this.form.title,
+ keyWords: this.form.keyWords,
+ abstrart: this.form.abstrart,
+ type: this.form.type,
+ username: this.form.username,
+ user_id: this.form.user_id,
+ approval: this.form.approval,
+ approval_file: this.form.approval_file,
+ approval_content: this.form.approval_content,
+ fund: this.form.fund
+ })
+ )
.then((res) => {
if (res.code == 0) {
this.stagingID = res.data.article_id;
@@ -3722,7 +3859,7 @@ export default {
}
this.form.keyWords = fstr == '' ? '' : fstr.substring(0, fstr.length - 1);
this.save(
- {
+ this.withSpecialId({
article_id: this.form.article_id,
journal: this.form.journal,
title: this.form.title,
@@ -3734,9 +3871,8 @@ export default {
approval: this.form.approval,
approval_file: this.form.approval_file,
approval_content: this.form.approval_content,
-
fund: this.form.fund
- },
+ }),
(res) => {
if (res.status == 1) {
const url = new URL(window.location.href);
@@ -3855,26 +3991,16 @@ export default {
}
if (this.tuiJianForm.length > 0) {
- // const hasInvalidEmail = this.tuiJianForm.some((item) => {
- // // 假设邮箱字段为 item.email,根据实际字段名修改
- // return !item.email || item.email.trim() === '';
- // });
-
- // if (hasInvalidEmail) {
- // // 提示用户“所有项的邮箱为必填项”
- // this.$message.error(`Each reviewer's email is required, please fill it out completely`);
- // return; // 终止后续逻辑(比如不执行下面的 data.major 赋值)
- // }
- // 方法2:使用map返回新数组(如果不想修改原数组)
- var list = this.tuiJianForm.map((item) => {
- // 复制原对象,避免修改原数组元素
- const newItem = { ...item };
- newItem.major =
- item.major_all && Array.isArray(item.major_all) && item.major_all.length > 0
- ? item.major_all[item.major_all.length - 1]
- : '';
- return newItem;
- });
+ var list = this.tuiJianForm
+ .filter((item) => !this.isReviewerRowEmpty(item))
+ .map((item) => {
+ const newItem = { ...item };
+ newItem.major =
+ item.major_all && Array.isArray(item.major_all) && item.major_all.length > 0
+ ? item.major_all[item.major_all.length - 1]
+ : '';
+ return newItem;
+ });
console.log('list:', list);
data.reviewers = list;
console.log('data.reviewers at line 3219:', data.reviewers);
@@ -3954,6 +4080,9 @@ export default {
this.form.journal = res.data.base.journal_id;
this.$forceUpdate();
this.form.type = res.data.base.type;
+ this.form.special_num =
+ res.data.base.special_num || res.data.base.special_id || '';
+ this.form.special_title = res.data.base.special_title || '';
this.form.title = res.data.base.title;
this.form.approval = res.data.base.approval;
this.form.approval_file = res.data.base.approval_file;
@@ -3966,35 +4095,12 @@ export default {
console.log('this.form.is_use_ai at line 3442:', this.form.is_use_ai);
this.form.code = res.data.base.code;
if (res.data.reviewer.length > 0) {
- // 处理原有评审员数据
- const processedList = res.data.reviewer.map((e) => ({
+ this.tuiJianForm = res.data.reviewer.slice(0, 3).map((e) => ({
...e,
major_all: e.p_major ? e.p_major.split(',').map(Number) : []
}));
-
- // 计算需要补充的数量(不足3个则补全)
- const needAddCount = Math.max(0, 3 - processedList.length);
-
- // 补充空白对象(结构与处理后的数据一致,可根据实际需求调整默认值)
- const List = Array.from({ length: needAddCount }, () => ({
- // 这里可以根据实际业务需求设置默认值,保持字段结构一致
- id: '', // 示例字段,可根据实际情况调整
- name: '', // 示例字段,可根据实际情况调整
- p_major: '', // 与原数据字段对应
- major_all: [] // 保持处理后的字段结构
- // 其他必要字段可按需添加
- }));
-
- // 合并处理后的数据和补充数据,赋值给tuiJianForm
- this.tuiJianForm = [...processedList, ...List];
} else {
- // 可选:如果原reviewer为空,也默认设置3个空白对象(根据需求决定是否保留)
- this.tuiJianForm = Array.from({ length: 3 }, () => ({
- id: '',
- name: '',
- p_major: '',
- major_all: []
- }));
+ this.tuiJianForm = [this.createEmptyReviewer()];
}
console.log('this.tuiJianForm at line 3506:', this.tuiJianForm);
@@ -4007,6 +4113,7 @@ export default {
if (this.items.find((e) => e.journal_id == this.form.journal)) {
this.check_item = this.items.find((e) => e.journal_id == this.form.journal);
}
+ await this.loadSpecialsByJournal(this.form.journal, true);
let keyList = res.data.base.keywords.split(',');
this.keywordsList = [];
for (let i = 0; i < keyList.length; i++) {
diff --git a/src/components/page/articleDetailEditor.vue b/src/components/page/articleDetailEditor.vue
index 38c5450..39d22a5 100644
--- a/src/components/page/articleDetailEditor.vue
+++ b/src/components/page/articleDetailEditor.vue
@@ -189,16 +189,19 @@
-
- Production started
-
+
+
+ Special Topic :
+ {{ form.special_num > 0 ? form.special_title : 'None' }}
+ Change
+
Manuscript :
Save
+
+
+ Special Topic
+
+
+
+
+
Current
+
+ {{ specialTopicForm.special_title }}
+
+
None
+
+
Clear
+
+
+
+
+
+
+
{{ scope.row.title }}
+
{{ scope.row.interests || scope.row.keywords }}
+
+
+
+
+
+ {{ scope.row.editor || '—' }}
+
+
+
+
+
+ Selected
+ Select
+
+
+
+
+
+
+
+
Close
+
+
+
+
+
+
+
+ -
+ {{ scope.row.compliance }}
+ {{ scope.row.compliance }}
+
+
+
+
+ {{ scope.row.indicesText || $t('commonTable.wordRefStatsIndicesEmpty') }}
+
+
+
+
+
{{ $t('commonTable.wordRefStatsDetailTitle') }}
+
+ {{ group.label }}:
+ {{ group.indicesText || $t('commonTable.wordRefStatsIndicesEmpty') }}
+
+
+
+
{{ $t('commonTable.wordRefStatsItemDetailTitle') }}
+
+
+
+
+ {{ scope.row.yearText }}
+
+
+
+
+ {{ tag.label }}
+ -
+
+
+
+
+
+
+
+
@@ -1563,6 +1778,8 @@ import timetalk from './time_talk';
import reviewerDetail from '../../components/page/components/articleDetail/reviewerdetail.vue';
import FigureCopyright from '../../components/page/components/articleDetail/FigureCopyright.vue';
import ReReviewNotifyMailDialog from '../../components/page/components/articleDetail/ReReviewNotifyMailDialog.vue';
+import { isZyModeEnabled } from '@/utils/zyMode';
+import { analyzeManuscriptWordReferenceStatistics } from '@/utils/wordReferenceStatistics';
export default {
components: {
timetalk,
@@ -1598,6 +1815,9 @@ export default {
drawer: false,
loading: false,
beginProduceLoading: false,
+ wordRefStatsDialogVisible: false,
+ wordRefStatsLoading: false,
+ wordRefStats: null,
loading1: false,
loading2: false,
loading3: false,
@@ -1606,6 +1826,18 @@ export default {
editbox: false,
resubmitVisible: false,
repebox: false,
+ specialTopicVisible: false,
+ specialTopicOpening: false,
+ specialTopicSaving: false,
+ specialTopicAllList: [],
+ specialTopicQuery: {
+ pageIndex: 1,
+ pageSize: 20
+ },
+ specialTopicForm: {
+ special_num: 0,
+ special_title: ''
+ },
HEditVisible: false,
HIxForm: {
index: ''
@@ -1944,6 +2176,18 @@ export default {
upload_zip: function () {
return this.baseUrl + 'api/Article/up_file/type/repezip';
},
+ specialTopicFilteredList() {
+ return Array.isArray(this.specialTopicAllList) ? this.specialTopicAllList : [];
+ },
+ specialTopicFilteredTotal() {
+ return this.specialTopicFilteredList.length;
+ },
+ specialTopicPageList() {
+ const page = Math.max(1, Number(this.specialTopicQuery.pageIndex) || 1);
+ const size = Math.max(1, Number(this.specialTopicQuery.pageSize) || 20);
+ const start = (page - 1) * size;
+ return this.specialTopicFilteredList.slice(start, start + size);
+ },
journal_me: function () {
var frag = this.form.journalname;
if (this.form.special_num > 0) {
@@ -1951,11 +2195,164 @@ export default {
}
return frag;
},
+ // 顶部期刊信息加载完成后再显示 Special Topic Change
+ specialTopicChangeReady() {
+ const journalId = this.form.journal || this.form.journal_id;
+ const journalName = this.form.journalname || this.form.journal_name;
+ return !!(journalId && journalName);
+ },
showBeginProduceBtn() {
const state = Number(this.form.state);
const hasProduce = Number(this.form.has_produce);
return state === 6 && hasProduce === 0;
},
+ zyModeEnabled() {
+ return isZyModeEnabled(this.$route);
+ },
+ wordRefStatsTableRows() {
+ const stats = this.wordRefStats;
+ if (!stats || !Array.isArray(stats.rows)) {
+ return [];
+ }
+ const self = this;
+ return stats.rows.map(function (row) {
+ let category = '';
+ let goal = '';
+ if (row.key === 'total') {
+ category = self.$t('commonTable.wordRefStatsTotal');
+ } else if (row.key === 'chinese') {
+ category = self.$t('commonTable.wordRefStatsChinese');
+ goal = self.$t('commonTable.wordRefStatsChineseGoal');
+ } else if (row.key === 'fiveYear') {
+ category =
+ self.$t('commonTable.wordRefStatsFiveYear') +
+ ' ' +
+ self.$t('commonTable.wordRefStatsYearRange', {
+ start: row.rangeStart,
+ end: row.rangeEnd
+ });
+ goal = self.$t('commonTable.wordRefStatsFiveYearGoal');
+ } else if (row.key === 'threeYear') {
+ category =
+ self.$t('commonTable.wordRefStatsThreeYear') +
+ ' ' +
+ self.$t('commonTable.wordRefStatsYearRange', {
+ start: row.rangeStart,
+ end: row.rangeEnd
+ });
+ goal = self.$t('commonTable.wordRefStatsThreeYearGoal');
+ }
+ let compliance = '-';
+ if (row.pass === true) {
+ compliance = self.$t('commonTable.wordRefStatsPass') + goal;
+ } else if (row.pass === false) {
+ compliance = self.$t('commonTable.wordRefStatsFail') + ' (' + self.$t('commonTable.wordRefStatsGoal') + goal + ')';
+ }
+ return {
+ category: category,
+ result: self.$t('commonTable.wordRefStatsCountUnit', { count: row.count }),
+ percent: row.percent + '%',
+ compliance: compliance,
+ pass: row.pass,
+ indicesText: row.indicesText || ''
+ };
+ });
+ },
+ wordRefStatsDetailGroups() {
+ const stats = this.wordRefStats;
+ if (!stats) {
+ return [];
+ }
+ const groups = [];
+
+ function pushGroup(key, label) {
+ const source = (stats.detailGroups || []).find(function (item) {
+ return item.key === key;
+ });
+ groups.push({
+ key: key,
+ label: label,
+ indicesText: (source && source.indicesText) || stats[key + 'IndicesText'] || ''
+ });
+ }
+
+ pushGroup('chinese', this.$t('commonTable.wordRefStatsChinese'));
+ pushGroup(
+ 'fiveYear',
+ this.$t('commonTable.wordRefStatsFiveYear') +
+ ' ' +
+ this.$t('commonTable.wordRefStatsYearRange', {
+ start: stats.fiveYearStart,
+ end: stats.currentYear
+ })
+ );
+ pushGroup(
+ 'threeYear',
+ this.$t('commonTable.wordRefStatsThreeYear') +
+ ' ' +
+ this.$t('commonTable.wordRefStatsYearRange', {
+ start: stats.threeYearStart,
+ end: stats.currentYear
+ })
+ );
+ pushGroup('noYear', this.$t('commonTable.wordRefStatsNoYearLabel'));
+
+ return groups;
+ },
+ wordRefStatsBaselineText() {
+ const stats = this.wordRefStats;
+ if (!stats) {
+ return '';
+ }
+ return this.$t('commonTable.wordRefStatsBaselineNote', {
+ year: stats.currentYear,
+ source: this.$t('commonTable.wordRefStatsBaselineToday')
+ });
+ },
+ wordRefStatsItemRows() {
+ const stats = this.wordRefStats;
+ if (!stats || !Array.isArray(stats.itemDetails)) {
+ return [];
+ }
+ const self = this;
+ const tagLabelMap = {
+ threeYear: 'wordRefStatsTagThreeYear',
+ fiveYear: 'wordRefStatsTagFiveYear',
+ chinese: 'wordRefStatsTagChinese',
+ noYear: 'wordRefStatsTagNoYear',
+ older: 'wordRefStatsTagOlder'
+ };
+ return stats.itemDetails.map(function (item) {
+ const tagLabels = (item.tags || []).map(function (tag) {
+ return {
+ key: tag,
+ label: self.$t('commonTable.' + tagLabelMap[tag])
+ };
+ });
+ return {
+ index: item.index,
+ yearText: item.noYear ? '-' : String(item.year),
+ noYear: item.noYear,
+ tagLabels: tagLabels,
+ preview: item.preview || ''
+ };
+ });
+ },
+ wordRefStatsAiCompareVisible() {
+ const ai = this.currentArticleData && this.currentArticleData.ai_review;
+ if (!ai) {
+ return false;
+ }
+ return !!(ai.references_past_three || ai.references_past_five);
+ },
+ wordRefStatsAiThreeYearText() {
+ const ai = this.currentArticleData && this.currentArticleData.ai_review;
+ return (ai && ai.references_past_three) || '-';
+ },
+ wordRefStatsAiFiveYearText() {
+ const ai = this.currentArticleData && this.currentArticleData.ai_review;
+ return (ai && ai.references_past_five) || '-';
+ },
articleState: function () {
let str = '';
@@ -2306,6 +2703,52 @@ export default {
isReReviewNotifyEnabled() {
return Object.prototype.hasOwnProperty.call(this.$route.query, 'zy');
},
+ resolveManuscriptPath() {
+ const formPath = String(this.form.manuscirpt || '').trim();
+ if (formPath) {
+ return formPath;
+ }
+ const list = this.manuscirptFileList || [];
+ if (list.length) {
+ const last = list[list.length - 1];
+ return String((last && last.file_url) || '').trim();
+ }
+ return '';
+ },
+ async handleShowWordReferenceStatistics() {
+ if (this.wordRefStatsLoading) {
+ return;
+ }
+ const articleId = this.$route.query.id || this.form.articleId;
+ if (!articleId) {
+ this.$message.warning(this.$t('commonTable.wordRefsPreviewNoArticle'));
+ return;
+ }
+ this.wordRefStatsLoading = true;
+ try {
+ const result = await analyzeManuscriptWordReferenceStatistics(this.$api, {
+ articleId: articleId,
+ manuscriptPath: this.resolveManuscriptPath(),
+ mediaUrl: this.mediaUrl,
+ baseUrl: this.baseUrl
+ });
+ if (!result.found || !result.stats || !result.stats.total) {
+ this.$message.warning(this.$t('commonTable.wordRefsPreviewEmpty'));
+ return;
+ }
+ this.wordRefStats = result.stats;
+ this.wordRefStatsDialogVisible = true;
+ } catch (err) {
+ console.error(err);
+ if (err && err.message === 'NO_MANUSCRIPT_FILE') {
+ this.$message.warning(this.$t('commonTable.wordRefsPreviewNoManuscript'));
+ } else {
+ this.$message.error(this.$t('commonTable.wordRefsPreviewFail'));
+ }
+ } finally {
+ this.wordRefStatsLoading = false;
+ }
+ },
openReReviewNotifyMail(reviewer) {
this.reReviewNotifyReviewer = reviewer ? { ...reviewer } : null;
this.reReviewNotifyVisible = true;
@@ -2484,6 +2927,108 @@ export default {
changeRepe() {
this.repebox = true;
},
+ async openSpecialTopic() {
+ const journalId = this.form.journal || this.form.journal_id;
+ if (!journalId) {
+ this.$message.warning('Journal info is missing');
+ return;
+ }
+ if (this.specialTopicOpening) {
+ return;
+ }
+ this.specialTopicForm.special_num = this.form.special_num > 0 ? Number(this.form.special_num) : 0;
+ this.specialTopicForm.special_title = this.form.special_title || '';
+ this.specialTopicQuery.pageIndex = 1;
+ this.specialTopicOpening = true;
+ try {
+ const ok = await this.loadSpecialTopicList(journalId);
+ if (ok) {
+ this.specialTopicVisible = true;
+ }
+ } finally {
+ this.specialTopicOpening = false;
+ }
+ },
+ async loadSpecialTopicList(journalId) {
+ const id = journalId || this.form.journal || this.form.journal_id;
+ if (!id) {
+ return false;
+ }
+ try {
+ const res = await this.$api.post('api/Special/getSpecials', {
+ journal_id: id
+ });
+ if (res.code == 0) {
+ this.specialTopicAllList = (res.data && res.data.specials) || [];
+ return true;
+ }
+ this.specialTopicAllList = [];
+ this.$message.error(res.msg || 'Failed to load special list');
+ return false;
+ } catch (err) {
+ this.specialTopicAllList = [];
+ this.$message.error(err);
+ return false;
+ }
+ },
+ handleSpecialTopicPageChange(page) {
+ this.specialTopicQuery.pageIndex = page;
+ },
+ handleSpecialTopicSizeChange(size) {
+ this.specialTopicQuery.pageSize = size;
+ this.specialTopicQuery.pageIndex = 1;
+ },
+ selectSpecialTopicNone() {
+ this.specialTopicForm.special_num = 0;
+ this.specialTopicForm.special_title = '';
+ },
+ selectSpecialTopicRow(row) {
+ if (!row) {
+ return;
+ }
+ this.specialTopicForm.special_num = row.journal_special_id;
+ this.specialTopicForm.special_title = row.title || '';
+ },
+ isSpecialTopicSelected(row) {
+ return row && this.specialTopicForm.special_num > 0 && row.journal_special_id == this.specialTopicForm.special_num;
+ },
+ specialTopicRowClassName({ row }) {
+ return this.isSpecialTopicSelected(row) ? 'special-topic-row-active' : '';
+ },
+ saveSpecialTopic() {
+ let specialNum = this.specialTopicForm.special_num;
+ if (specialNum === '' || specialNum === null || specialNum === undefined) {
+ specialNum = 0;
+ }
+ let specialTitle = '';
+ if (specialNum > 0) {
+ const hit = this.specialTopicAllList.find((item) => item.journal_special_id == specialNum);
+ specialTitle = hit ? hit.title : this.specialTopicForm.special_title || '';
+ }
+ this.specialTopicSaving = true;
+ this.$api
+ .post('api/Article/changeArticleSpecialForSubmit', {
+ article_id: this.$route.query.id,
+ journal_special_id: specialNum,
+ special_title: specialTitle
+ })
+ .then((res) => {
+ if (res.code == 0) {
+ this.form.special_num = specialNum;
+ this.form.special_title = specialTitle;
+ this.specialTopicVisible = false;
+ this.$message.success(res.msg || 'Successfully!');
+ } else {
+ this.$message.error(res.msg);
+ }
+ })
+ .catch((err) => {
+ this.$message.error(err);
+ })
+ .finally(() => {
+ this.specialTopicSaving = false;
+ });
+ },
mystate(mystate) {
let str = '';
switch (mystate) {
@@ -3379,9 +3924,148 @@ export default {
gap: 16px;
}
-.crumbs-produce-btn.el-button {
+.crumbs-header-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
flex-shrink: 0;
margin-right: 18px;
+}
+
+.crumbs-word-refs-btn.el-button {
+ font-weight: 600;
+}
+
+.word-ref-stats-pass {
+ color: #67c23a;
+ font-weight: 600;
+}
+
+.word-ref-stats-fail {
+ color: #f56c6c;
+ font-weight: 600;
+}
+
+.word-ref-stats-neutral {
+ color: #909399;
+}
+
+.word-ref-stats-meta {
+ margin-top: 14px;
+ font-size: 13px;
+ line-height: 1.6;
+ color: #606266;
+}
+
+.word-ref-stats-baseline {
+ margin: 0 0 6px;
+ color: #303133;
+ font-weight: 600;
+}
+
+.word-ref-stats-hint {
+ margin: 0 0 8px;
+ color: #e6a23c;
+}
+
+.word-ref-stats-ai-compare {
+ margin: 10px 0;
+ padding: 10px 12px;
+ background: #f5f7fa;
+ border-radius: 4px;
+}
+
+.word-ref-stats-ai-title {
+ margin: 0 0 6px;
+ font-weight: 600;
+ color: #303133;
+}
+
+.word-ref-stats-ai-compare p {
+ margin: 0 0 4px;
+}
+
+.word-ref-stats-diff-note {
+ margin: 8px 0 0;
+ color: #909399;
+ font-size: 12px;
+}
+
+.word-ref-stats-indices {
+ color: #303133;
+ word-break: break-word;
+ line-height: 1.5;
+}
+
+.word-ref-stats-detail {
+ margin-top: 16px;
+ padding-top: 12px;
+ border-top: 1px solid #ebeef5;
+}
+
+.word-ref-stats-detail-title {
+ margin: 0 0 10px;
+ font-size: 14px;
+ font-weight: 600;
+ color: #303133;
+}
+
+.word-ref-stats-detail-item {
+ margin-bottom: 8px;
+ font-size: 13px;
+ line-height: 1.6;
+}
+
+.word-ref-stats-detail-label {
+ color: #606266;
+ font-weight: 600;
+}
+
+.word-ref-stats-item-detail {
+ margin-top: 16px;
+ padding-top: 12px;
+ border-top: 1px solid #ebeef5;
+}
+
+.word-ref-stats-tag {
+ display: inline-block;
+ margin: 0 6px 4px 0;
+ padding: 0 6px;
+ border-radius: 3px;
+ font-size: 12px;
+ line-height: 20px;
+ background: #ecf5ff;
+ color: #409eff;
+}
+
+.word-ref-stats-tag-threeYear,
+.word-ref-stats-tag-fiveYear {
+ background: #f0f9eb;
+ color: #67c23a;
+}
+
+.word-ref-stats-tag-chinese {
+ background: #fdf6ec;
+ color: #e6a23c;
+}
+
+.word-ref-stats-tag-noYear {
+ background: #fef0f0;
+ color: #f56c6c;
+}
+
+.word-ref-stats-tag-older {
+ background: #f4f4f5;
+ color: #909399;
+}
+
+.word-ref-stats-no-year-cell {
+ color: #f56c6c;
+ font-weight: 600;
+}
+
+.crumbs-produce-btn.el-button {
+ flex-shrink: 0;
border: none;
color: #fff;
font-size: 13px;
@@ -4092,4 +4776,128 @@ td {
.copyright-declaration-wrapper :deep(.el-radio.is-checked .el-radio__label) {
font-weight: 500;
}
+.special-topic-dialog {
+ min-height: 480px;
+}
+.special-topic-dialog-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 24px;
+}
+.special-topic-current-bar {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 12px;
+ padding: 10px 12px;
+ background: #f7fbff;
+ border: 1px solid #d6e8f5;
+ border-left: 3px solid #006699;
+ border-radius: 4px;
+}
+.special-topic-current-main {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: baseline;
+ gap: 8px;
+}
+.special-topic-current-label {
+ flex-shrink: 0;
+ font-size: 12px;
+ color: #909399;
+ letter-spacing: 0.02em;
+}
+.special-topic-current-text {
+ margin: 0;
+ flex: 1;
+ min-width: 0;
+ font-size: 13px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 1.45;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.special-topic-current-text.is-empty {
+ font-weight: 500;
+ color: #909399;
+}
+.special-topic-clear-btn {
+ flex-shrink: 0;
+ padding: 0;
+ color: #006699;
+}
+.special-topic-title-cell {
+ padding: 4px 0;
+}
+.special-topic-row-title {
+ margin: 0;
+ font-size: 13px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 1.45;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+.special-topic-row-keywords {
+ margin: 4px 0 0;
+ font-size: 12px;
+ color: #909399;
+ line-height: 1.4;
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+.special-topic-footer-bar {
+ margin-top: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+.special-topic-passed-tip {
+ margin: 0;
+ flex: 1;
+ min-width: 200px;
+ font-size: 12px;
+ color: #909399;
+ line-height: 1.5;
+}
+.special-topic-pagination {
+ text-align: right;
+ flex-shrink: 0;
+}
+
+
+
diff --git a/src/components/page/articleListEditor_B1.vue b/src/components/page/articleListEditor_B1.vue
index d59c027..de6eb50 100644
--- a/src/components/page/articleListEditor_B1.vue
+++ b/src/components/page/articleListEditor_B1.vue
@@ -258,9 +258,23 @@
{{ tabsList[1].name }}
-
- Add Author
+
+
+ {{ $t('commonTable.zyBatchDeleteAuthors') }}
+
+
+ Add Author
+
+
@@ -483,9 +499,23 @@
Affiliation Information
-
- Add affiliation
+
+
+ {{ $t('commonTable.zyBatchDeleteAffiliations') }}
+
+
+ Add affiliation
+
+
@@ -987,6 +1019,9 @@
:article_id="detailMes.w_article_id"
:p_article_id="this.p_article_id"
:article_title="detailMes.title"
+ :keywords="detailMes.keywords"
+ :journal_id="detailMes.journal_id"
+ :journal_title="deMesYul.journal_title || ''"
v-if="detailMes.article_id"
>
@@ -1212,7 +1247,10 @@ import {
sortAuthorsByOrderString,
moveAuthorInList,
getAuthorDisplayName,
- getAuthorAffiliationPreview
+ getAuthorAffiliationPreview,
+ fetchLastSubmissionManuscriptPath,
+ fetchContributeFileParsedContent,
+ mergeParsedArticleOntoEssential
} from '@/utils/productionSubmissionImport';
import { isZyModeEnabled, isZySkipCheckEnabled } from '@/utils/zyMode';
import { fetchWordReferencesSection } from '@/utils/manuscriptWordReferences';
@@ -1459,6 +1497,10 @@ export default {
addSchool: false,
authorData: [],
schoolData: [],
+ selectedAuthorRows: [],
+ selectedSchoolRows: [],
+ authorBatchDeleting: false,
+ schoolBatchDeleting: false,
addFomauthor: {
is_first: '0',
is_report: '0',
@@ -2233,9 +2275,30 @@ export default {
articleId,
human: 'editor'
});
- const article = (detailRes && detailRes.article) || {};
+ let article = (detailRes && detailRes.article) || {};
const userId = article.user_id;
+ // 最新稿件路径:getFilelistByArticleID → type_name=manuscirpt 最后一条
+ let manuscriptPath = '';
+ let parsedFromWord = null;
+ try {
+ manuscriptPath = await fetchLastSubmissionManuscriptPath(this.$api, articleId);
+ if (manuscriptPath) {
+ this.gridData = manuscriptPath;
+ parsedFromWord = {};
+ // parsedFromWord = await fetchContributeFileParsedContent(this.$api, manuscriptPath, {
+ // articleId,
+ // userId
+ // });
+ }
+ } catch (parseErr) {
+ console.warn('contributeFileUrl parse skipped:', parseErr);
+ }
+
+ if (parsedFromWord && parsedFromWord.article) {
+ article = mergeParsedArticleOntoEssential(article, parsedFromWord.article);
+ }
+
const requestList = [this.$api.post('api/Article/getAuthors', { article_id: articleId }).catch(() => null)];
if (userId) {
requestList.push(
@@ -2244,7 +2307,15 @@ export default {
}
const [authorsRes, organsRes] = await Promise.all(requestList);
- const authors = normalizeSubmissionAuthors(resolveSubmissionAuthors(authorsRes, detailRes));
+ let authors = normalizeSubmissionAuthors(resolveSubmissionAuthors(authorsRes, detailRes));
+ if (
+ (!authors || !authors.length) &&
+ parsedFromWord &&
+ Array.isArray(parsedFromWord.authors) &&
+ parsedFromWord.authors.length
+ ) {
+ authors = normalizeSubmissionAuthors(parsedFromWord.authors);
+ }
const submissionOrgans = collectSubmissionOrgans(
organsRes && Number(organsRes.status) === 1 && Array.isArray(organsRes.data) ? organsRes.data : [],
authors
@@ -2255,7 +2326,9 @@ export default {
article,
authors,
submissionOrgans,
- mapped
+ mapped,
+ manuscriptPath: manuscriptPath || (parsedFromWord && parsedFromWord.manuscriptPath) || '',
+ parsedFromWord
};
},
applyImportedEssentialFields(mapped) {
@@ -2276,7 +2349,7 @@ export default {
const loading = this.$loading({
lock: true,
- text: 'Loading submission data...',
+ text: 'Loading submission manuscript...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
@@ -2284,6 +2357,15 @@ export default {
try {
const context = await this.fetchSubmissionImportContext(articleId);
+ if (!context.manuscriptPath) {
+ this.$message.warning(
+ 'No manuscript Word file found (manuscirpt). Essential fields will use article detail only.'
+ );
+ } else if (!context.parsedFromWord) {
+ this.$message.warning(
+ 'Manuscript found but contributeFileUrl parse failed. Using article detail fields.'
+ );
+ }
this.importPreviewContext = context;
this.importPreviewAuthors = [...context.authors];
this.importAuthorOrderText = '';
@@ -2658,6 +2740,63 @@ export default {
});
},
// 2----删除作者
+ onAuthorSelectionChange(rows) {
+ this.selectedAuthorRows = rows || [];
+ },
+ onSchoolSelectionChange(rows) {
+ this.selectedSchoolRows = rows || [];
+ },
+ clearAuthorTableSelection() {
+ this.selectedAuthorRows = [];
+ this.$nextTick(() => {
+ if (this.$refs.authorTable) {
+ this.$refs.authorTable.clearSelection();
+ }
+ });
+ },
+ clearSchoolTableSelection() {
+ this.selectedSchoolRows = [];
+ this.$nextTick(() => {
+ if (this.$refs.schoolTable) {
+ this.$refs.schoolTable.clearSelection();
+ }
+ });
+ },
+ async batchAuthorDelete() {
+ const selected = (this.selectedAuthorRows || []).slice();
+ const rows = selected.length ? selected : (this.authorData || []).slice();
+ if (!rows.length) {
+ return;
+ }
+ try {
+ await this.$confirm(
+ this.$t('commonTable.zyBatchDeleteAuthorsConfirm', { count: rows.length }),
+ 'Tips',
+ { type: 'warning' }
+ );
+ } catch (err) {
+ return;
+ }
+ this.authorBatchDeleting = true;
+ let ok = 0;
+ let fail = 0;
+ for (let i = 0; i < rows.length; i++) {
+ try {
+ const res = await this.$api.post('api/Production/delAuthor', rows[i]);
+ if (res && res.code == 0) {
+ ok += 1;
+ } else {
+ fail += 1;
+ }
+ } catch (err) {
+ fail += 1;
+ }
+ }
+ this.authorBatchDeleting = false;
+ this.$message.success(this.$t('commonTable.zyBatchDeleteResult', { ok: ok, fail: fail }));
+ this.clearAuthorTableSelection();
+ this.getAuthorJG();
+ },
authorDelete(index, row) {
// 二次确认删除
this.$confirm('Whether to delete the authors joint and several institutional relationships?', 'Tips', {
@@ -2740,6 +2879,41 @@ export default {
});
},
// 2----删除机构
+ async batchSchoolDelete() {
+ const selected = (this.selectedSchoolRows || []).slice();
+ const rows = selected.length ? selected : (this.schoolData || []).slice();
+ if (!rows.length) {
+ return;
+ }
+ try {
+ await this.$confirm(
+ this.$t('commonTable.zyBatchDeleteAffiliationsConfirm', { count: rows.length }),
+ 'Tips',
+ { type: 'warning' }
+ );
+ } catch (err) {
+ return;
+ }
+ this.schoolBatchDeleting = true;
+ let ok = 0;
+ let fail = 0;
+ for (let i = 0; i < rows.length; i++) {
+ try {
+ const res = await this.$api.post('api/Production/delAuthorOrgan', rows[i]);
+ if (res && res.code == 0) {
+ ok += 1;
+ } else {
+ fail += 1;
+ }
+ } catch (err) {
+ fail += 1;
+ }
+ }
+ this.schoolBatchDeleting = false;
+ this.$message.success(this.$t('commonTable.zyBatchDeleteResult', { ok: ok, fail: fail }));
+ this.clearSchoolTableSelection();
+ this.getAuthorJG();
+ },
schoolDelete(index, row) {
// 二次确认删除
this.$confirm('Do you want to delete the author relationship between the organization and its associated authors?', 'Tips', {
@@ -3972,6 +4146,13 @@ export default {
letter-spacing: -0.5px;
}
+.author-section-actions {
+ float: right;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+}
+
.captcha-img.el-switch.is-disabled {
opacity: 1;
}
diff --git a/src/components/page/components/article/Related.vue b/src/components/page/components/article/Related.vue
index a61128b..1efce67 100644
--- a/src/components/page/components/article/Related.vue
+++ b/src/components/page/components/article/Related.vue
@@ -2,7 +2,20 @@
Related Articles Selected
- Related Articles
+
+
+
+ 按 keywords 批量查询
+
+
+ Related Articles
+
@@ -35,6 +48,17 @@
Search
+
+
+ 按 keywords 批量查询
+
+
No Articles
@@ -54,15 +78,67 @@
-
-
-
{{ item.title }}
+
+
+ 近3年
+ ({{ selectRelateRecent.length }})
+
+
+
+
+ {{ item.title }}
+ ({{ item._pub_date_ymd }})
+ {{
+ formatHitKeywords(item)
+ }}
+
+
+
Add
-
- Add
-
+
近3年暂无文章
+
+ 3年前
+ ({{ selectRelateOlder.length }})
+
+
+
+
+ {{ item.title }}
+ ({{ item._pub_date_ymd }})
+ {{
+ formatHitKeywords(item)
+ }}
+
+
+
Add
+
+
3年前暂无文章
+
+
+
+
+
+ {{ item.title }}
+ ({{ formatArticlePubDate(item) }})
+
+
+
Add
+
+
@@ -79,8 +155,26 @@