Web 软件的一些资料的收集整理.

来源:互联网 发布:淘宝淘营销在哪里 编辑:程序博客网 时间:2024/05/31 19:42

WEB软件结构原则

一、 目录结构清楚,不宜过深,复杂,路径最好用相对地址 
二、 命名适当 
三、 常变内容、界面使模板较好 
四、 共公信息统一存储 
五、 Include文件不可嵌入较多 
六、 目录下不可存储太多内容文件 
七、 数据结构要设计合理 
八、 数据校验应在服务器端 
九、 连接数据库近晚,断开连接近早 
十、 尽量少使用SESSION与COOKIE 

详细说明: 

(一) 目录结构清楚,不宜过深,复杂,路径最好用相对地址 
a) 什么样的目录放什么样的内容,这样便于管理,使WEB程序的目录结构,清楚明了,一看便知道某个文件夹下存储了哪些功能模块与内容。若随便存放,时间一长久自己都将不从了解某目录是用来做什么的。如:经常要使用的可执行文件最要存放在(项目根目录)根目录,这样做主要是便于了解其作用,同时也为在程序中少输入些地址字符。程序所用到的图片统一存放在根目录下images目录中,若项目较大,分枝较多,可再在其目录下建立也分枝程序相关的目录名,存储相关的图片内容。程序的配置文件与常用共公函数类库存放在include目录中,存放在此目录下的函数类库文件扩展名得命名为:.php切不命名为.inc .ini之类为扩展名的文件,主要是防此此类文件可供用户下载,或查阅其源码内容,这样对其调用方便明确。模板文件应存储在根目录下templates目录中,扩展名为.html,如果项目较大,分类较多,模板文件可分类存放在下极目录中。临时文件存储在根目录tmp目录中,此目录通常设置为任何人都可读可写。使用相对地址主要是方便程序移植。

 (二) 命名适当 
a) 命名最好是以程序用来作什么用来命名。若一个单词就要描述则用小写单词来命名,若要用多个单词方能代表,也以小写单词之间加下划线连接。要注意命名不可过长,这样就不方便了,虽然能表达的更明确,但打字难打啊。程序中函数命名也可与此相同。不好之上也有,那就是每次命名都得要花时间去想个较合适的名字,由其是对于是我们这种英文水评较差的人来说可不是一件容易的事啊。(惨啊,哈哈!) 

(三) 常变内容、界面使模板较好 
a) 常变内容、界面使用模板较好,这是因为当我某天感觉某不页面不美观时尚时,我想更换较新较好的界面,这时就用得上了。如果是按照传统的制作将HTML页面内容放在程序中处理输入时,较麻烦非得要更改程序不可,这可能会带来较大的不便万一更改出错,这就不太好了。(程序有很长一段时没有维护了,突然要改,一时之间是难免不发生改错的情况发生)。若是使用了模板则不用改程序,只要更改一下模板文件就行了。好了说了这么我模板的好处,好像传统的做法没有一点好处是的,好像分文不值是的,也不是,模板也有它不好的地方,现在我也来说说它是怎么个不好的。传统做法是把HTML代码嵌入在WEB程序中,这样做的好处是,执行速度要比使用模板的要快,这是因为它不用经过任何处理就能直接输出,而模板就不一样啦。模板先要打开读取模板文件到字符串变量可数组字符串变量中,这是要时间的吧?读处完了之后还得花时间用字符串操作函数替换模板中模板变量吧?替换完成了方能进入输出。传统做法与使用模板作法,您觉得哪个好呢?(我个人认为如果是开发访问量相当大的网站,选择传统的作法是一个不错的选择,我所说的是相对不是绝对,如果访问量再大那就不能用脚本语言去写了,那得用CGI + Socket + Demon了。不说了,说远了,哈哈) 

(四) 共公信息统一存储 
a) 共公信息统一存储,这主要为了方便团队开发时都能进行调用用的最常的函数,不用每个开发人员都复制一份或自己写一份存储在程序文件中,这样做浪费空间同时效率效果也不好。 

(五) Include文件不可嵌入较多 
a) Include文件不可嵌入较多,这是因为每次程序include某个文件时,是要打开读取这个文件的,这是要时间的哦,再就是说处理路径时可能会遇到较难发现的BUG问题。 

