This commit is contained in:
owenchen 2026-06-23 15:32:12 +08:00
parent 996bb243df
commit 5f1062c010
15 changed files with 769 additions and 104 deletions

View File

@ -61,8 +61,9 @@ namespace CloudBuilder.AI.Gui
statusCol = new DataGridViewTextBoxColumn();
tabPage2 = new TabPage();
tableLayoutPanel7 = new TableLayoutPanel();
kryptonDataGridView1 = new Krypton.Toolkit.KryptonDataGridView();
kryptonDataGridView2 = new Krypton.Toolkit.KryptonDataGridView();
bookPersonGv = new Krypton.Toolkit.KryptonDataGridView();
bookPersonNameCol = new DataGridViewTextBoxColumn();
bookActorNameCol = new DataGridViewComboBoxColumn();
tableLayoutPanel2 = new TableLayoutPanel();
statusCombo = new Krypton.Toolkit.KryptonComboBox();
guidLabel = new Krypton.Toolkit.KryptonLabel();
@ -113,8 +114,7 @@ namespace CloudBuilder.AI.Gui
((System.ComponentModel.ISupportInitialize)dataGv).BeginInit();
tabPage2.SuspendLayout();
tableLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)kryptonDataGridView1).BeginInit();
((System.ComponentModel.ISupportInitialize)kryptonDataGridView2).BeginInit();
((System.ComponentModel.ISupportInitialize)bookPersonGv).BeginInit();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)statusCombo).BeginInit();
processPanel.SuspendLayout();
@ -415,34 +415,48 @@ namespace CloudBuilder.AI.Gui
//
// tableLayoutPanel7
//
tableLayoutPanel7.ColumnCount = 2;
tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel7.Controls.Add(kryptonDataGridView1, 0, 0);
tableLayoutPanel7.Controls.Add(kryptonDataGridView2, 1, 0);
tableLayoutPanel7.Location = new Point(76, 31);
tableLayoutPanel7.ColumnCount = 1;
tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tableLayoutPanel7.Controls.Add(bookPersonGv, 0, 0);
tableLayoutPanel7.Dock = DockStyle.Fill;
tableLayoutPanel7.Location = new Point(3, 3);
tableLayoutPanel7.Name = "tableLayoutPanel7";
tableLayoutPanel7.RowCount = 2;
tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 69.93671F));
tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 30.0632915F));
tableLayoutPanel7.Size = new Size(622, 316);
tableLayoutPanel7.RowCount = 1;
tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel7.Size = new Size(998, 392);
tableLayoutPanel7.TabIndex = 0;
//
// kryptonDataGridView1
// bookPersonGv
//
kryptonDataGridView1.BorderStyle = BorderStyle.None;
kryptonDataGridView1.Location = new Point(3, 3);
kryptonDataGridView1.Name = "kryptonDataGridView1";
kryptonDataGridView1.Size = new Size(209, 173);
kryptonDataGridView1.TabIndex = 0;
bookPersonGv.AllowUserToAddRows = false;
bookPersonGv.AllowUserToDeleteRows = false;
bookPersonGv.BorderStyle = BorderStyle.None;
bookPersonGv.Columns.AddRange(new DataGridViewColumn[] { bookPersonNameCol, bookActorNameCol });
bookPersonGv.Dock = DockStyle.Fill;
bookPersonGv.Location = new Point(3, 3);
bookPersonGv.Name = "bookPersonGv";
bookPersonGv.Size = new Size(992, 386);
bookPersonGv.TabIndex = 0;
//
// kryptonDataGridView2
// bookPersonNameCol
//
kryptonDataGridView2.BorderStyle = BorderStyle.None;
kryptonDataGridView2.Location = new Point(314, 3);
kryptonDataGridView2.Name = "kryptonDataGridView2";
kryptonDataGridView2.Size = new Size(209, 173);
kryptonDataGridView2.TabIndex = 0;
bookPersonNameCol.DataPropertyName = "PersonName";
bookPersonNameCol.HeaderText = "人名";
bookPersonNameCol.Name = "bookPersonNameCol";
bookPersonNameCol.Resizable = DataGridViewTriState.True;
bookPersonNameCol.Width = 200;
//
// bookActorNameCol
//
bookActorNameCol.DataPropertyName = "ActorName";
bookActorNameCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
bookActorNameCol.HeaderText = "配音";
bookActorNameCol.Name = "bookActorNameCol";
bookActorNameCol.Resizable = DataGridViewTriState.True;
bookActorNameCol.SortMode = DataGridViewColumnSortMode.Automatic;
bookActorNameCol.Width = 500;
//
// tableLayoutPanel2
//
@ -904,8 +918,7 @@ namespace CloudBuilder.AI.Gui
((System.ComponentModel.ISupportInitialize)dataGv).EndInit();
tabPage2.ResumeLayout(false);
tableLayoutPanel7.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)kryptonDataGridView1).EndInit();
((System.ComponentModel.ISupportInitialize)kryptonDataGridView2).EndInit();
((System.ComponentModel.ISupportInitialize)bookPersonGv).EndInit();
tableLayoutPanel2.ResumeLayout(false);
tableLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)statusCombo).EndInit();
@ -975,8 +988,7 @@ namespace CloudBuilder.AI.Gui
private TableLayoutPanel processPanel;
private Krypton.Toolkit.KryptonButton extractNamesBut;
private TableLayoutPanel tableLayoutPanel7;
private Krypton.Toolkit.KryptonDataGridView kryptonDataGridView1;
private Krypton.Toolkit.KryptonDataGridView kryptonDataGridView2;
private Krypton.Toolkit.KryptonDataGridView bookPersonGv;
private TableLayoutPanel tableLayoutPanel6;
private CloudBuilder.Gui.GridViewPagination gridViewPagination;
private Krypton.Toolkit.KryptonDataGridView sentenceGv;
@ -992,5 +1004,7 @@ namespace CloudBuilder.AI.Gui
private Krypton.Toolkit.KryptonDataGridViewTextBoxColumn sentimentCol;
private Krypton.Toolkit.KryptonDataGridViewComboBoxColumn sentenceStatusCol;
private Krypton.Toolkit.KryptonButton generaterMp3But;
private DataGridViewTextBoxColumn bookPersonNameCol;
private DataGridViewComboBoxColumn bookActorNameCol;
}
}

