崔文远 Troy Cui 老崔先生的上海生活、技术博客

把吉日嘎拉GPM自带的DotNet.WebForm Web Site 转换为Web Application

昨晚上折腾了一晚上终于把吉日嘎拉的GPM自带的DotNet.WebForm转换为Web Application项目了。之所以要费这个劲,一个原因是公司里开发的OA项目,在使用Web Site模式发布的时候,每个页面都会生成随机名称的dll,每次更新发布到服务器的时候就很费劲,不如一个Web Application最终生成一个dll方便。另一个原因是吉日嘎拉的官方SVN上的源码也已经转换为Web Application,我也要与时俱进才行。

转换过程中遇到的问题主要有:

1、添加引用的问题,不要漏掉引用NPOI、CuteEditor、CuteEditor.ImageEditor、System.ServiceModel
2、重复的类名:Common/WorkFlow/Report.ascx和Common/Report/Report.ascx、Common/User/UserCode.aspx和Common/UserAdmin/UserCode.aspx

参考文章:[URL=http://blogs.msdn.com/b/webdev/archive/2009/10/29/converting-a-web-site-project-to-a-web-application-project.aspx]Converting a Web Site Project to a Web Application Project[/URL]

Tags:

发布: cuiwenyuan 分类: Web技术 评论: 0 浏览: 147

C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)