(六) 目录下不可存储太多内容文件 
a) 目录下不可存储太多内容文件,你有没有发现?每当你进入windows的system32文件夹时通常打开的时间要比打开其它文件夹时要长久点呢?这主要是因为system32这个文件夹中文件较多,当你打开系统得花时间查找文件并显示吧?如果文件较多较大时最好是分目录分盘符来处理。假若您的机器够好够强劲的话,就当我没说过,那就得另当别论了。 

(七) 数据结构要设计合理 
a) 数据结构要设计合理,如果数据结构设计不合理的话,不管你的程序写的多精典,写得我容易,也不是不能发挥其最大作用与价值的。这就相当于一个女人的胸部最大最丰满,但人不够高,而且又黑,身体又不好,身架又残疾,你会说她美丽完美吗?程序也一样,有些代码沉长又不起作用,存在也没有什么用。数据结构要精简明了。 

(八) 数据校验应在服务器端

a) 数据校验应在服务器端,这是因为就算是他人不从我们的页面输入数据,自己做了个链接地址(GET)或自己做了个表单用POST方式传送数据,我们的程序也将进入核对查验。若是放在客户端,他人就能用以上方法逃过审核了。但这样做也有他不好之处,那就是当数据量大时,服务器会负载运行,审核数据完整性是可开销时间与系统资源的。在客户端就不会占用服务器太多的资源,因为他占用的是用户的资源。 

(九) 连接数据库近晚,断开连接近早 
a) 连接数据库近晚,断开连接近早,这主要是因为连接数据是要时间的吧?连接上了不即时使用也要占用系统资源吧?连接数据库连接数量是有限制的吧?所以得尽晚连接,尽早断开连接,这个做能使占用系统资源最少,为下一次连接提供条件。 

(十) 尽量少使用SESSION与COOKIE 
a) 尽量少使用SESSION与COOKIE,因为使用SESSION是要占用系统资源的,SESSION是存储在服务器端的,每次读取SESSION中的数据是要较大开销的。COOKIE虽然不占用服务器资源,但COOKIE不太安全。  

 