View File

@ -103,6 +103,7 @@ namespace CloudBuilder.AI.Gui
private void InitComBox()
{
statusCombo.SetDataSource(bookStatusPolicy.GetDataSource(), true);
bookPersonGv.SetColumnDataSource(bookActorNameCol, SoVITSTtsVoicePolicy.GetInstance().GetComposeMessages(), true);
}
/// <summary>
/// DataGridView分页控件初始化
@ -132,9 +133,11 @@ namespace CloudBuilder.AI.Gui
authorTxt.Set(AiBookEntity.AUTHOR);
bookTypeTxt.Set(AiBookEntity.BOOK_TYPE);
filePathTxt.Set(AiBookData.FILE_NAME, EnumEditModeColor.ReadOnly);
bookPersonNameCol.Set(EnumEditModeColor.ReadOnly);
dataGv.InitColumn(false, false);
sentenceGv.InitColumn(true, false);
bookPersonGv.InitColumn(true, false);
guiOperateHelper = new GuiOperateHelper();
}
@ -285,6 +288,7 @@ namespace CloudBuilder.AI.Gui
private void PackUIToEntity()
{
guiBindingContext.DataPack();
data.AiBookPersons = bookPersonGv.GetUpdateRows<AiBookPersonEntity>();
}
private bool SaveValidate()
@ -416,6 +420,7 @@ namespace CloudBuilder.AI.Gui
private void PackEntityToUI()
{
guiBindingContext.DataBind(data.AiBook, this);
bookPersonGv.SetDataSource(data.AiBookPersons);
filePathTxt.Text = data.FileName;
@ -752,7 +757,7 @@ namespace CloudBuilder.AI.Gui
AiChapterEntity chapter = dataGv.GetRowData<AiChapterEntity>(dataGv.SelectedCells[0].RowIndex);
AiSentenceViewEntity[] aiSentences = aiSentenceRequest.FindByChapterId(chapter.ChapterId);
AiSentenceViewEntity[] aiSentences = aiSentenceRequest.FindByChapterId(chapter.BookId, chapter.ChapterId);
sentenceGv.SetDataSource(aiSentences);
}

