Вот как выглядит веб парта ознакомление.
До нажатия на кнопку:
И после нажатия:
Создаем собственно сам список, с элементами которого пользователи должны ознакомиться. Я назвал его TestReadList, добавляем дополнительное поле Assigned to тип поля Person or Group смысл этого поля станет ясен когда будем создавать веб парту для просмотра ознакомленных.
В Visual Studio создаем пустой проект SharePoint2010 SPConfirmReadProject.
Добавляем в проект Visual Web Part назовем её ConfirmWebPart, так же добавим к проекту ссылку на папку Images SharePoint’a (Правой кнопкой на проекте. Add->SharePoint “Images” Mapped Folder) после этого добавьте к папку Images\SPConfirmReadProject свой рисунок кнопки. Он будет использоваться в LinkButton.
Вот код ConfirmWebPart.ascx
<table> <tr> <td> <asp:LinkButton ID="bRead" runat="server" OnClick="bRead_Click"><img src="../_Layouts/Images/SPConfirmReadProject/accept.png" style="border:0px;"/>Прочитал</asp:LinkButton> </td> </tr> <tr> <td> <asp:Label ID="lStatus" runat="server" Text=""></asp:Label> </td> </tr> </table>
Тут собственно создаём LinkButton и Label.
Переходим к коду ConfirmWebPart.asxc.cs:
protected void Page_Load(object sender, EventArgs e) { bool isReal = false; //Проверяем сеществует ли список для записи данных о прочтении. foreach (SPList list in SPContext.Current.Web.Lists) { if (list.Title == "ReadList_" + SPContext.Current.ListId) { isReal = true; } } SPList listConfirmReadUser; //Если сеществует то обращаемся к нему if (isReal) listConfirmReadUser = SPContext.Current.Web.Lists["ReadList_"+SPContext.Current.ListId]; //Если нет то создаем его else { SPContext.Current.Web.Lists.Add("ReadList_" + SPContext.Current.ListId, "", SPListTemplateType.GenericList); listConfirmReadUser = SPContext.Current.Site.RootWeb.Lists["ReadList_" + SPContext.Current.ListId]; listConfirmReadUser.Fields.Add("User", SPFieldType.User, true); listConfirmReadUser.Fields.Add("Date", SPFieldType.DateTime, true); listConfirmReadUser.Fields.AddLookup("ListItem", SPContext.Current.ListId, true); listConfirmReadUser.Update(); } //И собственно ищем текущего пользователя и текущий элемент списка SPListItemCollection listItems = listConfirmReadUser.Items; foreach (SPListItem item in listItems) { string user = item["User"].ToString().Split('#')[1]; string listItem = item["ListItem"].ToString().Split('#')[0]; if ((listItem.Remove(listItem.Length-1) == SPContext.Current.ItemId.ToString()) && (user.ToString() == SPContext.Current.Web.CurrentUser.Name.ToString())) { //если находим то прячем кнопку остовляем только текст с временем ознакомления. bRead.Visible = false; lStatus.Text = "Вы ознакомлены с документом " + item["Date"].ToString(); } } } //А вот так записываем данные пользователя при нажатии на кнопку protected void ConfirmUser() { var listConfirmReadUser = SPContext.Current.Site.RootWeb.Lists["ReadList_" + SPContext.Current.ListId]; SPListItemCollection listItems = listConfirmReadUser.Items; SPListItem item = listItems.Add(); item["Date"] = DateTime.Now; item["ListItem"] = SPContext.Current.ItemId; item["User"] = SPContext.Current.Web.CurrentUser; item["Title"] = "Ознакомлен: " + SPContext.Current.Web.CurrentUser.ToString() + " - " + DateTime.Now; item.Update(); bRead.Visible = false; lStatus.Text = "Вы ознакомлены с документом " + item["Date"].ToString(); } protected void bRead_Click(object sender, EventArgs e) { ConfirmUser(); }
Всё теперь можно деплоить. Веб парта размещается на форме просмотра элемента.
Для этого на вкладке ленты List выберите Form Web Parts -> Default Display Form как показано на рисунке.
В окне формы нажмите Add a Web Part. В Categories выберем Custom, а в Web Parts нашу веб парту у меня она называется SPConfirmReadProject — ReadUsersWebPart. Жмём кнопку Add и Stop Editing.
Вот собственно и все по веб парте ознакомление.
Теперь напишем веб парту просмотра кто ознакомился, а кто нет.
Веб парта состоит из 2 LinkButton, Label и GridView.
Вот как это выглядит при нажатии на кнопку «С документом ознакомлены».
Тут все просто мы тупо лезем в список ознакомленных и вытаскиваем их. А интересное происходит если мы нажмем на кнопку «Не ознакомлены».
Для этого используется поле «Assigned to» в котором перечислены люди и\или группы которым назначено читать элемент. Для решения этой задачи мы берем список людей из поля «Assigned to» и сопоставляем его с людьми из списка прочитавших. Приступим.
Добавим VisualWebPart в проект. Назовем её ReadUsersWebPart.
Добавим в ReadUsersWebPart.ascx
<table> <tr> <td> <asp:LinkButton ID="lbRead" runat="server" OnClick="lbRead_Click" BorderWidth="0"><img src="../_Layouts/Images/SPConfirmReadProject/thumb_up.png" style="border:0px;" />С документом ознакомлены</asp:LinkButton> </td> <td> <p> </p> </td> <td> <asp:LinkButton ID="lbUnRead" runat="server" OnClick="lbUnRead_Click" BorderWidth="0"><img src="../_Layouts/Images/SPConfirmReadProject/thumb_down.png" style="border:0px;" />Не ознакомлены</asp:LinkButton> </td> </tr> </table> <p></p> <asp:Label ID="Label1" runat="server"></asp:Label> <asp:GridView ID="gridView" runat="server" AllowPaging="True" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" CellPadding="4" EnableModelValidation="True" ForeColor="Black" GridLines="Horizontal" PageSize="20"> <FooterStyle BackColor="#CCCC99" ForeColor="Black" /> <HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" /> <SelectedRowStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" /> </asp:GridView>
А в ReadUsersWebPart.ascx.cs запишем следующее:
private SPGroup SearchGroup(string group) { SPGroup groupObject = null; foreach (SPGroup singleGroup in SPContext.Current.Web.Groups) { if (group == singleGroup.Name) { groupObject = singleGroup; } } return groupObject; } //Формируем таблицу читавших protected void ReadUsers() { var table = new DataTable("ReadList"); var colFIO = new DataColumn(); colFIO.DataType = System.Type.GetType("System.String"); colFIO.ColumnName = "Сотрудник"; table.Columns.Add(colFIO); var colDate = new DataColumn(); colDate.DataType = System.Type.GetType("System.DateTime"); colDate.ColumnName = "Прочитал"; table.Columns.Add(colDate); string idItem = SPContext.Current.ItemId.ToString(); string idUser = SPContext.Current.Web.CurrentUser.ID.ToString().Split('#')[0].ToString().Replace(";",""); var listConfirmReadUser = SPContext.Current.Web.Lists["ReadList_" + SPContext.Current.ListId]; var query = new SPQuery(); string calmQuery = "<Where><And><Eq><FieldRef Name='ListItem' LookupId='true'/><Value Type='Lookup'>" + idItem + "</Value></Eq><Eq><FieldRef Name='User' LookupId='true'/><Value Type='User'>" + idUser + "</Value></Eq></And></Where>"; query.Query = calmQuery; SPListItemCollection listItems = listConfirmReadUser.GetItems(query); if (listItems.Count > 0) foreach (SPListItem item in listItems) { DataRow row; row = table.NewRow(); row["Сотрудник"] = item["User"].ToString().Split('#')[1]; row["Прочитал"] = item["Date"]; table.Rows.Add(row); } Label1.Text = ""; gridView.DataSource = table; gridView.DataBind(); if (table.Rows.Count < 1) { Label1.Text = "Никто не читал документ."; } } //Формируем таблицу не читавших protected void UnReadUsers() { string idItem = SPContext.Current.ItemId.ToString(); string idUser = SPContext.Current.Web.CurrentUser.ID.ToString().Split('#')[0].ToString().Replace(";", ""); string currentValue = string.Empty; string FieldName = string.Empty; try { currentValue = SPContext.Current.Item["Кому назначено"].ToString(); FieldName = "Кому назначено"; } catch { currentValue = SPContext.Current.Item["Assigned to"].ToString(); FieldName = "Assigned to"; } List<SPUser> listAllUser = new List<SPUser>(); SPFieldUser UsersColumn = (SPFieldUser)SPContext.Current.Fields.GetField(FieldName); SPFieldUserValueCollection Users = (SPFieldUserValueCollection)UsersColumn.GetFieldValue(SPContext.Current.Item[FieldName].ToString()); foreach (SPFieldUserValue user in Users) { SPGroup group = SearchGroup(user.LookupValue); if (group != null) { SPUserCollection groupUsers = group.Users; foreach (SPUser groupUser in groupUsers) { if (groupUser != null) listAllUser.Add(groupUser); } } else { if (user.User != null) listAllUser.Add(user.User); } } var query = new SPQuery(); string calmQuery = "<Where><And><Eq><FieldRef Name='ListItem' LookupId='true'/><Value Type='Lookup'>" + idItem + "</Value></Eq><Eq><FieldRef Name='User' LookupId='true'/><Value Type='User'>" + idUser + "</Value></Eq></And></Where>"; query.Query = calmQuery; SPList list = SPContext.Current.Web.Lists["ReadList_" + SPContext.Current.ListId]; SPListItemCollection listReadUsers = list.GetItems(query); if (listReadUsers.Count > 0) { List<SPUser> listReadUser = new List<SPUser>(); foreach (SPListItem item in listReadUsers) { SPFieldUser UserReadColumn = (SPFieldUser)item.Fields.GetField("User"); SPFieldUserValue ur = (SPFieldUserValue)UserReadColumn.GetFieldValue(item["User"].ToString()); listReadUser.Add(ur.User); } if (listReadUser.Count() > 0) foreach (SPUser rUser in listReadUser) { if (rUser != null) listAllUser.RemoveAll(u => u.ID == rUser.ID); } } List<SPUser> usd = new List<SPUser>(); foreach (SPUser spUser in listAllUser) { List<SPUser> listUsr = (from u in listAllUser where (u.ID == spUser.ID) select u).ToList(); if (listUsr.Count() > 1) { usd.Add(listUsr[0]); } } foreach (SPUser spUser in usd) { listAllUser.Remove(spUser); } var table = new DataTable("UnReadList"); var colFIO = new DataColumn(); colFIO.DataType = System.Type.GetType("System.String"); colFIO.ColumnName = "Сотрудник"; table.Columns.Add(colFIO); foreach (SPUser spUser in listAllUser) { DataRow row; row = table.NewRow(); row["Сотрудник"] = spUser.Name; table.Rows.Add(row); } Label1.Text = ""; gridView.DataSource = table; gridView.DataBind(); if (listAllUser.Count() < 1) { Label1.Text = "Документ прочтен всеми сотрудниками."; } } protected void lbRead_Click(object sender, EventArgs e) { ReadUsers(); } protected void lbUnRead_Click(object sender, EventArgs e) { UnReadUsers(); }
Далее можно сделать рассылку пользователям которые прописаны в поле Assigned to с помощью Workflow в Visual Studio или SharePoint Designer.
Надеюсь статья окажется Вам полезной. В скором времени напишу как можно напечатать эти списки, а за одно и как написать Workflow рассылки под эту задачу в VS.
ссылка на оригинал статьи http://habrahabr.ru/post/192506/
Добавить комментарий