根据html页面模板动态生成html页面(c#类)

一直以为动态生成静态页面不好做,昨天在网上找了下,我晕,其实很简单,思路大概是这样的,
1:建立一个HTML页面模板,在这个页面中把你想要动态显示的地方用特殊的字符串表示(如$HTMLstrstr$);
2:在程序中用将这个HTML页面读到一个字符串变量如str;
3:用字符串的resplace方法将在第一步中特殊字符替换成你想要的内容;
4保存;
OK,so easy,今天就用C#写了一个这样的类,用来处理动态生成HTML页面的,自认为还写的完整,刚接触.NET不久,望指教

注:此类中的代码不全是原创,部份代码参照网友的代码!

以下是转换类的代码


代码
  1using System;
  2using System.Text;
  3using System.Web;
  4using System.Configuration;
  5using System.IO;
  6namespace solucky
  7{
  8    /**//// <summary>
  9    /// ASPxToHTML 的摘要说明。
 10    /// 注:使用此类,你可以在web.config文件对模板类进行配置.如下
 11    /**//*<appSettings>
 12    <add key="templateFilePath" value="HTMLmoudel.htm" />
 13    <add key="HTMLFilePath" value="new/"></add>
 14    <add key="ErrLogPath" value="ASPxToHTML_log.txt"></add>   
 15    </appSettings>*/
 16    /**//// </summary>
 17    public class ASPxToHTML
 18    {
 19        /**//// <summary>
 20        /// 模板文件中要替代的参数个数
 21        /// </summary>
 22        private int            _templateParamCount=0;
 23        /**//// <summary>
 24        /// 模板文件所在的路径
 25        /// </summary>
 26        private string        _templateFilePath        =ConfigurationSettings.AppSettings["templateFilePath"];
 27        /**//// <summary>
 28        /// 转换后的HTML文件所存放的路径
 29        /// </summary>
 30        private string        _HTMLFilePath            =ConfigurationSettings.AppSettings["HTMLFilePath"];
 31       
 32        /**//// <summary>
 33        /// 模板页页面编码
 34        /// </summary>
 35        private Encoding _templateHTMLCode            =Encoding.GetEncoding("gb2312");
 36
 37        /**//// <summary>
 38        /// 转换后的文件编码
 39        /// </summary>
 40        private Encoding _code = Encoding.GetEncoding("gb2312");
 41
 42        /**//// <summary>
 43        /// 转换后的HTML文件名
 44        /// </summary>
 45        private string  _convertedFilename="";
 46        /**//// <summary>
 47        /// 模板文件中的参数
 48        /// </summary>
 49        private string[]    _templateFileparameter    ;
 50       
 51        /**//// <summary>
 52        /// ASPx文件中的要代替HTML文件中的参数实际值
 53        /// </summary>
 54        private string[]    _ASPxFileparameter;
 55
 56        private string _errlogPath = ConfigurationSettings.AppSettings["ErrLogPath"];
 57
 58        属性#region 属性
 59       
 60        /**//// <summary>
 61        /// 模板文件中要替代的参数个数
 62        /// </summary>
 63        public int TemplateParamCount
 64        {
 65            get
 66            {
 67                return    this._templateParamCount;
 68            }
 69            set//分配参数个数时,同时为模板文件中的参数和ASPx文件中的要代替HTML文件中的参数实际值这两个分配实际数组
 70            {
 71                if (value < 0)
 72                    throw new ArgumentException();
 73
 74                if(value>0)               
 75                {
 76                    this._templateParamCount=value;
 77                    //模板文件中的参数                   
 78                    _templateFileparameter    = new string[value];
 79                    //ASPx文件中的要代替HTML文件中的参数实际值
 80                    _ASPxFileparameter        = new string[value];
 81                }
 82                else
 83                    this._templateParamCount=0;
 84            }
 85        }
 86       
 87        /**//// <summary>
 88        /// 模板文件所在的路径
 89        ///
 90        /// </summary>
 91        public string TemplateFilePath
 92        {
 93            get{    return this._templateFilePath;}
 94            set{    this._templateFilePath=value;}
 95        }
 96        /**//// <summary>
 97        /// 转换后的HTML文件所存放的路径
 98        /// </summary>
 99        public string HTMLFilePath
100        {
101            get{    return this._HTMLFilePath;}
102            set{    this._HTMLFilePath=value;}
103        }
104
105        /**//// <summary>
106        /// HTML模板文件编码
107        /// </summary>
108        public Encoding TemplateHTMLCode
109        {
110            get{    return this._templateHTMLCode;}
111            set{    this._templateHTMLCode=Encoding.GetEncoding(value.ToString());}
112        }
113        /**//// <summary>
114        /// 编码
115        /// </summary>
116        public Encoding Code
117        {
118            get{    return this._code;}
119            set{    this._code=Encoding.GetEncoding(value.ToString());}
120        }
121        /**//// <summary>
122        /// 错误文件所在路径
123        /// </summary>
124        public string ErrLogPath
125        {
126            get{
127                if(!(this._errlogPath==null))
128                    return this._errlogPath;
129                else
130                    return "ASPxToHTML_log.txt";
131            }
132            set{this._errlogPath=value;}
133        }
134
135       
136        #endregion
137       
138        操作#region 操作
139
140        /**//// <summary>
141        /// 获取转换后的HTML文件所在相对文件路径
142        /// 如:如果HTMLFilePath="/news/"
143        /// 转换后的HTML文件名为200505050505.HTML
144        /// 则返回的值为/news/200505050505.HTML
145        /// </summary>
146        /// <remarks>如果在未调用StartConvert方法之前调用此属性则返回null</remarks>
147        public string HTMLFileVirtualPath
148        {
149            get
150            {   
151                if(!(this._convertedFilename==""))
152                    return    this.HTMLFilePath+this._convertedFilename;
153                else
154                    return null;
155            }
156        }
157
158        /**//// <summary>
159        /// 为HTML页面参数数组付值
160        /// </summary>
161        /// <param name="param"></param>
162        public void    setTemplateFileparameter(string[] param)
163        {
164            try
165            {
166                if(param.Length==this.TemplateParamCount)
167                    this._templateFileparameter=param;
168                //else//与原定义的个数不等
169                    //
170            }
171            catch(System.Exception    ex)
172            {
173                WriteErrFile(ex);
174            }
175        }
176        /**//// <summary>
177        /// 为ASPx文件中将要替换HTML文件中的参数数组付值
178        /// </summary>
179        /// <param name="param"></param>
180        public void setASPxFileparameter(string[] param)
181        {
182            try
183            {
184                if(param.Length==this.TemplateParamCount)
185                    this._ASPxFileparameter=param;
186                //else//与原定义的个数不等
187                //
188            }
189            catch(System.Exception    ex)
190            {
191            WriteErrFile(ex);
192            }
193        }
194        /**//// <summary>
195        /// 开始进行ASPxToHTML转换
196        /// </summary>
197        /// <returns>返回值为成功创建后的文件名称</returns>
198        /// <remarks>在调用此方法之前必需确定已调用setTemplateFileparameter 和setASPxFileparameter方法进行相应的付值操作</remarks>
199        public string StartConvert()
200        {
201            if(this._templateFileparameter.Length==this._ASPxFileparameter.Length)
202            {
203                return writeFile();
204            }
205            else{
206                return null;
207            }
208        }
209        /**//// <summary>
210        /// 开始进行ASPxToHTML转换
211        /// </summary>
212        /// <param name="HTMLparam">HTML模板页中的所有参数数组</param>
213        /// <param name="ASPxparam">ASPx页面中要代替HTML模板页中参数值数组</param>
214        /// <returns>返回值为成功创建后的文件名称</returns>
215        public string StartConvert(string[] HTMLparam,string[] ASPxparam)
216        {
217            //先调用setTemplateFileparameter 和setASPxFileparameter方法,进行付值操作
218            setTemplateFileparameter(HTMLparam);
219            setASPxFileparameter(ASPxparam);
220            //
221            string fn=this.StartConvert();
222            //
223            _convertedFilename=fn;
224            //
225            return fn;
226        }
227       
228        /**//// <summary>
229        /// 用时间加随机数生成一个文件名
230        /// </summary>
231        /// <returns></returns>
232        private string getfilename()
233        {
234            //用时间加随机数生成一个文件名
235            System.Threading.Thread.Sleep(50);
236            string yearStr = System.DateTime.Now.Year.ToString();
237            string monthStr = string.Format("{0:0#}",System.DateTime.Now.Month);
238            string dayStr = string.Format("{0:0#}",System.DateTime.Now.Day);
239            string hourStr = string.Format("{0:0#}",System.DateTime.Now.Hour);
240            string minuteStr = string.Format("{0:0#}",System.DateTime.Now.Minute);
241            string secondStr = string.Format("{0:0#}",System.DateTime.Now.Second);
242            string millisecondStr = string.Format("{0:000#}",System.DateTime.Now.Millisecond);                   
243            System.Random rd = new System.Random();
244            return yearStr + monthStr + dayStr + hourStr + minuteStr + secondStr + millisecondStr + string.Format("{0:0000#}",rd.Next(100))+".HTML";
245            //return DateTime.Now.ToString("yyyyMMddHHmmss")+".HTML";
246        }
247        /**//// <summary>
248        /// 进行转换处理
249        /// </summary>
250        /// <returns>返回以时间命名的文件名</returns>
251        private string writeFile()
252        {
253           
254            // 读取模板文件
255            string temp = HttpContext.Current.Server.MapPath(this.TemplateFilePath);
256            StreamReader sr=null;           
257            string str="";
258            try
259            {
260                sr = new StreamReader(temp, this.TemplateHTMLCode);
261                str = sr.ReadToEnd(); // 读取文件
262            }
263            catch(Exception ex)
264            {
265                //HttpContext.Current.Response.Write(exp.Message);
266                //HttpContext.Current.Response.End();       
267                WriteErrFile(ex);
268            }
269            finally
270            {
271                sr.Close();
272            }           
273            // 替换内容
274            // 这时,模板文件已经读入到名称为str的变量中了
275            for(int i=0;i<this.TemplateParamCount;i++)
276            {
277                str =str.Replace(this._templateFileparameter[i],this._ASPxFileparameter[i]);
278            }       
279
280            return savefile(str);
281        }
282
283        /**//// <summary>
284        ///
285        /// </summary>
286        /// <param name="str"></param>
287        /// <returns></returns>
288
289        private string savefile(string str)
290        {
291            // 写文件
292            StreamWriter sw=null;
293            try
294            {
295               
296                string path = HttpContext.Current.Server.MapPath(this.HTMLFilePath);
297                //HTML文件名称   
298                string HTMLfilename=getfilename();
299                sw = new StreamWriter(path + HTMLfilename , false, this.Code);
300                sw.Write(str);
301                sw.Flush();
302                return HTMLfilename;
303            }
304            catch(Exception ex)
305            {               
306                WriteErrFile(ex);
307            }
308            finally
309            {
310                sw.Close();
311            }
312            return "";
313        }
314
315        /**//// <summary>
316        /// 传入URL返回网页的HTML代码
317        /// </summary>
318        /// <param name="Url">URL</param>
319        /// <returns></returns>
320        public string getUrltoHTML(string Url)
321        {           
322            try
323            {
324                System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);           
325                System.Net.WebResponse wResp =wReq.GetResponse();               
326                System.IO.Stream respStream  = wResp.GetResponseStream();               
327                System.IO.StreamReader reader = new System.IO.StreamReader(respStream, System.Text.Encoding.GetEncoding("gb2312"));
328                return  savefile(reader.ReadToEnd());
329
330            }
331            catch(System.Exception ex)
332            {
333                WriteErrFile(ex);
334            }
335            return "";
336        }
337        #endregion
338
339
340        构造#region 构造       
341       
342        public ASPxToHTML()
343        {
344            //
345            // TODO: 在此处添加构造函数逻辑
346            //           
347        }
348
349        private void settemplateParamCount(int templateParamCount)
350        {
351            if (templateParamCount>0)
352                this.TemplateParamCount=templateParamCount;
353        }
354        /**//// <summary>
355        /// 提供欲代替的参数个数
356        /// </summary>
357        /// <param name="templateParamCount"></param>
358        public ASPxToHTML(int templateParamCount)
359        {   
360            settemplateParamCount(templateParamCount);
361           
362        }
363        /**//// <summary>
364        ///
365        /// </summary>
366        /// <param name="templateParamCount">HTML模板页中的参数个数</param>
367        /// <param name="HTMLFilePath">生成的HTML文件所存放的文件夹路径</param>
368        /// <param name="templateFilePath">HTML模板页路径</param>
369        public ASPxToHTML(int templateParamCount,string HTMLFilePath,string templateFilePath)
370        {
371            settemplateParamCount(templateParamCount);
372            this.HTMLFilePath        =    HTMLFilePath;
373            this.TemplateFilePath    =    templateFilePath;
374           
375        }
376        #endregion
377
378        #region
379       
380        /**//// <summary>
381        /// 把错误写入文件方法#region 把错误写入文件方法
382        /// </summary>
383        /// <param name="ee"></param>
384        private  void WriteErrFile(Exception ee)
385        {
386           
387            FileStream fs1 = new FileStream(HttpContext.Current.Server.MapPath(ErrLogPath), System.IO.FileMode.Append);
388            StreamWriter sw1 = new StreamWriter(fs1);
389            sw1.WriteLine("**************************************************");
390            sw1.WriteLine("错误日期:" + System.DateTime.Now);
391            sw1.WriteLine("错误描述:" + ee.Message);
392            sw1.WriteLine("错误名称:" + ee.Source);
393            sw1.WriteLine("详细:" + ee.ToString());
394            sw1.WriteLine("*************************************************");
395            sw1.Close();
396        }
397        #endregion
398    }
399}