View File

@ -135,6 +135,12 @@
<metadata name="statusCol.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="bookPersonNameCol.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="bookActorNameCol.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="createBut.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>

View File

@ -41,6 +41,9 @@ namespace CloudBuilder.AI.Service
{
AiBookData data = new AiBookData();
data.AiBook = repository.DetachedEntities.Where(x => x.BookId == key).FirstOrDefault()!;
IRepository<AiBookPersonEntity> repositoryAiBookPersonEntity = service.GetRepository<IRepository<AiBookPersonEntity>>();
data.AiBookPersons = repositoryAiBookPersonEntity.DetachedEntities.Where(x => x.BookId == key).ToArray();
if (data.AiBook.FileId > 0)
{
@ -156,6 +159,14 @@ namespace CloudBuilder.AI.Service
repository.UpdateNow(aiBook);
if (data.AiBookPersons != null && data.AiBookPersons.Length > 0)
{
IRepository<AiBookPersonEntity> repositoryAiBookPersonEntity = service.GetRepository<IRepository<AiBookPersonEntity>>();
repositoryAiBookPersonEntity.UpdateNow(data.AiBookPersons);
}
return data;
}
@ -278,8 +289,8 @@ namespace CloudBuilder.AI.Service
string save_path = Path.Combine(service.Configuration["FileServiceSettings:BackupDmsFileDirectory"], @"voice");
foreach (AiChapterEntity sentence in chapters)
{
string param = PackTtsParameters(ChineseTtsVoice.Sherpa2.ToString(), save_path, sentence.BookId, sentence.ChapterId.ToString());
RunMyProcess(service.Configuration["CloudBuilder.Topshelf:Path"], param);
string param = PackTtsParameters(save_path, sentence.BookId, sentence.ChapterId.ToString());
RunMyProcessAsync(service.Configuration["CloudBuilder.Topshelf:Path"], param);
}
}
@ -293,8 +304,8 @@ namespace CloudBuilder.AI.Service
string save_path = Path.Combine(service.Configuration["FileServiceSettings:BackupDmsFileDirectory"], @"voice");
foreach (AiChapterEntity sentence in chapters)
{
string param = PackTtsParameters(ChineseTtsVoice.Sherpa2.ToString(), save_path, sentence.BookId, sentence.ChapterId.ToString());
RunMyProcess(service.Configuration["CloudBuilder.Topshelf:Path"], param);
string param = PackTtsParameters(save_path, sentence.BookId, sentence.ChapterId.ToString());
RunMyProcessAsync(service.Configuration["CloudBuilder.Topshelf:Path"], param);
}
}
@ -335,7 +346,7 @@ namespace CloudBuilder.AI.Service
return para.ToArray().ToDelimiteredList(' ');
}
private string PackTtsParameters(string voice, string save_path, string bookId, string chapterId)
private string PackTtsParameters(string save_path, string bookId, string chapterId)
{
//速度快,音质差
//task:TtsTask book_id:B000008 chapter_id:3 speed:1 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice
@ -346,10 +357,10 @@ namespace CloudBuilder.AI.Service
para.Add("task:" + "SoVITSTtsTask");
para.Add("book_id:" + bookId);
para.Add("chapter_id:" + chapterId);
para.Add("voice:" + voice);
//para.Add("voice:" + voice);
para.Add("save_path:" + save_path);
para.Add("speed:1");
para.Add("actor:NA");
//para.Add("speed:1");
//para.Add("actor:NA");
return para.ToArray().ToDelimiteredList(' ');
}

View File

