ASP.NET中常用功能代码总结(1)——发送邮件篇
ASP.NET中常用功能代码总结(1)——发送邮件篇
整理:Terrylee
一. 用Asp.net实现邮件系统
1/// <summary>
2 /// 功能:实现在Web页面中发送Email
3 /// </summary>
4 private void SendMail()
5 {
6 MailMessage m = new MailMessage();
7
8 ///发件人地址
9 m.From = tbFrom.Text;
10
11 ///收件人地址
12 m.To = tbTo.Text;
13
14 ///邮件主题
15 m.Subject = tbSubject.Text;
16
17 ///邮件内容
18 m.Body = tbBody.Text;
19
20 ///优先级
21 switch(ddlp.SelectedIndex)
22 {
23 case 0:
24 m.Priority = MailPriority.High;
25 break;
26 case 1:
27 m.Priority = MailPriority.Low;
28 break;
29 default:
30 m.Priority = MailPriority.Normal;
31 break;
32 }
33
34 ///设置邮件格式
35 if(ddlp.SelectedIndex==0)
36 m.BodyFormat = MailFormat.Text;
37 else
38 m.BodyFormat = MailFormat.Html;
39
40 ///设置服务器
41 if(tbServer.Text!="")
42 {
43 SmtpMail.SmtpServer = tbServer.Text;
44 }
45
46 ///以下处理附件
47 string strFileName = FileSelect.PostedFile.FileName;
48 if(strFileName!="")
49 m.Attachments.Add(new MailAttachment(strFileName));
50
51 ///发送邮件
52 SmtpMail.Send(m);
53 }
2 /// 功能:实现在Web页面中发送Email
3 /// </summary>
4 private void SendMail()
5 {
6 MailMessage m = new MailMessage();
7
8 ///发件人地址
9 m.From = tbFrom.Text;
10
11 ///收件人地址
12 m.To = tbTo.Text;
13
14 ///邮件主题
15 m.Subject = tbSubject.Text;
16
17 ///邮件内容
18 m.Body = tbBody.Text;
19
20 ///优先级
21 switch(ddlp.SelectedIndex)
22 {
23 case 0:
24 m.Priority = MailPriority.High;
25 break;
26 case 1:
27 m.Priority = MailPriority.Low;
28 break;
29 default:
30 m.Priority = MailPriority.Normal;
31 break;
32 }
33
34 ///设置邮件格式
35 if(ddlp.SelectedIndex==0)
36 m.BodyFormat = MailFormat.Text;
37 else
38 m.BodyFormat = MailFormat.Html;
39
40 ///设置服务器
41 if(tbServer.Text!="")
42 {
43 SmtpMail.SmtpServer = tbServer.Text;
44 }
45
46 ///以下处理附件
47 string strFileName = FileSelect.PostedFile.FileName;
48 if(strFileName!="")
49 m.Attachments.Add(new MailAttachment(strFileName));
50
51 ///发送邮件
52 SmtpMail.Send(m);
53 }
二. 利用Socket来接收邮件
1/// <summary>
2 /// 接收邮件
3 /// </summary>
4 private void SocketPopMail()
5 {
6 POP3 pop = new POP3(tbServer.Text,tbUser.Text,tbPass.Text);
7 int n = pop.GetNumberOfNewMessages();
8 if(n==-1)
9 {
10 Response.Write("<script language='javascript'>alert('服务器连接错误!')</script>");
11 return;
12 }
13 ddlNew.Items.Clear();
14 for(int i=1;i<=n;i++)
15 ddlNew.Items.Add("第"+i.ToString()+"封邮件");
16 if(n>0)
17 {
18 MailMessage msg = pop.GetNewMessages(0);
19 if(msg!=null)
20 tbBody.Text = msg.Body;
21 }
22 }
POP3类的实现如下:2 /// 接收邮件
3 /// </summary>
4 private void SocketPopMail()
5 {
6 POP3 pop = new POP3(tbServer.Text,tbUser.Text,tbPass.Text);
7 int n = pop.GetNumberOfNewMessages();
8 if(n==-1)
9 {
10 Response.Write("<script language='javascript'>alert('服务器连接错误!')</script>");
11 return;
12 }
13 ddlNew.Items.Clear();
14 for(int i=1;i<=n;i++)
15 ddlNew.Items.Add("第"+i.ToString()+"封邮件");
16 if(n>0)
17 {
18 MailMessage msg = pop.GetNewMessages(0);
19 if(msg!=null)
20 tbBody.Text = msg.Body;
21 }
22 }
1/// <summary>
2 /// 接收邮件类
3 /// </summary>
4 public class POP3
5 {
6 string POPServer;
7 string user;
8 string pwd;
9 NetworkStream ns;
10 StreamReader sr;
11
12 public POP3(){}
13
14 public POP3(string server, string _user, string _pwd)
15 {
16 POPServer = server;
17 user = _user;
18 pwd = _pwd;
19 }
20
21 /// <summary>
22 /// 连接服务器
23 /// </summary>
24 /// <returns></returns>
25 private bool Connect()
26 {
27 TcpClient sender = new TcpClient(POPServer,110);
28 byte[] outbytes;
29 string input;
30
31 try
32 {
33 ns = sender.GetStream();
34 sr = new StreamReader(ns);
35
36 sr.ReadLine();
37 input = "user " + user + "\r\n";
38 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
39 ns.Write(outbytes,0,outbytes.Length) ;
40 sr.ReadLine();
41
42 input = "pass " + pwd + "\r\n";
43 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
44 ns.Write(outbytes,0,outbytes.Length) ;
45 sr.ReadLine();
46 return true;
47
48 }
49 catch
50 {
51 return false;
52 }
53 }
54
55 /// <summary>
56 /// 断开与服务器的连接
57 /// </summary>
58 private void Disconnect()
59 {
60 string input = "quit" + "\r\n";
61 Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
62 ns.Write(outbytes,0,outbytes.Length);
63 ns.Close();
64 }
65
66 public int GetNumberOfNewMessages()
67 {
68 byte[] outbytes;
69 string input;
70
71 try
72 {
73 Connect();
74
75 input = "stat" + "\r\n";
76 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
77 ns.Write(outbytes,0,outbytes.Length);
78 string resp = sr.ReadLine();
79 string[] tokens = resp.Split(new Char[] {' '});
80
81 Disconnect();
82
83 return Convert.ToInt32(tokens[1]);
84 }
85 catch
86 {
87 return -1;
88 }
89 }
90 public ArrayList GetNewMessages(string subj)
91 {
92
93 int newcount;
94 ArrayList newmsgs = new ArrayList();
95
96 try
97 {
98 newcount = GetNumberOfNewMessages();
99 Connect();
100
101 for(int n=1; n<newcount+1; n++)
102 {
103 ArrayList msglines = GetRawMessage(n);
104 string msgsubj = GetMessageSubject(msglines);
105 if(msgsubj.CompareTo(subj) == 0)
106 {
107 System.Web.Mail.MailMessage msg = new MailMessage();
108 msg.Subject = msgsubj;
109 msg.From = GetMessageFrom(msglines);
110 msg.Body = GetMessageBody(msglines);
111 newmsgs.Add(msg);
112 DeleteMessage(n);
113 }
114 }
115
116 Disconnect();
117 return newmsgs;
118 }
119 catch(Exception e)
120 {
121 return newmsgs;
122 }
123 }
124
125 /// <summary>
126 /// 获取新邮件
127 /// </summary>
128 /// <param name="nIndex"></param>
129 /// <returns></returns>
130 public MailMessage GetNewMessages(int nIndex)
131 {
132 int newcount;
133 System.Web.Mail.MailMessage msg = new MailMessage();
134
135 try
136 {
137 newcount = GetNumberOfNewMessages();
138 Connect();
139 int n = nIndex+1;
140
141 if(n<newcount+1)
142 {
143 ArrayList msglines = GetRawMessage(n);
144 string msgsubj = GetMessageSubject(msglines);
145
146
147 msg.Subject = msgsubj;
148 msg.From = GetMessageFrom(msglines);
149 msg.Body = GetMessageBody(msglines);
150 }
151
152 Disconnect();
153 return msg;
154 }
155 catch
156 {
157 return null;
158 }
159 }
160 private ArrayList GetRawMessage (int messagenumber)
161 {
162 Byte[] outbytes;
163 string input;
164 string line = "";
165
166 input = "retr " + messagenumber.ToString() + "\r\n";
167 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
168 ns.Write(outbytes,0,outbytes.Length);
169
170 ArrayList msglines = new ArrayList();
171 do
172 {
173 line = sr.ReadLine();
174 msglines.Add(line);
175 } while (line != ".");
176 msglines.RemoveAt(msglines.Count-1);
177
178 return msglines;
179 }
180
181 /// <summary>
182 /// 获取邮件主题
183 /// </summary>
184 /// <param name="msglines"></param>
185 /// <returns></returns>
186 private string GetMessageSubject(ArrayList msglines)
187 {
188 string[] tokens;
189 IEnumerator msgenum = msglines.GetEnumerator();
190 while (msgenum.MoveNext() )
191 {
192 string line = (string)msgenum.Current;
193 if(line.StartsWith("Subject:") )
194 {
195 tokens = line.Split(new Char[] {' '});
196 return tokens[1].Trim();
197 }
198 }
199 return "None";
200 }
201
202 /// <summary>
203 /// 获取邮件源地址
204 /// </summary>
205 /// <param name="msglines"></param>
206 /// <returns></returns>
207 private string GetMessageFrom (ArrayList msglines)
208 {
209 string[] tokens;
210 IEnumerator msgenum = msglines.GetEnumerator();
211 while (msgenum.MoveNext() )
212 {
213 string line = (string)msgenum.Current;
214 if(line.StartsWith("From:") )
215 {
216 tokens = line.Split(new Char[] {'<'});
217 return tokens[1].Trim(new Char[] {'<','>'});
218 }
219 }
220 return "None";
221 }
222
223 /// <summary>
224 /// 获取邮件内容
225 /// </summary>
226 /// <param name="msglines"></param>
227 /// <returns></returns>
228 private string GetMessageBody(ArrayList msglines)
229 {
230 string body = "";
231 string line = " ";
232 IEnumerator msgenum = msglines.GetEnumerator();
233
234 while(line.CompareTo("") != 0)
235 {
236 msgenum.MoveNext();
237 line = (string)msgenum.Current;
238 }
239
240 while (msgenum.MoveNext() )
241 {
242 body = body + (string)msgenum.Current + "\r\n";
243 }
244 return body;
245 }
246
247 /// <summary>
248 /// 删除邮件
249 /// </summary>
250 /// <param name="messagenumber"></param>
251 private void DeleteMessage(int messagenumber)
252 {
253 Byte[] outbytes;
254 string input;
255
256 try
257 {
258 input = "dele " + messagenumber.ToString() + "\r\n";
259 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
260 ns.Write(outbytes,0,outbytes.Length);
261 }
262 catch(Exception e)
263 {
264 return;
265 }
266
267 }
268
269 }
2 /// 接收邮件类
3 /// </summary>
4 public class POP3
5 {
6 string POPServer;
7 string user;
8 string pwd;
9 NetworkStream ns;
10 StreamReader sr;
11
12 public POP3(){}
13
14 public POP3(string server, string _user, string _pwd)
15 {
16 POPServer = server;
17 user = _user;
18 pwd = _pwd;
19 }
20
21 /// <summary>
22 /// 连接服务器
23 /// </summary>
24 /// <returns></returns>
25 private bool Connect()
26 {
27 TcpClient sender = new TcpClient(POPServer,110);
28 byte[] outbytes;
29 string input;
30
31 try
32 {
33 ns = sender.GetStream();
34 sr = new StreamReader(ns);
35
36 sr.ReadLine();
37 input = "user " + user + "\r\n";
38 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
39 ns.Write(outbytes,0,outbytes.Length) ;
40 sr.ReadLine();
41
42 input = "pass " + pwd + "\r\n";
43 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
44 ns.Write(outbytes,0,outbytes.Length) ;
45 sr.ReadLine();
46 return true;
47
48 }
49 catch
50 {
51 return false;
52 }
53 }
54
55 /// <summary>
56 /// 断开与服务器的连接
57 /// </summary>
58 private void Disconnect()
59 {
60 string input = "quit" + "\r\n";
61 Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
62 ns.Write(outbytes,0,outbytes.Length);
63 ns.Close();
64 }
65
66 public int GetNumberOfNewMessages()
67 {
68 byte[] outbytes;
69 string input;
70
71 try
72 {
73 Connect();
74
75 input = "stat" + "\r\n";
76 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
77 ns.Write(outbytes,0,outbytes.Length);
78 string resp = sr.ReadLine();
79 string[] tokens = resp.Split(new Char[] {' '});
80
81 Disconnect();
82
83 return Convert.ToInt32(tokens[1]);
84 }
85 catch
86 {
87 return -1;
88 }
89 }
90 public ArrayList GetNewMessages(string subj)
91 {
92
93 int newcount;
94 ArrayList newmsgs = new ArrayList();
95
96 try
97 {
98 newcount = GetNumberOfNewMessages();
99 Connect();
100
101 for(int n=1; n<newcount+1; n++)
102 {
103 ArrayList msglines = GetRawMessage(n);
104 string msgsubj = GetMessageSubject(msglines);
105 if(msgsubj.CompareTo(subj) == 0)
106 {
107 System.Web.Mail.MailMessage msg = new MailMessage();
108 msg.Subject = msgsubj;
109 msg.From = GetMessageFrom(msglines);
110 msg.Body = GetMessageBody(msglines);
111 newmsgs.Add(msg);
112 DeleteMessage(n);
113 }
114 }
115
116 Disconnect();
117 return newmsgs;
118 }
119 catch(Exception e)
120 {
121 return newmsgs;
122 }
123 }
124
125 /// <summary>
126 /// 获取新邮件
127 /// </summary>
128 /// <param name="nIndex"></param>
129 /// <returns></returns>
130 public MailMessage GetNewMessages(int nIndex)
131 {
132 int newcount;
133 System.Web.Mail.MailMessage msg = new MailMessage();
134
135 try
136 {
137 newcount = GetNumberOfNewMessages();
138 Connect();
139 int n = nIndex+1;
140
141 if(n<newcount+1)
142 {
143 ArrayList msglines = GetRawMessage(n);
144 string msgsubj = GetMessageSubject(msglines);
145
146
147 msg.Subject = msgsubj;
148 msg.From = GetMessageFrom(msglines);
149 msg.Body = GetMessageBody(msglines);
150 }
151
152 Disconnect();
153 return msg;
154 }
155 catch
156 {
157 return null;
158 }
159 }
160 private ArrayList GetRawMessage (int messagenumber)
161 {
162 Byte[] outbytes;
163 string input;
164 string line = "";
165
166 input = "retr " + messagenumber.ToString() + "\r\n";
167 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
168 ns.Write(outbytes,0,outbytes.Length);
169
170 ArrayList msglines = new ArrayList();
171 do
172 {
173 line = sr.ReadLine();
174 msglines.Add(line);
175 } while (line != ".");
176 msglines.RemoveAt(msglines.Count-1);
177
178 return msglines;
179 }
180
181 /// <summary>
182 /// 获取邮件主题
183 /// </summary>
184 /// <param name="msglines"></param>
185 /// <returns></returns>
186 private string GetMessageSubject(ArrayList msglines)
187 {
188 string[] tokens;
189 IEnumerator msgenum = msglines.GetEnumerator();
190 while (msgenum.MoveNext() )
191 {
192 string line = (string)msgenum.Current;
193 if(line.StartsWith("Subject:") )
194 {
195 tokens = line.Split(new Char[] {' '});
196 return tokens[1].Trim();
197 }
198 }
199 return "None";
200 }
201
202 /// <summary>
203 /// 获取邮件源地址
204 /// </summary>
205 /// <param name="msglines"></param>
206 /// <returns></returns>
207 private string GetMessageFrom (ArrayList msglines)
208 {
209 string[] tokens;
210 IEnumerator msgenum = msglines.GetEnumerator();
211 while (msgenum.MoveNext() )
212 {
213 string line = (string)msgenum.Current;
214 if(line.StartsWith("From:") )
215 {
216 tokens = line.Split(new Char[] {'<'});
217 return tokens[1].Trim(new Char[] {'<','>'});
218 }
219 }
220 return "None";
221 }
222
223 /// <summary>
224 /// 获取邮件内容
225 /// </summary>
226 /// <param name="msglines"></param>
227 /// <returns></returns>
228 private string GetMessageBody(ArrayList msglines)
229 {
230 string body = "";
231 string line = " ";
232 IEnumerator msgenum = msglines.GetEnumerator();
233
234 while(line.CompareTo("") != 0)
235 {
236 msgenum.MoveNext();
237 line = (string)msgenum.Current;
238 }
239
240 while (msgenum.MoveNext() )
241 {
242 body = body + (string)msgenum.Current + "\r\n";
243 }
244 return body;
245 }
246
247 /// <summary>
248 /// 删除邮件
249 /// </summary>
250 /// <param name="messagenumber"></param>
251 private void DeleteMessage(int messagenumber)
252 {
253 Byte[] outbytes;
254 string input;
255
256 try
257 {
258 input = "dele " + messagenumber.ToString() + "\r\n";
259 outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
260 ns.Write(outbytes,0,outbytes.Length);
261 }
262 catch(Exception e)
263 {
264 return;
265 }
266
267 }
268
269 }
三. 利用Socket来发送邮件
1/// <summary>
2 /// 功能:利用Socket来发送邮件
3 /// </summary>
4 private void SocketSendMail()
5 {
6 SMTP smtp = new SMTP();
7 bool bSuccess = smtp.Send(tbSmtp.Text,25,tbSend.Text,tbReceive.Text,tbSubject.Text,tbBody.Text);
8 if(bSuccess)
9 Response.Write("<script language='javascript'>alert('邮件发送成功!')</script>");
10 else
11 Response.Write("<script language='javascript'>alert('邮件发送失败!')</script>");
12 }
2 /// 功能:利用Socket来发送邮件
3 /// </summary>
4 private void SocketSendMail()
5 {
6 SMTP smtp = new SMTP();
7 bool bSuccess = smtp.Send(tbSmtp.Text,25,tbSend.Text,tbReceive.Text,tbSubject.Text,tbBody.Text);
8 if(bSuccess)
9 Response.Write("<script language='javascript'>alert('邮件发送成功!')</script>");
10 else
11 Response.Write("<script language='javascript'>alert('邮件发送失败!')</script>");
12 }
SMTP类的实现如下:
1/// <summary>
2 /// 发送邮件类
3 /// </summary>
4 public class SMTP
5 {
6 public SMTP(){}
7
8 public bool Send(string strSmtpServer,int nPort,string strSend,string strReceive
9 ,string strSubject,string strContent)
10 {
11 /// smtp服务器的IP地址
12 string smtpserver=strSmtpServer;
13 TcpClient tcpc = new TcpClient();
14 try
15 {
16 tcpc.Connect(smtpserver, nPort);
17 StreamReader sr ;
18 string strCmd;
19 sr = new StreamReader(tcpc.GetStream(),Encoding.Default);
20
21 ///服务器连接成功以后,首先向服务器发送HeLlo命令
22 strCmd="HELO shaozhd";
23 SenSmtpCmd(tcpc,strCmd);
24
25 ///然后向服务器发送信件的成员的信箱
26 strCmd="mail from:"+ strSend;
27 SenSmtpCmd(tcpc,strCmd);
28
29 ///向服务器发送收件人的信箱
30 strCmd="rcpt to:" + strReceive;
31 SenSmtpCmd(tcpc,strCmd);
32
33 ///所有的准备工作都已经作好了,下面开始进行邮件的部分
34 strCmd="data";
35 SenSmtpCmd(tcpc,strCmd);
36
37 ///邮件内容
38 strCmd="Date: 1234567\r\n";
39 strCmd=strCmd+"From: " + strSend +"\r\n";
40 strCmd=strCmd+"To: " + strReceive +"\r\n";
41 strCmd=strCmd+"Subject: " + strSubject +"\r\n\r\n";
42 strCmd=strCmd + strContent +"\r\n\r\n";
43 SenSmtpCmd(tcpc,strCmd);
44 strCmd="\r\n.\r\n";
45 SenSmtpCmd(tcpc,strCmd);
46
47 ///最后 关闭与smtp 服务器的连接
48 tcpc.Close();
49 return true;
50 }
51 catch
52 {
53 return false;
54 }
55 }
56
57 /// <summary>
58 /// 发送SMTP命令
59 /// </summary>
60 /// <param name="tcpc"></param>
61 /// <param name="strCmd"></param>
62 void SenSmtpCmd(TcpClient tcpc,String strCmd)
63 {
64
65 byte[] arrCmd;
66 string strRet;
67 StreamReader sr;
68 Stream s;
69 s=tcpc.GetStream();
70 strCmd = strCmd + "\r\n";
71 arrCmd= Encoding.Default.GetBytes(strCmd.ToCharArray());
72 s=tcpc.GetStream();
73 s.Write(arrCmd, 0, strCmd.Length);
74
75 ///以下用于程序调试,显示服务器回应信息
76 sr = new StreamReader(tcpc.GetStream(), Encoding.Default);
77 strRet=sr.ReadLine();
78 return;
79 }
80 }
2 /// 发送邮件类
3 /// </summary>
4 public class SMTP
5 {
6 public SMTP(){}
7
8 public bool Send(string strSmtpServer,int nPort,string strSend,string strReceive
9 ,string strSubject,string strContent)
10 {
11 /// smtp服务器的IP地址
12 string smtpserver=strSmtpServer;
13 TcpClient tcpc = new TcpClient();
14 try
15 {
16 tcpc.Connect(smtpserver, nPort);
17 StreamReader sr ;
18 string strCmd;
19 sr = new StreamReader(tcpc.GetStream(),Encoding.Default);
20
21 ///服务器连接成功以后,首先向服务器发送HeLlo命令
22 strCmd="HELO shaozhd";
23 SenSmtpCmd(tcpc,strCmd);
24
25 ///然后向服务器发送信件的成员的信箱
26 strCmd="mail from:"+ strSend;
27 SenSmtpCmd(tcpc,strCmd);
28
29 ///向服务器发送收件人的信箱
30 strCmd="rcpt to:" + strReceive;
31 SenSmtpCmd(tcpc,strCmd);
32
33 ///所有的准备工作都已经作好了,下面开始进行邮件的部分
34 strCmd="data";
35 SenSmtpCmd(tcpc,strCmd);
36
37 ///邮件内容
38 strCmd="Date: 1234567\r\n";
39 strCmd=strCmd+"From: " + strSend +"\r\n";
40 strCmd=strCmd+"To: " + strReceive +"\r\n";
41 strCmd=strCmd+"Subject: " + strSubject +"\r\n\r\n";
42 strCmd=strCmd + strContent +"\r\n\r\n";
43 SenSmtpCmd(tcpc,strCmd);
44 strCmd="\r\n.\r\n";
45 SenSmtpCmd(tcpc,strCmd);
46
47 ///最后 关闭与smtp 服务器的连接
48 tcpc.Close();
49 return true;
50 }
51 catch
52 {
53 return false;
54 }
55 }
56
57 /// <summary>
58 /// 发送SMTP命令
59 /// </summary>
60 /// <param name="tcpc"></param>
61 /// <param name="strCmd"></param>
62 void SenSmtpCmd(TcpClient tcpc,String strCmd)
63 {
64
65 byte[] arrCmd;
66 string strRet;
67 StreamReader sr;
68 Stream s;
69 s=tcpc.GetStream();
70 strCmd = strCmd + "\r\n";
71 arrCmd= Encoding.Default.GetBytes(strCmd.ToCharArray());
72 s=tcpc.GetStream();
73 s.Write(arrCmd, 0, strCmd.Length);
74
75 ///以下用于程序调试,显示服务器回应信息
76 sr = new StreamReader(tcpc.GetStream(), Encoding.Default);
77 strRet=sr.ReadLine();
78 return;
79 }
80 }
支持TerryLee的创业产品Worktile
Worktile,新一代简单好用、体验极致的团队协同、项目管理工具,让你和你的团队随时随地一起工作。完全免费,现在就去了解一下吧。
https://worktile.com
Worktile,新一代简单好用、体验极致的团队协同、项目管理工具,让你和你的团队随时随地一起工作。完全免费,现在就去了解一下吧。
https://worktile.com