asp.net动态生成html页面

简介

此功能适用于后台数据库功能不强的web站点,即大部分文本不是存放在数据库的记录中,而是放在html文件或者xml文件中,仅仅把索引放到数据库中,如文章标题、类别、查询关键字等。这样适合于后台没有诸如ms Sql Server这样的数据库支持的Web站点。

适用于新闻发布系统,比如sina、163等都是采用动态生成html页面的。

适用于需动态定制页面的程序。比如论坛、聊天室等。可以加载定制好的html页面,来加强美观。

思路

1. 利用如Dw-Mx这样的工具生成html格式的模板,在需要添加格式的地方加入特殊标记(如$htmlformat$),动态生成文件时利用代码读取此模板,然后获得前台输入的内容,添加到此模板的标记位置中,生成新文件名后写入磁盘,写入后再向数据库中写入相关数据。

2. 使用后台代码硬编码Html文件,可以使用HtmlTextWriter类来写html文件。

优点

1. 可以建立非常复杂的页面,利用包含js文件的方法,在js文件内加入document.write()方法可以在所有页面内加入如页面头,广告等内容。

2. 静态html文件利用MS Windows2000的Index Server可以建立全文搜索引擎,利用asp.net可以以DataTable的方式得到搜索结果。而Win2000的Index服务无法查找xml文件的内容。如果包括了数据库搜索与Index索引双重查找,那么此搜索功能将非常强大。