@ -29,11 +29,11 @@ namespace CloudBuilder.AI.Service
[PermissionOperate(name: AIPermissionPolicy.AiBook, operate: Operate.Find)]
public AiSentenceViewEntity[] FindByChapterId(long chapterId)
public AiSentenceViewEntity[] FindByChapterId(string bookId, long chapterId)
{
IRepository<AiSentenceViewEntity> repositoryAiSentenceViewEntity = repository.GetRepository<IRepository<AiSentenceViewEntity>>();
return repositoryAiSentenceViewEntity.DetachedEntities.Where(x => x.ChapterId == chapterId).OrderBy(x => x.ParagraphId).ThenBy(x=>x.SentenceIndex).ToArray();
return repositoryAiSentenceViewEntity.DetachedEntities.Where(x => x.BookId == bookId && x.ChapterId == chapterId).OrderBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray();
}
[PermissionOperate(name: AIPermissionPolicy.AiBook, operate: Operate.Find)]

View File

@ -28,7 +28,7 @@ namespace CloudBuilder.AI.Entity
[Column("book_id")]
public string BookId { get; set; }
[Column("person_name")]
public string PersonName { get; set; }
public string? PersonName { get; set; }
[Column("actor_name")]
public string? ActorName { get; set; }

View File

@ -1,4 +1,8 @@
using System;
using CloudBuilder.Core.DependencyInjection.Form;
using CloudBuilder.Core.DependencyInjection.Policy;
using CloudBuilder.Core.DependencyInjection.Request;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -102,4 +106,76 @@ namespace CloudBuilder.AI.Policy
FEMALE_CHILD4,
}
public class SoVITSTtsVoicePolicy : AbstractPolicy, IPolicy
{
public const string OLD_MAN1 = "OLD_MAN1";
public const string OLD_MAN2 = "OLD_MAN2";
public const string OLD_MAN3 = "OLD_MAN3";
public const string OLD_MAN4 = "OLD_MAN4";
public const string OLD_MAN5 = "OLD_MAN5";
public const string OLD_MAN6 = "OLD_MAN6";
public const string OLD_MAN7 = "OLD_MAN7";
public const string MIDDLE_AGED_MAN1 = "MIDDLE_AGED_MAN1";
public const string MIDDLE_AGED_MAN2 = "MIDDLE_AGED_MAN2";
public const string MIDDLE_AGED_MAN3 = "MIDDLE_AGED_MAN3";
public const string MIDDLE_AGED_MAN4 = "MIDDLE_AGED_MAN4";
public const string MIDDLE_AGED_MAN5 = "MIDDLE_AGED_MAN5";
public const string MIDDLE_AGED_MAN6 = "MIDDLE_AGED_MAN6";
public const string MIDDLE_AGED_MAN7 = "MIDDLE_AGED_MAN7";
public const string YOUNG_MALE1 = "YOUNG_MALE1";
public const string YOUNG_MALE2 = "YOUNG_MALE2";
public const string YOUNG_MALE3 = "YOUNG_MALE3";
public const string YOUNG_MALE4 = "YOUNG_MALE4";
public const string YOUNG_MALE5 = "YOUNG_MALE5";
public const string YOUNG_MALE6 = "YOUNG_MALE6";
public const string YOUNG_MALE7 = "YOUNG_MALE7";
public const string MALE_CHILD1 = "MALE_CHILD1";
public const string MALE_CHILD2 = "MALE_CHILD2";
public const string MALE_CHILD3 = "MALE_CHILD3";
public const string MALE_CHILD4 = "MALE_CHILD4";
public const string ELDERLY_FEMALE1 = "ELDERLY_FEMALE1";
public const string ELDERLY_FEMALE2 = "ELDERLY_FEMALE2";
public const string ELDERLY_FEMALE3 = "ELDERLY_FEMALE3";
public const string MIDDLE_AGED_FEMALE1 = "MIDDLE_AGED_FEMALE1";
public const string MIDDLE_AGED_FEMALE2 = "MIDDLE_AGED_FEMALE2";
public const string MIDDLE_AGED_FEMALE3 = "MIDDLE_AGED_FEMALE3";
public const string MIDDLE_AGED_FEMALE4 = "MIDDLE_AGED_FEMALE4";
public const string MIDDLE_AGED_FEMALE5 = "MIDDLE_AGED_FEMALE5";
public const string MIDDLE_AGED_FEMALE6 = "MIDDLE_AGED_FEMALE6";
public const string MIDDLE_AGED_FEMALE7 = "MIDDLE_AGED_FEMALE7";
public const string YOUNG_FEMALE1 = "YOUNG_FEMALE1";
public const string YOUNG_FEMALE2 = "YOUNG_FEMALE2";
public const string YOUNG_FEMALE3 = "YOUNG_FEMALE3";
public const string YOUNG_FEMALE4 = "YOUNG_FEMALE4";
public const string YOUNG_FEMALE5 = "YOUNG_FEMALE5";
public const string YOUNG_FEMALE6 = "YOUNG_FEMALE6";
public const string YOUNG_FEMALE7 = "YOUNG_FEMALE7";
public const string FEMALE_CHILD1 = "FEMALE_CHILD1";
public const string FEMALE_CHILD2 = "FEMALE_CHILD2";
public const string FEMALE_CHILD3 = "FEMALE_CHILD3";
public const string FEMALE_CHILD4 = "FEMALE_CHILD4";
public static SoVITSTtsVoicePolicy instance = null;
public SoVITSTtsVoicePolicy(IContext context) : base(context)
{
this.values = new string[] {
OLD_MAN1, OLD_MAN2, OLD_MAN3, OLD_MAN4, OLD_MAN5, OLD_MAN6, OLD_MAN7,
MIDDLE_AGED_MAN1,MIDDLE_AGED_MAN2,MIDDLE_AGED_MAN3,MIDDLE_AGED_MAN4,MIDDLE_AGED_MAN5,MIDDLE_AGED_MAN6,
YOUNG_MALE1,YOUNG_MALE2,YOUNG_MALE3,YOUNG_MALE4,YOUNG_MALE5,YOUNG_MALE6,YOUNG_MALE7,
MALE_CHILD1,MALE_CHILD2,MALE_CHILD3,MALE_CHILD4,
ELDERLY_FEMALE1,ELDERLY_FEMALE2,ELDERLY_FEMALE3,
MIDDLE_AGED_FEMALE1,MIDDLE_AGED_FEMALE2,MIDDLE_AGED_FEMALE3,MIDDLE_AGED_FEMALE4,MIDDLE_AGED_FEMALE5,MIDDLE_AGED_FEMALE6,MIDDLE_AGED_FEMALE7,
YOUNG_FEMALE1,YOUNG_FEMALE2,YOUNG_FEMALE3,YOUNG_FEMALE4,YOUNG_FEMALE5,YOUNG_FEMALE6,YOUNG_FEMALE7,
FEMALE_CHILD1,FEMALE_CHILD2,FEMALE_CHILD3,FEMALE_CHILD4};
}
public static SoVITSTtsVoicePolicy GetInstance()
{
instance = ApplicationServiceContext.ServiceProvider.GetKeyedService<SoVITSTtsVoicePolicy>(typeof(SoVITSTtsVoicePolicy).Name);
return instance;
}
}
}

