Commit 6c9edc0e LN

多PCB间距精确到0.1mm

1 个父辈 c941d69b
......@@ -86,6 +86,7 @@
<ItemGroup>
<Compile Include="bean\BoardInfo.cs" />
<Compile Include="bean\ConfigIO.cs" />
<Compile Include="bean\DPoint.cs" />
<Compile Include="bean\LogAnalyzeManager.cs" />
<Compile Include="bean\ProjectorPInfo.cs" />
<Compile Include="bean\WorkCountManager.cs" />
......
......@@ -71,11 +71,11 @@ namespace TSA_V.DeviceLibrary
/// <summary>
/// 多PCB模式-行间距(mm)
/// </summary>
public int pcbRowValue { get; set; } = 1;
public double pcbRowValue { get; set; } = 1;
/// <summary>
/// 多PCB模式-列间距(mm)
/// </summary>
public int pcbColValue { get; set; } = 1;
public double pcbColValue { get; set; } = 1;
/// <summary>
/// 多点位投射功能,=true所有点位同时显示。
/// </summary>
......@@ -554,20 +554,23 @@ namespace TSA_V.DeviceLibrary
{
public PcbOffsetInfo() { }
public PcbOffsetInfo(int x, int y, double a)
public PcbOffsetInfo(double x, double y, double a)
{
this.X = x;
this.Y = y;
this.A = a;
}
public int X { get; set; }
public double X { get; set; }
public int Y { get; set; }
public double Y { get; set; }
public double A { get; set; }
public string getShowText(int index)
{
return $"PCB{index}(X={Math.Round(X,1)},Y={Math.Round(Y,1)},A={Math.Round(A, 1)})";
}
}
public class PcbOffsetInfoConverter : JsonConverter<PcbOffsetInfo>
{
......@@ -622,8 +625,8 @@ namespace TSA_V.DeviceLibrary
case JsonToken.StartArray:
{
var arr = JArray.Load(reader);
int x = arr.Count > 0 ? SafeInt(arr[0]) : 0;
int y = arr.Count > 1 ? SafeInt(arr[1]) : 0;
double x = arr.Count > 0 ? SafeDouble(arr[0]) : 0.0;
double y = arr.Count > 1 ? SafeDouble(arr[1]) : 0.0;
// 关键:A 用 SafeDouble 解析,保留一位小数
double a = arr.Count > 2 ? SafeDouble(arr[2]) : 0.0;
return new PcbOffsetInfo(x, y, Math.Round(a, 1));
......@@ -633,8 +636,8 @@ namespace TSA_V.DeviceLibrary
case JsonToken.StartObject:
{
var obj = JObject.Load(reader);
int x = SafeInt(obj["X"] ?? obj["x"]);
int y = SafeInt(obj["Y"] ?? obj["y"]);
double x = SafeDouble(obj["X"] ?? obj["x"]);
double y = SafeDouble(obj["Y"] ?? obj["y"]);
// 关键:A 解析支持大小写键,保留一位小数
double a = SafeDouble(obj["A"] ?? obj["a"]);
return new PcbOffsetInfo(x, y, Math.Round(a, 1));
......@@ -660,14 +663,14 @@ namespace TSA_V.DeviceLibrary
}
// 原有:安全解析 int(不变)
private static int SafeInt(JToken t)
{
if (t == null) return 0;
if (t.Type == JTokenType.Integer) return (int)t;
if (t.Type == JTokenType.Float) return (int)Math.Round((double)t);
if (t.Type == JTokenType.String && int.TryParse((string)t, out var v)) return v;
return 0;
}
//private static int SafeInt(JToken t)
//{
// if (t == null) return 0;
// if (t.Type == JTokenType.Integer) return (int)t;
// if (t.Type == JTokenType.Float) return (int)Math.Round((double)t);
// if (t.Type == JTokenType.String && int.TryParse((string)t, out var v)) return v;
// return 0;
//}
// 新增:安全解析 double(适配 A 的 double 类型)
private static double SafeDouble(JToken t)
......
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TSA_V.DeviceLibrary
{
public class DPoint
{
public DPoint()
{
}
public DPoint(double x, double y)
{
X = x;
Y = y;
}
public double X { get; set; } = 0.0;
public double Y { get; set; } = 0.0;
public Point ToPoint()
{
return new Point((int)X, (int)Y);
}
}
}
......@@ -835,6 +835,7 @@ namespace TSA_V
display.ImageNormal = chbNormal.Checked;
display.LoadPoint(width, height, pointList);
imageXiShu = display.imageXiShu;
imageYShu = display.imageYShu;
}
private void txtBoardLength_TextChanged(object sender, EventArgs e)
......
......@@ -233,9 +233,9 @@ namespace TSA_V
}
if (angle != 0)
{
var pointR =XYConvertManager.RotatePoint(point.PositionX, point.PositionY, 0, 0, angle);
point.PositionX = pointR.Item1;
point.PositionY = pointR.Item2;
DPoint pointR =XYConvertManager.RotatePoint(point.PositionX, point.PositionY, 0, 0, angle);
point.PositionX = pointR.X;
point.PositionY = pointR.Y;
}
resultPointList.Add(point);
......
......@@ -41,19 +41,21 @@
this.label1 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.txtColS = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
this.txtRowS = new System.Windows.Forms.TextBox();
this.label11 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.btnClose = new System.Windows.Forms.Button();
this.btnSave = new System.Windows.Forms.Button();
this.numRowS = new System.Windows.Forms.NumericUpDown();
this.numColS = new System.Windows.Forms.NumericUpDown();
this.panel1.SuspendLayout();
this.groupBox1.SuspendLayout();
this.groupCopy.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numCol)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numRow)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numRowS)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numColS)).BeginInit();
this.SuspendLayout();
//
// dataGridViewImageColumn1
......@@ -127,15 +129,15 @@
//
// groupCopy
//
this.groupCopy.Controls.Add(this.numColS);
this.groupCopy.Controls.Add(this.numRowS);
this.groupCopy.Controls.Add(this.numCol);
this.groupCopy.Controls.Add(this.numRow);
this.groupCopy.Controls.Add(this.label1);
this.groupCopy.Controls.Add(this.label3);
this.groupCopy.Controls.Add(this.label5);
this.groupCopy.Controls.Add(this.txtColS);
this.groupCopy.Controls.Add(this.label2);
this.groupCopy.Controls.Add(this.label12);
this.groupCopy.Controls.Add(this.txtRowS);
this.groupCopy.Controls.Add(this.label11);
this.groupCopy.Controls.Add(this.label7);
this.groupCopy.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
......@@ -147,7 +149,7 @@
//
// numCol
//
this.numCol.Location = new System.Drawing.Point(156, 60);
this.numCol.Location = new System.Drawing.Point(156, 61);
this.numCol.Maximum = new decimal(new int[] {
10,
0,
......@@ -169,7 +171,7 @@
//
// numRow
//
this.numRow.Location = new System.Drawing.Point(156, 23);
this.numRow.Location = new System.Drawing.Point(156, 20);
this.numRow.Maximum = new decimal(new int[] {
10,
0,
......@@ -203,7 +205,7 @@
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label3.Location = new System.Drawing.Point(529, 64);
this.label3.Location = new System.Drawing.Point(549, 64);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(30, 17);
this.label3.TabIndex = 303;
......@@ -213,26 +215,16 @@
//
this.label5.AutoSize = true;
this.label5.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label5.Location = new System.Drawing.Point(529, 23);
this.label5.Location = new System.Drawing.Point(549, 23);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(30, 17);
this.label5.TabIndex = 302;
this.label5.Text = "mm";
//
// txtColS
//
this.txtColS.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.txtColS.Location = new System.Drawing.Point(432, 60);
this.txtColS.MaxLength = 12;
this.txtColS.Name = "txtColS";
this.txtColS.Size = new System.Drawing.Size(89, 23);
this.txtColS.TabIndex = 300;
this.txtColS.Text = "1";
//
// label2
//
this.label2.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label2.Location = new System.Drawing.Point(292, 63);
this.label2.Location = new System.Drawing.Point(292, 64);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(137, 17);
this.label2.TabIndex = 299;
......@@ -242,27 +234,17 @@
// label12
//
this.label12.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label12.Location = new System.Drawing.Point(4, 63);
this.label12.Location = new System.Drawing.Point(4, 64);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(137, 17);
this.label12.TabIndex = 297;
this.label12.Text = "列:";
this.label12.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// txtRowS
//
this.txtRowS.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.txtRowS.Location = new System.Drawing.Point(432, 19);
this.txtRowS.MaxLength = 12;
this.txtRowS.Name = "txtRowS";
this.txtRowS.Size = new System.Drawing.Size(89, 23);
this.txtRowS.TabIndex = 296;
this.txtRowS.Text = "1";
//
// label11
//
this.label11.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label11.Location = new System.Drawing.Point(292, 22);
this.label11.Location = new System.Drawing.Point(292, 23);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(137, 17);
this.label11.TabIndex = 295;
......@@ -272,7 +254,7 @@
// label7
//
this.label7.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label7.Location = new System.Drawing.Point(4, 25);
this.label7.Location = new System.Drawing.Point(4, 23);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(137, 17);
this.label7.TabIndex = 293;
......@@ -305,6 +287,52 @@
this.btnSave.UseVisualStyleBackColor = true;
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
//
// numRowS
//
this.numRowS.DecimalPlaces = 1;
this.numRowS.Increment = new decimal(new int[] {
10,
0,
0,
0});
this.numRowS.Location = new System.Drawing.Point(423, 20);
this.numRowS.Maximum = new decimal(new int[] {
1000000,
0,
0,
0});
this.numRowS.Name = "numRowS";
this.numRowS.Size = new System.Drawing.Size(120, 23);
this.numRowS.TabIndex = 307;
this.numRowS.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// numColS
//
this.numColS.DecimalPlaces = 1;
this.numColS.Increment = new decimal(new int[] {
10,
0,
0,
0});
this.numColS.Location = new System.Drawing.Point(423, 61);
this.numColS.Maximum = new decimal(new int[] {
1000000,
0,
0,
0});
this.numColS.Name = "numColS";
this.numColS.Size = new System.Drawing.Size(120, 23);
this.numColS.TabIndex = 308;
this.numColS.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// FrmMPcbConfig
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
......@@ -321,6 +349,8 @@
this.groupCopy.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numCol)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numRow)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numRowS)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numColS)).EndInit();
this.ResumeLayout(false);
}
......@@ -333,9 +363,7 @@
private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn2;
private System.Windows.Forms.GroupBox groupCopy;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox txtRowS;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.TextBox txtColS;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.Label label3;
......@@ -346,5 +374,7 @@
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numCol;
private System.Windows.Forms.NumericUpDown numRow;
private System.Windows.Forms.NumericUpDown numColS;
private System.Windows.Forms.NumericUpDown numRowS;
}
}
\ No newline at end of file
......@@ -55,8 +55,8 @@ namespace TSA_V
// 使用已有配置填充界面
numRow.Value = (currBoardInfo.pcbRow > 0 ? currBoardInfo.pcbRow : 1);
numCol.Value = (currBoardInfo.pcbCol > 0 ? currBoardInfo.pcbCol : 1);
txtRowS.Text = (currBoardInfo.pcbRowValue > 0 ? currBoardInfo.pcbRowValue : 1).ToString();
txtColS.Text = (currBoardInfo.pcbColValue > 0 ? currBoardInfo.pcbColValue : 1).ToString();
numRowS.Value = (decimal)(currBoardInfo.pcbRowValue > 0 ? currBoardInfo.pcbRowValue : 1) ;
numColS.Value = (decimal)(currBoardInfo.pcbColValue > 0 ? currBoardInfo.pcbColValue : 1) ;
// 更新提示文案:可单独设置相对偏移
try { label1.Text = ResourceControl.GetString("MPCBTips" ,"*点击下方PCB块可设置其相对PCB1的偏移(单位:mm)。未设置则按上方行/列间距均匀排布"); } catch { }
......@@ -130,8 +130,8 @@ namespace TSA_V
// 输入校验
int pcbRow =(int)(numRow.Value);
int pcbCol = (int)(numCol.Value);
int pcbRowValue = FormUtil.GetIntValue(txtRowS);
int pcbColValue = FormUtil.GetIntValue(txtColS);
double pcbRowValue = (double)numRowS.Value;
double pcbColValue =(double )numColS.Value;
if (pcbRow < 1 || pcbCol < 1)
{
......@@ -152,7 +152,7 @@ namespace TSA_V
{
MessageBox.Show(ResourceCulture.GetString("PcbRowValueInvalid", "行间距必须大于0!"),
ResourceCulture.GetString("MsgTitle", "提示"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtRowS.Focus();
numRowS.Focus();
return;
}
......@@ -160,7 +160,7 @@ namespace TSA_V
{
MessageBox.Show(ResourceCulture.GetString("PcbColValueInvalid", "列间距必须大于0!"),
ResourceCulture.GetString("MsgTitle", "提示"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtColS.Focus();
numColS.Focus();
return;
}
......@@ -191,8 +191,8 @@ namespace TSA_V
// 容错与输入校验
int pcbRow = (int)numRow.Value;
int pcbCol = (int)numCol.Value;
int pcbRowValue = FormUtil.GetIntValue(txtRowS);
int pcbColValue = FormUtil.GetIntValue(txtColS);
double pcbRowValue = (double)numRowS.Value;
double pcbColValue = (double)numColS.Value;
if (pcbRow < 1 || pcbCol < 1)
{
......@@ -204,7 +204,7 @@ namespace TSA_V
{
MessageBox.Show(ResourceCulture.GetString("PcbRowValueInvalid", "行间距必须大于0!"),
ResourceCulture.GetString("MsgTitle", "提示"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtRowS.Focus();
numRowS.Focus();
return;
}
......@@ -212,7 +212,7 @@ namespace TSA_V
{
MessageBox.Show(ResourceCulture.GetString("PcbColValueInvalid", "列间距必须大于0!"),
ResourceCulture.GetString("MsgTitle", "提示"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtColS.Focus();
numColS.Focus();
return;
}
if (currBoardInfo == null)
......@@ -261,7 +261,7 @@ namespace TSA_V
}
}
private void SimulatePcbGrid(int rows, int cols,int pcbRowValue,int pcbColValue)
private void SimulatePcbGrid(int rows, int cols,double pcbRowValue, double pcbColValue)
{
if (tableLayoutPanel1 == null) return;
tableLayoutPanel1.SuspendLayout();
......@@ -302,12 +302,10 @@ namespace TSA_V
{
int index = r * cols + c + 1;
// 计算默认偏移(均匀排布)
int defDx = c * pcbColValue;
int defDy = r * pcbRowValue;
// 如果有单独设置,则使用已设置的值
int showDx = defDx;
int showDy = defDy;
double showA = 0;
double defDx = c * pcbColValue;
double defDy = r * pcbRowValue;
// 如果有单独设置,则使用已设置的值
PcbOffsetInfo offset = new PcbOffsetInfo(defDx, defDy, 0);
try
{
if (currBoardInfo != null)
......@@ -315,13 +313,11 @@ namespace TSA_V
var p = currBoardInfo.GetPCBOffsetPoint(index);
if (index == 1)
{
showDx = 0; showDy = 0; // PCB1 固定为(0,0)
showA = 0;
offset = new PcbOffsetInfo(0, 0, 0);
}
else if (p.X != 0 || p.Y != 0)
{
showDx = p.X; showDy = p.Y;
showA = p.A;
offset= new PcbOffsetInfo(p.X, p.Y, p.A);
}
}
}
......@@ -333,7 +329,7 @@ namespace TSA_V
lblPcbInfo.Margin = new Padding(6);
lblPcbInfo.AutoSize = false;
lblPcbInfo.Font = new Font("微软雅黑", 12f, FontStyle.Bold);
lblPcbInfo.Text = $"PCB{index}(X={showDx},Y={showDy},A={Math.Round(showA,1)})";
lblPcbInfo.Text = offset.getShowText(index);
lblPcbInfo.Tag = index;
lblPcbInfo.Cursor = Cursors.Hand;
lblPcbInfo.Click += LabelPcb_Click;
......@@ -378,17 +374,17 @@ namespace TSA_V
// 计算当前默认偏移:若已有单独设置则用已设置值,否则按行列间距均匀排布
int rows = (int)numRow.Value;
int cols = (int)numCol.Value;
int colGap = FormUtil.GetIntValue(txtColS);
double colGap =(double) numColS.Value;
if (colGap <= 0) colGap = currBoardInfo != null && currBoardInfo.pcbColValue > 0 ? currBoardInfo.pcbColValue : 1;
int rowGap = FormUtil.GetIntValue(txtRowS);
double rowGap = (double)numRowS.Value;
if (rowGap <= 0) rowGap = currBoardInfo != null && currBoardInfo.pcbRowValue > 0 ? currBoardInfo.pcbRowValue : 1;
int r0 = (index - 1) / Math.Max(1, cols);
int c0 = (index - 1) % Math.Max(1, cols);
int defDx = c0 * colGap;
int defDy = r0 * rowGap;
int currDx = defDx;
int currDy = defDy;
double defDx = c0 * colGap;
double defDy = r0 * rowGap;
double currDx = defDx;
double currDy = defDy;
double currDA = 0;
try
{
......@@ -405,13 +401,11 @@ namespace TSA_V
using (var dlg = new TSA_V.frmBoard.FrmPCbOffsetConfig(index, currDx, currDy,currDA))
{
if (dlg.ShowDialog(this) == DialogResult.OK)
{
int x = dlg.OffsetX;
int y = dlg.OffsetY;
double a = dlg.OffsetA;
currBoardInfo.SetPCBOffset(index, new PcbOffsetInfo(x, y, a));
{
PcbOffsetInfo offset = new PcbOffsetInfo(dlg.OffsetX, dlg.OffsetY, dlg.OffsetA);
currBoardInfo.SetPCBOffset(index, offset);
// 更新标签显示
lbl.Text = $"PCB{index}(X={x},Y={y},A={Math.Round(a,1)})";
lbl.Text = offset.getShowText(index);
try
{
if (FrmProjectorScreen.instance != null)
......
......@@ -61,6 +61,7 @@ namespace TSA_V.frmBoard
//
// numX
//
this.numX.DecimalPlaces = 1;
this.numX.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.numX.Location = new System.Drawing.Point(158, 27);
this.numX.Maximum = new decimal(new int[] {
......@@ -79,6 +80,7 @@ namespace TSA_V.frmBoard
//
// numY
//
this.numY.DecimalPlaces = 1;
this.numY.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.numY.Location = new System.Drawing.Point(158, 65);
this.numY.Maximum = new decimal(new int[] {
......
......@@ -5,28 +5,25 @@ namespace TSA_V.frmBoard
{
public partial class FrmPCbOffsetConfig : FrmBase
{
public int OffsetX { get; private set; }
public int OffsetY { get; private set; }
public double OffsetX { get; private set; }
public double OffsetY { get; private set; }
public double OffsetA{get;private set; } //角度
private readonly int pcbIndex;
private readonly int defaultX;
private readonly int defaultY;
private readonly double defaultA;
private readonly int pcbIndex;
public FrmPCbOffsetConfig(int pcbIndex, int defaultX, int defaultY,double defaultA)
public FrmPCbOffsetConfig(int pcbIndex, double defaultX, double defaultY,double defaultA)
{
this.pcbIndex = pcbIndex;
this.defaultX = defaultX;
this.defaultY = defaultY;
this.defaultA=defaultA;
this.OffsetX = defaultX;
this.OffsetY = defaultY;
this.OffsetA = defaultA;
InitializeComponent();
this.Text = ResourceControl.GetString("FrmPCbOffsetConfig_Text", "设置 PCB{0} 相对偏移(mm)", pcbIndex+"");
// 初始化控件默认值
try
{
numX.Value = defaultX;
numY.Value = defaultY;
numX.Value =(decimal) defaultX;
numY.Value =(decimal) defaultY;
numA.Value =(decimal) defaultA;
}
......@@ -35,8 +32,8 @@ namespace TSA_V.frmBoard
private void btnOK_Click(object sender, EventArgs e)
{
OffsetX = (int)numX.Value;
OffsetY = (int)numY.Value;
OffsetX = Math.Round((double)numX.Value,1);
OffsetY = Math.Round((double)numY.Value,1);
OffsetA =Math.Round( (double)numA.Value,1);
this.DialogResult = DialogResult.OK;
this.Close();
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!