3. 节省服务器的负荷,请求一个静态的html文件比一个aspx文件服务器资源节省许多。

缺点

思路二: 如果用硬编码的方式,工作量非常大,需要非常多的html代码。调试困难。而且使用硬编码生成的html样式无法修改,如果网站更换样式,那么必须得重新编码,给后期带来巨大的工作量。

因此这里采用的是第一种思路

示列代码

1.定义(template.htm)html模板页面

<html>

<head>

<title></title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body >

<table $htmlformat[0] height="100%" border="0" width="100%" cellpadding="10" cellspacing="0" bgcolor="#eeeeee" style="border:1px solid #000000">

<tr>

<td width="100%" valign="middle" align="left">

<span style="color: $htmlformat[1];font-size: $htmlformat[2]">$htmlformat[3]</span>

</td>

</tr>

</table>

</body>

</html>

2.asp.net代码:

//---------------------读html模板页面到stringbuilder对象里----

string[] format=new string[4];//定义和htmlyem标记数目一致的数组

stringbuilder htmltext=new StringBuilder();

try

{

using (StreamReader sr = new StreamReader("存放模板页面的路径和页面名"))

{

string line;

while ((line = sr.ReadLine()) != null)

{

htmltext.append(line);

}

sr.close();

}

}

catch

{

response.write("<script>alert('读取文件错误')</script>");

}