View File

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ELDERLY_FEMALE1" xml:space="preserve">
<value>老年人女性1 音质好</value>
</data>
<data name="ELDERLY_FEMALE2" xml:space="preserve">
<value>老年人女性2</value>
</data>
<data name="ELDERLY_FEMALE3" xml:space="preserve">
<value>老年人女性3 音质好</value>
</data>
<data name="FEMALE_CHILD1" xml:space="preserve">
<value>女儿童女性1 音质好</value>
</data>
<data name="FEMALE_CHILD2" xml:space="preserve">
<value>女儿童女性2</value>
</data>
<data name="FEMALE_CHILD3" xml:space="preserve">
<value>女儿童女性3</value>
</data>
<data name="FEMALE_CHILD4" xml:space="preserve">
<value>女儿童女性4 音质好</value>
</data>
<data name="MALE_CHILD1" xml:space="preserve">
<value>男儿童男性1 音质好</value>
</data>
<data name="MALE_CHILD2" xml:space="preserve">
<value>男儿童男性2</value>
</data>
<data name="MALE_CHILD3" xml:space="preserve">
<value>男儿童男性3 音质好</value>
</data>
<data name="MALE_CHILD4" xml:space="preserve">
<value>男儿童男性4</value>
</data>
<data name="MIDDLE_AGED_FEMALE1" xml:space="preserve">
<value>女中年女性1</value>
</data>
<data name="MIDDLE_AGED_FEMALE2" xml:space="preserve">
<value>女中年女性2</value>
</data>
<data name="MIDDLE_AGED_FEMALE3" xml:space="preserve">
<value>女中年女性3 音质好</value>
</data>
<data name="MIDDLE_AGED_FEMALE4" xml:space="preserve">
<value>女中年女性4</value>
</data>
<data name="MIDDLE_AGED_FEMALE5" xml:space="preserve">
<value>女中年女性5 音质好</value>
</data>
<data name="MIDDLE_AGED_FEMALE6" xml:space="preserve">
<value>女中年女性6</value>
</data>
<data name="MIDDLE_AGED_FEMALE7" xml:space="preserve">
<value>女中年女性7</value>
</data>
<data name="MIDDLE_AGED_MAN1" xml:space="preserve">
<value>男中年男性1</value>
</data>
<data name="MIDDLE_AGED_MAN2" xml:space="preserve">
<value>男中年男性2</value>
</data>
<data name="MIDDLE_AGED_MAN3" xml:space="preserve">
<value>男中年男性3 音质好</value>
</data>
<data name="MIDDLE_AGED_MAN4" xml:space="preserve">
<value>男中年男性4</value>
</data>
<data name="MIDDLE_AGED_MAN5" xml:space="preserve">
<value>男中年男性5 音质好</value>
</data>
<data name="MIDDLE_AGED_MAN6" xml:space="preserve">
<value>男中年男性6</value>
</data>
<data name="MIDDLE_AGED_MAN7" xml:space="preserve">
<value>男中年男性7 音质好</value>
</data>
<data name="OLD_MAN1" xml:space="preserve">
<value>老年人男性1</value>
</data>
<data name="OLD_MAN2" xml:space="preserve">
<value>老年人男性2 音质好</value>
</data>
<data name="OLD_MAN3" xml:space="preserve">
<value>老年人男性3</value>
</data>
<data name="OLD_MAN4" xml:space="preserve">
<value>老年人男性4</value>
</data>
<data name="OLD_MAN5" xml:space="preserve">
<value>老年人男性5 音质好</value>
</data>
<data name="OLD_MAN6" xml:space="preserve">
<value>老年人男性6</value>
</data>
<data name="OLD_MAN7" xml:space="preserve">
<value>老年人男性7</value>
</data>
<data name="YOUNG_FEMALE1" xml:space="preserve">
<value>女青年女性1 音质好</value>
</data>
<data name="YOUNG_FEMALE2" xml:space="preserve">
<value>女青年女性2</value>
</data>
<data name="YOUNG_FEMALE3" xml:space="preserve">
<value>女青年女性3</value>
</data>
<data name="YOUNG_FEMALE4" xml:space="preserve">
<value>女青年女性4</value>
</data>
<data name="YOUNG_FEMALE5" xml:space="preserve">
<value>女青年女性5</value>
</data>
<data name="YOUNG_FEMALE6" xml:space="preserve">
<value>女青年女性6</value>
</data>
<data name="YOUNG_FEMALE7" xml:space="preserve">
<value>女青年女性7 音质好</value>
</data>
<data name="YOUNG_MALE1" xml:space="preserve">
<value>男青年男性1</value>
</data>
<data name="YOUNG_MALE2" xml:space="preserve">
<value>男青年男性2 音质好</value>
</data>
<data name="YOUNG_MALE3" xml:space="preserve">
<value>男青年男性3</value>
</data>
<data name="YOUNG_MALE4" xml:space="preserve">
<value>男青年男性4</value>
</data>
<data name="YOUNG_MALE5" xml:space="preserve">
<value>男青年男性5</value>
</data>
<data name="YOUNG_MALE6" xml:space="preserve">
<value>男青年男性6</value>
</data>
<data name="YOUNG_MALE7" xml:space="preserve">
<value>男青年男性7 音质好</value>
</data>
</root>