上午写了一篇《[URL=http://www.cuiwenyuan.com/shanghai/post/Windows-AD-Logon-Intergrated-into-Jirigala-CSharp-Framework.html]C#开发中Windows域认证登录[/URL]》,然后跟[URL=http://www.cnblogs.com/jirigala/]吉日嘎拉[/URL]沟通了一下,还是把这个Windows AD用户登录的功能扩展到DotNet.Business中,重新命名为LDAP方式的登录,因为需要引用System.DirectoryServices,暂时用不到此功能的朋友,可以exclude此文件(DotNet.Business\WebUtilities\Utilities.LogOnLDAP.cs)。

<br/>//-----------------------------------------------------------------<br/>// All Rights Reserved , Copyright (C) 2013 , Hairihan TECH, Ltd .<br/>//-----------------------------------------------------------------<br/><br/>using System;<br/>using System.Collections.Generic;<br/>using System.Configuration;<br/>using System.Data;<br/>using System.Text;<br/>using System.Web;<br/>using System.Web.Caching;<br/>using System.Web.Security;<br/>using System.DirectoryServices;<br/>using DotNet.Utilities;<br/><br/>namespace DotNet.Business<br/>{<br/>    /// <summary><br/>    /// LDAP登录功能相关部分<br/>    /// </summary><br/>    public partial class Utilities<br/>    {<br/>        // LDAP域用户登录部分:包括Windows AD域用户登录<br/>        #region public static BaseUserInfo LogOnByLDAP(string domain, string lDAP, string userName, string password, string permissionCode, bool persistCookie, bool formsAuthentication, out string statusCode, out string statusMessage)<br/>        /// <summary><br/>        /// 验证LDAP用户<br/>        /// </summary><br/>        /// <param name="domain">域</param><br/>        /// <param name="lDAP">LDAP</param><br/>        /// <param name="userName">域用户名</param><br/>        /// <param name="password">域密码</param><br/>        /// <param name="permissionCode">权限编号</param><br/>        /// <param name="persistCookie">是否保存密码</param><br/>        /// <param name="formsAuthentication">表单验证,是否需要重定位</param><br/>        /// <param name="statusCode"></param><br/>        /// <param name="statusMessage"></param><br/>        /// <returns></returns><br/>        public static BaseUserInfo LogOnByLDAP(string domain, string lDAP, string userName, string password, string permissionCode, bool persistCookie, bool formsAuthentication, out string statusCode, out string statusMessage)<br/>        {<br/>            DirectoryEntry dirEntry = new DirectoryEntry();<br/>            dirEntry.Path = lDAP;<br/>            dirEntry.Username = domain + "\\" + userName;<br/>            dirEntry.Password = password;<br/>            dirEntry.AuthenticationType = AuthenticationTypes.Secure;<br/><br/>            try<br/>            {<br/>                DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);<br/>                dirSearcher.Filter = String.Format("(&(objectClass=user)(samAccountName={0}))", userName);<br/>                System.DirectoryServices.SearchResult result = dirSearcher.FindOne();<br/>                if (result != null)<br/>                {<br/>                    // 统一的登录服务<br/>                    DotNetService dotNetService = new DotNetService();<br/>                    BaseUserInfo userInfo = dotNetService.LogOnService.LogOnByUserName(Utilities.GetUserInfo(), userName, out statusCode, out statusMessage);<br/>                    // 检查身份<br/>                    if (statusCode.Equals(Status.OK.ToString()))<br/>                    {<br/>                        userInfo.IPAddress = GetIPAddressId();<br/><br/>                        bool isAuthorized = true;<br/>                        // 用户是否有哪个相应的权限<br/>                        if (!string.IsNullOrEmpty(permissionCode))<br/>                        {<br/>                            isAuthorized = dotNetService.PermissionService.IsAuthorized(userInfo, permissionCode, null);<br/>                        }<br/>                        // 有相应的权限才可以登录<br/>                        if (isAuthorized)<br/>                        {<br/>                            if (persistCookie)<br/>                            {<br/>                                // 相对安全的方式保存登录状态<br/>                                // SaveCookie(userName, password);<br/>                                // 内部单点登录方式<br/>                                SaveCookie(userInfo);<br/>                            }<br/>                            else<br/>                            {<br/>                                RemoveUserCookie();<br/>                            }<br/>                            LogOn(userInfo, formsAuthentication);<br/>                        }<br/>                        else<br/>                        {<br/>                            statusCode = Status.LogOnDeny.ToString();<br/>                            statusMessage = "访问被拒绝、您的账户没有后台管理访问权限。";<br/>                        }<br/>                    }<br/><br/>                    return userInfo;<br/>                }<br/>                else<br/>                {<br/>                    statusCode = Status.LogOnDeny.ToString();<br/>                    statusMessage = "应用系统用户不存在,请联系管理员。";<br/>                    return null;<br/>                }<br/>            }<br/>            catch (Exception e)<br/>            {<br/>                //Logon failure: unknown user name or bad password.<br/>                statusCode = Status.LogOnDeny.ToString();<br/>                statusMessage = "域服务器返回信息" + e.Message.Replace("\r\n", "");<br/>                return null;<br/>            }<br/><br/>            <br/>        }<br/>        #endregion<br/><br/>    }<br/>}<br/>



前端的登录文件-SigninLDAP.aspx,代码较多可参考Signin.aspx。

Tags:

发布: cuiwenyuan 分类: Web技术 评论: 0 浏览: 606

C#开发中Windows域认证登录

吉日嘎了的Webform例子程序做的很好,但在我们公司,除了使用GPM通用权限管理自带的账户系统登录,还需要集成Windows域账户登录。对于如何实现,我思考了一段时间,大体的思路如下:

1、在GPM中创建的用户账号和其在Windows域中的账号一致,如域账号为Troy.Cui,那么GPM中登录userName也是Troy.Cui
2、GPM中的账号需要单独手工创建,因为涉及到的权限、角色的设定,如果使用域账号登录的时候,自动创建GPM的账号意义不大
3、不启用IIS中的Windows集成认证,因为我们还有一部分用户是没有域账号的,所以必须使用模拟域用户登录的方式进行认证
4、模拟域账号登录成功后,需要在GPM中增加一个DomainLogon的方法,直接使用域账号进行登录,无需密码。

昨天在实现的过程中,在DoNet.Business中增加了DomainLogon(string userName)的方法调用BaseUserManager.LogOnByUserName,但是在做模拟域用户登录的时候,一直报各种各样的错误:

1、There is no such object on the server.
2、0x80005000
3、A referral was returned from the server

最后通过参考《[URL=http://www.codeproject.com/Articles/18102/Howto-Almost-Everything-In-Active-Directory-via-C]Howto: (Almost) Everything In Active Directory via C#[/URL]》和《[URL=http://www.cnblogs.com/netlover/archive/2011/03/30/1999836.html]Asp.Net模拟域验证登录及密码修改[/URL]》,最后终于调试通过,代码如下:

创建DomainSigin.aspx,在DomainSigin.aspx.cs中增加引用:using System.DirectoryServices;

<br/>/// <summary><br/>    /// 域用户登录<br/>    /// </summary><br/>    /// <param name="userName">用户名</param><br/>    /// <param name="password">密码</param><br/>    private void DomainUserLogOn(string userName, string password)<br/>    {<br/>        //China Only<br/>        //string lDAP = "OU=Users,OU=China,DC=CORP,DC=yourdomain,DC=com";<br/>        string lDAP = "DC=CORP,DC=yourdomain,DC=com";<br/>        <br/>        DirectoryEntry dirEntry = new DirectoryEntry();<br/>        dirEntry.Path = string.Format("LDAP://{0}", lDAP);<br/>        dirEntry.Username = "corpwaiglobal\\" + userName;<br/>        dirEntry.Password = password;<br/>        dirEntry.AuthenticationType = AuthenticationTypes.Secure;<br/>        <br/>        string checkInput = string.Empty;<br/><br/>        try<br/>        {<br/>            DirectorySearcher searcher = new DirectorySearcher(dirEntry);<br/>            searcher.Filter = String.Format("(&(objectClass=user)(samAccountName={0}))", userName);<br/>            System.DirectoryServices.SearchResult result = searcher.FindOne();<br/>            if (result != null)<br/>            {<br/>                // 正常登录<br/>                <br/>                try<br/>                {<br/>                    string statusCode = string.Empty;<br/>                    string statusMessage = "没有此用户。";<br/><br/>                    // 有什么权限的人才可以登录到系统<br/>                    string permissionItemCode = string.Empty;<br/><br/>                    // 登录验证<br/>                    string openId = Utilities.GetOpenId();<br/>                    BaseUserInfo userInfo = Utilities.DomainLogOn(userName);<br/><br/>                    // txtVerifyCode.Text = string.Empty;<br/>                    // 登录结果<br/>                    if (userInfo!=null)<br/>                    {<br/>                        this.AfterLogOn(userInfo);<br/>                        // 登录成功,重新定向到跳转的页面<br/>                        // Page.Response.Redirect(this.ReturnURL);<br/>                        // 若是单点登录,还需要把OpenId传递过去,这样在其他子网站里可以获取到OpenId,而不是用户名密码了,可以进行加密登录了<br/>                        if (!string.IsNullOrEmpty(this.ReturnURL) && !string.IsNullOrEmpty(userInfo.OpenId))<br/>                        {<br/>                            if (this.ReturnURL.IndexOf('?') > 0)<br/>                            {<br/>                                this.ReturnURL = this.ReturnURL + "&OpenId=" + userInfo.OpenId;<br/>                            }<br/>                            else<br/>                            {<br/>                                this.ReturnURL = this.ReturnURL + "?OpenId=" + userInfo.OpenId;<br/>                            }<br/>                        }<br/>                        Response.Redirect(this.ReturnURL, false);<br/>                    }<br/>                    else<br/>                    {<br/>                        checkInput = "<script>alert('提示信息:" + statusMessage + "');</script>";<br/>                        Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput);<br/>                        this.txtUserName.Focus();<br/>                    }<br/>                }<br/>                catch (System.Exception exception)<br/>                {<br/>                    Page.Response.Write(exception.Message);<br/>                    checkInput = "<script>alert('提示信息:登录失败,请检查你的用户名和密码是否输入有误。');</script>";<br/>                    Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput);<br/>                    this.txtUserName.Focus();<br/>                }<br/>            }<br/>            dirEntry.Close();<br/>        }<br/>        catch (Exception ex)<br/>        {<br/>            Page.Response.Write(ex.Message);<br/>            checkInput = "<script>alert('提示信息:登录失败,请检查你的用户名和密码是否输入有误。');</script>";<br/>            Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput);<br/>            this.txtUserName.Focus();<br/>        }<br/>    }<br/>



坦白的说,这么实现的话,对DotNet.Business部分暴漏出来一个无需密码的LogOnByUserName登录,的确是一个风险,最好的做法是把域验证的部分也放到DotNet.Business,但是这么做,又有缺点,会对不需要域认证的用户早成负担。

Tags:

发布: cuiwenyuan 分类: Web技术 评论: 0 浏览: 1568

ERPLN中明明有库存,却没办法转库

再次感谢Infor的Russell He,帮我前天搞定了一个库存转移的Shortage报错,我这个case是修改whwmd216里面的committed数量来修复的。其实我自己查了半天,对tcibd100 Item Inventory, whinr140 Stock Point Inventory, whwmd215 Item Inventory by Warehouse都做了检查,也重新生成了Planned Inventory Transaction,对这些地方的allocated inventory和committed  inventory都做了检查,没想到是出在whwmd216 Inventory by Warehouse,Item and Effective Unit这个表。

以下是来自Russell的解决思路,记录一下,以后备用。

Hi Troy,

在有可见现有库存的情况下,出库通知报短缺会有以下的原因。

1. 该物料处于周期盘点中 (这个可以通过查周期盘点单whinh5100m000和周期盘点数据whinh5140m000进行排除)

2. 库存已经被其他订单占用 (如果其它订单已经生成了出库通知,则在确认装运前,库存依然会显示在现有库存栏里,这个可以查计划事务处理whinp1500m000查到其他的订单然后看仓单执行到哪步了)

3. 库存承诺 (这个可以在库存承诺whinp2100m000里查)

4. 数据损毁或冗余 (库存相关数据都是存在whwmd开头的表里,其中,如果是现有库存,分配库存,在购库存有数据错误,可以通过修复进程whwmd6290m000进行检查和修复。如果是其他字段比如承诺库存损毁,则需要人工检查,检查范围在whwmd215 - whwmd220)

鉴于此case问题已解决,我在此先将其关闭。您有任何问题,欢迎随时提问。

Best Regards,
Russell He

More...

Tags: ERPLN

发布: cuiwenyuan 分类: Infor ERP LN(BaaN ERP) 评论: 0 浏览: 136

ERP LN中Batch不同步造成的发票没法Post

今天财务销售发票打印之后,发票状态一直是Printed状态,本以为是财务执行Compose/Print/Post Invoice没有选择Post选项,让他们手工Post的时候,他们说报错,我自己运行了一下,报错如下:

<br/>can not update batch status because it is deleted, in termination or terminated<br/>



第一个念头就是Batch被人为删除了,但转念想想不对,这是系统的Batch,不应该呀。无奈之下,官方搜索了一下文档,居然跟以前遇到的问题:《[URL=http://www.cuiwenyuan.com/shanghai/post/ERP-LN-Session-tfcor0214m000-Correction-of-Last-Used-Batch-Number.html]极少有机会用到的ERP LN Session tfcor0214m000 - Correction of Last Used Batch Number[/URL]》,是同一个原因。

官方的解决方案如下,记录一下:

<br/>Sometimes, the Last Used Batch Number in table Last Used Batch (tfgld014) is out-of-sync with the last batch number in table Batch Status (tfgld100). Therefore, a correction program is provided in order to update the Last Used Batch Number in table tfgld014.<br/>



到底什么原因造成的不同步,官方说网络问题,不稳定啥的,其实官方应该有自动保护机制。

Tags: Infor ERPLN

发布: cuiwenyuan 分类: Infor ERP LN(BaaN ERP) 评论: 0 浏览: 91

C#开发中表单提交Ctrl+Enter和Enter快捷键的jQuery实现方式

以前写HRM系统的时候,通过C#代码和javascript实现过文本输入框中Enter提交表单的功能,使用的原理是针对textbox进行Enter键的监控,如果输入了Enter就调用C#的指定Button功能,这里可以支持同一个表单多个button可以任意选择触发其中的某个button。

前端javascript代码如下:

<br/><script type=text/javascript><br/>    function doClick(buttonName, e) {<br/>        //the purpose of this function is to allow the enter key to <br/>        //point to the correct button to click.<br/>        var key;<br/><br/>        if (window.event)<br/>            key = window.event.keyCode;     //IE<br/>        else<br/>            key = e.which;     //firefox<br/><br/>        if (key == 13) {<br/>            //Get the button the user wants to have clicked<br/>            var btn = document.getElementById(buttonName);<br/>            if (btn != null) { //If we find the button click it<br/>                btn.click();<br/>                event.keyCode = 0<br/>            }<br/>        }<br/>    }</script><br/>


后端C#在Page_Load中的if (!IsPostBack)部分加入如下代码:

<br/>txtEmployeeID.Attributes.Add("onKeyPress", "doClick('" + btnSearch.ClientID + "',event)");<br/>



今天在搞OA里面的任务管理开发的时候,希望能后使用通用的Ctrl+Enter进行自动提交任务评论,找到如下完全客户端的解决方案,使用到jQuery库,原文:[URL=http://pangbu.com/jquery-ctrl-enter-submit-form/]http://pangbu.com/jquery-ctrl-enter-submit-form/[/URL],稍作修改代码如下:

<br/>$('body').keypress(function(event){<br/>  if(event.ctrlKey && (event.which == 13 || event.which == 10)) {<br/>    $('#btnSubmit').click();<br/>  }<br/>});<br/>



1、$(‘body’) 是表明焦点在哪里的时候Ctrl+Eenter才有用
2、keypress()是绑定按键按下事件
3、if(event.ctrlKey && (event.which == 13 || event.which == 10))这句很简单,就是检测你是不是同时按下了 Ctrl 和回车(event.which == 13大键盘区回车 、event.which == 10 小键盘区回车 )
4、$(‘#submit’).click();按下哪个按钮

补充阅读:[URL=http://api.jquery.com/event.which/]jQuery event.which[/URL]

Tags: jQuery

发布: cuiwenyuan 分类: Web技术 评论: 0 浏览: 144

好用的jQuery工作进度条

对于进度条,在HTML5下有个新标签就是用来呈现任务的进度,鉴于目前很多旧式浏览器还不完全支持HTML5,大家都喜欢用javascript和css实现进度条的功能。上周我在做OA里面的任务管理时,通过比较jQuery UI自带的[URL=http://jqueryui.com/progressbar]progress bar[/URL]还有jQuery easyui中的[URL=http://www.jeasyui.com/documentation/progressbar.php]progress bar[/URL],发现都不太符合我的需求,最后找到一个特别简单的实现,只需几行代码即可,读懂英文的看这里[URL=http://workshop.rs/2012/12/animated-progress-bar-in-4-lines-of-jquery/]ANIMATED PROGRESS BAR IN 4 LINES OF JQUERY[/URL],也可以看GitHub上的网址:[URL=https://github.com/kopipejst/progressbar]https://github.com/kopipejst/progressbar[/URL]

这里分享一下,我的样式表

<br/>#rateOfProgressBar {<br/>    width: 400px;<br/>    height: 22px;<br/>    border: 1px solid #ccc;<br/>    background-color: #f5f5f5;<br/>        }<br/><br/>        #rateOfProgressBar div {<br/>    height: 100%;<br/>    color: #fff;<br/>    text-align: right;<br/>    line-height: 22px; /* same as #progressBar height if we want text middle aligned */<br/>    width: 0;<br/>    background-color: #00cc33;/*#ff0000*/<br/>        }<br/>



C#页面调用的代码如下,我不喜欢把javascript的调用放在body中,于是放在jQuery的ready事件中,另外我这里的lblRateOfProgress在页面前端做一个display:none的隐藏。

<br/><script type="text/javascript"><br/>        $(document).ready(function () {<br/><br/>            progress($("#lblRateOfProgress").text()*100, $('#rateOfProgressBar'));<br/>        });<br/>function progress(percent, $element) {<br/><br/>    var progressBarWidth = percent * $element.width() / 100;<br/><br/>    $element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");<br/><br/>}<br/>    </script><br/>

你有一百万吨的信念

近期搞OA开发,没想到吧,的确是OA,曾经多年前在第二家公司(马可)搞过,后来就是工作流,然后就是BPM,没想到逃不过轮回,又回到原点。应该是当初没做好OA的缘故吧。不过,近期感觉挺有状态,也挺有进展,现在对OA的认识就是:这东西说起来简单,能设计的好,用得好,对公司有帮助的话,还是相当有挑战的。

More...

Tags:

发布: cuiwenyuan 分类: 五音五色 评论: 0 浏览: 88

终于跟吉日嘎拉见了一面

这几年,我经常跟做技术的几个好朋友提到一个人,那就是[URL=http://www.cnblogs.com/jirigala/]吉日嘎拉[/URL],一个在技术上我崇拜的人,一个在软件行业有建树的偶像。他能够坚持一件事情10多年,他的产品,他的人能够被众多同行所接受,并且他还在坚持。

想去杭州见见[URL=http://www.cnblogs.com/jirigala/]吉日嘎拉[/URL]是我的一个几年前的念头,每隔几个月都会冒出来,想跟他学习C#开发以及他的通用权限管理及快速开发平台,这几年来,相继也购买了学习版、个人开发版,但一直未能用起来,见面的事情也一直拖着,心想着何时才能专程去杭州呢?怎想到他今年居然来了上海工作(年薪不方便透漏,但绝对很高),更没想到公司的老板还是希望我们自己开发自己的内部办公平台,有了这个机缘,我打算说服老板让公司购买这套开发平台,在正式购买之前,我想先用起来这个系统(先用我的个人开发版进行开发),让老板看到一些应用,看到开发的效率和可见性的投资回报。看了几天的学习视频,实际操作了Winform的应用,收获很大,但还是遇到实际使用部署方面的疑问,想亲自请教他一下,本希望他能抽时间出来,我到他公司拜访的,没想到我一说明问题,他居然说月底亲自过来一趟。

今天中午,QQ上临时约了一下,几个小时后,在我公司见到了期待已久的吉日嘎拉,不过可惜的是晚上下了班,因为他是请了1小时假从青浦赶过来的,路途也堵。晚上我们就在我家门口的丰收日吃了顿便饭,席间了解到吉日的近况,饭后花了半个小时不到,打开我的笔记本,几分钟就把我遇到的调试问题搞定,同时回答了我近期的不少疑问。现在想想,这人和人的差别真大呀,他作为程序员曾经也是公司技术骨干,年薪近30万,自己也出来创业过,失败过,但一直坚持自己的这个理想和兴趣,持续的改进和完善这个权限管理系统及快速开发平台,能够被大型国企、银行金融企业、外资企业、中小型软件创业团队、个人程序员所接受,付费用户达到600多个,自己的产品能被他现在的一家全国前5的物流快递公司使用,并担负起2年内完成所有内部系统的重构、整合工作,这所有一切背后的坚持都值得我去学习和仰望。“近朱者赤”,希望以此为契机吧,能够专注在某一方面有所建树,能够在职业、事业发展方面越走越宽,越走越稳固。

另外,吉日送了一本他写的书《程序员,你伤不起》给我,还签了名,看来不仅是技术上需要向他学习,在处事上更需要向他学习。

Tags:

发布: cuiwenyuan 分类: 技术管理与生活 评论: 0 浏览: 309

1747公里

国庆节当天起了个大早,本想着4点半出发应该是空当,可还是堵了,中午12点还在通往江阴大桥的路上堵着,2个小时走了14公里。后来折道镇江,走扬州,但过了扬州一上京沪又堵上了。到达徐州的时候已经晚上11点多了,不知哪来的动力,还是上了省道,摸黑跑回家去了,到家门口凌晨2点零6分,家都没进,趟车座位上就睡着了。现在想想,还觉得心惊胆战,再来一次肯定就不去抢节假日头一天了,不会一口气开到家了。回来的时候,开车疲惫的状态体现出来了,中午12点到了南京之后,开一个小时就想要睡着,只能到休息站睡半小时,那个状态真是困,好歹到了4点多以后,终于有些精神了,开到家也晚上7点多了。



回家拍了很多照片,不过都是手机拍的,去苹果园摘了趟苹果,跑去钓了会鱼,老婆说带孝在身不便去亲戚家,基本上都是也没走啥亲戚,其它都是都在家里呆着,还有去自家园子里摘南瓜、棉花,总之,发现很享受。不过父母就比较辛苦,除了安排饭菜,杀鸡弄肉,刚忙完了玉米的收获,也顾不上种小麦了,光忙活我们回家的事情呢,回来的时候,车里塞得满满的:姑姑送来自家种的柿子、地瓜、大豆,哥哥家的石榴,自家的小麦面、南瓜、木瓜、冬瓜...

这次回去,再次激发起我回农村住几年的念头,或者说改变一下目前生活状态、方式的强烈念头。9月里,家里有2位亲人离开了我们,今天写这段文字的时候应该都满了七七49天,亲人们真的已经离我们远去了,愿他们安息,而我们活着的人,将会更加珍惜活着的每一天,让他们放心。


上图的这只大公鸡,每天凌晨以后就开始打鸣,我弟媳妇说吵得影响睡眠,只好委屈一下它,把他放在后面没人住的院子里。

More...

Tags:

发布: cuiwenyuan 分类: 技术管理与生活 评论: 2 浏览: 104