//---------------------给标记数组赋值------------

format[0]="background=/"bg.jpg/"";//背景图片

format[1]= "#990099";//字体颜色

format[2]="150px";//字体大小

format[3]= "<marquee>生成的模板html页面</marquee>";//文字说明

//----------替换htm里的标记为你想加的内容

for(int i=0;i<4;i++)

{

htmltext.replace("$htmlformat["+i+"]",format[i]);

}

//----------生成htm文件------------------――

try

{

using(streamwriter sw=new StreamWriter("存放路径和页面名",false,System.Text.Encoding.GetEncoding("GB2312")))

{

sw.writeline(htmltext);

sw.flush();

sw.close();

}

}

catch

{

response.write ("The file could not be wirte:");

}

小结

用此方法可以方便的生成html文件。程序使用了是循环替换,因此对需替换大量元素的模板速度非常快。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 想要投诉纹身店怎么办 货车帮怎么办超级会员 中型客车怎么办营业证 转租的房子押金怎么办 卖方违约中介费怎么办 房子不想租了怎么办 转租房屋室友不同意怎么办 提前不租房押金怎么办 租房提前走押金怎么办 出租车上丢东西怎么办 我有车想租出租车手续怎么办? 东西落在顺风车怎么办 滴滴投诉不处理怎么办 的士车上丢东西怎么办 手机掉在出租车怎么办 出国痰培养不合格怎么办 教师资格证体检弱视怎么办 弱视不能考驾照怎么办 驾驶证b证扣分怎么办 c1并d照怎么办 钱包落出租车上怎么办 杭州车过户车牌怎么办 哈市医保卡丢失怎么办 退休时医保怎么办手续 社保退休了医保怎么办 工作调动后医保怎么办 异地工作调动医保怎么办 工作调动社保医保怎么办 工作调动了社保怎么办 医疗卡丢了怎么办 省直医保卡丢失怎么办 医保卡挂失失败怎么办 临时社保卡过期怎么办 医保卡补办期间怎么办 医保丢了住院怎么办 临时社保卡丢失怎么办 深圳社保卡丢失怎么办 医疗保险本丢了怎么办 人不在家怎么办社保卡 人外地怎么办社保卡 卡身份证丢了怎么办