View File

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ELDERLY_FEMALE1" xml:space="preserve">
<value>老年人女性1 音质好</value>
</data>
<data name="ELDERLY_FEMALE2" xml:space="preserve">
<value>老年人女性2</value>
</data>
<data name="ELDERLY_FEMALE3" xml:space="preserve">
<value>老年人女性3 音质好</value>
</data>
<data name="FEMALE_CHILD1" xml:space="preserve">
<value>女儿童女性1 音质好</value>
</data>
<data name="FEMALE_CHILD2" xml:space="preserve">
<value>女儿童女性2</value>
</data>
<data name="FEMALE_CHILD3" xml:space="preserve">
<value>女儿童女性3</value>
</data>
<data name="FEMALE_CHILD4" xml:space="preserve">
<value>女儿童女性4 音质好</value>
</data>
<data name="MALE_CHILD1" xml:space="preserve">
<value>男儿童男性1 音质好</value>
</data>
<data name="MALE_CHILD2" xml:space="preserve">
<value>男儿童男性2</value>
</data>
<data name="MALE_CHILD3" xml:space="preserve">
<value>男儿童男性3 音质好</value>
</data>
<data name="MALE_CHILD4" xml:space="preserve">
<value>男儿童男性4</value>
</data>
<data name="MIDDLE_AGED_FEMALE1" xml:space="preserve">
<value>女中年女性1</value>
</data>
<data name="MIDDLE_AGED_FEMALE2" xml:space="preserve">
<value>女中年女性2</value>
</data>
<data name="MIDDLE_AGED_FEMALE3" xml:space="preserve">
<value>女中年女性3 音质好</value>
</data>
<data name="MIDDLE_AGED_FEMALE4" xml:space="preserve">
<value>女中年女性4</value>
</data>
<data name="MIDDLE_AGED_FEMALE5" xml:space="preserve">
<value>女中年女性5 音质好</value>
</data>
<data name="MIDDLE_AGED_FEMALE6" xml:space="preserve">
<value>女中年女性6</value>
</data>
<data name="MIDDLE_AGED_FEMALE7" xml:space="preserve">
<value>女中年女性7</value>
</data>
<data name="MIDDLE_AGED_MAN1" xml:space="preserve">
<value>男中年男性1</value>
</data>
<data name="MIDDLE_AGED_MAN2" xml:space="preserve">
<value>男中年男性2</value>
</data>
<data name="MIDDLE_AGED_MAN3" xml:space="preserve">
<value>男中年男性3 音质好</value>
</data>
<data name="MIDDLE_AGED_MAN4" xml:space="preserve">
<value>男中年男性4</value>
</data>
<data name="MIDDLE_AGED_MAN5" xml:space="preserve">
<value>男中年男性5 音质好</value>
</data>
<data name="MIDDLE_AGED_MAN6" xml:space="preserve">
<value>男中年男性6</value>
</data>
<data name="MIDDLE_AGED_MAN7" xml:space="preserve">
<value>男中年男性7 音质好</value>
</data>
<data name="OLD_MAN1" xml:space="preserve">
<value>老年人男性1</value>
</data>
<data name="OLD_MAN2" xml:space="preserve">
<value>老年人男性2 音质好</value>
</data>
<data name="OLD_MAN3" xml:space="preserve">
<value>老年人男性3</value>
</data>
<data name="OLD_MAN4" xml:space="preserve">
<value>老年人男性4</value>
</data>
<data name="OLD_MAN5" xml:space="preserve">
<value>老年人男性5 音质好</value>
</data>
<data name="OLD_MAN6" xml:space="preserve">
<value>老年人男性6</value>
</data>
<data name="OLD_MAN7" xml:space="preserve">
<value>老年人男性7</value>
</data>
<data name="YOUNG_FEMALE1" xml:space="preserve">
<value>女青年女性1 音质好</value>
</data>
<data name="YOUNG_FEMALE2" xml:space="preserve">
<value>女青年女性2</value>
</data>
<data name="YOUNG_FEMALE3" xml:space="preserve">
<value>女青年女性3</value>
</data>
<data name="YOUNG_FEMALE4" xml:space="preserve">
<value>女青年女性4</value>
</data>
<data name="YOUNG_FEMALE5" xml:space="preserve">
<value>女青年女性5</value>
</data>
<data name="YOUNG_FEMALE6" xml:space="preserve">
<value>女青年女性6</value>
</data>
<data name="YOUNG_FEMALE7" xml:space="preserve">
<value>女青年女性7 音质好</value>
</data>
<data name="YOUNG_MALE1" xml:space="preserve">
<value>男青年男性1</value>
</data>
<data name="YOUNG_MALE2" xml:space="preserve">
<value>男青年男性2 音质好</value>
</data>
<data name="YOUNG_MALE3" xml:space="preserve">
<value>男青年男性3</value>
</data>
<data name="YOUNG_MALE4" xml:space="preserve">
<value>男青年男性4</value>
</data>
<data name="YOUNG_MALE5" xml:space="preserve">
<value>男青年男性5</value>
</data>
<data name="YOUNG_MALE6" xml:space="preserve">
<value>男青年男性6</value>
</data>
<data name="YOUNG_MALE7" xml:space="preserve">
<value>男青年男性7 音质好</value>
</data>
</root>

View File

@ -6,9 +6,9 @@ using CloudBuilder.Core.Service;
namespace CloudBuilder.AI.Service
{
public interface IAiSentenceService :IServiceBase<AiSentenceEntity, long ,AiSentenceSearchCriteria>
public interface IAiSentenceService : IServiceBase<AiSentenceEntity, long, AiSentenceSearchCriteria>
{
AiSentenceViewEntity[] FindByChapterId(long chapterId);
AiSentenceViewEntity[] FindByChapterId(string bookId, long chapterId);
AiSentenceViewResultData FindBySearchCriteria(AiSentenceSearchCriteria criteria);
void Inserts(AiSentenceEntity[] datas);
}

View File

@ -28,9 +28,15 @@ this.serviceRequest = serviceRequest;
{
return Task.Run(() => serviceRequest.PostAsJsonAsync<AiSentenceEntity>("/AiSentence/FindByKey?key=" + key.ToString())).GetAwaiter().GetResult(); }
public AiSentenceViewEntity[] FindByChapterId(Int64 chapterId)
public class FindByChapterIdCompositionData2 {
public string bookId { get; set; }
public Int64 chapterId { get; set; }
}
public AiSentenceViewEntity[] FindByChapterId(string bookId, Int64 chapterId)
{
return Task.Run(() => serviceRequest.PostAsJsonAsync<AiSentenceViewEntity[]>("/AiSentence/FindByChapterId?chapterId=" + chapterId.ToString())).GetAwaiter().GetResult(); }
var compositionData = new FindByChapterIdCompositionData2{ bookId = bookId, chapterId = chapterId }; return Task.Run(() => serviceRequest.PostAsJsonAsync<FindByChapterIdCompositionData2, AiSentenceViewEntity[]>("/AiSentence/FindByChapterId", compositionData)).GetAwaiter().GetResult(); }
public AiSentenceViewResultData FindBySearchCriteria(AiSentenceSearchCriteria criteria)
{

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NameOfLastUsedPublishProfile>D:\NET8\CloudBuilder\CloudBuilder.Web.Entry\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<NameOfLastUsedPublishProfile>D:\MAFAI\CloudBuilder\CloudBuilder.Web.Entry\Properties\PublishProfiles\FolderProfile1.pubxml</NameOfLastUsedPublishProfile>
</PropertyGroup>
</Project>

View File

@ -50,14 +50,21 @@ this.aiSentenceService= aiSentenceService;
}
}
public class FindByChapterIdCompositionData
{
public string bookId { get; set; }
public Int64 chapterId { get; set; }
}
[PermissionOperate(name: "AiBook", operate: "Find")]
[HttpPost]
public dynamic FindByChapterId(Int64 chapterId)
public dynamic FindByChapterId(FindByChapterIdCompositionData compositionData)
{
try
{
var result = aiSentenceService.FindByChapterId(chapterId);
var result = aiSentenceService.FindByChapterId(compositionData.bookId,compositionData.chapterId);
return result;
}
catch (ValidatedException vex)

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<DeleteExistingFiles>false</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>C:\inetpub\wwwroot\webapi</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
<_TargetId>Folder</_TargetId>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<_PublishTargetUrl>C:\inetpub\wwwroot\webapi</_PublishTargetUrl>
<History>True|2026-06-23T02:11:00.8522806Z||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>