migrate to new git

This commit is contained in:
2025-08-29 01:27:25 +08:00
parent 946eb9961e
commit af2c152ef6
8623 changed files with 1000453 additions and 1 deletions
+285
View File
@@ -0,0 +1,285 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="attendances.aspx.cs" Inherits="admin_hr_attendances" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<script>
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: {},
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '人員',
text_prop: 'u_name',
value_prop: 'num',
keys: [
{ id: 'm_number', title: '編號', value: '' },
{ id: 'u_name', title: '姓名', value: '' },
{ id: 'sex', title: '性別', value: '' },
],
api_url: HTTP_HOST + 'api/member/GetList',
columns: [
{ id: 'm_number', title: '編號'},
{ id: 'u_name', title: '姓名'},
{ id: 'sex', title: '性別'},
],
selected: {},
select(t) {
console.log("select search1", t);
}
},
},
show: false,
current: {},
list: [],
count: 0,
page:1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText:'',
},
},
snackbar: {
show: false,
text: "",
}
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
//console.log("mounted");
},
watch: {
options: {
handler() {
//console.log("watch1", this.search_dialog, this.search_dialog.page);
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
//this.search_get()//清除完自動會重抓, 故取消
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
//const { page, itemsPerPage } = this.options
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
this.search_dialog.page = this.options.page??1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show=true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(row);
}
this.search_dialog.show = false;
console.log(row, row["u_name"], row["f_number"], curr.id, target);
},
},
computed: {
},
})
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
</div>
<div class="">
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
</div>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<div class="card shadow-sm my-3">
<div class="card-header">
考勤管理
</div>
<asp:Panel ID="cardBodyPanel" runat="server" CssClass="card-body">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row g-1 gx-lg-2">
<label class="col-sm-2 col-form-label">人員 *</label>
<div class="col-sm-10 col-lg-4">
<%-- <asp:DropDownList ID="mem_num" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>--%>
<div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
id="mem_num_txt" runat="server" placeholder="人員" value="" >
<asp:HiddenField ID="mem_num" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="mem_num_txt"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">出勤型態 *</label>
<div class="col-sm-10 col-lg-4">
<asp:DropDownList ID="check_type" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" ControlToValidate="check_type"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">日期 * </label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="check_date" runat="server" CssClass="form-control" TextMode="Date"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="check_date"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">時間 *</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="check_time" runat="server" CssClass="form-control" TextMode="Time"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="check_time"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">請假時數 </label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="hour" MaxLength="5" runat="server" CssClass="form-control" placeholder="請輸入請假時數"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="hour" Display="Dynamic" SetFocusOnError="true"
ErrorMessage="只能輸入數字" ValidationGroup="Required" ID="RegularExpressionValidator3"
runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
</div>
<label class="col-sm-2 col-form-label">IP </label>
<div class="col-sm-10 col-lg-4">
<asp:Literal ID="ip" runat="server"></asp:Literal>
</div>
</div>
<hr />
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
</asp:Panel>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title"></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+187
View File
@@ -0,0 +1,187 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Globalization;
public partial class admin_hr_attendances : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
InitEnumsOptions<Model.member.attendances.type>(check_type); //出勤型態
if (isStrNull(Request["num"]))
{
}
else
{
int _num = Val(Request["num"]);
var qry = _db.member_check.AsEnumerable();
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
try //TODO: 迴圈裡的try catch可能導致效能問題
{
foreach (Control obj in cardBodyPanel.Controls)
{
if (obj is TextBox)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var textBox = (TextBox)obj;
if (textBox.TextMode == TextBoxMode.Date)
{
textBox.Text = Convert.ToDateTime(ObjValue).ToString("yyyy-MM-dd");
}
else
{
textBox.Text = ObjValue.ToString();
}
}
}
else if (obj is DropDownList && ((DropDownList)obj).SelectedIndex == 0)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var dropDown = (DropDownList)obj;
dropDown.SelectedValue = ObjValue.ToString();
}
}
}
}
catch (Exception ex)
{
}
if (prod.mem_num.HasValue)
{
mem_num_txt.Value = prod.member.u_name.ToString();
mem_num.Value = prod.mem_num.ToString();
}
ip.Text = prod.login_ip;
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
}
else
{
Response.Redirect("index2.aspx");
}
}
}
}
protected void goback_Click(object sender, EventArgs e)
{
Response.Redirect("index2.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
L_msg.Text = "";
Model.member_check member_check = new Model.member_check();
member_check.login_ip = Request.UserHostAddress;
member_check.login_type = (int)Model.member.attendances.login.Enter;
member_check.mem_num = Val(mem_num.Value);
member_check.check_type = Val(check_type.SelectedValue);
if (!isStrNull(check_date.Text) && isDate(check_date.Text))
member_check.check_date = ValDate(check_date.Text);
if (!isStrNull(check_time.Text))
member_check.check_time = TimeSpan.Parse(check_time.Text);
if (!isStrNull(hour.Text))
member_check.hour = Val(hour.Text);
member_check.demo = demo.Text;
try
{
_db.member_check.Add(member_check);
_db.SaveChanges();
Response.Redirect("index2.aspx");
}
catch (Exception ex)
{
//L_msg.Text = ex.Message;
L_msg.Type = alert_type.danger;
L_msg.Text = "操作失敗";
}
}
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
Model.member_check member_check = _db.member_check.Where(q => q.num == _num).FirstOrDefault();
if (member_check != null)
{
member_check.login_type = (int)Model.member.attendances.login.Enter;
member_check.mem_num = Val(mem_num.Value);
member_check.check_type = Val(check_type.SelectedValue);
if (!isStrNull(check_date.Text) && isDate(check_date.Text))
member_check.check_date = ValDate(check_date.Text);
if (!isStrNull(check_time.Text))
member_check.check_time = TimeSpan.Parse(check_time.Text);
if (!isStrNull(hour.Text))
member_check.hour = Val(hour.Text);
member_check.demo = demo.Text;
}
try
{
_db.SaveChanges();
Response.Redirect("index2.aspx?page=" + Convert.ToString(Request["page"]));
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
}
}
#endregion
}
Binary file not shown.
+65
View File
@@ -0,0 +1,65 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="import.aspx.cs" Inherits="admin_hr_import" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<div class="card shadow-sm my-3">
<div class="card-header">
人員匯入
</div>
<asp:Panel ID="cardBodyPanel" runat="server" CssClass="card-body">
<div class="row g-1 gx-lg-2 label-sm-right">
<label class="col-sm-3 col-form-label">步驟 1</label>
<div class="col-sm-9 pt-1">
請先下載 EXCEL 表格,
<asp:LinkButton ID="databaseExport" runat="server" CssClass="btn btn-default" CausesValidation="false" OnClick="databaseExport_Click"><i class="mdi mdi-content-save"></i> 點擊此處下載</asp:LinkButton>。
</div>
<label class="col-sm-3 col-form-label">步驟 2</label>
<div class="col-sm-9 pt-2">
選擇已編輯好的 EXCEL 表格
<div>
<asp:FileUpload ID="FileUpload1" runat="server" />
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" ControlToValidate="FileUpload1" runat="server" ValidationGroup="Required"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-3 col-form-label">步驟 3</label>
<div class="col-sm-9 pt-1">
匯入資料
<asp:LinkButton ID="submitButton" runat="server" Text="匯入資料" CssClass="btn btn-outline-success" ValidationGroup="Required" OnClick="submitButton_Click"></asp:LinkButton>
</div>
<label class="col-sm-3 col-form-label">注意事項</label>
<div class="col-sm-9 pt-2">
如有大量資料,建議分批匯入,以免造成執行時間過久而導致網頁逾時。<br />
Excel匯入只做新增,不提供刪除或修改欄位的功能。<br />
不做「信眾編號」「人員編號」「系統帳號」重複的檢查,使用者轉檔時需自行過濾。<br />
「組別」「職稱」請輸入流水號,流水號碼可查看頁籤。<br />
匯入資料範例參考 <a href="example.xlsx" class="btn btn-outline-primary">觀看範例</a>
</div>
<label class="col-sm-3 col-form-label"></label>
<div class="col-sm-9 pt-2">
<asp:Label ID="msg" runat="server" ForeColor="Red"></asp:Label>
</div>
</div>
</asp:Panel>
</div>
</div>
</asp:Content>
+348
View File
@@ -0,0 +1,348 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
using System.Drawing;
using System.Web.UI.WebControls;
using System.Web;
using OfficeOpenXml;
using OfficeOpenXml.Style;
public partial class admin_hr_import : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
#region excel
protected void databaseExport_Click(object sender, EventArgs e)
{
excelEPPlus();
}
protected void excelEPPlus() //下載空excel
{
var memoryStream = new MemoryStream();
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var wb = doc.AddWorkbookPart();
wb.Workbook = new Workbook();
var sheets = wb.Workbook.AppendChild(new Sheets());
//建立第一個頁籤
var ws = wb.AddNewPart<WorksheetPart>();
ws.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws),
SheetId = 1,
Name = "人員資料"
});
//設定欄寬
var cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 3, Width = 15, CustomWidth = true },
new Column { Min =4 , Max = 4, Width = 10, CustomWidth = true },
new Column { Min = 5, Max = 6, Width = 15, CustomWidth = true },
new Column { Min = 7, Max = 7, Width = 10, CustomWidth = true },
new Column { Min = 8, Max = 15, Width = 20, CustomWidth = true },
new Column { Min = 16, Max = 17, Width = 10, CustomWidth = true },
new Column { Min = 18, Max = 23, Width = 20, CustomWidth = true }
);
ws.Worksheet.Append(cu);
//建立資料頁
var sd = new SheetData();
ws.Worksheet.AppendChild(sd);
//第一列資料
var tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("信眾編號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員編號 *"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員姓名 *"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("性別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("身分證字號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("生日"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("血型"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("最高學歷"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("皈依日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("皈依法名"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("備註"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("系統帳號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("到職日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("離職日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("薪資"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("組別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("職稱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("公司電子信箱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("個人電子信箱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("其他聯絡方式"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("戶籍地址"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("居住地址"), DataType = CellValues.String }
);
sd.AppendChild(tr);
//================組別
//建立第二個頁籤
var ws2 = wb.AddNewPart<WorksheetPart>();
ws2.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws2),
SheetId = 2,
Name = "組別"
});
//設定欄寬
cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 1, Width = 7, CustomWidth = true },
new Column { Min = 2, Max = 2, Width = 15, CustomWidth = true }
);
ws2.Worksheet.Append(cu);
//建立資料頁
var sd2 = new SheetData();
ws2.Worksheet.AppendChild(sd2);
//第一列資料
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("流水號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("組別名稱"), DataType = CellValues.String }
);
sd2.AppendChild(tr);
//查詢要匯出的資料
var list = _db.member_group.AsEnumerable().ToList();
if (list.Count > 0)
{
foreach (var item in list)
{
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.num.ToString()), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.kind.ToString()), DataType = CellValues.String }
);
sd2.AppendChild(tr);
}
}
//================職稱
//建立第3個頁籤
var ws3 = wb.AddNewPart<WorksheetPart>();
ws3.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws3),
SheetId = 3,
Name = "職稱"
});
//設定欄寬
cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 1, Width = 7, CustomWidth = true },
new Column { Min = 2, Max = 2, Width = 15, CustomWidth = true }
);
ws3.Worksheet.Append(cu);
//建立資料頁
var sd3 = new SheetData();
ws3.Worksheet.AppendChild(sd3);
//第一列資料
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("流水號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("職稱"), DataType = CellValues.String }
);
sd3.AppendChild(tr);
//查詢要匯出的資料
var list2 = _db.member_title.AsEnumerable().ToList();
if (list2.Count > 0)
{
foreach (var item in list2)
{
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.num.ToString()), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.kind.ToString()), DataType = CellValues.String }
);
sd3.AppendChild(tr);
}
}
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=hr_import.xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
HttpContext.Current.Response.End();
}
#endregion
#region
protected void submitButton_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string errorLog = "";
string jumpLog = "";
msg.Text = "";
//開檔
//載入Excel檔案
using (ExcelPackage ep = new ExcelPackage(FileUpload1.PostedFile.InputStream))
{
ExcelWorksheet sheet = ep.Workbook.Worksheets[1];//取得Sheet1
int startRowNumber = sheet.Dimension.Start.Row;//起始列編號,從1算起
int endRowNumber = sheet.Dimension.End.Row;//結束列編號,從1算起
int startColumn = sheet.Dimension.Start.Column;//開始欄編號,從1算起
int endColumn = sheet.Dimension.End.Column;//結束欄編號,從1算起
bool isHeader = true;
if (isHeader)//有包含標題
{
startRowNumber += 1;
}
var fDt = _db.followers.AsEnumerable().ToList(); //信眾
var aDt = _db.admins.AsEnumerable().ToList(); //後台系統
var gDt = _db.member_group.AsEnumerable().Select(x => x.num).ToList(); //組別
var tDt = _db.member_title.AsEnumerable().Select(x => x.num).ToList(); //職稱
MyWeb.encrypt encrypt = new MyWeb.encrypt();
for (int currentRow = startRowNumber; currentRow <= endRowNumber; currentRow++)
{
ExcelRange range = sheet.Cells[currentRow, startColumn, currentRow, endColumn];//抓出目前的Excel列
if (range.Any(c => !string.IsNullOrEmpty(c.Text)) == false)//這是一個完全空白列(使用者用Delete鍵刪除動作)
{
continue;//略過此列
}
//--------- pro_num 判斷新增修改-----
if (!isStrNull(sheet.Cells[currentRow, 2].Text) && !isStrNull(sheet.Cells[currentRow, 3].Text))
{
int f_num = fDt.Where(x => x.f_number == ValString(sheet.Cells[currentRow, 1].Text.Trim())).Select(x => x.num).FirstOrDefault(); //信眾編號id
int a_num = aDt.Where(x => x.u_id == ValString(sheet.Cells[currentRow, 12].Text.Trim())).Select(x => x.num).FirstOrDefault(); //系統帳號id
int g_sum = gDt.Where(x => x.ToString() == ValString(sheet.Cells[currentRow, 16].Text.Trim())).FirstOrDefault(); //組別
int t_sum = tDt.Where(x => x.ToString() == ValString(sheet.Cells[currentRow, 17].Text.Trim())).FirstOrDefault(); //職稱
//定義日期欄位格式
sheet.Cells[currentRow, 6].Style.Numberformat.Format = "yyyy-MM-dd";
sheet.Cells[currentRow, 9].Style.Numberformat.Format = "yyyy-MM-dd";
sheet.Cells[currentRow, 12].Style.Numberformat.Format = "yyyy-MM-dd";
sheet.Cells[currentRow, 14].Style.Numberformat.Format = "yyyy-MM-dd";
//寫值---
//新增
Model.member member = new Model.member();//新增
if (f_num > 0) { member.f_num = f_num; }
member.m_number = ValString(sheet.Cells[currentRow, 2].Text.Trim());
member.u_name = ValString(sheet.Cells[currentRow, 3].Text.Trim());
member.sex = ValString(sheet.Cells[currentRow, 4].Text.Trim());
member.id_code = encrypt.EncryptAutoKey(ValString(sheet.Cells[currentRow, 5].Text.Trim()));
if (isDate(sheet.Cells[currentRow, 6].Text.Trim())) { member.birthday = ValDate(sheet.Cells[currentRow, 6].Text.Trim()); }
member.blood = ValString(sheet.Cells[currentRow, 7].Text.Trim()).Replace("型", "").ToUpper();
member.educational = ValString(sheet.Cells[currentRow, 8].Text.Trim());
if (isDate(sheet.Cells[currentRow, 9].Text.Trim())) { member.refugedate = ValDate(sheet.Cells[currentRow, 9].Text.Trim()); }
member.refuge_name = ValString(sheet.Cells[currentRow, 10].Text.Trim());
member.demo = ValString(sheet.Cells[currentRow, 11].Text.Trim());
if (a_num > 0) { member.admin_num = a_num; }
if (isDate(sheet.Cells[currentRow, 13].Text.Trim())) { member.takedate = ValDate(sheet.Cells[currentRow, 13].Text.Trim()); }
if (isDate(sheet.Cells[currentRow, 14].Text.Trim())) { member.leavedate = ValDate(sheet.Cells[currentRow, 14].Text.Trim()); }
if (isDate(sheet.Cells[currentRow, 15].Text.Trim())) { member.salary = ValFloat(ValString(sheet.Cells[currentRow, 15].Text.Trim()).Replace("元", "").Replace("$", "").Trim()); }
if (g_sum > 0) { member.group_kind = g_sum; }
if (t_sum > 0) { member.title_kind = t_sum; }
member.phone = encrypt.EncryptAutoKey(ValString(sheet.Cells[currentRow, 18].Text.Trim()));
member.com_email = ValString(sheet.Cells[currentRow, 19].Text.Trim());
member.email = ValString(sheet.Cells[currentRow, 20].Text.Trim());
member.contact = ValString(sheet.Cells[currentRow, 21].Text.Trim());
member.address1 = ValString(sheet.Cells[currentRow, 22].Text.Trim());
member.address2 = ValString(sheet.Cells[currentRow, 23].Text.Trim());
_db.members.Add(member);
}
else
{
jumpLog += "第" + currentRow + "行,欄位輸入不完整";
}
}
try
{
_db.SaveChanges();
}
catch (Exception ex)
{
errorLog = ex.InnerException.Message;
}
if (!isStrNull(errorLog))
{
L_msg.Type = alert_type.danger;
L_msg.Text = "匯入失敗";
msg.Text = errorLog;
if (!isStrNull(jumpLog))
{
msg.Text += "<br>資料匯入不齊全:<br>" + jumpLog;
}
}
else if (!isStrNull(jumpLog))
{
L_msg.Type = alert_type.warning;
L_msg.Text = "資料匯入不齊全";
msg.Text = "未匯入:<br>" + jumpLog;
}
else
{
L_msg.Type = alert_type.success;
L_msg.Text = "匯入成功";
}
}//end using
}
else
{
ScriptMsg("請上傳excel檔", "", msgIcon.error);
}
}
#endregion
}
+247
View File
@@ -0,0 +1,247 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index.aspx.cs" Inherits="admin_hr_index" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<a href="reg.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
</div>
<div class="">
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success"
OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
{ text: '人員編號', value: 'm_number' },
{ text: '人員姓名', value: 'u_name'},
{ text: '性別', value: 'sex' },
{ text: '組別', value: 'group_kindTxt2' },
{ text: '職稱', value: 'title_kindTxt' },
{ text: '上班時間', value: 'starttime' },
{ text: '備註', value: 'demo', sortable: false },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
],
footer:{
showFirstLastPage: true,
itemsPerPageOptions:[5,10,20,30],
},
},
search: {
group_kind: 0,
title_kind: 0,
u_name: '',
starttime:'',
offtime: ''
}
}
},
watch: {
options: {
handler() {
this.getDefault()
},
deep: true,
},
},
methods: {
getDefault(clearpage=false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage? '1': page, pageSize: itemsPerPage
};
this.data_table.loading = true
axios
.post(HTTP_HOST + 'api/member/GetList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
})
.catch(error => console.log(error))
},
editItem(item) {
console.log("edit", item);
},
deleteItem(item) {
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/member/' + item.num)
.then(response => {
console.log("del", item);
this.data_table.list.splice(index, 1);
this.data_table.count = this.data_table.list.length
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/member/Delete/' + this.data_table.selected.map(x => x.num))
.then(response => {
//console.log("delAll");
//for (var i = 0; i < this.data_table.selected.length; i++) {
// const index = this.data_table.list.indexOf(this.data_table.selected[i]);
// this.data_table.list.splice(index, 1);
//}
//this.data_table.selected = [];
//this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
//this.options.page = 1;
this.getDefault(true)
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
demoOpen(item) {
if (item.demo != null && item.demo != '')
msgbox($('#dd_' + item.num).html());
}
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
},
})
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.demo="{ item }" >
<div v-if="item.demo !=null && item.demo !=''" class="d-none" :id="'dd_'+item.num">{{ item.demo}} </div>
<a v-if="item.demo !=null && item.demo !=''" class="btn btn-outline-secondary btn-sm" @click="demoOpen(item)" >
<i class='mdi mdi-magnify'></i></a>
</template>
<template #item.slot_btn="{ item }">
<a :href="'reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<label class="form-label">組別</label>
<asp:DropDownList ID="s_kind" runat="server" CssClass="form-select" v-model="search.group_kind">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">職稱</label>
<asp:DropDownList ID="s_kind2" runat="server" CssClass="form-select" v-model="search.title_kind">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">人員姓名 </label>
<asp:TextBox ID="s_u_name" runat="server" CssClass="form-control" v-model="search.u_name" placeholder="可輸入關鍵字查詢"></asp:TextBox>
</div>
<div class="mb-3">
<label class="form-label">上班時間</label>
<div class="input-group">
<input type="time" v-model="search.starttime" class="form-control" id="s_starttime" runat="server">
<span class="input-group-text">~</span>
<input type="time" v-model="search.offtime" class="form-control" id="s_offtime" runat="server">
</div>
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
</asp:Content>
+238
View File
@@ -0,0 +1,238 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
using static TreeView;
public partial class admin_hr_index : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BuildKind();
}
}
#region
public void BuildKind()
{
s_kind.Items.Clear();
s_kind.Items.Add(new ListItem("", ""));
s_kind2.Items.Clear();
s_kind2.Items.Add(new ListItem("", ""));
//buildMultiKind(s_kind, "member_group", 0, "", 1, Model.member.KindLevelMax);
var qry1 = new TreeView().get_data2(_db.member_group.Select(o => new TreeItem()
{
kind = o.kind,
num = o.num,
root = o.root,
range = o.range,
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
if (qry1.Count() > 0)
foreach (var qq in qry1)
s_kind.Items.Add(new ListItem(new TreeView().RptDash(qq.Level) + qq.kind, qq.num.ToString()));
//buildMultiKind(s_kind2, "member_title", 0, "", 1, Model.member.TitleLevelMax);
var qry2 = new TreeView().get_data2(_db.member_title.Select(o => new TreeItem()
{
kind = o.kind,
num = o.num,
root = o.root,
range = o.range,
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
if (qry1.Count() > 0)
foreach (var qq in qry2)
s_kind2.Items.Add(new ListItem(new TreeView().RptDash(qq.Level) + qq.kind, qq.num.ToString()));
}
#endregion
#region GridView相關
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string _demoTxt = (DataBinder.Eval(e.Row.DataItem, "demo") ?? "").ToString();
if (!isStrNull(_demoTxt))
{
Literal demo = (Literal)e.Row.FindControl("demo");
demo.Text = _demoTxt;
string tbID = "dd" + e.Row.RowIndex.ToString();
demo.Text = "<div class=\"d-none\" id=\"" + tbID + "\">" + demo.Text + "</div>";
HyperLink demoPanel = (HyperLink)e.Row.FindControl("demoPanel");
demoPanel.Attributes.Add("onclick", "msgbox($('#" + tbID + "').html())");
demoPanel.Visible = true;
}
}
}
#endregion
#region Excel
protected void excel_Click(object sender, EventArgs e)
{
var memoryStream = new MemoryStream();
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var wb = doc.AddWorkbookPart();
wb.Workbook = new Workbook();
var sheets = wb.Workbook.AppendChild(new Sheets());
//建立第一個頁籤
var ws = wb.AddNewPart<WorksheetPart>();
ws.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws),
SheetId = 1,
Name = "人員資料"
});
//設定欄寬
var cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 3, Width = 15, CustomWidth = true },
new Column { Min = 4, Max = 4, Width = 10, CustomWidth = true },
new Column { Min = 5, Max = 6, Width = 15, CustomWidth = true },
new Column { Min = 7, Max = 7, Width = 10, CustomWidth = true },
new Column { Min = 8, Max = 15, Width = 20, CustomWidth = true },
new Column { Min = 16, Max = 17, Width = 10, CustomWidth = true },
new Column { Min = 18, Max = 23, Width = 20, CustomWidth = true }
);
ws.Worksheet.Append(cu);
//建立資料頁
var sd = new SheetData();
ws.Worksheet.AppendChild(sd);
//第一列資料
var tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("信眾編號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員編號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員姓名"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("性別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("身分證字號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("生日"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("血型"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("最高學歷"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("皈依日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("皈依法名"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("備註"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("系統帳號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("到職日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("離職日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("薪資"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("組別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("職稱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("公司電子信箱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("個人電子信箱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("其他聯絡方式"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("戶籍地址"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("居住地址"), DataType = CellValues.String }
);
sd.AppendChild(tr);
//查詢要匯出的資料
var qry = _db.members.AsEnumerable();
if (!isStrNull(s_kind.SelectedValue))
qry = qry.Where(o => o.group_kind == Convert.ToInt32(s_kind.SelectedValue));
if (!isStrNull(s_kind2.SelectedValue))
qry = qry.Where(o => o.title_kind == Convert.ToInt32(s_kind2.SelectedValue));
if (!isStrNull(s_u_name.Text))
qry = qry.Where(o => o.u_name.Contains(s_u_name.Text.Trim()));
if (!isStrNull(s_starttime.Value) )
qry = qry.Where(o => o.group_kind.HasValue && o.member_group.starttime >= TimeSpan.Parse(s_starttime.Value));
if (!isStrNull(s_offtime.Value))
qry = qry.Where(o => o.group_kind.HasValue && o.member_group.starttime <= TimeSpan.Parse(s_offtime.Value));
qry = qry.OrderByDescending(o => o.reg_time);
var list = qry.ToList();
if (list.Count > 0)
{
MyWeb.encrypt encrypt = new MyWeb.encrypt();
foreach (var item in list)
{
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.f_num.HasValue ? item.follower.f_number : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.m_number), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.u_name), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.sex), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey( item.id_code)), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.birthday.HasValue ? ValDate(item.birthday.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.blood), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.educational), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.refugedate.HasValue ? ValDate(item.refugedate.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.refuge_name), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.demo), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.admin_num.HasValue ? item.admin.uid : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.takedate.HasValue ? ValDate(item.takedate.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.leavedate.HasValue ? ValDate(item.leavedate.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.salary.HasValue ? ValMoney(item.salary.Value) : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.group_kind.HasValue ? item.member_group.kind : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.title_kind.HasValue ? item.member_title.kind : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.com_email), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.email), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.contact), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.address1), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.address2), DataType = CellValues.String }
);
sd.AppendChild(tr);
}
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Excel, admin_log.LogViewBtn(list.Select(x => x.m_number + x.u_name).ToList()));
}
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=hr_data.xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
HttpContext.Current.Response.End();
}
#endregion
}
+261
View File
@@ -0,0 +1,261 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index2.aspx.cs" Inherits="admin_hr_index2" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<a href="attendances.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
</div>
<div class="">
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<%--<link href="<%=ResolveUrl("~/js/vuetify_ez.css")%>" rel="stylesheet" />--%>
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
{ text: '人員編號', value: 'm_number' },
{ text: '人員姓名', value: 'u_name'},
{ text: '日期', value: 'check_date' },
{ text: '時間', value: 'check_time' },
{ text: '考勤型態', value: 'check_type_desc' },
{ text: '登錄型態', value: 'login_type_desc' },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
],
footer:{
showFirstLastPage: true,
itemsPerPageOptions:[5,10,20,30],
},
},
search: {
group_kind: 0,
u_name: '',
check_date_year:0,
check_date_month:0
}
}
},
watch: {
options: {
handler() {
this.getDefault()
},
deep: true,
},
},
methods: {
getDefault(clearpage = false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage ? '1' : page, pageSize: itemsPerPage
};
this.data_table.loading = true
axios
.post(HTTP_HOST + 'api/member/GetCheckList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
})
.catch(error => console.log(error))
},
editItem(item) {
console.log("edit", item);
},
deleteItem(item) {
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/member/DeleteCheck/' + item.num)
.then(response => {
console.log("del", item);
this.data_table.list.splice(index, 1);
this.data_table.count = this.data_table.list.length
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/member/DeleteAllCheck/' + this.data_table.selected.map(x => x.num))
.then(response => {
console.log("delAll");
for (var i = 0; i < this.data_table.selected.length; i++) {
const index = this.data_table.list.indexOf(this.data_table.selected[i]);
this.data_table.list.splice(index, 1);
}
this.data_table.selected = [];
this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
this.getDefault(true)
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
},
})
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.check_date="{ item }" >
{{ item.check_date|timeString('YYYY/MM/DD') }}
</template>
<template #item.slot_btn="{ item }">
<a :href="'attendances.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<div class="row align-items-center">
<label class="col-sm-1 col-form-label">年</label>
<div class="col-sm-5 ">
<asp:DropDownList ID="s_year" runat="server" CssClass="form-select" v-model="search.check_date_year">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
<label class="col-sm-1 col-form-label">月</label>
<div class="col-sm-5 ">
<asp:DropDownList ID="s_month" runat="server" CssClass="form-select" v-model="search.check_date_month">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
</div>
</div>
<div class="mb-3 d-none">
<label class="form-label">時間</label>
<div class="row align-items-center gx-sm-2 gx-1">
<div class="col">
<asp:TextBox ID="start_day" runat="server" CssClass="form-control " TextMode="Time"></asp:TextBox>
</div>
<div class="col-auto">
~
</div>
<div class="col">
<asp:TextBox ID="end_day" runat="server" CssClass="form-control " TextMode="Time"></asp:TextBox>
</div>
</div>
</div>
<div class="mb-3 d-none">
<label class="form-label">人員</label>
<asp:DropDownList ID="s_mem_num" runat="server" CssClass="form-select">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">人員</label>
<input type="text" v-model="search.u_name" class="form-control" placeholder="可輸入關鍵字查詢" id="u_name" runat="server">
</div>
<div class="mb-3">
<label class="form-label">組別</label>
<asp:DropDownList ID="s_kind" runat="server" CssClass="form-select" v-model="search.group_kind">
<asp:ListItem Value="" Text=""></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
</asp:Content>
+178
View File
@@ -0,0 +1,178 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
public partial class admin_hr_index2 : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BuildKind();
for (int i = DateTime.Now.Year; i >= 1911; i--)
s_year.Items.Add(i.ToString());
for (int i = 1; i <= 12; i++)
s_month.Items.Add(i.ToString());
}
}
#region
public void BuildKind()
{
s_mem_num.Items.Clear();
s_mem_num.Items.Add(new ListItem("", ""));
s_kind.Items.Clear();
s_kind.Items.Add(new ListItem("", ""));
var qry = _db.members.AsEnumerable();
foreach (Model.member item in qry)
s_mem_num.Items.Add(new ListItem(item.u_name, item.num.ToString()));
buildMultiKind(s_kind, "member_group", 0, "", 1, Model.member.KindLevelMax);
}
#endregion
#region
protected void Button_All_Click(object sender, EventArgs e)
{
Response.Redirect(Request.Url.AbsolutePath);
}
#endregion
#region Excel
protected void excel_Click(object sender, EventArgs e)
{
var memoryStream = new MemoryStream();
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var wb = doc.AddWorkbookPart();
wb.Workbook = new Workbook();
var sheets = wb.Workbook.AppendChild(new Sheets());
//建立第一個頁籤
var ws = wb.AddNewPart<WorksheetPart>();
ws.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws),
SheetId = 1,
Name = "考勤統計表"
});
//設定欄寬
var cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 7, Width = 10, CustomWidth = true }
);
ws.Worksheet.Append(cu);
//建立資料頁
var sd = new SheetData();
ws.Worksheet.AppendChild(sd);
//第一列資料
var tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("組別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員編號"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("人員姓名"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("時間"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("考勤型態"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("登錄型態"), DataType = CellValues.String }
);
sd.AppendChild(tr);
//查詢要匯出的資料
var qry = _db.member_check.AsEnumerable();
if (!string.IsNullOrEmpty(u_name.Value))
qry = qry.Where(o => o.member.u_name.Contains(u_name.Value));
if (!string.IsNullOrEmpty(s_kind.SelectedValue))
qry = qry.Where(o => o.member.group_kind == Convert.ToInt32(s_kind.SelectedValue));
if (!string.IsNullOrEmpty(s_year.SelectedValue))
qry = qry.Where(o => o.check_date.Value.Year == Convert.ToInt32(s_year.SelectedValue));
if (!string.IsNullOrEmpty(s_month.SelectedValue))
qry = qry.Where(o => o.check_date.Value.Month == Convert.ToInt32(s_month.SelectedValue));
qry = qry.OrderByDescending(o => o.num);
var list = qry.ToList();
if (list.Count > 0)
{
var tdesc = publicFun.enum_desc<Model.member.attendances.type>();
var tdesc2 = publicFun.enum_desc<Model.member.attendances.login>();
foreach (var item in list)
{
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.mem_num.HasValue ? item.member.member_group?.kind:""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.mem_num.HasValue ? item.member.m_number:""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.mem_num.HasValue ? item.member.u_name : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.check_date.HasValue ? item.check_date.Value.ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.check_time.HasValue ? item.check_time.Value.ToString() : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.check_type.HasValue ? tdesc[item.check_type ?? 1] : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.login_type.HasValue ? tdesc2[item.login_type ?? 1] : ""), DataType = CellValues.String }
);
sd.AppendChild(tr);
}
}
//儲存文件(如果有要儲實體的檔案在upload才需要)
//wb.Workbook.Save();
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=考勤匯出.xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
HttpContext.Current.Response.End();
}
#endregion
}
+106
View File
@@ -0,0 +1,106 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg.aspx.cs" Inherits="admin_hr_kind_reg" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" CssClass="btn btn-primary"
OnClick="ImageButton4_Click">
<i class="mdi mdi-plus"></i> 新增組別</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" CssClass="btn btn-outline-secondary" CausesValidation="False"
OnClick="ImageButton5_Click">
<i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" CssClass="btn btn-outline-secondary"
OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);"
OnClick="ImageButton6_Click" >
<i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇組別</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal" role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">* 名稱</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入組別名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">休息時數</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="resttime" runat="server" CssClass="form-control" TextMode="Number" placeholder="請輸入休息時數"></asp:TextBox>
</div>
</div>
<div class="row mb-1 gy-2 gy-sm-3">
<label class="col-sm-2 col-form-label">* 上班時間</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="starttime" runat="server" CssClass="form-control" TextMode="Time"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="starttime" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">* 下班時間</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="offtime" runat="server" CssClass="form-control" TextMode="Time"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="offtime"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+336
View File
@@ -0,0 +1,336 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_hr_kind_reg : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.member.KindLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var qry = _db.member_group.AsEnumerable();
var prod = _db.member_group.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind.Trim() + "】</span>的組別名稱";
item_name.Text = prod.kind;
demo.Text = prod.demo;
if (prod.starttime.HasValue)
starttime.Text = prod.starttime.Value.ToString();
if (prod.offtime.HasValue)
offtime.Text = prod.offtime.Value.ToString();
if (prod.resttime.HasValue)
resttime.Text = prod.resttime.Value.ToString();
HiddenField1.Value = prod.kind;
}
else
Response.Redirect(Request.Url.AbsolutePath );
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的組別】"; }
}
}
}
#region
protected void TreeTopology()
{
var qry = _db.member_group.AsEnumerable();
var prod = _db.member_group.ToList();
//treeDt = prod.CopyToDataTable();
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM member_group ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString();
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>組別下,新增次組別";
item_name.Text = "";
starttime.Text = "";
offtime.Text = "";
resttime.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增組別</span>";
table.Visible = true;
item_name.Text = "";
starttime.Text = "";
offtime.Text = "";
resttime.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.member_group member_group = _db.member_group.Where(q => q.num == _num).FirstOrDefault();//修改
if (member_group != null)
{
member_group.kind = item_name.Text;
member_group.demo = demo.Text;
member_group.starttime = TimeSpan.Parse(starttime.Text);
member_group.offtime = TimeSpan.Parse(offtime.Text);
if (!isStrNull(resttime.Text))
member_group.resttime = Val(resttime.Text);
else member_group.resttime = null;
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Update, "組別:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.member_group.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.member_group member_group = new Model.member_group();//新增
member_group.kind = item_name.Text;
member_group.root = root;
member_group.range = range;
member_group.demo = demo.Text;
member_group.starttime = TimeSpan.Parse(starttime.Text);
member_group.offtime = TimeSpan.Parse(offtime.Text);
if (!isStrNull(resttime.Text))
member_group.resttime = Val(resttime.Text);
else member_group.resttime = null;
_db.member_group.Add(member_group);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Insert, "組別:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.member_group.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.member_group.Remove(prod);
_db.SaveChanges(); //執行
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Delete, "組別:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.member_group.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.member_group.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.members.AsEnumerable().Where(q => q.group_kind == num).ToList();
if (prod.Count > 0)
{
//清空組別分類
foreach (var item in prod)
item.group_kind = null;
_db.SaveChanges();
}
}
#endregion
}
+571
View File
@@ -0,0 +1,571 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="reg.aspx.cs" Inherits="admin_hr_reg" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<%--<link href="<%=ResolveUrl("~/js/vuetify_ez.css")%>" rel="stylesheet" />--%>
<script>
function checkNumber(btn) {
$('#errormsg').hide();
var _txt = $(btn).val();
$.ajax({
method: "POST",
url: "reg.aspx",
data: {
type: 'chkNo',
txt: _txt,
id: '<%= Request["num"]%>'
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
//alert('Error - ' + errorMessage);
console.log('Error - ' + errorMessage);
}
}).done(function (data) {
if (data.isOk) {
} else {
console.log(data.msg);
$('#errormsg').text(data.msg);
$('#errormsg').show();
}
});
}
// 模組化工作: 結合: UC, MIXIN...
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
hr_id: '<%= Request["num"] %>',
admin_id: '<%=_admin_id %>',
options: {},
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '信眾',
text_prop: 'f_number',
value_prop: 'num',
keys: [
{ id: 'f_number', title: '編號', value: '' },
{ id: 'u_name', title: '姓名', value: '' },
{ id: 'address', title: '地址', value: '' },
],
api_url: HTTP_HOST + 'api/follower/GetList',
columns: [
{ id: 'f_number', title: '編號'},
{ id: 'u_name', title: '姓名'},
{ id: 'address', title: '地址'},
],
selected: {},
select(t) {
console.log("select search1", t);
$('#<%= u_name.ClientID %>').val(t.u_name);
$('#<%= sex.ClientID %>').val(t.sex.replace('眾', ''));
$('#<%= birthday.ClientID %>').val(moment(t.birthday).format('YYYY-MM-DD'));
$('#<%= phone.ClientID %>').val(t.phoneDes);
$('#<%= refuge_name.ClientID %>').val(t.refuge_name);
$('#<%= refugedate.ClientID %>').val(moment(t.refugedate).format('YYYY-MM-DD'));
$('#<%= email.ClientID %>').val(t.email);
$('#<%= address2.ClientID %>').val(t.address);
}
},
search2: {
id: 'search2',
title: '系統帳號',
text_prop: 'u_id',
value_prop: 'num',
keys: [
{ id: 'u_id', title: '帳號', value: '' },
{ id: 'power', title: '群組', value: '' },
{ id: 'u_name', title: '姓名', value: '' },
],
api_url: HTTP_HOST + 'api/adminUser/GetList',
columns: [
{ id: 'u_id', title: '帳號', value: '' },
{ id: 'power', title: '群組', value: '' },
{ id: 'u_name', title: '姓名', value: '' },
],
selected: {},
select(t) {
console.log("select search2", t);
}
},
search3: {
id: 'search3',
title: '組別',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '組別名稱', value: '' },
],
api_url: HTTP_HOST + 'api/member/GetGroupList',
columns: [
{ id: 'kind', title: '組別名稱', value: '' },
],
selected: {},
select(t) {
console.log("select search3", t);
}
},
search4: {
id: 'search4',
title: '職稱',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '職稱', value: '' },
],
api_url: HTTP_HOST + 'api/member/GetTitleList',
columns: [
{ id: 'kind', title: '職稱', value: '' },
],
selected: {},
select(t) {
console.log("select search4", t);
}
},
},
show: false,
current: {},
list: [],
count: 0,
page:1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText:'',
},
},
snackbar: {
show: false,
text: "",
}
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
//console.log("mounted");
},
watch: {
options: {
handler() {
//console.log("watch1", this.search_dialog, this.search_dialog.page);
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
//this.search_get()//清除完自動會重抓, 故取消
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
//const { page, itemsPerPage } = this.options
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
this.search_dialog.page = this.options.page??1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
//necessary parameter===
if (this.search_dialog.current.id == 'search2') {
search['num'] = this.admin_id;
search['removeExist'] = true;
}
if (this.search_dialog.current.id == 'search4') {
search['inTime'] = (this.hr_id != '' ? false : true);
}
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show=true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(row);
}
this.search_dialog.show = false;
console.log(row, row["u_name"], row["f_number"], curr.id, target);
},
},
computed: {
},
})
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
</div>
<div class="">
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
</div>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-xl">
<div class="card shadow-sm my-2" id="sec2">
<div class="card-header py-0">
<nav class="navbar py-0">
<div class="nav nav-tabs">
<button class="nav-link active" id="sec2-tab1" data-bs-toggle="tab" data-bs-target="#sec2-page1"
type="button" role="tab" aria-controls="home" aria-selected="true">
基本資料</button>
<button class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2"
type="button" role="tab" aria-controls="profile" aria-selected="false">
職務管理</button>
<button class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
type="button" role="tab" aria-controls="profile" aria-selected="false">
聯絡方式</button>
<button class="nav-link" id="sec2-tab4" data-bs-toggle="tab" data-bs-target="#sec2-page4"
type="button" role="tab" aria-controls="profile" aria-selected="false">
圖片管理</button>
</div>
</nav>
</div>
<div class="card-body">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="sec2-page1" role="tabpanel" aria-labelledby="sec2-tab1">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="label-sm-right">
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">信眾編號</label>
<div class="col-sm-4 col-lg-3">
<div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
id="f_num_txt" runat="server" placeholder="信眾" value="" >
<asp:HiddenField ID="f_num" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">人員編號 *</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="m_number" MaxLength="20" runat="server" CssClass="form-control" onchange="checkNumber(this)" placeholder="請輸入人員編號"></asp:TextBox>
<span id="errormsg" class="text-danger" style="display:none;"></span>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" ControlToValidate="m_number" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">人員姓名 *</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="u_name" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入人員姓名"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" ControlToValidate="u_name" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">性別</label>
<div class="col-sm-4 col-lg-3">
<asp:DropDownList ID="sex" CssClass="form-select" runat="server">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
<asp:ListItem Value="男" Text="男"></asp:ListItem>
<asp:ListItem Value="女" Text="女"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="sex" Visible="false" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">身分證字號</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="id_code" MaxLength="10" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="請輸入身分證字號"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator8" ControlToValidate="id_code" Visible="false" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">生日</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="birthday" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
</div>
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">血型</label>
<div class="col-sm-4 col-lg-3">
<asp:DropDownList ID="blood" CssClass="form-select" runat="server">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
<asp:ListItem Value="A" Text="A型"></asp:ListItem>
<asp:ListItem Value="B" Text="B型"></asp:ListItem>
<asp:ListItem Value="AB" Text="AB型"></asp:ListItem>
<asp:ListItem Value="O" Text="O型"></asp:ListItem>
</asp:DropDownList>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">最高學歷</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="educational" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入最高學歷"></asp:TextBox>
</div>
</div>
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">皈依日期</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="refugedate" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">皈依法名</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="refuge_name" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入皈依法名"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">皈依道場</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="refuge_area" MaxLength="50" runat="server" CssClass="form-control" placeholder="請輸入皈依道場"></asp:TextBox>
</div>
</div>
</div>
<hr />
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
</div>
<div class="tab-pane fade label-sm-right" id="sec2-page2" role="tabpanel" aria-labelledby="sec2-tab2">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">系統帳號</label>
<div class="col-sm-4 col-lg-3">
<%--<asp:DropDownList ID="admin_num" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>--%>
<div class="input-group mb-3" data-search-control="search2" @click="search_show(search_dialog.controls.search2)">
<input class="form-control search-text" type="text" readonly
id="admin_num_txt" runat="server" placeholder="系統帳號" value="" >
<asp:HiddenField ID="admin_num" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">到職日期</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="takedate" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">離職日期</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="leavedate" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
</div>
<div class="row mb-1 ">
<label class="col-sm-2 col-lg-1 col-form-label">薪資</label>
<div class="col-sm-4 col-lg-3">
<asp:TextBox ID="salary" MaxLength="10" runat="server" CssClass="form-control" TextMode="Number" placeholder="請輸入薪資"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">組別</label>
<div class="col-sm-4 col-lg-3">
<div class="input-group mb-3" data-search-control="search3" @click="search_show(search_dialog.controls.search3)">
<input class="form-control search-text" type="text" readonly
id="group_kind_txt" runat="server" placeholder="組別" value="" >
<asp:HiddenField ID="group_kind" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="group_kind_txt" Visible="false" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">職稱</label>
<div class="col-sm-4 col-lg-3">
<div class="input-group mb-3" data-search-control="search4" @click="search_show(search_dialog.controls.search4)">
<input class="form-control search-text" type="text" readonly
id="title_kind_txt" runat="server" placeholder="職稱" value="" >
<asp:HiddenField ID="title_kind" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator10" ControlToValidate="title_kind_txt" Visible="false" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
</div>
<div class="tab-pane fade label-sm-right" id="sec2-page3" role="tabpanel" aria-labelledby="sec2-tab3">
<div class="row mb-1">
<label class="col-sm-2 col-form-label">聯絡電話</label>
<div class="col-sm-10">
<asp:TextBox ID="phone" MaxLength="15" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="請輸入聯絡電話,如: 04-2237-0000"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="phone" ErrorMessage="格式有誤" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^[+-]?\d+([+-]?\d*)*$" Display="Dynamic" SetFocusOnError="true" />
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">公司電子信箱</label>
<div class="col-sm-10">
<asp:TextBox ID="com_email" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入公司電子信箱"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="com_email" Display="Dynamic" SetFocusOnError="true" ErrorMessage="格式有誤!" ID="RegularExpressionValidator2" runat="server" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">個人電子信箱</label>
<div class="col-sm-10">
<asp:TextBox ID="email" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入個人電子信箱"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="email" Display="Dynamic" SetFocusOnError="true" ErrorMessage="格式有誤!" ID="RegularExpressionValidator1" runat="server" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">其他聯絡方式</label>
<div class="col-sm-10">
<asp:TextBox ID="contact" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入其他聯絡方式"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">戶籍地址</label>
<div class="col-sm-10">
<asp:TextBox ID="address1" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入戶籍地址"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">居住地址</label>
<div class="col-sm-10">
<asp:TextBox ID="address2" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入居住地址"></asp:TextBox>
</div>
</div>
</div>
<div class="tab-pane fade" id="sec2-page4" role="tabpanel" aria-labelledby="sec2-tab4">
<asp:Panel ID="Panel1" runat="server" CssClass="row mb-1">
<div class="border rounded col-md-4">
<p class="form-control-static" style="height: 35px">建議尺寸:300*300象素 &nbsp;<asp:CheckBox ID="CheckBox1" Text="刪除" runat="server" Visible="false" /></p>
<table border="0">
<tr>
<td><asp:FileUpload ID="FileUpload1" runat="server" /></td>
</tr>
<tr>
<td width="160" height="160">
<asp:Image ID="Image1" runat="server" Visible="false" ImageUrl="~/admin/images/showpic.gif" /></td>
</tr>
</table>
</div>
</asp:Panel>
</div>
</div>
</div>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title"></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+429
View File
@@ -0,0 +1,429 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_hr_reg : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
public string _admin_id = "";
protected void Page_Load(object sender, EventArgs e)
{
CallAjax();
if (!IsPostBack)
{
if (isStrNull(Request["num"]))
{
}
else
{
int _num = Val(Request["num"]);
var qry = _db.members.AsEnumerable();
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
//var prod = _db.members.Where(q => q.num == _num).ToList();
if (prod != null)
//if (prod.Count>0)
{
MyWeb.encrypt encrypt = new MyWeb.encrypt();
object[] ctrlist = { f_num, m_number, u_name, sex, id_code, birthday, blood, educational, refugedate, refuge_name,refuge_area, demo
, takedate, leavedate, salary, group_kind, title_kind, phone, com_email, email, contact, address1, address2 };
try
{
foreach (Control obj in ctrlist)
{
if (obj is TextBox)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var textBox = (TextBox)obj;
if (textBox.TextMode == TextBoxMode.Date)
{
textBox.Text = Convert.ToDateTime(ObjValue).ToString("yyyy-MM-dd");
}
else if (!isStrNull(textBox.Attributes["data-encrypt"]) && ValString(textBox.Attributes["data-encrypt"]).Equals("Y"))
textBox.Text = encrypt.DecryptAutoKey(ObjValue.ToString());
else
{
textBox.Text = ObjValue.ToString();
}
}
}
else if (obj is DropDownList && ((DropDownList)obj).SelectedIndex == 0)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var dropDown = (DropDownList)obj;
dropDown.SelectedValue = ObjValue.ToString();
}
}
}
}
catch (Exception)
{
}
for (int i = 1; i <= Model.member.picMax; i++)
{
if (prod.pic1 != "")
{
((CheckBox)Panel1.FindControl("CheckBox" + i.ToString())).Visible = true;
ViewState["pic" + i.ToString()] = prod.pic1;
Image img = (Image)Panel1.FindControl("Image" + i.ToString());
img.Visible = true;
img.ImageUrl = "../../App_Script/DisplayCut.ashx?file=" + Model.member.Dir.Replace("~/upload/","") + "/" + prod.pic1 + "&w=150&h=150";
}
}
if (prod.f_num.HasValue)
{
f_num_txt.Value = prod.follower.f_number.ToString();
f_num.Value = prod.f_num.ToString();
}
if (prod.admin_num.HasValue)
{
admin_num_txt.Value = prod.admin.u_id.ToString();
admin_num.Value = prod.admin_num.ToString();
_admin_id = prod.admin_num.ToString();
}
if (prod.group_kind.HasValue)
{
group_kind_txt.Value = prod.member_group.kind.ToString();
group_kind.Value = prod.group_kind.ToString();
}
if (prod.title_kind.HasValue)
{
title_kind_txt.Value = prod.member_title.kind.ToString();
title_kind.Value = prod.title_kind.ToString();
}
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
}
else
{
Response.Redirect("index.aspx");
}
}
}
}
protected void goback_Click(object sender, EventArgs e)
{
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
L_msg.Text = "";
if (chk_pro_num(m_number.Text))
{
MyWeb.fileSystem fileSystem = new MyWeb.fileSystem();
string[] pic_name = fileSystem.UploadPhoto(Model.member.Dir, 800, admin.info.num); //縮圖的寬高不得超過800象素,如果不是圖片也會傳
MyWeb.encrypt encrypt = new MyWeb.encrypt();
Model.member member = new Model.member();//新增
object[] ctrlist = { f_num, m_number, u_name, sex, id_code, birthday, blood, educational, refugedate, refuge_name,refuge_area, demo
, admin_num, takedate, leavedate, salary, group_kind, title_kind, phone, com_email, email, contact, address1, address2 };
member.pic1 = pic_name[0];
try
{
foreach (Control obj in ctrlist)
{
if (obj is TextBox)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var textBox = (TextBox)obj;
if (!isStrNull(textBox.Text))
{
if (textBox.TextMode == TextBoxMode.Date)
ObjValue.SetValue(member, selectDate(textBox));
else if (!isStrNull(((TextBox)obj).Attributes["data-encrypt"]) && ValString(textBox.Attributes["data-encrypt"]).Equals("Y"))
ObjValue.SetValue(member, encrypt.EncryptAutoKey(textBox.Text.Trim()));
else
ObjValue.SetValue(member, ((TextBox)obj).Text.Trim());
}
else
ObjValue.SetValue(member, null);
}
else if (obj is DropDownList)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var dropDown = (DropDownList)obj;
if (!isStrNull(dropDown.SelectedValue))
{
if (!isStrNull(dropDown.Attributes["data-int"]) && ValString(dropDown.Attributes["data-int"]).Equals("Y"))
ObjValue.SetValue(member, Val(dropDown.SelectedValue));
else
ObjValue.SetValue(member, dropDown.SelectedValue);
}
else
ObjValue.SetValue(member, null);
}
else if (obj is HiddenField)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var dropDown = (HiddenField)obj;
if (!isStrNull(dropDown.Value))
{
ObjValue.SetValue(member, Val(dropDown.Value));
}
else
ObjValue.SetValue(member, null);
}
}
_db.members.Add(member);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Insert, m_number.Text+ u_name.Text);
Response.Redirect("index.aspx");
}
catch (Exception ex)
{
//L_msg.Text = ex.Message;
}
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "人員編號重複";
}
}
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
if (chk_pro_num(m_number.Text, _num))
{
MyWeb.fileSystem fileSystem = new MyWeb.fileSystem();
string[] pic_name = fileSystem.UploadPhoto(Model.member.Dir, 800, admin.info.num); //縮圖的寬高不得超過800象素,如果不是圖片也會傳
MyWeb.encrypt encrypt = new MyWeb.encrypt();
Model.member member = _db.members.Where(q => q.num == _num).FirstOrDefault();//修改
if (member != null)
{
object[] ctrlist = { f_num, m_number, u_name, sex, id_code, birthday, blood, educational, refugedate, refuge_name,refuge_area, demo
, admin_num, takedate, leavedate, salary, group_kind, title_kind, phone, com_email, email, contact, address1, address2 };
try
{
foreach (Control obj in ctrlist)
{
if (obj is TextBox)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var textBox = (TextBox)obj;
if (!isStrNull(textBox.Text))
{
if (textBox.TextMode == TextBoxMode.Date)
ObjValue.SetValue(member, selectDate(textBox));
else if (!isStrNull(((TextBox)obj).Attributes["data-encrypt"]) && ValString(textBox.Attributes["data-encrypt"]).Equals("Y"))
ObjValue.SetValue(member, encrypt.EncryptAutoKey(textBox.Text.Trim()));
else
ObjValue.SetValue(member, ((TextBox)obj).Text.Trim());
}
else
ObjValue.SetValue(member, null);
}
else if (obj is DropDownList)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var dropDown = (DropDownList)obj;
if (!isStrNull(dropDown.SelectedValue))
{
if (!isStrNull(dropDown.Attributes["data-int"]) && ValString(dropDown.Attributes["data-int"]).Equals("Y"))
ObjValue.SetValue(member, Val(dropDown.SelectedValue));
else
ObjValue.SetValue(member, dropDown.SelectedValue);
}
else
ObjValue.SetValue(member, null);
}
else if (obj is HiddenField)
{
var ObjValue = member.GetType().GetProperty(obj.ID);
var dropDown = (HiddenField)obj;
if (!isStrNull(dropDown.Value))
{
ObjValue.SetValue(member, Val(dropDown.Value));
}
else
ObjValue.SetValue(member, null);
}
}
}
catch (Exception ex)
{
L_msg.Text = ex.Message;
}
for (int i = 1; i <= fileSystem.Count(); i++)
{
CheckBox ck = (CheckBox)Panel1.FindControl("CheckBox" + i.ToString());
if (pic_name[i - 1] != "" | ck.Checked)
{
member.pic1 = pic_name[i - 1].ToString();
if (!isStrNull(ViewState["pic" + i.ToString()]))
{
fileSystem.Delete(Model.member.Dir + "/" + ViewState["pic" + i.ToString()]);
}
}
}
try
{
if (isStrNull(L_msg.Text))
{
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Update, m_number.Text + u_name.Text);
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "查無資料";
}
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "人員編號重複";
}
}
}
#endregion
#region
protected bool chk_pro_num(string txt,int num=0)
{
bool success=false;
var qry = _db.members.AsEnumerable();
qry = qry.Where(q => q.m_number == txt);
if (num > 0)
qry = qry.Where(q => q.num != num);
var prod = qry.FirstOrDefault();
success = (prod == null);
return success;
}
#endregion
#region Ajax
protected void CallAjax()
{
if (!isStrNull(Request["type"]))
{
Response.Clear();
Response.ContentType = "application/json";
AjaxInfo info = new AjaxInfo();
info.isOk = false;
info.msg = "";
if (ValString(Request["type"]) == "chkNo")
{
if (!isStrNull(Request["txt"]) )
{
info.isOk = chk_pro_num(ValString(Request["txt"]), !isStrNull(Request["id"]) ? Val(Request["id"]) : 0);
if (!info.isOk)
info.msg = "人員編號重複";
}
else
{
info.isOk = true;
info.msg = "";
}
}
else
{
info.msg = "參數不正確";
}
Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(info));
Response.End();
}
}
public class AjaxInfo
{
public bool isOk { get; set; }
public string msg { get; set; }
}
#endregion
}
+95
View File
@@ -0,0 +1,95 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="title_reg.aspx.cs" Inherits="admin_hr_kind_reg" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增職稱</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇職稱</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label></div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label></div>
</div>
<div class="card-body form-horizontal" role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-form-label">* 職稱</label>
<div class="col-sm-10 col-lg-4">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入職務名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">* 狀態</label>
<div class="col-sm-10 col-lg-4">
<label class="col-form-control">
<input type="checkbox" id="status" runat="server"
data-toggle="toggle" data-on="啟用" data-off="停用" data-onstyle="success" />
</label>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+303
View File
@@ -0,0 +1,303 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
public partial class admin_hr_kind_reg : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.member.TitleLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var qry = _db.member_title.AsEnumerable();
var prod = _db.member_title.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind.Trim() + "】</span>的職稱名稱";
item_name.Text = prod.kind;
demo.Text = prod.demo;
status.Checked = prod.status.Equals("Y");
HiddenField1.Value = prod.kind.ToString();
}
else
Response.Redirect(Request.Url.AbsolutePath );
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
status.Checked = true;
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的職稱】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM member_title ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString();
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>職稱下,新增次職稱";
item_name.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增職稱</span>";
table.Visible = true;
item_name.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
status.Checked = true;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.member_title member_title = _db.member_title.Where(q => q.num == _num).FirstOrDefault();
if (member_title != null)
{
member_title.kind = item_name.Text;
member_title.demo = demo.Text;
member_title.status = status.Checked ? "Y" : "N";
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Update, "職稱:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.member_title.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.member_title member_title = new Model.member_title();//新增
member_title.kind = item_name.Text;
member_title.root = root;
member_title.range = range;
member_title.demo = demo.Text;
member_title.status = status.Checked ? "Y" : "N";
_db.member_title.Add(member_title);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Insert, "職稱:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.member_title.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.member_title.Remove(prod);
_db.SaveChanges(); //執行
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.HR, (int)Model.admin_log.Status.Delete, "職稱:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.member_title.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.member_title.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.members.AsEnumerable().Where(q => q.title_kind == num).ToList();
if (prod.Count > 0)
{
//清空分類
foreach (var item in prod)
item.title_kind = null;
_db.SaveChanges();
}
}
#endregion
}
@@ -0,0 +1,82 @@
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="admin_Templates_TBS5ADM001_MasterPage" %>
<%@ Register Src="~/admin/Templates/TBS5ADM001/uc/nav.ascx" TagPrefix="uc1" TagName="nav" %>
<%@ Register Src="~/admin/Templates/TBS5ADM001/uc/footer.ascx" TagPrefix="uc1" TagName="footer" %>
<%@ Register Src="~/admin/Templates/TBS5ADM001/uc/menu.ascx" TagPrefix="uc1" TagName="menu" %>
<!DOCTYPE html>
<html lang="zh-TW">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title><%= Page.Title %></title>
<%--
<%: Styles.Render("~/bundles/css") %>
<link href="~/css/bundle.css" rel="stylesheet" />
--%>
<link href="~/js/bootstrap5/bootstrap.min.css" rel="stylesheet" />
<%--<link href="~/js/fontawesome6/css/all.css" rel="stylesheet" />--%>
<link href="~/js/mdi-font/css/materialdesignicons.min.css" rel="stylesheet" />
<link href="~/js/vuetify_ez.css" rel="stylesheet" />
<link href="~/js/sweetalert2/sweetalert2.min.css" rel="stylesheet" />
<link href="~/admin/Templates/TBS5ADM001/css/Style.css" rel="stylesheet" />
<asp:ContentPlaceHolder id="page_header" runat="server">
</asp:ContentPlaceHolder>
</head>
<body id="PageBody" class="" runat="server">
<form id="form1" runat="server">
<%-- ScriptManager 必需移除 --%>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div id="app">
<v-app>
<uc1:nav runat="server" ID="nav"/>
<div id="layoutSidenav" class="">
<div id="layoutSidenav_nav" class="shadow" runat="server" ClientIDMode="static">
<uc1:menu runat="server" id="menu" />
</div>
<div id="layoutSidenav_content" class="bg-light" runat="server" ClientIDMode="static">
<main>
<nav class="page-nav navbar bg-white navbar-light px-2 mb-2 border-bottom"
><asp:ContentPlaceHolder id="page_nav" runat="server"></asp:ContentPlaceHolder></nav>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</main>
<uc1:footer runat="server" ID="footer" />
</div>
</div>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight" aria-labelledby="offcanvasRightLabel">
<div class="offcanvas-header shadow">
<h5 id="offcanvasRightLabel">查詢</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<asp:ContentPlaceHolder id="offCanvasRight" runat="server">
</asp:ContentPlaceHolder>
</div>
</div>
</v-app>
</div>
<%--
<%:Scripts.Render("~/bundles/js") %>
<script src="<%=ResolveClientUrl("~/js/bundle.js")%>"></script>
--%>
<script>
let HTTP_HOST = "<%=UrlHost()%>";
</script>
<script src="<%=ResolveUrl("~/js/bootstrap5/js/bootstrap.bundle.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/jquery-3.6.0.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/vue.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/vuetify.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/axios.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/moment.min.js")%>"></script>
<script src="<%=ResolveUrl("~/js/sweetalert2/sweetalert2.all.min.js") %>"></script>
<script src="<%=ResolveUrl("~/admin/Templates/TBS5ADM001/js/Script.js")%>"></script>
<asp:ContentPlaceHolder id="footer_script" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_Templates_TBS5ADM001_MasterPage : MyWeb.master
{
protected void Page_Load(object sender, EventArgs e)
{
MasterLoad();
}
public void set_navs(bool visible=true, string body_class="")
{
this.nav.Visible = visible;
this.layoutSidenav_nav.Visible = visible;
this.PageBody.Attributes["class"] += " "+ body_class;
}
/* From MyWeb.config*/
public static bool IsHttps()
{
return HttpContext.Current.Request.IsSecureConnection;
}
public static string UrlHost()
{
string url = (IsHttps() ? "https://" : "http://")
//+ HttpContext.Current.Request.Url.Host
+ HttpContext.Current.Request.ServerVariables["HTTP_HOST"]
+ VirtualPathUtility.ToAbsolute("~/");
return url;
}
}
@@ -0,0 +1,675 @@
html, body {
/* height: 100%*/
overflow:hidden;
}
#layoutAuthentication {
display: flex;
flex-direction: column;
min-height: 100vh
}
#layoutAuthentication #layoutAuthentication_content {
min-width: 0;
flex-grow: 1
}
#layoutAuthentication #layoutAuthentication_footer {
min-width: 0
}
#layoutSidenav {
display: flex;
}
#layoutSidenav #layoutSidenav_nav .sb-sidenav .sb-sidenav-menu .nav .nav-link {
padding:0.25rem 0.75rem;
}
#layoutSidenav #layoutSidenav_nav {
flex-basis: 225px;
flex-shrink: 0;
transition: transform .15s ease-in-out;
z-index: 1038;
transform: translateX(-225px)
}
@media (max-width:991px){
#layoutSidenav #layoutSidenav_nav{
box-shadow:none !important;
}
}
#layoutSidenav #layoutSidenav_content {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
min-width: 0;
flex-grow: 1;
min-height: calc(100vh - 56px);
margin-left: -225px
}
#layoutSidenav,
#layoutSidenav_nav,
#layoutSidenav_content {
max-height: calc(100vh - 3.5rem);
overflow-y: auto;
}
#layoutSidenav_nav > .sb-sidenav {
min-height: 100%;
height: auto;
}
#layoutSidenav_nav > .sb-sidenav {
min-height: 100%;
height: auto;
}
#layoutSidenav_nav::-webkit-scrollbar {
height: 0.5rem;
width: 0.5rem;
background: #EEE;
}
#layoutSidenav_nav::-webkit-scrollbar-thumb {
background: #CCC;
border-radius: 1ex;
border: 2px solid transparent;
background-clip: content-box;
}
#layoutSidenav_nav::-webkit-scrollbar-thumb:hover {
background: #AAA;
border: 0 solid transparent;
}
#layoutSidenav_nav::-webkit-scrollbar-button {
width: 0.5rem;
height: 0.5rem;
background-color: #EEE;
}
#layoutSidenav_nav::-webkit-scrollbar-button:hover {
background-color: #AAA;
}
#layoutSidenav_nav::-webkit-scrollbar-corner {
}
.sb-sidenav-toggled #layoutSidenav #layoutSidenav_nav {
transform: translateX(0)
}
.sb-sidenav-toggled #layoutSidenav #layoutSidenav_content:before {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
z-index: 1037;
opacity: .5;
transition: opacity .3s ease-in-out
}
@media(min-width:992px) {
#layoutSidenav #layoutSidenav_nav {
transform: translateX(0)
}
#layoutSidenav #layoutSidenav_content {
margin-left: 0;
transition: margin .15s ease-in-out
}
.sb-sidenav-toggled #layoutSidenav #layoutSidenav_nav {
transform: translateX(-225px)
}
.sb-sidenav-toggled #layoutSidenav #layoutSidenav_content {
margin-left: -225px
}
.sb-sidenav-toggled #layoutSidenav #layoutSidenav_content:before {
display: none
}
}
.sb-nav-fixed .sb-topnav {
z-index: 1039
}
.sb-nav-fixed #layoutSidenav #layoutSidenav_nav {
width: 225px;
height: 100vh;
z-index: 1038
}
.sb-nav-fixed #layoutSidenav #layoutSidenav_nav .sb-sidenav {
padding-top: 56px
}
.sb-nav-fixed #layoutSidenav #layoutSidenav_nav .sb-sidenav .sb-sidenav-menu {
overflow-y: auto
}
.sb-nav-fixed #layoutSidenav #layoutSidenav_content {
padding-left: 225px;
top: 56px
}
#layoutError {
display: flex;
flex-direction: column;
min-height: 100vh
}
#layoutError #layoutError_content {
min-width: 0;
flex-grow: 1
}
#layoutError #layoutError_footer {
min-width: 0
}
.img-error {
max-width: 20rem
}
.nav .nav-link .sb-nav-link-icon, .sb-sidenav-menu .nav-link .sb-nav-link-icon {
margin-right: .5rem
}
.sb-topnav {
padding-left: 0;
height: 3.5rem; /*56px;*/
z-index: 100;/*1039*/
}
.sb-topnav .navbar-brand {
}
.sb-topnav .breadcrumb {
margin:0;
}
.sb-topnav .breadcrumb li{
color: var(--bs-light);
}
.sb-topnav .breadcrumb li.active {
color: var(--bs-white);
}
.sb-topnav .breadcrumb a {
color: var(--bs-light);
}
.sb-topnav.navbar-dark #sidebarToggle {
color: rgba(255,255,255,.5)
}
.sb-topnav.navbar-light #sidebarToggle {
color: #212529
}
.sb-sidenav {
display: flex;
flex-direction: column;
height: 100%;
flex-wrap: nowrap
}
.sb-sidenav .sb-sidenav-menu {
flex-grow: 1
}
.sb-sidenav .sb-sidenav-menu .nav {
flex-direction: column;
flex-wrap: nowrap
}
.sb-sidenav .sb-sidenav-menu .nav .sb-sidenav-menu-heading {
padding: 1.75rem 1rem .75rem;
font-size: .75rem;
font-weight: bold;
text-transform: uppercase
}
.sb-sidenav .sb-sidenav-menu .nav .nav-link {
display: flex;
align-items: center;
padding-top: .75rem;
padding-bottom: .75rem;
position: relative
}
.sb-sidenav .sb-sidenav-menu .nav .nav-link .sb-nav-link-icon {
font-size: .9rem
}
.sb-sidenav .sb-sidenav-menu .nav .nav-link .sb-sidenav-collapse-arrow {
display: inline-block;
margin-left: auto;
transition: transform .15s ease
}
.sb-sidenav .sb-sidenav-menu .nav .nav-link.collapsed .sb-sidenav-collapse-arrow {
transform: rotate(-90deg)
}
.sb-sidenav .sb-sidenav-menu .nav .sb-sidenav-menu-nested {
margin-left: 1.5rem;
flex-direction: column
}
.sb-sidenav .sb-sidenav-footer {
padding: .75rem;
flex-shrink: 0
}
.sb-sidenav-dark {
background-color: #212529;
color: rgba(255,255,255,.5)
}
.sb-sidenav-dark .sb-sidenav-menu .sb-sidenav-menu-heading {
color: rgba(255,255,255,.25)
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link {
color: rgba(255,255,255,.5)
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link .sb-nav-link-icon {
color: rgba(255,255,255,.25)
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link .sb-sidenav-collapse-arrow {
color: rgba(255,255,255,.25)
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link:hover {
color: #fff
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link.active {
color: #fff
}
.sb-sidenav-dark .sb-sidenav-menu .nav-link.active .sb-nav-link-icon {
color: #fff
}
.sb-sidenav-dark .sb-sidenav-footer {
background-color: #343a40
}
.sb-sidenav-light {
background-color: #f8f9fa;
color: #212529
}
.sb-sidenav-light .sb-sidenav-menu .sb-sidenav-menu-heading {
color: #adb5bd
}
.sb-sidenav-light .sb-sidenav-menu .nav-link {
color: #212529
}
.sb-sidenav-light .sb-sidenav-menu .nav-link .sb-nav-link-icon {
color: #adb5bd
}
.sb-sidenav-light .sb-sidenav-menu .nav-link .sb-sidenav-collapse-arrow {
color: #adb5bd
}
.sb-sidenav-light .sb-sidenav-menu .nav-link:hover {
color: #0d6efd
}
.sb-sidenav-light .sb-sidenav-menu .nav-link.active {
color: #0d6efd
}
.sb-sidenav-light .sb-sidenav-menu .nav-link.active .sb-nav-link-icon {
color: #0d6efd
}
.sb-sidenav-light .sb-sidenav-footer {
background-color: #e9ecef
}
.dataTable-wrapper .dataTable-container {
font-size: .875rem
}
.btn-datatable {
height: 20px !important;
width: 20px !important;
font-size: .75rem;
border-radius: .25rem !important
}
.btn.rounded-circle {
padding: 0;
width: 2em;
height: 2em;
line-height: 2;
}
body.nav_hide #layoutSidenav {
min-height: 100vh;
margin: 0;
}
body.nav_hide #layoutSidenav #layoutSidenav_content {
min-height: 100vh;
margin: 0;
}
body.nav_hide .row.recaptcha {
align-items: center;
}
body.nav_hide .validation-msg {
position: absolute;
top: 0;
right: 0;
padding: 0.5rem;
color: var(--bs-red) !important;
}
#offcanvasRightLabel {
margin: 0;
}
#offcanvasRight .offcanvas-body>div {
display:none;
}
#search_btn{
display:none;
}
body.home {
/*background-image: url(../images/bg2.jpg);*/
background-size: cover;
background-blend-mode: unset;
}
body.home .card {
background-color: rgba(255,255,255,0.25);
backdrop-filter: blur(50px);
}
body.home footer{
position:fixed;
bottom:0;
left:0;
right:0;
opacity: 0.5;
}
/* .bg-ani */
body.home {
/*body .home, :root {*/
--bg-ani-image: url(../images/bg2.jpg);
--bg-ani-zoom: 0.2;
--bg-ani-duration: 30s;
--bg-ani-transition: 5s;
}
body.home .bg-ani > svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color:rgb(102,58,34,.4);
}
.bg-ani {
overflow: hidden;
text-align: center;
position: fixed;
top: 0;
bottom: -3rem;
left: 0;
right: 0;
/*z-index: -1;*/
}
.bg-ani .zoominheader {
width: 100%;
height: 100%;
background-image: var(--bg-ani-image);
background-size: cover;
background-attachment: fixed;
background-repeat: repeat;
background-blend-mode: unset;
position: relative;
animation: zoomin var(--bg-ani-duration) ease-in infinite;
transition: all var(--bg-ani-transition) ease-in-out;
overflow: hidden;
}
.bg-ani .zoomoutheader {
width: 100%;
height: 100%;
animation: zoomout var(--bg-ani-duration) ease-in infinite;
transition: all var(--bg-ani-transition) ease-in-out;
overflow: hidden;
}
@keyframes zoomin {
0% {
transform: scale(1);
}
50% {
transform: scale(calc(1 + var(--bg-ani-zoom)));
}
100% {
transform: scale(1);
}
}
@keyframes zoomout {
0% {
transform: scale(1);
}
50% {
transform: scale(calc(1 - var(--bg-ani-zoom)));
}
100% {
transform: scale(1);
}
}
/* /.bg-ani */
.btn-default {
color: #333333;
background-color: #ffffff;
border-color: #cccccc;
}
/* alert */
main .alert {
position: sticky;
top: 0;
z-index: 99;
}
main .page-nav {
position: sticky;
top: 0;
z-index: 99;
}
/* bootstrap-toggle */
main .checkbox label .toggle, main .checkbox-inline .toggle {
margin-left: 0;
}
main .toggle-group label{
font-size:.875rem;
}
html, body, #layoutSidenav, #layoutSidenav_nav, #layoutSidenav_content {
scroll-behavior: smooth;
}
#sidebarToggle {
font-size: 1.2rem;
border-radius: 37% !important;
color: rgba(255,255,255,0.75) !important;
}
.page-nav ~ #content [id]{
scroll-margin: 60px !important;
}
.page-nav:empty{
display:none;
}
.aspxTree a{
color: var(--bs-dark);
}
.aspxTree img{
width:12px;
opacity:0.6;
margin-top:-4px;
margin-right:4px;
}
.aspxTree>div img{
/*display:none;*/
visibility:hidden;
}
.aspxTree a > b > * {
color: var(--bs-primary) !important;
}
.sort-iframe{
width:100%;
min-height:500px;
overflow:auto;
}
.label-right .col-form-label{
text-align:right;
}
.col-form-label::after{
/*content:":";*/
}
@media (min-width:576px) {
.label-sm-right .col-form-label {
text-align: right;
}
}
@media (min-width:768px) {
.label-md-right .col-form-label {
text-align: right;
}
}
@media (min-width:992px) {
.label-lg-right .col-form-label {
text-align: right;
}
}
@media (min-width:1200px) {
.label-xl-right .col-form-label {
text-align: right;
}
}
@media (min-width:1400px) {
.label-xl-right .col-form-label {
text-align: right;
}
}
/*------------ theme: win11 ------------*/
.sb-topnav {
background-color: #006FC9 !important;
}
.sb-topnav.navbar-dark #sidebarToggle:hover {
background-color: rgba(255,255,255,0.3) !important;
}
.breadcrumb-item + .breadcrumb-item::before {
color: var(--bs-light);
}
.sb-sidenav-light .sb-sidenav-menu .nav-link.active .sb-nav-link-icon,
.sb-sidenav-light .sb-sidenav-menu .nav-link.active {
color: var(--bs-primary);
}
.sb-sidenav-light {
background-color: #FFF;
}
#layoutSidenav #layoutSidenav_content {
background-color: rgb(242, 242, 242) !important;
}
.card {
border: 0 none;
box-shadow: rgb(0 0 0 / 13%) 0px 1.6px 3.6px 0px, rgb(0 0 0 / 11%) 0px 0.3px 0.9px 0px !important;
}
.card-header {
background-color: transparent;
}
.card-header:hover {
background-color: rgba(0,0,0,.03);
}
.nav-tabs .nav-link {
border: 0 none;
color: var(--bs-dark);
position: relative;
}
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link:hover {
/*outline: 1px solid rgb(0 0 0 / 10%);*/
border-bottom: 1px solid var(--bs-blue);
padding-bottom: calc( 0.5rem - 1px);
color: var(--bs-blue);
z-index: 9;
}
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
background-color: #FFF;
border-bottom: 2px solid var(--bs-blue);
padding-bottom: calc( 0.5rem - 1px);
}
.dropdown-menu-macos {
padding: .5rem;
border-radius: .5rem;
}
.dropdown-menu-macos .dropdown-item {
border-radius: .25rem;
}
table.gridview {
}
table.gridview .thead {
}
table.gridview .thead a {
text-decoration: none;
}
table.gridview .thead a:hover {
text-decoration: underline;
text-underline-offset: 2px;
}
table.gridview tr:last-of-type:hover,
table.gridview tr:last-of-type:hover td {
--bs-table-accent-bg: var(--bs-white);
}
table.gridview td input[type=checkbox] {
border-radius: 0.25em;
width: 1em;
height: 1em;
border: 1px solid rgba(0,0,0,.25);
}
/*------------ theme: win11 ------------*/
[data-search-control] .form-control[readonly] {
background-color:#FFF;
}
/*--vuetify fix--*/
.v-application--wrap {
min-height: auto !important;
}
html {
overflow-x: auto !important;
overflow-y: auto !important;
}
.v-application .primary {
background-color: #1976d2 !important;
border-color: #1976d2 !important;
}
.readonly {
pointer-events: none;
}
.text-white-space-pre{
white-space:pre;
}
@@ -0,0 +1,703 @@
.v-application a {
color: #1976d2;
}
.v-application .primary {
background-color: #1976d2 !important;
border-color: #1976d2 !important;
}
.v-application .primary--text {
color: #1976d2 !important;
caret-color: #1976d2 !important;
}
.v-application .primary.lighten-5 {
background-color: #c7fdff !important;
border-color: #c7fdff !important;
}
.v-application .primary--text.text--lighten-5 {
color: #c7fdff !important;
caret-color: #c7fdff !important;
}
.v-application .primary.lighten-4 {
background-color: #a8e0ff !important;
border-color: #a8e0ff !important;
}
.v-application .primary--text.text--lighten-4 {
color: #a8e0ff !important;
caret-color: #a8e0ff !important;
}
.v-application .primary.lighten-3 {
background-color: #8ac5ff !important;
border-color: #8ac5ff !important;
}
.v-application .primary--text.text--lighten-3 {
color: #8ac5ff !important;
caret-color: #8ac5ff !important;
}
.v-application .primary.lighten-2 {
background-color: #6aaaff !important;
border-color: #6aaaff !important;
}
.v-application .primary--text.text--lighten-2 {
color: #6aaaff !important;
caret-color: #6aaaff !important;
}
.v-application .primary.lighten-1 {
background-color: #488fef !important;
border-color: #488fef !important;
}
.v-application .primary--text.text--lighten-1 {
color: #488fef !important;
caret-color: #488fef !important;
}
.v-application .primary.darken-1 {
background-color: #005eb6 !important;
border-color: #005eb6 !important;
}
.v-application .primary--text.text--darken-1 {
color: #005eb6 !important;
caret-color: #005eb6 !important;
}
.v-application .primary.darken-2 {
background-color: #00479b !important;
border-color: #00479b !important;
}
.v-application .primary--text.text--darken-2 {
color: #00479b !important;
caret-color: #00479b !important;
}
.v-application .primary.darken-3 {
background-color: #003180 !important;
border-color: #003180 !important;
}
.v-application .primary--text.text--darken-3 {
color: #003180 !important;
caret-color: #003180 !important;
}
.v-application .primary.darken-4 {
background-color: #001e67 !important;
border-color: #001e67 !important;
}
.v-application .primary--text.text--darken-4 {
color: #001e67 !important;
caret-color: #001e67 !important;
}
.v-application .secondary {
background-color: #424242 !important;
border-color: #424242 !important;
}
.v-application .secondary--text {
color: #424242 !important;
caret-color: #424242 !important;
}
.v-application .secondary.lighten-5 {
background-color: #c1c1c1 !important;
border-color: #c1c1c1 !important;
}
.v-application .secondary--text.text--lighten-5 {
color: #c1c1c1 !important;
caret-color: #c1c1c1 !important;
}
.v-application .secondary.lighten-4 {
background-color: #a6a6a6 !important;
border-color: #a6a6a6 !important;
}
.v-application .secondary--text.text--lighten-4 {
color: #a6a6a6 !important;
caret-color: #a6a6a6 !important;
}
.v-application .secondary.lighten-3 {
background-color: #8b8b8b !important;
border-color: #8b8b8b !important;
}
.v-application .secondary--text.text--lighten-3 {
color: #8b8b8b !important;
caret-color: #8b8b8b !important;
}
.v-application .secondary.lighten-2 {
background-color: #727272 !important;
border-color: #727272 !important;
}
.v-application .secondary--text.text--lighten-2 {
color: #727272 !important;
caret-color: #727272 !important;
}
.v-application .secondary.lighten-1 {
background-color: #595959 !important;
border-color: #595959 !important;
}
.v-application .secondary--text.text--lighten-1 {
color: #595959 !important;
caret-color: #595959 !important;
}
.v-application .secondary.darken-1 {
background-color: #2c2c2c !important;
border-color: #2c2c2c !important;
}
.v-application .secondary--text.text--darken-1 {
color: #2c2c2c !important;
caret-color: #2c2c2c !important;
}
.v-application .secondary.darken-2 {
background-color: #171717 !important;
border-color: #171717 !important;
}
.v-application .secondary--text.text--darken-2 {
color: #171717 !important;
caret-color: #171717 !important;
}
.v-application .secondary.darken-3 {
background-color: #000000 !important;
border-color: #000000 !important;
}
.v-application .secondary--text.text--darken-3 {
color: #000000 !important;
caret-color: #000000 !important;
}
.v-application .secondary.darken-4 {
background-color: #000000 !important;
border-color: #000000 !important;
}
.v-application .secondary--text.text--darken-4 {
color: #000000 !important;
caret-color: #000000 !important;
}
.v-application .accent {
background-color: #82b1ff !important;
border-color: #82b1ff !important;
}
.v-application .accent--text {
color: #82b1ff !important;
caret-color: #82b1ff !important;
}
.v-application .accent.lighten-5 {
background-color: #ffffff !important;
border-color: #ffffff !important;
}
.v-application .accent--text.text--lighten-5 {
color: #ffffff !important;
caret-color: #ffffff !important;
}
.v-application .accent.lighten-4 {
background-color: #f8ffff !important;
border-color: #f8ffff !important;
}
.v-application .accent--text.text--lighten-4 {
color: #f8ffff !important;
caret-color: #f8ffff !important;
}
.v-application .accent.lighten-3 {
background-color: #daffff !important;
border-color: #daffff !important;
}
.v-application .accent--text.text--lighten-3 {
color: #daffff !important;
caret-color: #daffff !important;
}
.v-application .accent.lighten-2 {
background-color: #bce8ff !important;
border-color: #bce8ff !important;
}
.v-application .accent--text.text--lighten-2 {
color: #bce8ff !important;
caret-color: #bce8ff !important;
}
.v-application .accent.lighten-1 {
background-color: #9fccff !important;
border-color: #9fccff !important;
}
.v-application .accent--text.text--lighten-1 {
color: #9fccff !important;
caret-color: #9fccff !important;
}
.v-application .accent.darken-1 {
background-color: #6596e2 !important;
border-color: #6596e2 !important;
}
.v-application .accent--text.text--darken-1 {
color: #6596e2 !important;
caret-color: #6596e2 !important;
}
.v-application .accent.darken-2 {
background-color: #467dc6 !important;
border-color: #467dc6 !important;
}
.v-application .accent--text.text--darken-2 {
color: #467dc6 !important;
caret-color: #467dc6 !important;
}
.v-application .accent.darken-3 {
background-color: #2364aa !important;
border-color: #2364aa !important;
}
.v-application .accent--text.text--darken-3 {
color: #2364aa !important;
caret-color: #2364aa !important;
}
.v-application .accent.darken-4 {
background-color: #004c90 !important;
border-color: #004c90 !important;
}
.v-application .accent--text.text--darken-4 {
color: #004c90 !important;
caret-color: #004c90 !important;
}
.v-application .error {
background-color: #ff5252 !important;
border-color: #ff5252 !important;
}
.v-application .error--text {
color: #ff5252 !important;
caret-color: #ff5252 !important;
}
.v-application .error.lighten-5 {
background-color: #ffe4d5 !important;
border-color: #ffe4d5 !important;
}
.v-application .error--text.text--lighten-5 {
color: #ffe4d5 !important;
caret-color: #ffe4d5 !important;
}
.v-application .error.lighten-4 {
background-color: #ffc6b9 !important;
border-color: #ffc6b9 !important;
}
.v-application .error--text.text--lighten-4 {
color: #ffc6b9 !important;
caret-color: #ffc6b9 !important;
}
.v-application .error.lighten-3 {
background-color: #ffa99e !important;
border-color: #ffa99e !important;
}
.v-application .error--text.text--lighten-3 {
color: #ffa99e !important;
caret-color: #ffa99e !important;
}
.v-application .error.lighten-2 {
background-color: #ff8c84 !important;
border-color: #ff8c84 !important;
}
.v-application .error--text.text--lighten-2 {
color: #ff8c84 !important;
caret-color: #ff8c84 !important;
}
.v-application .error.lighten-1 {
background-color: #ff6f6a !important;
border-color: #ff6f6a !important;
}
.v-application .error--text.text--lighten-1 {
color: #ff6f6a !important;
caret-color: #ff6f6a !important;
}
.v-application .error.darken-1 {
background-color: #df323b !important;
border-color: #df323b !important;
}
.v-application .error--text.text--darken-1 {
color: #df323b !important;
caret-color: #df323b !important;
}
.v-application .error.darken-2 {
background-color: #bf0025 !important;
border-color: #bf0025 !important;
}
.v-application .error--text.text--darken-2 {
color: #bf0025 !important;
caret-color: #bf0025 !important;
}
.v-application .error.darken-3 {
background-color: #9f0010 !important;
border-color: #9f0010 !important;
}
.v-application .error--text.text--darken-3 {
color: #9f0010 !important;
caret-color: #9f0010 !important;
}
.v-application .error.darken-4 {
background-color: #800000 !important;
border-color: #800000 !important;
}
.v-application .error--text.text--darken-4 {
color: #800000 !important;
caret-color: #800000 !important;
}
.v-application .info {
background-color: #2196f3 !important;
border-color: #2196f3 !important;
}
.v-application .info--text {
color: #2196f3 !important;
caret-color: #2196f3 !important;
}
.v-application .info.lighten-5 {
background-color: #d4ffff !important;
border-color: #d4ffff !important;
}
.v-application .info--text.text--lighten-5 {
color: #d4ffff !important;
caret-color: #d4ffff !important;
}
.v-application .info.lighten-4 {
background-color: #b5ffff !important;
border-color: #b5ffff !important;
}
.v-application .info--text.text--lighten-4 {
color: #b5ffff !important;
caret-color: #b5ffff !important;
}
.v-application .info.lighten-3 {
background-color: #95e8ff !important;
border-color: #95e8ff !important;
}
.v-application .info--text.text--lighten-3 {
color: #95e8ff !important;
caret-color: #95e8ff !important;
}
.v-application .info.lighten-2 {
background-color: #75ccff !important;
border-color: #75ccff !important;
}
.v-application .info--text.text--lighten-2 {
color: #75ccff !important;
caret-color: #75ccff !important;
}
.v-application .info.lighten-1 {
background-color: #51b0ff !important;
border-color: #51b0ff !important;
}
.v-application .info--text.text--lighten-1 {
color: #51b0ff !important;
caret-color: #51b0ff !important;
}
.v-application .info.darken-1 {
background-color: #007cd6 !important;
border-color: #007cd6 !important;
}
.v-application .info--text.text--darken-1 {
color: #007cd6 !important;
caret-color: #007cd6 !important;
}
.v-application .info.darken-2 {
background-color: #0064ba !important;
border-color: #0064ba !important;
}
.v-application .info--text.text--darken-2 {
color: #0064ba !important;
caret-color: #0064ba !important;
}
.v-application .info.darken-3 {
background-color: #004d9f !important;
border-color: #004d9f !important;
}
.v-application .info--text.text--darken-3 {
color: #004d9f !important;
caret-color: #004d9f !important;
}
.v-application .info.darken-4 {
background-color: #003784 !important;
border-color: #003784 !important;
}
.v-application .info--text.text--darken-4 {
color: #003784 !important;
caret-color: #003784 !important;
}
.v-application .success {
background-color: #4caf50 !important;
border-color: #4caf50 !important;
}
.v-application .success--text {
color: #4caf50 !important;
caret-color: #4caf50 !important;
}
.v-application .success.lighten-5 {
background-color: #dcffd6 !important;
border-color: #dcffd6 !important;
}
.v-application .success--text.text--lighten-5 {
color: #dcffd6 !important;
caret-color: #dcffd6 !important;
}
.v-application .success.lighten-4 {
background-color: #beffba !important;
border-color: #beffba !important;
}
.v-application .success--text.text--lighten-4 {
color: #beffba !important;
caret-color: #beffba !important;
}
.v-application .success.lighten-3 {
background-color: #a2ff9e !important;
border-color: #a2ff9e !important;
}
.v-application .success--text.text--lighten-3 {
color: #a2ff9e !important;
caret-color: #a2ff9e !important;
}
.v-application .success.lighten-2 {
background-color: #85e783 !important;
border-color: #85e783 !important;
}
.v-application .success--text.text--lighten-2 {
color: #85e783 !important;
caret-color: #85e783 !important;
}
.v-application .success.lighten-1 {
background-color: #69cb69 !important;
border-color: #69cb69 !important;
}
.v-application .success--text.text--lighten-1 {
color: #69cb69 !important;
caret-color: #69cb69 !important;
}
.v-application .success.darken-1 {
background-color: #2d9437 !important;
border-color: #2d9437 !important;
}
.v-application .success--text.text--darken-1 {
color: #2d9437 !important;
caret-color: #2d9437 !important;
}
.v-application .success.darken-2 {
background-color: #00791e !important;
border-color: #00791e !important;
}
.v-application .success--text.text--darken-2 {
color: #00791e !important;
caret-color: #00791e !important;
}
.v-application .success.darken-3 {
background-color: #006000 !important;
border-color: #006000 !important;
}
.v-application .success--text.text--darken-3 {
color: #006000 !important;
caret-color: #006000 !important;
}
.v-application .success.darken-4 {
background-color: #004700 !important;
border-color: #004700 !important;
}
.v-application .success--text.text--darken-4 {
color: #004700 !important;
caret-color: #004700 !important;
}
.v-application .warning {
background-color: #fb8c00 !important;
border-color: #fb8c00 !important;
}
.v-application .warning--text {
color: #fb8c00 !important;
caret-color: #fb8c00 !important;
}
.v-application .warning.lighten-5 {
background-color: #ffff9e !important;
border-color: #ffff9e !important;
}
.v-application .warning--text.text--lighten-5 {
color: #ffff9e !important;
caret-color: #ffff9e !important;
}
.v-application .warning.lighten-4 {
background-color: #fffb82 !important;
border-color: #fffb82 !important;
}
.v-application .warning--text.text--lighten-4 {
color: #fffb82 !important;
caret-color: #fffb82 !important;
}
.v-application .warning.lighten-3 {
background-color: #ffdf67 !important;
border-color: #ffdf67 !important;
}
.v-application .warning--text.text--lighten-3 {
color: #ffdf67 !important;
caret-color: #ffdf67 !important;
}
.v-application .warning.lighten-2 {
background-color: #ffc24b !important;
border-color: #ffc24b !important;
}
.v-application .warning--text.text--lighten-2 {
color: #ffc24b !important;
caret-color: #ffc24b !important;
}
.v-application .warning.lighten-1 {
background-color: #ffa72d !important;
border-color: #ffa72d !important;
}
.v-application .warning--text.text--lighten-1 {
color: #ffa72d !important;
caret-color: #ffa72d !important;
}
.v-application .warning.darken-1 {
background-color: #db7200 !important;
border-color: #db7200 !important;
}
.v-application .warning--text.text--darken-1 {
color: #db7200 !important;
caret-color: #db7200 !important;
}
.v-application .warning.darken-2 {
background-color: #bb5900 !important;
border-color: #bb5900 !important;
}
.v-application .warning--text.text--darken-2 {
color: #bb5900 !important;
caret-color: #bb5900 !important;
}
.v-application .warning.darken-3 {
background-color: #9d4000 !important;
border-color: #9d4000 !important;
}
.v-application .warning--text.text--darken-3 {
color: #9d4000 !important;
caret-color: #9d4000 !important;
}
.v-application .warning.darken-4 {
background-color: #802700 !important;
border-color: #802700 !important;
}
.v-application .warning--text.text--darken-4 {
color: #802700 !important;
caret-color: #802700 !important;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 508 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 129 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 462 KiB

+300
View File
@@ -0,0 +1,300 @@
// navigation and breadcrumb
window.addEventListener('DOMContentLoaded', event => {
// Toggle the side navigation
const sidebarToggle = document.body.querySelector('#sidebarToggle');
if (sidebarToggle) {
// Uncomment Below to persist sidebar toggle between refreshes
//if (localStorage.getItem('sb|sidebar-toggle') === 'true') {
// document.body.classList.toggle('sb-sidenav-toggled');
//}
sidebarToggle.addEventListener('click', event => {
event.preventDefault();
document.body.classList.toggle('sb-sidenav-toggled');
localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
});
}
});
$(document).ready(function () {
// navigation and breadcrumb
//$(".leaf-node").parents("tr").find("img").hide();
var breadcrumb_last = $(".breadcrumb li").last().text().trim();
var item = $("#sideNav_1 a.nav-link").filter((i, t) => {
//console.log($(t).text().trim(), breadcrumb_last, $(t).text().trim() == breadcrumb_last);
return $(t).text().trim() == breadcrumb_last;
});
var panel = item.parents(".collapse").eq(0);
item.addClass("active");
panel.toggle();
panel.prev().addClass("active");
$("a[data-bs-target='#offcanvasRight']").click(function (e) {
let t = $(this).attr("href");
console.log("right:", this, t);
$("#offcanvasRight .offcanvas-body>div").hide();
$(t).show();
$("#offcanvasRightLabel").text($(t).data("title"));
});
let show_search = !!$("#offcanvasRight .offcanvas-body #search_panel").length;
$("#search_btn").toggle(show_search);
// search-control
$("[data-search-control]").each((i, t) => {
console.log("[data-search-control]", i, t,
$(t).children("button").eq(0),
$(t).children("[type=hidden]").val(),
$(t).children(".search-text").attr("placeholder"),
$(t).children(".search-text").val(),
);
});
});
// Sweet Alert
function msgbox(html, icon = '', url = '') {
Swal.fire({
icon: icon,
html: html,
confirmButtonText: '關閉',
onClose: () => {
if (url != '') {
window.location = url;
}
}
});
}
function msgtop(html, icon = 'success') {
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
heightAuto: false,
timerProgressBar: true,
onOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
Toast.fire({
icon: icon,
html: '<div class="swal2-toast-cus">' + html + '</div>'
})
}
var mctmp = '0';
function msgconfirm(html, btn, icon = 'question') {
if (mctmp == '0') {
Swal.fire({
html: html,
icon: icon,
showCancelButton: true,
confirmButtonText: '<i class="mdi mdi-check"></i> 確定',
cancelButtonText: '<i class="mdi mdi-close"></i> 取消'
}).then((result) => {
if (result.value) {
mctmp = '1';
if ($(btn)[0].hasAttribute('href')) {
var href = $(btn).attr('href');
window.location.href = href;
} else {
$(btn).click();
}
}
})
mctmp = '0';
return false;
} else {
mctmp = '0';
return true;
}
}
function clearObjProps(obj) {
for (const prop of Object.getOwnPropertyNames(obj)) {
obj[prop] = null;
}
}
//---------------------------------列印---------------------------------------------------
function PrintTagData(id) {
if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0) {
window.print();
} else {
var Item = document.getElementById(id);
var printdetail = window.open("", "TextareaDetail");
printdetail.document.open();
printdetail.document.write("<HTML><head><link href=\"../../module/js/css/adminroot.css\" rel=\"stylesheet\" type=\"text/css\">");
printdetail.document.write("<script type =\"text/javascript\">");
printdetail.document.write("function mouseover(obj,color_word){obj.style.backgroundColor = color_word;}");
printdetail.document.write("function mouseout(obj,color_word){obj.style.backgroundColor = color_word;}");
printdetail.document.write("<\/script>");
printdetail.document.write("</head>");
printdetail.document.write("<BODY onload=\"window.print();\"><div style=\"width:720px\">");
printdetail.document.write(Item.outerHTML);
printdetail.document.write("</div></BODY></HTML>");
printdetail.document.close();
}
}
function PrintTagRWD(id) {
if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0) {
window.print();
} else {
var Item = document.getElementById(id);
var printdetail = window.open("", "TextareaDetail");
printdetail.document.open();
printdetail.document.write("<HTML><head>\n");
printdetail.document.write('<link href="../../App_Script/bootstrap3/css/bootstrap.css" rel="stylesheet" />\n');
printdetail.document.write('<link href="../../App_Script/bootstrap_datepicker/css/datepicker.css" rel="stylesheet" />\n');
printdetail.document.write('<link href="../../admin/skin/css/style.css" rel="stylesheet" media="screen" />\n');
printdetail.document.write('<link href="../../admin/skin/css/print.css" rel="stylesheet" media="print" />\n');
printdetail.document.write('<!--[if lt IE 9]>\n');
printdetail.document.write('<link href="../../admin/skin/css/ie8-and-down.css" rel="stylesheet" type="text/css" />\n');
printdetail.document.write('<![endif]-->\n');
printdetail.document.write("<style type=\"text/css\">.hidden-print{display:none;}</style>");
printdetail.document.write("</head>");
printdetail.document.write("<BODY onload=\"window.print();\">");
printdetail.document.write(Item.outerHTML);
printdetail.document.write("</BODY></HTML>");
printdetail.document.close();
}
}
//---------------------------------checkbox全選用---------------------------------------------------
function Check(parentChk, ChildId) {
var oElements = document.getElementsByTagName("INPUT");
var bIsChecked = parentChk.checked;
for (i = 0; i < oElements.length; i++) {
if (IsCheckBox(oElements[i]) &&
IsMatch(oElements[i].id, ChildId)) {
oElements[i].checked = bIsChecked;
}
}
}
function IsMatch(id, ChildId) {
var sPattern = '^ctl00_ContentPlaceHolder1_Repeater1.*' + ChildId + '$';
var oRegExp = new RegExp(sPattern);
if (oRegExp.exec(id))
return true;
else
return false;
}
function IsCheckBox(chk) {
if (chk.type == 'checkbox') return true;
else return false;
}
function checkListAll(chk) {
$('.listCheck input').each(function () {
this.checked = chk;
});
}
function checkAll2(chk, num) {
$('#root_' + num).show();
$('#root_' + num + ' input:checkbox').each(function () {
this.checked = chk;
});
}
// Vuetify
let vuetify_options = {
theme: { disable: true },
lang: {
locales: {
zhHant: {
badge: '徽章',
close: '關閉',
dataIterator: {
noResultsText: '沒有符合條件的結果',
loadingText: '讀取中...',
},
dataTable: {
itemsPerPageText: '每頁列數:',
ariaLabel: {
sortDescending: ':降序排列。',
sortAscending: ':升序排列。',
sortNone: '無排序方式。點擊以升序排列。',
activateNone: '點擊以移除排序方式。',
activateDescending: '點擊以降序排列。',
activateAscending: '點擊以移除排序方式。',
},
sortBy: '排序方式',
},
dataFooter: {
itemsPerPageText: '每頁項目:',
itemsPerPageAll: '全部',
nextPage: '下一頁',
prevPage: '上一頁',
firstPage: '第一頁',
lastPage: '最後頁',
pageText: '{2} 項中的 {0}~{1} 項',
},
datePicker: {
itemsSelected: '已選擇 {0}',
nextMonthAriaLabel: '下個月',
nextYearAriaLabel: '明年',
prevMonthAriaLabel: '上個月',
prevYearAriaLabel: '去年',
},
noDataText: '沒有資料',
carousel: {
prev: '上一張',
next: '下一張',
ariaLabel: {
delimiter: '輪播圖 {0} / {1}',
},
},
calendar: {
moreEvents: '還有其他 {0} 項',
},
fileInput: {
counter: '{0} 個檔案',
counterSize: '{0} 個檔案(共 {1}',
},
timePicker: {
am: 'AM',
pm: 'PM',
},
pagination: {
ariaLabel: {
wrapper: '分頁導覽',
next: '下一頁',
previous: '上一頁',
page: '到頁面 {0}',
currentPage: '當前頁 {0}',
},
},
rating: {
ariaLabel: {
icon: '評分 {0} / {1}',
},
},
}
},
current: 'zhHant',
},
//theme: { disable: false},
};
@@ -0,0 +1,11 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="footer.ascx.cs" Inherits="admin_Templates_TBS5ADM001_uc_footer" %>
<footer class="py-4 bg-light mt-auto">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted">Copyright &copy; 17168ERP</div>
<div>
<a href="#">17168ERP</a>
</div>
</div>
</div>
</footer>
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_Templates_TBS5ADM001_uc_footer : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
+112
View File
@@ -0,0 +1,112 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="menu.ascx.cs" Inherits="admin_Templates_TBS5ADM001_uc_sideNav" %>
<nav class="sb-sidenav accordion sb-sidenav-light pt-2" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav" id="sideNav_1">
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<a class="nav-link collapsed num<%#Eval("num") %>" href="#"
data-bs-toggle="collapse" data-bs-target="#navitem_<%#Eval("num") %>" aria-expanded="false" aria-controls="navitem_<%#Eval("num") %>">
<div class="sb-nav-link-icon"><i class="mdi mdi-folder"></i></div>
<%#Eval("title") %>
<div class="sb-sidenav-collapse-arrow"><i class="mdi mdi-chevron-down"></i></div>
</a>
<div class="collapse" id="navitem_<%#Eval("num") %>" aria-labelledby="headingOne"
data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav">
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
<ItemTemplate>
<a class="nav-link" href="<%#ResolveUrl(ValString(Eval("url"))) %>"
target="<%#(ValString(Eval("target"))=="B"?"_blank":"_self") %>">
<%#Eval("title") %></a>
</ItemTemplate>
</asp:Repeater>
</nav>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
<div class="nav d-none">
<div class="sb-sidenav-menu-heading">Core</div>
<a class="nav-link" href="index.html">
<div class="sb-nav-link-icon"><i class="mdi mdi-gauge"></i></div>
Dashboard
</a>
<div class="sb-sidenav-menu-heading">Interface</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapseLayouts" aria-expanded="false" aria-controls="collapseLayouts">
<div class="sb-nav-link-icon"><i class="mdi mdi-television-guide"></i></div>
Layouts
<div class="sb-sidenav-collapse-arrow"><i class="mdi mdi-chevron-down"></i></div>
</a>
<div class="collapse" id="collapseLayouts" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="layout-static.html">Static Navigation</a>
<a class="nav-link" href="layout-sidenav-light.html">Light Sidenav</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapsePages" aria-expanded="false" aria-controls="collapsePages">
<div class="sb-nav-link-icon"><i class="mdi mdi-book-open-blank-variant"></i></div>
Pages
<div class="sb-sidenav-collapse-arrow"><i class="mdi mdi-chevron-down"></i></div>
</a>
<div class="collapse" id="collapsePages" aria-labelledby="headingTwo" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav accordion" id="sidenavAccordionPages">
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseAuth" aria-expanded="false" aria-controls="pagesCollapseAuth">Authentication
<div class="sb-sidenav-collapse-arrow"><i class="mdi mdi-chevron-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseAuth" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="login.html">Login</a>
<a class="nav-link" href="register.html">Register</a>
<a class="nav-link" href="password.html">Forgot Password</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseError" aria-expanded="false" aria-controls="pagesCollapseError">Error
<div class="sb-sidenav-collapse-arrow"><i class="mdi mdi-chevron-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseError" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
<hr />
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
</nav>
</div>
</nav>
</div>
<div class="sb-sidenav-menu-heading">Addons</div>
<a class="nav-link" href="charts.html">
<div class="sb-nav-link-icon"><i class="mdi mdi-chart-areaspline-variant"></i></div>
Charts
</a>
<a class="nav-link" href="tables.html">
<div class="sb-nav-link-icon"><i class="mdi mdi-table"></i></div>
Tables
</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">名稱:</div>
17168ERP
</div>
</nav>
<asp:HiddenField ID="rtmp" runat="server" />
<asp:HiddenField ID="HiddenField1" runat="server" />
<asp:Literal ID="ExpandMenu" runat="server"></asp:Literal>
@@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
public partial class admin_Templates_TBS5ADM001_uc_sideNav :
MyWeb.web_uc, MyWeb.config.IMenu
{
string PageUrl = ""; //目前後台的路徑
string Power = ""; //帳號權限
bool isDesigner = false;
List<string> nItem = new List<string>();
int setNav = 0;
DataTable menuDt = new DataTable();
private string item_collapsed { get; set; }
private string item_active { get; set; }
public void Data(DataTable dt)
{
menuDt = dt;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyWeb.admin admin = new MyWeb.admin();
if (admin.isLoign() && HttpContext.Current.Request.RawUrl.ToLower().IndexOf("admin/index.aspx") == -1)
{
Power = admin.info.power;
if (Left(Power, 1) == ",") { Power = Right(Power, Power.Length - 1); }
if (Right(Power, 1) == ",") { Power = Left(Power, Power.Length - 1); }
string[] UrlTmp = Request.Url.AbsolutePath.ToLower().Split('/');
PageUrl = UrlTmp[UrlTmp.Length - 2] + "/" + UrlTmp[UrlTmp.Length - 1];
if (admin.info.u_id == "Designer" && admin.info.group == "EZ") { isDesigner = true; }
Repeater1.DataSource = MenuRows();
Repeater1.DataBind();
((MyWeb.config.MenuNav)Page.Master.FindControl("nav")).InitNav(nItem);
}
}
}
protected DataTable MenuRows(int root = 0)
{
DataTable dt = new DataTable();
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
if (!isDesigner)
{
//非設計師模式檢查權限
if (!isStrNull(Power))
{
sqlCmd.CommandText = "SELECT * FROM [item] Where root=? and num in (" + Power + ") order by range";
sqlCmd.Parameters.Add(new OleDbParameter("root", root));
dt = sql.dataTable(sqlCmd);
}
}
else
{
sqlCmd.CommandText = "SELECT * FROM [item] Where root=? order by range";
sqlCmd.Parameters.Add(new OleDbParameter("root", root));
dt = sql.dataTable(sqlCmd);
}
}
catch (Exception ex)
{
//Response.Write(ex.Message);
}
finally
{
sqlConn.Close(); sqlConn.Dispose();
}
return dt;
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
try
{
DataRowView row = (DataRowView)e.Item.DataItem;
HiddenField1.Value = ValString(row["num"]);
rtmp.Value = ValString(row["title"]);
if (menuDt.Rows.Count > 0)
{
DataTable dt = menuDt.Copy();
for (int i = dt.Rows.Count - 1; i >= 0; i--) {
if (dt.Rows[i]["root"].ToString() != HiddenField1.Value) { dt.Rows.Remove(dt.Rows[i]); }
}
if (dt.Rows.Count > 0)
{
Repeater Repeater2 = (Repeater)e.Item.FindControl("Repeater2");
Repeater2.DataSource = dt;
Repeater2.DataBind();
Repeater2.DataBind();
dt.Dispose();
}
else
{
}
}
else
{
}
}
catch(Exception ex)
{
}
}
protected void Repeater2_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DataRowView row = (DataRowView)e.Item.DataItem;
if (ValString(row["url"]).ToLower().IndexOf(PageUrl) > -1)
{
setNav++;
}
else if (ValString(row["other_url"]).ToLower().IndexOf(PageUrl) > -1)
{
setNav++;
}
if (setNav == 1)
{
setNav++;
ExpandMenu.Text = "<input type=\"hidden\" id=\"ExpandMenuNum\" value=\"" + HiddenField1.Value + "\" />";
nItem.Add(rtmp.Value);
if ((PageUrl.IndexOf("reg.aspx") > -1 || PageUrl.IndexOf("edit.aspx") > -1) && !isStrNull(Request["num"]))
{
nItem.Add(ValString(row["title"]).Replace("登錄", "修改").Replace("查詢", "修改").Replace("新增", "修改"));
}
else
{
nItem.Add(ValString(row["title"]));
}
}
}
}
@@ -0,0 +1,69 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="nav.ascx.cs" Inherits="admin_Templates_TBS5ADM001_uc_nav" %>
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark ps-1 ps-md-2">
<!-- Sidebar Toggle-->
<button class="btn btn-link btn-sm order-0 me-0 bg-white bg-opacity-10 rounded-circle" id="sidebarToggle" href="#!">
<i class="mdi mdi-menu"></i>
</button>
<!-- Navbar Brand-->
<asp:HyperLink ID="pageTitle" runat="server" CssClass="navbar-brand ps-sm-2 me-2"></asp:HyperLink>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="<%=ResolveUrl("~/admin/index2.aspx") %>">
<i class="mdi mdi-home"></i></a>
</li>
<asp:Repeater ID="breadCrumb" runat="server" ItemType="System.String" >
<ItemTemplate>
<li class="breadcrumb-item d-none d-lg-inline-block"><%# Item %></li>
</ItemTemplate>
</asp:Repeater>
</ol>
</nav>
<!-- Navbar Search-->
<div class="d-none d-md-none form-inline ms-auto me-0 me-md-3 my-2 my-md-0">
<div class="input-group rounded-pill overflow-hidden">
<input class="form-control" type="text" placeholder="搜尋..." aria-label="搜尋..." aria-describedby="btnNavbarSearch" />
<button class="btn btn-primary" id="btnNavbarSearch" type="button"><i class="mdi mdi-magnify"></i></button>
</div>
</div>
<!-- Navbar-->
<ul class="navbar-nav ms-auto ms-md-auto me-3 me-lg-4">
<li class="nav-item me-2" id="search_btn">
<a href="#search_panel" class="btn btn-outline-light rounded-pill" title="查詢"
data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">
<i class="mdi mdi-magnify"></i>查詢
</a>
</li>
<li class="nav-item dropdown bg-light bg-opacity-25 px-1 rounded-pill">
<a class="nav-link dropdown-toggle text-white" id="navbarDropdown" href="#"
role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="mdi mdi-account"></i>
<span class="d-none d-md-inline"> <%=admin.info.u_id %></span>
</a>
<ul class="dropdown-menu dropdown-menu-macos dropdown-menu-end" aria-labelledby="navbarDropdown">
<li class="d-md-none dropdown-item text-muted">
<i class="mdi mdi-card-account-details-outline text-primary me-2"></i> <%=admin.info.u_id %></li>
<li class="d-md-none"><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item text-secondary" href="#!">
<i class="mdi mdi-cog text-primary me-2"></i> 設定</a></li>
<li><a class="dropdown-item text-secondary" href="#!">
<i class="mdi mdi-bell-outline text-primary me-2"></i> 通知</a></li>
<li><a class="dropdown-item text-secondary" href="#!">
<i class="mdi mdi-help-circle-outline text-primary me-2"></i>說明</a></li>
<li id="attenAddLi" runat="server">
<asp:LinkButton ID="attenAdd" runat="server" CausesValidation="false" OnClick="attenAdd_Click" CssClass="dropdown-item text-secondary">
<i class="mdi mdi-account-check text-primary me-2"></i> 上班</asp:LinkButton>
</li>
<li id="attenOutLi" runat="server">
<asp:LinkButton ID="attenOut" runat="server" CausesValidation="false" OnClick="attenOut_Click" CssClass="dropdown-item text-secondary">
<i class="mdi mdi-account-arrow-down text-primary me-2"></i> 下班</asp:LinkButton>
</li>
<li><hr class="dropdown-divider" /></li>
<li>
<asp:LinkButton ID="logout" OnClick="logout_Click" runat="server" CausesValidation="false" CssClass="dropdown-item text-secondary">
<i class="mdi mdi-power text-primary me-2"></i> 登出</asp:LinkButton>
</li>
</ul>
</li>
</ul>
</nav>
@@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_Templates_TBS5ADM001_uc_nav : MyWeb.web_uc, MyWeb.config.MenuNav
{
public MyWeb.admin admin = new MyWeb.admin();
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
admin.isLoign();
MyWeb.master m = (MyWeb.master)Page.Master;
pageTitle.Text = m.company.name;
pageTitle.NavigateUrl = "~/admin/index2.aspx";
if (!IsPostBack)
{
//設計師模式不可打卡
if(admin.info.u_id == "Designer")
{
attenAddLi.Visible = false;
attenOutLi.Visible = false;
}
//判斷考勤IP
List<string> IPs = new List<string>();
string[] ips = System.Configuration.ConfigurationManager.AppSettings["attendancesIP"].ToString().Split(',');
if (ips.Length > 0)
{
bool success = false;
for (int i = 0; i <= ips.Length - 1; i++)
IPs.Add(ips[i]);
string myip = MyWeb.ip.Get();
if (IPs.Count > 0)
foreach (string IP in IPs)
if (myip.IndexOf(IP) == 0)
success = true;
if (!success)
{
attenAddLi.Visible = false;
attenOutLi.Visible = false;
}
}
}
}
protected void logout_Click(object sender, EventArgs e)
{
admin.ClearInfo();
Response.Redirect("~/admin/index.aspx");
}
public void InitNav(List<string> nItem)
{
breadCrumb.DataSource = nItem;
breadCrumb.DataBind();
this.Page.Title = String.Join("-",nItem.ToArray());
}
#region
protected void attenAdd_Click(object sender, EventArgs e)
{
int hr = _db.members.Where(q => q.admin_num == admin.info.num).Select(q => q.num).FirstOrDefault(); //人員num
//檢查是否已打卡
var qry = _db.member_check.Where(q => q.mem_num == hr);
qry = qry.Where(q => q.check_type == (int)Model.member.attendances.type.Start);
qry = qry.Where(q => q.check_date == DateTime.Today);
Model.member_check member_check = qry.FirstOrDefault();
if (member_check != null)
{
//已打卡
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('重複打卡','" + MyWeb.function.msgIcon.warning + "')", true);
}
else
{
if (hr != 0)
{
member_check = new Model.member_check();
member_check.login_ip = Request.UserHostAddress;
member_check.login_type = (int)Model.member.attendances.login.Account;
member_check.mem_num = hr;
member_check.check_type = (int)Model.member.attendances.type.Start;
member_check.check_date = DateTime.Today;
member_check.check_time = TimeSpan.Parse(DateTime.Now.ToString("HH:mm"));
try
{
_db.member_check.Add(member_check);
_db.SaveChanges();
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('打卡成功','" + MyWeb.function.msgIcon.success + "')", true);
}
catch (Exception ex)
{
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('打卡失敗','" + MyWeb.function.msgIcon.error + "')", true);
}
}
else
{
//未建立系統帳號
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('人員資料請先綁定系統帳號','" + MyWeb.function.msgIcon.warning + "')", true);
}
}
}
#endregion
#region
protected void attenOut_Click(object sender, EventArgs e)
{
int hr = _db.members.Where(q => q.admin_num == admin.info.num).Select(q => q.num).FirstOrDefault(); //人員num
//檢查是否已打卡
var qry = _db.member_check.Where(q => q.mem_num == hr);
qry = qry.Where(q => q.check_type == (int)Model.member.attendances.type.GetOff);
qry = qry.Where(q => q.check_date == DateTime.Today);
Model.member_check member_check = qry.FirstOrDefault();
if (member_check != null)
{
//已打卡
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('重複打卡','" + MyWeb.function.msgIcon.warning + "')", true);
}
else
{
if (hr != 0)
{
member_check = new Model.member_check();
member_check.login_ip = Request.UserHostAddress;
member_check.login_type = (int)Model.member.attendances.login.Account;
member_check.mem_num = hr;
member_check.check_type = (int)Model.member.attendances.type.GetOff;
member_check.check_date = DateTime.Today;
member_check.check_time = TimeSpan.Parse(DateTime.Now.ToString("HH:mm"));
try
{
_db.member_check.Add(member_check);
_db.SaveChanges();
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('打卡成功','" + MyWeb.function.msgIcon.success + "')", true);
}
catch (Exception ex)
{
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('打卡失敗','" + MyWeb.function.msgIcon.error + "')", true);
}
}
else
{
//未建立系統帳號
ScriptManager.RegisterStartupScript(Page, GetType(), "JsStatus", "msgtop('人員資料請先綁定系統帳號','" + MyWeb.function.msgIcon.warning + "')", true);
}
}
}
#endregion
}
@@ -0,0 +1,247 @@
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="admin_Templates_Template003_MasterPage" %>
<%@ Register Src="~/admin/menu.ascx" TagPrefix="uc1" TagName="menu" %>
<%@ Register Src="~/admin/nav.ascx" TagPrefix="uc1" TagName="nav" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>後端管理</title>
<link href="<%=ResolveUrl("~/App_Script/bootstrap3/css/bootstrap.css") %>" rel="stylesheet" />
<link href="<%=ResolveUrl("~/App_Script/bootstrap_datepicker/css/datepicker.css") %>" rel="stylesheet" />
<link href="<%=ResolveUrl("~/admin/skin/ezweb-admin-icons/style.css") %>" rel="stylesheet" />
<link href="<%=ResolveUrl("~/admin/Templates/Template003/css/style.css") %>" rel="stylesheet" media="screen" />
<link href="<%=ResolveUrl("~/App_Script/custom-scrollbar-plugin/jquery.mCustomScrollbar.css") %>" rel="stylesheet" />
<link href="<%=ResolveUrl("~/App_Script/fontawesome/css/all.min.css") %>" rel="stylesheet" />
<!--[if lt IE 9]>
<link href="../skin/css/ie8-and-down.css" rel="stylesheet" type="text/css" />
<![endif]-->
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/js/jquery-3.5.1.min.js") %>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/js/admin.js") %>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/bootstrap3/js/bootstrap.js") %>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/bootstrap_datepicker/js/bootstrap-datepicker-tw.js") %>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/custom-scrollbar-plugin/jquery.mCustomScrollbar.js") %>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/App_Script/js/req.js") %>"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#goTop").click(function () {
$("html,body").animate({ scrollTop: 0 }, 800);
//$("html,body").animate({scrollTop:0},900,"easeOutBounce");
return false;
});
var side_height = $(window).height() - $('.header').height();
//$(".side1").css({ "min-height": side_height });
if ($(window).width() < 768) {
$(".main").attr({ "class": "main side_hide" });
} else {
$(".main").attr({ "class": "main" });
}
$(window).resize(function () {
if ($(window).width() < 768) {
$(".main").attr({ "class": "main side_hide" });
//$(".side1").css({ "height": side_height });
} else {
//$(".side1").css({ "height": side_height });
}
});
/*收合左側選單*/
$(".btn-side-toggle").click(function () {
$(".main").toggleClass("side_hide", 500);
});
/*左側選單項目收合功能*/
$("ul.collapsible_item").hide();
$("li.collapsible > a").click(function (e) {
e.preventDefault();
var cindex = $(this).index("li.collapsible > a");
var collapsibles = $("li.collapsible > a");
for (i = 0; i < collapsibles.length; i++) {
if ($(collapsibles[i]).hasClass("active") && i != cindex) {
$(collapsibles[i]).removeClass("active");
$(collapsibles[i]).parents("li.collapsible").find("ul.collapsible_item").slideUp();
$(collapsibles[i]).find("span").attr('class', 'glyphicon glyphicon-plus');
// break;
} else if (i == cindex) {
if ($(collapsibles[i]).find("span").attr('class') == 'glyphicon glyphicon-minus') {
$(collapsibles[i]).find("span").attr('class', 'glyphicon glyphicon-plus');
} else {
$(collapsibles[i]).find("span").attr('class', 'glyphicon glyphicon-minus');
}
}
}
$(this).parents("li.collapsible").find("ul.collapsible_item")
.slideToggle(400, function (e) {
$(".scroll-box").mCustomScrollbar("update");
});
$(this).toggleClass("active");
});
/*進階搜尋收合*/
$('.btn-search').click(function () {
if ($('.search_panel').css("display") == "none") {
$(this).html('<span class="glyphicon glyphicon-search"></span> 回列表頁');
} else {
$(this).html('<span class="glyphicon glyphicon-search"></span> 條件搜尋');
}
$('.search_panel').slideToggle();
$('#printArea').slideToggle();
});
/*日期選擇器*/
if ($(".datepicker").length > 0) {
$(".datepicker").datepicker().on('changeDate', function (e) {
$(this).datepicker('hide');
});
$('.datepicker').css("cursor", "pointer");
}
if ($('#ExpandMenuNum').length > 0) {
var num = $('#ExpandMenuNum').val();
$('li.collapsible > a.num' + num).siblings("ul.collapsible_item").show();
$('li.collapsible > a.num' + num).addClass("active");
$('li.collapsible > a.num' + num + ' span').attr('class', 'glyphicon glyphicon-minus');
}
});
$(document).ready(function () {
$(".scroll-box").mCustomScrollbar({
axis: "yx",
scrollInertia: 80
});
});
</script>
<%-- <script type="text/javascript" src="<%=ResolveUrl("~/App_Script/js/jquery-1.10.2.js") %>"></script>
<script type="text/javascript">
function msgbox(text) {
$.msgbox('<div style="min-width:200px;">' + text + '</div>');
}
</script>--%>
<script src="<%=ResolveUrl("~/App_Script/sweetalert2-9.10.9/dist/sweetalert2.min.js") %>"></script>
<link href="<%=ResolveUrl("~/App_Script/sweetalert2-9.10.9/dist/sweetalert2.min.css") %>" rel="stylesheet" />
<script>
function msgbox(html, icon = '', url = '') {
Swal.fire({
icon: icon,
html: html,
confirmButtonText: '關閉',
onClose: () => {
if (url != '') {
window.location = url;
}
}
});
}
function msgtop(html, icon = 'success') {
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
heightAuto: false,
timerProgressBar: true,
onOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
Toast.fire({
icon: icon,
html: '<div class="swal2-toast-cus">' + html + '</div>'
})
}
var mctmp = '0';
function msgconfirm(html, btn, icon = 'question') {
if (mctmp == '0') {
Swal.fire({
html: html,
icon: icon,
showCancelButton: true,
confirmButtonText: '<i class="fas fa-check"></i> 確定',
cancelButtonText: '<i class="fas fa-times"></i> 取消'
}).then((result) => {
if (result.value) {
mctmp = '1';
if ($(btn)[0].hasAttribute('href')) {
var href = $(btn).attr('href');
window.location.href = href;
} else {
$(btn).click();
}
}
})
mctmp = '0';
return false;
} else {
mctmp = '0';
return true;
}
}
</script>
<link href="<%=ResolveUrl("~/App_Script/css/expand.css") %>" rel="stylesheet" />
<asp:ContentPlaceHolder ID="page_header" runat="server">
</asp:ContentPlaceHolder>
</head>
<body class="<% =(isHome()?"home login":"")%>" id="Body">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div class="page-wrap">
<!-- Header -->
<div class="header hidden-print">
<div class="page-title login-center">
<h1><a><%=company.name %></a></h1>
</div>
</div>
<!-- /.header -->
<div class="main">
<div class="side1 hidden-print scroll-box">
<ul class="list-unstyled">
<%--<uc1:menu runat="server" ID="menu" />--%>
<uc1:menu runat="server" ID="menu" />
</ul>
</div>
<!-- /.side1 -->
<div class="content">
<div class="navigation hidden-login">
<button type="button" class="btn btn-side-toggle hidden-print">
<span class="sr-only">開合側選單</span>
<i class="fas fa-bars" style="font-size: 20px; color: #FFF"></i>
</button>
<%--<uc1:nav runat="server" ID="nav" />--%>
<uc1:nav runat="server" ID="nav" />
</div>
<!-- /.navbar -->
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
<!-- /.content -->
<div id="floating"></div>
</div>
<!-- /.main -->
<div class="footer">
</div>
<!-- /.footer -->
</div>
<!-- /.page-wrap -->
</form>
</body>
</html>
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_Templates_Template003_MasterPage : MyWeb.master
{
protected void Page_Load(object sender, EventArgs e)
{
MasterLoad();
}
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<xml id="cat_template" type="master">
<title>樣版3</title>
<description>
樣版3描述
</description>
<img id="thumb" src="~/admin/Templates/Template003/images/body_bg.jpg"/>
<assets>
<file id="control" href="~/admin/Templates/Template003/default.master"/>
</assets>
</xml>
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

+20
View File
@@ -0,0 +1,20 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="alert.ascx.cs" Inherits="admin__uc_alert" %>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="success" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="warning" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
<symbol id="danger" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
<div class="alert d-flex align-items-center mx-2" role="alert" id="alert" runat="server">
<svg width="24" height="24" role="img" aria-label="<%=Type%>:"><use xlink:href="#<%=Type%>"/></svg>
<div class="ms-2"><%=Text%></div>
</div>
+43
View File
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin__uc_alert : System.Web.UI.UserControl
{
//asp.net Framework 4.8 website 預設不支援 C#6功能替代方案
private alert_type? _Type = alert_type.info;
public alert_type? Type {
get { return _Type; }
set {
_Type = value;
ChangeStatus();
}
}
private string _Text;
public string Text {
get { return _Text; }
set {
_Text = value;
ChangeStatus();
}
}
private string init_class= "alert d-flex align-items-center mx-2";
protected void Page_Load(object sender, EventArgs e)
{
//init_class = alert.Attributes["class"];
ChangeStatus();
}
protected void ChangeStatus()
{
alert.Visible = !(Type == null || String.IsNullOrEmpty(Text));
alert.Attributes["class"] = init_class + " alert-" + Type;
}
}
public enum alert_type
{
info, success, warning, danger
}
+303
View File
@@ -0,0 +1,303 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index.aspx.cs" Inherits="admin_accounting_index" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<a href="news_reg.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
<%-- <a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>--%>
</div>
<div class="">
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<%--<link href="<%=ResolveUrl("~/js/vuetify_ez.css")%>" rel="stylesheet" />--%>
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
//
{ text: '單據日期', value: 'uptime', },
{ text: '收支類別', value: 'category_Txt'},
{ text: '收支帳戶', value: 'kinds2Txt'},
{ text: '收支項目', value: 'kindsTxt'},
{ text: '未稅金額', value: 'price' },
{ text: '稅額', value: 'tax' },
{ text: '總額', value: 'total' },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
],
footer:{
showFirstLastPage: true,
itemsPerPageOptions:[5,10,20,30],
},
},
search: {
kind: '',
kind2: '',
uptime1: '',
uptime2: '',
category: '',
activity_num_txt: '',
mem_num_txt: '',
debtor: '',
},
order_total_price: 0,
order_total_tax: 0,
order_amount: 0,
}
},
watch: {
options: {
handler() {
this.getDefault()
},
deep: true,
},
},
methods: {
getDefault(clearpage = false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage ? '1' : page, pageSize: itemsPerPage
};
this.data_table.loading = true
this.order_total_price = 0;
this.order_total_tax = 0;
this.order_amount = 0;
axios
.post(HTTP_HOST + 'api/accounting/GetList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
if (this.data_table.list.length > 0) {
for (var i = 0; i < this.data_table.list.length; i++) {
if (this.data_table.list[i].category == 1) //收入
this.order_total_price += parseInt(this.data_table.list[i].price);
else if (this.data_table.list[i].category == 2) //支出
this.order_total_price -= parseInt(this.data_table.list[i].price);
//this.order_total_tax += parseInt(this.data_table.list[i].tax);
if (this.data_table.list[i].category == 1) //收入
this.order_amount += parseInt(this.data_table.list[i].total);
else if (this.data_table.list[i].category == 2) //支出
this.order_amount -= parseInt(this.data_table.list[i].total);
}
}
})
.catch(error => console.log(error))
},
editItem(item) {
console.log("edit", item);
},
deleteItem(item) {
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/accounting/' + item.num)
.then(response => {
console.log("del", item);
this.data_table.list.splice(index, 1);
this.data_table.count = this.data_table.list.length
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/accounting/Delete/' + this.data_table.selected.map(x => x.num))
.then(response => {
//console.log("delAll");
//for (var i = 0; i < this.data_table.selected.length; i++) {
// const index = this.data_table.list.indexOf(this.data_table.selected[i]);
// this.data_table.list.splice(index, 1);
//}
//this.data_table.selected = [];
//this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
this.getDefault(true)
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
},
filters: {
currency: function (value) {
return value == null || value === "" ? "" :
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
},
}
})
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-md">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.uptime="{ item }" >
{{ item.uptime|timeString('YYYY/MM/DD') }}
</template>
<template v-slot:item.price="{ item }">
{{item.price | currency }}
</template>
<template v-slot:item.tax="{ item }">
{{item.tax | currency }}
</template>
<template v-slot:item.total="{ item }">
{{item.total | currency }}
</template>
<template #item.slot_btn="{ item }">
<a :href="'news_reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-magnify"></i>查看</a>
<%-- <a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a> --%>
</template>
<template v-slot:body.append>
<tr>
<td colspan="4" ></td>
<td class="text-start">合計</td>
<td class="text-start"> {{order_total_price | currency }}</td>
<td class="text-start"> </td>
<td class="text-start"> {{order_amount | currency }}</td>
</tr>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<label class="form-label">單據日期</label>
<div class="input-group">
<asp:TextBox ID="s_uptime1" runat="server" TextMode="Date" CssClass="form-control" autocomplete="off" v-model="search.uptime1"></asp:TextBox>
<span class="input-group-text">~</span>
<asp:TextBox ID="s_uptime2" runat="server" TextMode="Date" CssClass="form-control" autocomplete="off" v-model="search.uptime2"></asp:TextBox>
</div>
</div>
<div class="mb-3">
<label class="form-label">收支類別</label>
<asp:DropDownList ID="s_category" runat="server" CssClass="form-select" v-model="search.category" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">收支帳戶</label>
<asp:DropDownList ID="s_kind2" runat="server" CssClass="form-select" v-model="search.kind2" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">收支項目</label>
<asp:DropDownList ID="s_kind" runat="server" CssClass="form-select" v-model="search.kind" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">相關活動</label>
<input type="text" v-model="search.activity_num_txt" class="form-control" placeholder="可輸入關鍵字查詢">
</div>
<div class="mb-3">
<label class="form-label">內部負責人 </label>
<input type="text" v-model="search.mem_num_txt" class="form-control" placeholder="可輸入關鍵字查詢">
</div>
<div class="mb-3">
<label class="form-label">外部負責人 </label>
<input type="text" v-model="search.debtor" class="form-control" placeholder="可輸入關鍵字查詢">
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
</asp:Content>
+156
View File
@@ -0,0 +1,156 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
public partial class admin_accounting_index : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
InitEnumsOptions<Model.accounting.type>(s_category); //收支類別
BuildKind();
}
}
#region
public void BuildKind()
{
s_kind.Items.Clear();
s_kind.Items.Add(new ListItem("請選擇", ""));
buildMultiKind(s_kind, "accounting_kind", 0, "", 1, Model.accounting.KindLevelMax);
s_kind2.Items.Clear();
s_kind2.Items.Add(new ListItem("請選擇", ""));
buildMultiKind(s_kind2, "accounting_kind2", 0, "", 1, Model.accounting.KindLevelMax);
}
#endregion
#region Excel
protected void excel_Click(object sender, EventArgs e)
{
var memoryStream = new MemoryStream();
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var wb = doc.AddWorkbookPart();
wb.Workbook = new Workbook();
var sheets = wb.Workbook.AppendChild(new Sheets());
//建立第一個頁籤
var ws = wb.AddNewPart<WorksheetPart>();
ws.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws),
SheetId = 1,
Name = "收支"
});
//設定欄寬
var cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 1, Width = 15, CustomWidth = true },
new Column { Min = 2, Max = 4, Width = 10, CustomWidth = true },
new Column { Min = 5, Max = 5, Width = 20, CustomWidth = true },
new Column { Min = 6, Max = 7, Width = 10, CustomWidth = true }
);
ws.Worksheet.Append(cu);
//建立資料頁
var sd = new SheetData();
ws.Worksheet.AppendChild(sd);
//第一列資料
var tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("單據日期"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("收支類別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("收支帳戶"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("收支項目"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("未稅金額"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("稅額"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("總額"), DataType = CellValues.String }
);
sd.AppendChild(tr);
//查詢要匯出的資料
var qry = _db.accountings.AsEnumerable();
if (!isStrNull(s_category.SelectedValue))
qry = qry.Where(o => o.category == Convert.ToInt32(s_category.SelectedValue));
if (!isStrNull(s_kind.SelectedValue))
qry = qry.Where(o => o.kind == Convert.ToInt32(s_kind.SelectedValue));
if (!isStrNull(s_kind2.SelectedValue))
qry = qry.Where(o => o.kind2 == Convert.ToInt32( s_kind2.SelectedValue));
if (!isStrNull(s_uptime1.Text) && isDate(s_uptime1.Text))
qry = qry.Where(o => o.uptime >= Convert.ToDateTime(s_uptime1.Text));
if (!isStrNull(s_uptime2.Text) && isDate(s_uptime2.Text))
qry = qry.Where(o => o.uptime < Convert.ToDateTime(s_uptime2.Text).AddDays(1));
qry = qry.OrderByDescending(o => o.num);
var list = qry.ToList();
if (list.Count > 0)
{
foreach (var item in list)
{
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.uptime.HasValue? item.uptime.Value.ToString("yyyy/MM/dd"):""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.category.HasValue ? GetEnumsDescription((Model.accounting.type)Val(item.category.Value)):""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.kind2.HasValue ? item.accounting_kind2.kind : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.kind.HasValue ? item.accounting_kind.kind : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.price.HasValue ? ValMoney(item.price.Value) : "0"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.tax.HasValue ? ValMoney(item.tax.Value) : "0"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(ValMoney((item.price.HasValue ? item.price.Value : 0) +(item.tax.HasValue ? item.tax.Value : 0))), DataType = CellValues.String }
);
sd.AppendChild(tr);
}
}
//儲存文件(如果有要儲實體的檔案在upload才需要)
//wb.Workbook.Save();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Excel, admin_log.LogViewBtn(list.Select(x => (x.uptime.HasValue ? x.uptime.Value.ToString("yyyy/MM/dd") : "") + (x.kind2.HasValue ? x.accounting_kind2.kind : "")).ToList()));
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=收支.xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
HttpContext.Current.Response.End();
}
#endregion
}
+90
View File
@@ -0,0 +1,90 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg.aspx.cs" Inherits="admin_accounting_kind_reg" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增主分類</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇分類</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal label-sm-right " role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">* 分類名稱</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入分類名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">會計科目編號</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="title" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入會計科目編號"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="title" Visible="false" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">備註</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+312
View File
@@ -0,0 +1,312 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_accounting_kind_reg : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.accounting.KindLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的分類名稱";
item_name.Text = prod.kind;
title.Text = prod.title;
demo.Text = prod.demo;
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的分類】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM accounting_kind ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>分類下,新增次分類";
item_name.Text = "";
title.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增主分類</span>";
table.Visible = true;
item_name.Text = "";
title.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.accounting_kind accounting_kind = _db.accounting_kind.Where(q => q.num == _num).FirstOrDefault();//修改
if (accounting_kind != null)
{
accounting_kind.kind = item_name.Text;
accounting_kind.title = title.Text;
accounting_kind.demo = demo.Text;
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Update, "分類(收支項目)" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.accounting_kind accounting_kind = new Model.accounting_kind();//新增
accounting_kind.kind = item_name.Text;
accounting_kind.title = title.Text;
accounting_kind.root = root;
accounting_kind.range = range;
accounting_kind.demo = demo.Text;
_db.accounting_kind.Add(accounting_kind);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Insert, "分類(收支項目)" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.accounting_kind.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Delete, "分類(收支項目)" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.accounting_kind.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.accountings.AsEnumerable().Where(q => q.kind == num).ToList();
if (prod.Count > 0)
{
////查詢結果全部刪除
//_db.accountings.RemoveRange(prod);
//_db.SaveChanges();
//清空分類
foreach (var item in prod)
item.kind = null;
_db.SaveChanges();
}
}
#endregion
}
+116
View File
@@ -0,0 +1,116 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg2.aspx.cs" Inherits="admin_accounting_kind_reg2" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增主分類</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-md pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇分類</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal label-sm-right " role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">* 分類名稱</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入分類名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">會計科目編號</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="title" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入會計科目編號"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="title" Visible="false" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">分行名稱</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="bank_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入分行名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="bank_name" Visible="false" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">戶名</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="bank_code" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入戶名"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="bank_code" Visible="false" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">帳號</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="bank_id" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入帳號"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" ControlToValidate="bank_id" Visible="false" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label"></label>
<div class="col-sm-10 col-lg-9">
<asp:CheckBox ID="record_payment" runat="server" Text="報名收款帳戶​" />
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">備註</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+326
View File
@@ -0,0 +1,326 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_accounting_kind_reg2 : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.accounting.KindLevelMax2; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的分類名稱";
item_name.Text = prod.kind;
title.Text = prod.title;
bank_name.Text = prod.bank_name;
bank_code.Text = prod.bank_code;
bank_id.Text = prod.bank_id;
record_payment.Checked = !isStrNull(prod.record_payment) && prod.record_payment.Equals("Y");
demo.Text = prod.demo;
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的分類】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM accounting_kind2 ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>分類下,新增次分類";
item_name.Text = "";
title.Text = "";
demo.Text = "";
bank_name.Text = "";
bank_code.Text = "";
bank_id.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
record_payment.Checked = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增主分類</span>";
table.Visible = true;
item_name.Text = "";
title.Text = "";
demo.Text = "";
bank_name.Text = "";
bank_code.Text = "";
bank_id.Text = "";
record_payment.Checked =false;
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.accounting_kind2 accounting_kind2 = _db.accounting_kind2.Where(q => q.num == _num).FirstOrDefault();//修改
if (accounting_kind2 != null)
{
accounting_kind2.kind = item_name.Text;
accounting_kind2.title = title.Text;
accounting_kind2.demo = demo.Text;
accounting_kind2.bank_name = bank_name.Text;
accounting_kind2.bank_code = bank_code.Text;
accounting_kind2.bank_id = bank_id.Text;
accounting_kind2.record_payment = record_payment.Checked?"Y":"";
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Update, "分類(收支帳戶)" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.accounting_kind2 accounting_kind2 = new Model.accounting_kind2();//新增
accounting_kind2.kind = item_name.Text;
accounting_kind2.title = title.Text;
accounting_kind2.root = root;
accounting_kind2.range = range;
accounting_kind2.demo = demo.Text;
accounting_kind2.bank_name = bank_name.Text;
accounting_kind2.bank_code = bank_code.Text;
accounting_kind2.bank_id = bank_id.Text;
accounting_kind2.record_payment = record_payment.Checked ? "Y" : "";
_db.accounting_kind2.Add(accounting_kind2);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Insert, "分類(收支帳戶)" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.accounting_kind2.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Delete, "分類(收支帳戶)" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.accounting_kind2.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.accountings.AsEnumerable().Where(q => q.kind2 == num).ToList();
if (prod.Count > 0)
{
////查詢結果全部刪除
//_db.accountings.RemoveRange(prod);
//_db.SaveChanges();
//清空分類
foreach (var item in prod)
item.kind2 = null;
_db.SaveChanges();
}
}
#endregion
}
+706
View File
@@ -0,0 +1,706 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="news_reg.aspx.cs" Inherits="admin_accounting_new_reg" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<script>
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
this_id: '<%= Request["num"] %>',
options: {},
optionsDetail: { multiSort: false },
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '收支項目',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '項目名稱', value: '' },
],
api_url: HTTP_HOST + 'api/accounting/GetTitleKindList',
columns: [
{ id: 'kind', title: '項目名稱', value: '' },
],
selected: {},
select(t) {
console.log("select search1", t);
}
}, search2: {
id: 'search2',
title: '收支帳戶',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '帳戶名稱', value: '' },
],
api_url: HTTP_HOST + 'api/accounting/GetAccountKindList',
columns: [
{ id: 'kind', title: '帳戶名稱', value: ''},
],
selected: {},
select(t) {
console.log("select search2", t);
}
},
search3: {
id: 'search3',
title: '相關活動',
text_prop: 'subject',
value_prop: 'num',
keys: [
{ id: 'subject', title: '活動名稱', value: '' },
{ id: 'kindTxt', title: '活動分類' },
],
api_url: HTTP_HOST + 'api/activity/GetList',
columns: [
{ id: 'subject', title: '活動名稱' },
{ id: 'kindTxt', title: '活動分類' },
],
selected: {},
select(t) {
console.log("select search3", t);
}
},
search4: {
id: 'search4',
title: '人員',
text_prop: 'u_name',
value_prop: 'num',
keys: [
{ id: 'm_number', title: '編號', value: '' },
{ id: 'u_name', title: '姓名', value: '' },
{ id: 'sex', title: '性別', value: '' },
],
api_url: HTTP_HOST + 'api/member/GetList',
columns: [
{ id: 'm_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'sex', title: '性別' },
],
selected: {},
select(t) {
console.log("select search4", t);
}
},
},
show: false,
current: {},
list: [],
count: 0,
page:1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText:'',
},
},
snackbar: {
show: false,
text: "",
},
total: '<%= _t %>',
//檔案上傳
filePath: '<%= ResolveUrl( Model.accounting.Dir) %>/',
filerules: [
value => !value || value.size < 2000000 || '檔案限制 2 MB 以內',
value => !!value || '檔案必填',
],
searchDetail: '',
headersDetail: [
{ text: '檔案名稱', value: 'pic1', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "200px" },
],
desserts: [],
desserts_count: 0,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
accounting_num: 0,
pic1: '',
pic1_name: '',
pic1push: [],
},
defaultItem: {
id: 0,
num: 0,
accounting_num: 0,
pic1: '',
pic1_name: '',
pic1push: [],
},
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
//console.log("mounted");
},
watch: {
options: {
handler() {
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
optionsDetail: {
handler() {
this.initialize();
},
deep: true,
},
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
//this.search_get()//清除完自動會重抓, 故取消
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
//const { page, itemsPerPage } = this.options
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
this.search_dialog.page = this.options.page??1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show=true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(row);
}
this.search_dialog.show = false;
},
initialize() {
if (this.this_id != '') {
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
};
var searchItemDetail = {
accounting_num: this.this_id,
}
axios
.post(HTTP_HOST + 'api/accounting/GetAccFiles', searchItemDetail, { params: params })
.then(response => {
this.desserts = response.data.list
this.desserts_count = response.data.count
})
.catch(
error => console.log(error)
)
}
},
cancel() {
this.spliceNullData();
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
}
}
}
},
close() {
setTimeout(() => {
this.editedItem = $.extend(true, {}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
addNew() {
this.spliceNullData();
//addObj.id = this.desserts.length + 1;
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
const addObj = $.extend(true, {}, this.defaultItem);
addObj.id = (isFinite(_c) ? _c : 0) + 1;
this.desserts.unshift(addObj);
this.editItem(addObj);
},
editItem(item) {
this.editedIndex = this.desserts.indexOf(item);
this.editedItem = $.extend(true, {}, item);
}, save() {
if (this.editedIndex > -1) {
if (this.this_id != '') {
if (this.editedItem.pic1push != null) {
var reader = new FileReader();
reader.onload = function (e) {
if (e.total <= 2000000) {
//上傳檔案
const formData = new FormData();
formData.append('file-to-upload', VueApp.editedItem.pic1push)
axios
.post(HTTP_HOST + 'api/accounting/uploadFiles', formData, {
Headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
if (response.data != "") {
//寫入
var accounting_files = {
accounting_num: VueApp.this_id,
pic1: response.data,
pic1_name: VueApp.editedItem.pic1push.name,
}
axios
.post(HTTP_HOST + 'api/accounting/SaveFileData', accounting_files)
.then(response => {
VueApp.editedItem.num = response.data;
VueApp.editedItem.pic1 = accounting_files.pic1;
VueApp.editedItem.pic1_name = accounting_files.pic1_name;
Object.assign(VueApp.desserts[VueApp.editedIndex], VueApp.editedItem)
VueApp.close()
})
.catch(
error => console.log(error)
)
}
})
.catch(
error => {
console.log(error)
VueApp.snackbar.text = "錯誤:" + error.response.data.message
VueApp.snackbar.show = true
}
)
} else {
VueApp.snackbar.text = "檔案限制 2 MB 以內";
VueApp.snackbar.show = true
}
}
reader.readAsDataURL(this.editedItem.pic1push);
}
else {
this.snackbar.text = "請選擇檔案";
this.snackbar.show = true
}
} else {
this.snackbar.text = "庫存資料錯誤";
this.snackbar.show = true
}
}
},
deleteItem(item) {
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/accounting/DeleteFilesItem/' + item.num)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
this.desserts_count = this.desserts_count - 1;
})
.catch(error => console.log(error))
}
} else {
this.desserts.splice(index, 1)
}
}
},
isPhoto(name) {
const n = name.split('.')[1];
const type = new Array("jpg", "jpeg", "gif", "png", "bmp");
return type.indexOf(n) > -1 ? true : false
},
},
computed: {
}, filters: {
currency: function (value) {
return value == null || value === "" ? "" :
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
},
}
})
$('#<%= price.ClientID %>').on("change", function () {
getTotalPrice();
})
$('#<%= tax.ClientID %>').on("change", function () {
getTotalPrice();
})
function getTotalPrice() {
const _pp = ($('#<%= price.ClientID %>').val() != null && $('#<%= price.ClientID %>').val() != "") ? parseFloat($('#<%= price.ClientID %>').val()) :0 ;
const _tt = ($('#<%= tax.ClientID %>').val() != null && $('#<%= tax.ClientID %>').val() != "") ? parseFloat($('#<%= tax.ClientID %>').val()) : 0;
let _tp = _pp + _tt;
_tp = ('$' + parseFloat(_tp).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
$('#totalPrice').text(_tp);
}
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
</div>
<div class="">
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:Button ID="edit" runat="server" Text="修改備註" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
</div>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-md">
<div class="card shadow-sm my-3">
<div class="card-header py-0">
<nav class="navbar py-0">
<div class="nav nav-tabs">
<button class="nav-link active" id="sec2-tab1" data-bs-toggle="tab" data-bs-target="#sec2-page1"
type="button" role="tab" aria-controls="home" aria-selected="true">
收支管理</button>
<button class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2"
type="button" role="tab" aria-controls="profile" aria-selected="false">
檔案上傳</button>
</div>
</nav>
</div>
<asp:Panel ID="cardBodyPanel" runat="server" CssClass="card-body">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active " id="sec2-page1" role="tabpanel" aria-labelledby="sec2-tab1">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 label-sm-right " :class="{readonly : this_id !='' }">
<label class="col-sm-2 col-lg-1 col-form-label">單據日期 *</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="uptime" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" ControlToValidate="uptime" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">收支類別 *</label>
<div class="col-sm-10 col-lg-3">
<asp:DropDownList ID="category" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="category"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">收支帳戶 *</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group mb-3" data-search-control="search2" @click="search_show(search_dialog.controls.search2)">
<input class="form-control search-text" type="text" readonly
id="kind2_txt" runat="server" placeholder="收支帳戶" value="">
<asp:HiddenField ID="kind2" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="kind2_txt" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right " :class="{readonly : this_id !='' }">
<label class="col-sm-2 col-lg-1 col-form-label">收支項目 *</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
id="kind_txt" runat="server" placeholder="收支項目" value="">
<asp:HiddenField ID="kind" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" ControlToValidate="kind_txt" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">相關活動</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group mb-3" data-search-control="search3" @click="search_show(search_dialog.controls.search3)">
<input class="form-control search-text" type="text" readonly
id="activity_num_txt" runat="server" placeholder="相關活動" value="">
<asp:HiddenField ID="activity_num" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
</div>
</div>
<div class="row mb-1 label-sm-right " :class="{readonly : this_id !='' }">
<label class="col-sm-2 col-lg-1 col-form-label">未稅金額 *</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="price" MaxLength="7" runat="server" CssClass="form-control" placeholder="請輸入未稅金額"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" ControlToValidate="price" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ControlToValidate="price" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ValidationGroup="Required" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^(\d+)?$" />
</div>
<label class="col-sm-2 col-lg-1 col-form-label">稅額 *</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="tax" MaxLength="7" runat="server" CssClass="form-control" placeholder="請輸入稅額"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator8" ControlToValidate="tax" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ControlToValidate="tax" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ValidationGroup="Required" ID="RegularExpressionValidator1" runat="server" ValidationExpression="^(\d+)?$" />
</div>
<label class="col-sm-2 col-lg-1 col-form-label">總額</label>
<div class="col-sm-10 col-lg-3 pt-2">
<span id="totalPrice">{{total | currency}}</span>
</div>
</div>
<div class="row mb-1 label-sm-right " :class="{readonly : this_id !='' }">
<label class="col-sm-2 col-lg-1 col-form-label">內部負責人 *</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group mb-3" data-search-control="search4" @click="search_show(search_dialog.controls.search4)">
<input class="form-control search-text" type="text" readonly
id="mem_num_txt" runat="server" placeholder="人員" value="" >
<asp:HiddenField ID="mem_num" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="mem_num_txt"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">外部負責人</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="debtor" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入外部負責人"></asp:TextBox>
</div>
</div>
<hr />
<div class="row mb-1">
<label class="col-form-label">摘要</label>
<div class="">
<asp:TextBox ID="excerpt" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入摘要(可入傳票)"></asp:TextBox>
</div>
</div>
<hr />
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<asp:Panel ID="timePanel1" runat="server" CssClass="col-12 text-right text-primary" Visible="false">建檔時間:<asp:Literal ID="reg_time" runat="server"></asp:Literal></asp:Panel>
</div>
</div>
<div class="tab-pane fade giftItems label-sm-right" id="sec2-page2" role="tabpanel" aria-labelledby="sec2-tab2">
<v-card class="mx-auto mt-10" outlined v-if="this_id!=''">
<v-data-table
hide-default-header
:headers="headersDetail"
:items="desserts"
<%-- :search="searchDetail"--%>
:options.sync="optionsDetail" class="elevation-1" fixed-header height="550px"
<%-- :server-items-length="desserts_count"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<%--<v-text-field v-model="searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>--%>
<v-btn
color="primary"
class="ml-2 white--text"
@click="addNew">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
<div class="form-text text-muted ml-5">檔案限制 2 MB 以內,僅接受jpg、png、pdf格式</div>
</template>
<template v-slot:item.pic1="{ item }" :cols="12" >
<div class="input-group mb-3" v-if="item.id === editedItem.id">
<v-file-input v-model="editedItem.pic1push"
required :rules="filerules" accept="image/png, image/jpeg, application/pdf"
show-size label="請選擇檔案"
truncate-length="25">
</v-file-input>
</div>
<template v-else>
<template v-if="isPhoto(item.pic1)">
<a :href="filePath+item.pic1" target="_blank" >
<v-img
max-height="138"
max-width="250"
:lazy-src="filePath+item.pic1"
:src="filePath+item.pic1"
:alt="item.pic1_name"
></v-img>
</a>
</template>
<template v-else>
<v-btn
outlined color="primary" class="ma-2" elevation="3" download
:href="filePath+item.pic1"
>
{{item.pic1_name}}
<v-icon right dark >mdi-cloud-download</v-icon>
</v-btn>
</template>
</template>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-3" @click="cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="red" @click="deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<div class="mx-auto" v-else >
<p class="lead">請先儲存收支管理後再新增檔案上傳</p>
</div>
</div>
</div>
</asp:Panel>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title"></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+221
View File
@@ -0,0 +1,221 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Globalization;
public partial class admin_accounting_new_reg : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
public float _t = 0;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
InitEnumsOptions<Model.accounting.type>(category); //收支類別
if (isStrNull(Request["num"]))
{
uptime.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
else
{
int _num = Val(Request["num"]);
var qry = _db.accountings.AsEnumerable();
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
try
{
foreach (Control obj in cardBodyPanel.Controls)
{
if (obj is TextBox)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var textBox = (TextBox)obj;
if (textBox.TextMode == TextBoxMode.Date)
{
textBox.Text = Convert.ToDateTime(ObjValue).ToString("yyyy-MM-dd");
}
else
{
textBox.Text = ObjValue.ToString();
}
}
}
else if (obj is DropDownList && ((DropDownList)obj).SelectedIndex == 0)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var dropDown = (DropDownList)obj;
dropDown.SelectedValue = ObjValue.ToString();
}
}
}
}
catch (Exception ex)
{
}
if (prod.kind.HasValue)
{
kind_txt.Value = prod.accounting_kind.kind.ToString();
kind.Value = prod.kind.ToString();
}
if (prod.kind2.HasValue)
{
kind2_txt.Value = prod.accounting_kind2.kind.ToString();
kind2.Value = prod.kind2.ToString();
}
if (prod.activity_num.HasValue)
{
activity_num_txt.Value = prod.activity.subject.ToString();
activity_num.Value = prod.activity_num.ToString();
}
if (prod.mem_num.HasValue)
{
mem_num_txt.Value = prod.member.u_name.ToString();
mem_num.Value = prod.mem_num.ToString();
}
if (prod.reg_time.HasValue)
{
timePanel1.Visible = true;
reg_time.Text = prod.reg_time.Value.ToString("yyyy/MM/dd HH:mm:ss");
}
_t = ((prod.price.HasValue) ? ValFloat(prod.price.Value) : 0) + ((prod.tax.HasValue) ? ValFloat(prod.tax.Value) : 0);
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
}
else
{
Response.Redirect("index.aspx");
}
}
}
}
protected void goback_Click(object sender, EventArgs e)
{
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
L_msg.Text = "";
Model.accounting accounting = new Model.accounting();
if (!isStrNull(uptime.Text)) { accounting.uptime = ValDate(uptime.Text); }
accounting.category = Val(category.SelectedValue);
if (!isStrNull(kind.Value)) { accounting.kind = Val(kind.Value); }
if (!isStrNull(kind2.Value)) { accounting.kind2 = Val(kind2.Value); }
if (!isStrNull(tax.Text)) { accounting.tax = Val(tax.Text); }
if (!isStrNull(price.Text)) { accounting.price = ValFloat(price.Text); }
if (!isStrNull(activity_num.Value)) { accounting.activity_num = Val(activity_num.Value); }
if (!isStrNull(mem_num.Value)) { accounting.mem_num = Val(mem_num.Value); }
accounting.debtor = debtor.Text;
accounting.demo = demo.Text;
accounting.excerpt = excerpt.Text;
accounting.reg_time = DateTime.Now;
try
{
_db.accountings.Add(accounting);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Insert, uptime.Text + kind2_txt.Value);
Response.Redirect("index.aspx");
}
catch (Exception ex)
{
L_msg.Text = ex.Message;
L_msg.Type = alert_type.danger;
//L_msg.Text = "操作失敗";
}
}
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
Model.accounting accounting = _db.accountings.Where(q => q.num == _num).FirstOrDefault();
if (accounting != null)
{
//if (!isStrNull(uptime.Text)) { accounting.uptime = ValDate(uptime.Text); }
//accounting.category = Val(category.SelectedValue);
//if (!isStrNull(kind.Value)) { accounting.kind = Val(kind.Value); }
//if (!isStrNull(kind2.Value)) { accounting.kind2 = Val(kind2.Value); }
//if (!isStrNull(tax.Text)) { accounting.tax = Val(tax.Text); }
//if (!isStrNull(price.Text)) { accounting.price = ValFloat(price.Text); }
//if (!isStrNull(activity_num.Value)) { accounting.activity_num = Val(activity_num.Value); }
//if (!isStrNull(mem_num.Value)) { accounting.mem_num = Val(mem_num.Value); }
//accounting.debtor = debtor.Text;
accounting.demo = demo.Text;
accounting.excerpt = excerpt.Text;
}
try
{
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Update, uptime.Text+ kind2_txt.Value);
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
//L_msg.Text = ex.InnerException.Message;
L_msg.Text = "操作失敗";
}
}
}
#endregion
}
+217
View File
@@ -0,0 +1,217 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index.aspx.cs" Inherits="admin_activity_index" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<a href="reg.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
</div>
<div class="">
<asp:LinkButton ID="excel" runat="server" Visible="false" CssClass="btn btn-outline-primary" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<%--<link href="<%=ResolveUrl("~/js/vuetify_ez.css")%>" rel="stylesheet" />--%>
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
{ text: '活動分類', value: 'kindsTxt' },
{ text: '活動名稱', value: 'subject', align: 'start' },
{ text: '開始日期', value: 'start_date' },
{ text: '結束日期', value: 'end_date' },
{ text: '報名截止日期', value: 'due_date' },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
],
footer:{
showFirstLastPage: true,
itemsPerPageOptions:[5,10,20,30],
},
},
search: {
kind: 0,
subject: '',
}
}
},
watch: {
options: {
handler() {
this.getDefault()
},
deep: true,
},
},
methods: {
getDefault(clearpage = false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage ? '1' : page, pageSize: itemsPerPage
};
this.data_table.loading = true
axios
.post(HTTP_HOST + 'api/activity/GetList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
})
.catch(error => console.log(error))
},
editItem(item) {
console.log("edit", item);
},
deleteItem(item) {
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/activity/' + item.num)
.then(response => {
console.log("del", item);
this.data_table.list.splice(index, 1);
this.data_table.count = this.data_table.list.length
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/activity/Delete/' + this.data_table.selected.map(x => x.num))
.then(response => {
//console.log("delAll");
//for (var i = 0; i < this.data_table.selected.length; i++) {
// const index = this.data_table.list.indexOf(this.data_table.selected[i]);
// this.data_table.list.splice(index, 1);
//}
//this.data_table.selected = [];
//this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
this.getDefault(true)
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
}
})
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.start_date="{ item }" >
<div v-if="item.startDate_solar !=null && item.startDate_solar !=''"><span class="badge bg-secondary">國曆</span> {{ item.startDate_solar|timeString('YYYY/MM/DD') }} </div>
<div v-if="item.startDate_lunar !=null && item.startDate_lunar !=''"><span class="badge bg-secondary">農曆</span> {{ item.startDate_lunar|timeString('YYYY/MM/DD') }} </div>
</template>
<template #item.end_date="{ item }" >
<div v-if="item.endDate_solar !=null && item.endDate_solar !=''"><span class="badge bg-secondary">國曆</span> {{ item.endDate_solar|timeString('YYYY/MM/DD') }} </div>
<div v-if="item.endDate_lunar !=null && item.endDate_lunar !=''"><span class="badge bg-secondary">農曆</span> {{ item.endDate_lunar|timeString('YYYY/MM/DD') }} </div>
</template>
<template #item.due_date="{ item }" >
{{ item.dueDate|timeString('YYYY/MM/DD') }}
</template>
<template #item.slot_btn="{ item }">
<a :href="'reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<label class="form-label">分類</label>
<asp:DropDownList ID="s_kind" runat="server" CssClass="form-select" v-model="search.kind" >
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">項目名稱</label>
<input type="text" v-model="search.subject" class="form-control" placeholder="可輸入關鍵字查詢">
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
</asp:Content>
+70
View File
@@ -0,0 +1,70 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using static TreeView;
public partial class admin_activity_index : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BuildKind();
}
}
#region
public void BuildKind()
{
s_kind.Items.Clear();
s_kind.Items.Add(new ListItem("", ""));
//buildMultiKind(s_kind, "activity_kind", 0, "", 1, Model.activity.KindLevelMax);
var qry1 = new TreeView().get_data2(_db.activity_kind.Select(o => new TreeItem()
{
kind = o.kind,
num = o.num,
root = o.root,
range = o.range,
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
if (qry1.Count() > 0)
foreach (var qq in qry1)
s_kind.Items.Add(new ListItem(new TreeView().RptDash(qq.Level) + qq.kind, qq.num.ToString()));
}
#endregion
#region Excel
protected void excel_Click(object sender, EventArgs e)
{
//請參考訂單系統的匯出
}
#endregion
}
+476
View File
@@ -0,0 +1,476 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index2.aspx.cs" Inherits="admin_activity_index2" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<ul class="nav ps-0">
<li class="nav-item pe-3">
<select class="form-select" v-model="search.kind" @change="btn_search">
<option value="">選擇分類</option>
<option v-for="item in itemKindList" :value="item.num">{{item.kind}}</option>
</select>
</li>
<li class="nav-item pe-1">
<a href="item_reg.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
</li>
<li class="nav-item pe-1">
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
</li>
</ul>
<%-- <div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
id="kind_txt" runat="server" placeholder="品項分類選擇" value="">
<input type="hidden" v-model="search.kind">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>--%>
</div>
<div class="">
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
{ text: '項目名稱', value: 'subject', align: 'start' },
{ text: '項目分類', value: 'kindsTxt' },
{ text: '類別', value: 'categoryTxt' },
{ text: '預設金額', value: 'price' },
{ text: '庫存狀態', value: 'stock' },
{ text: '停用', value: 'status' },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
],
footer:{
showFirstLastPage: true,
itemsPerPageOptions:[5,10,20,30],
},
},
search: {
kind: '',
subject: '',
selltime1:'',
selltime2: '',
uptime1: '',
uptime2: '',
fileTxt: '',
category: '',
},
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '品項分類',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '品項分類', value: '' },
],
api_url: HTTP_HOST + 'api/actItem_kind/GetList',
columns: [
{ id: 'kind', title: '品項分類', value: '' },
],
selected: {},
select(t,data) {
data.search.kind = t.num;
data.btn_search()
console.log("select search1", t);
}
}
},
show: false,
current: {},
list: [],
count: 0,
page: 1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
}, snackbar: {
show: false,
text: "",
}, itemKindList:{
num: 0,
kind:''
}
}
},
watch: {
options: {
handler() {
this.getDefault()
},
deep: true,
},
'options.page'(newVal) {
sessionStorage.setItem("actItemPage", newVal);
},
},
mounted() {
this.initKindList()
const navEntries = performance.getEntriesByType("navigation");
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
if (isReload) {
sessionStorage.removeItem("actItemPage");
}
else {
const actItemPage = parseInt(sessionStorage.getItem("actItemPage"));
if (!isNaN(actItemPage) && actItemPage !== 1) {
this.options.page = actItemPage;
}
}
},
methods: {
initKindList() {
axios
//.get(HTTP_HOST + 'api/activity_kind')
.get(HTTP_HOST + 'api/actItem_kind/GetAll')
.then(response => {
this.itemKindList = response.data
})
.catch(error => console.log(error))
//let params = { page: 1, pageSize: 99999 };
////var search = {};//post body
////search['kind'] = '';
////console.log("activity_kind/GetList",search, params);
//axios.post(HTTP_HOST + 'api/activity_kind/GetList', { kind:'' } , { params: params })
// .then(response => {
// this.itemKindList = response.data.list
// })
},
getDefault(clearpage = false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage ? '1' :page, pageSize: itemsPerPage
};
this.data_table.loading = true
axios
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
})
.catch(error => console.log(error))
},
editItem(item) {
console.log("edit", item);
},
deleteItem(item) {
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/activity/DeleteItem/' + item.num)
.then(response => {
this.getDefault();
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/activity/DeleteAllItem/' + this.data_table.selected.map(x => x.num))
.then(response => {
//console.log("delAll");
//for (var i = 0; i < this.data_table.selected.length; i++) {
// const index = this.data_table.list.indexOf(this.data_table.selected[i]);
// this.data_table.list.splice(index, 1);
//}
//this.data_table.selected = [];
//this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
this.getDefault(true)
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
//===
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
//this.search_get()//清除完自動會重抓, 故取消
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
//const { page, itemsPerPage } = this.options
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
this.search_dialog.page = this.options.page ?? 1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show = true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(row,this);
}
this.search_dialog.show = false;
},
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
},
filters: {
currency: function (value) {
return value == null || value == "" ? "" :
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
},
}
})
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.price="{ item }" >
{{item.price | currency }}
</template>
<template #item.stock="{ item }" >
<%--<span v-if="item.stock.cate1Qty>0"> {{item.stock.cate1Qty -item.stock.cate2Qty-item.stock.cate3Qty+item.stock.cate4Qty}}</span>
<span v-if="item.stock.cate3Qty-item.stock.cate4Qty>0" class="text-danger"> (租借未還:{{item.stock.cate3Qty-item.stock.cate4Qty}})</span>
--%>
<%--<span v-if="item.stock.catePQty>0"> {{item.stock.catePQty}}</span>
<span v-if="item.stock.cateRQty>0" class="text-danger"> (租借未還:{{item.stock.cateRQty}})</span>--%>
<span v-if="item.final_stock>0" > {{item.final_stock}}</span>
<span v-if="item.rent_stock>0" class="text-danger"> (租借未還:{{item.rent_stock}})</span>
</template>
<template #item.status="{ item }" >
<span v-if="item.status=='N'"><i class='mdi mdi-check'></i></span>
</template>
<template #item.slot_btn="{ item }">
<a :href="'item_reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<label class="form-label">分類</label>
<asp:DropDownList ID="s_kind" runat="server" CssClass="form-select" v-model="search.kind" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">項目類別</label>
<asp:DropDownList ID="s_category" runat="server" CssClass="form-select" v-model="search.category" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
</div>
<div class="mb-3">
<label class="form-label">項目名稱</label>
<input type="text" v-model="search.subject" class="form-control" placeholder="可輸入關鍵字查詢" id="s_subject" runat="server">
</div>
<div class="mb-3">
<label class="form-label">文件名稱</label>
<input type="text" v-model="search.fileTxt" class="form-control" placeholder="可輸入關鍵字查詢" id="fileTxt" runat="server">
</div>
<div class="mb-3">
<label class="form-label">狀態</label>
<select class="form-select" v-model="search.status">
<option value="">請選擇</option>
<option value="Y">啟用</option>
<option value="N">停用</option>
</select>
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title"></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>p
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</asp:Content>
+195
View File
@@ -0,0 +1,195 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using static TreeView;
public partial class admin_activity_index2 : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BuildKind();
InitEnumsOptions<Model.activity.category>(s_category);
}
}
#region
public void BuildKind()
{
s_kind.Items.Clear();
s_kind.Items.Add(new ListItem("請選擇", ""));
//buildMultiKind(s_kind, "actItem_kind", 0, "", 1, Model.activity.ItemLevelMax);
var qry1 = new TreeView().get_data2(_db.actItem_kind.Select(o => new TreeItem()
{
kind = o.kind,
num = o.num,
root = o.root,
range = o.range,
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
if (qry1.Count() > 0)
foreach (var qq in qry1)
s_kind.Items.Add(new ListItem(new TreeView().RptDash(qq.Level) + qq.kind, qq.num.ToString()));
}
#endregion
#region Excel
protected void excel_Click(object sender, EventArgs e)
{
var memoryStream = new MemoryStream();
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var wb = doc.AddWorkbookPart();
wb.Workbook = new Workbook();
var sheets = wb.Workbook.AppendChild(new Sheets());
//建立第一個頁籤
var ws = wb.AddNewPart<WorksheetPart>();
ws.Worksheet = new Worksheet();
sheets.Append(new Sheet()
{
Id = wb.GetIdOfPart(ws),
SheetId = 1,
Name = "品項管理​"
});
//設定欄寬
var cu = new Columns();
cu.Append(
new Column { Min = 1, Max = 5, Width = 15, CustomWidth = true },
new Column { Min = 6, Max = 7, Width = 10, CustomWidth = true }
);
ws.Worksheet.Append(cu);
//建立資料頁
var sd = new SheetData();
ws.Worksheet.AppendChild(sd);
//第一列資料
var tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue("項目名稱"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("項目分類"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("類別"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("預設金額"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("庫存狀態"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("停用"), DataType = CellValues.String }
);
sd.AppendChild(tr);
//查詢要匯出的資料
var fileDt = _db.files.AsEnumerable().Where(f => f.subject.Contains(fileTxt.Value)).Select(f => f.num.ToString());//文件
var qry = _db.actItems.AsEnumerable();
//每個品項在每個倉庫的結餘量
var stockDt = (
from t_min_max in (
from stock in _db.stocks
group stock by new { stock.kind, stock.actItem_num } into g
select new
{
g.Key.kind,
g.Key.actItem_num,
min_id = g.Min(x => x.num),
max_id = g.Max(x => x.num)
}
)
join t_min in _db.stocks on t_min_max.min_id equals t_min.num
join t_max in _db.stocks on t_min_max.max_id equals t_max.num into t_maxGroup
from t_max in t_maxGroup.DefaultIfEmpty()
select new
{
t_min_max.kind,
t_min_max.actItem_num,
final_last = t_min_max.min_id != t_min_max.max_id ? t_max.final_stock ?? 0 : t_min.final_stock ?? 0,
rent_last = t_min_max.min_id != t_min_max.max_id ? t_max.rent_stock ?? 0 : t_min.rent_stock ?? 0
}
).ToList();
if (!string.IsNullOrEmpty(s_subject.Value))
qry = qry.Where(o => o.subject.Contains(s_subject.Value.Trim()));
if (!string.IsNullOrEmpty(s_kind.SelectedValue))
qry = qry.Where(o => o.kind == Convert.ToInt32(s_kind.SelectedValue));
if (!string.IsNullOrEmpty(fileTxt.Value))
qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.ToArray().Contains(f2.files_num.ToString())).Count() > 0);
var tdesc = publicFun.enum_desc<Model.activity.category>();
qry = qry.OrderByDescending(o => o.num);
var list = qry.ToList();
if (list.Count > 0)
{
foreach (var item in list)
{
var stock = new
{
//catePQty = (item.stocks.Where(o => o.category == (int)Model.stock.type.Purchase || o.category == (int)Model.stock.type.Return).Select(o => o.qty).Sum() ?? 0) - (item.stocks.Where(o => o.category == (int)Model.stock.type.Reduce || o.category == (int)Model.stock.type.Rent).Select(o => o.qty).Sum() ?? 0),
//cateRQty = (item.stocks.Where(o => o.category == (int)Model.stock.type.Rent).Select(o => o.qty).Sum() ?? 0) - (item.stocks.Where(o => o.category == (int)Model.stock.type.Return).Select(o => o.qty).Sum() ?? 0),
final_stock = stockDt.Where(o => o.actItem_num == item.num).Select(o => o.final_last).Sum(),
rent_stock = stockDt.Where(o => o.actItem_num == item.num).Select(o => o.rent_last).Sum(),
};
//新增資料列
tr = new Row();
tr.Append(
new Cell() { CellValue = new CellValue(item.subject), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.kind.HasValue ? item.actItem_kind.kind : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.category.HasValue ? tdesc[item.category ?? 1] : ""), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.price.HasValue ? ValMoney(item.price.Value) : ""), DataType = CellValues.String },
//new Cell() { CellValue = new CellValue((stock.catePQty > 0? stock.catePQty.ToString():"")+(stock.cateRQty > 0?("(租借未還:"+ stock.cateRQty+")"):"")), DataType = CellValues.String },
new Cell() { CellValue = new CellValue((stock.final_stock > 0? stock.final_stock.ToString():"")+(stock.rent_stock > 0?("(租借未還:"+ stock.rent_stock + ")"):"")), DataType = CellValues.String },
new Cell() { CellValue = new CellValue(item.status.Equals("N")? "是":""), DataType = CellValues.String }
);
sd.AppendChild(tr);
}
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Excel, admin_log.LogViewBtn(list.Select(x => x.subject).ToList()));
}
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=品項管理.xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
HttpContext.Current.Response.End();
}
#endregion
}
+95
View File
@@ -0,0 +1,95 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="itemKind.aspx.cs" Inherits="admin_activity_itemKind" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增主分類</asp:LinkButton>
<asp:LinkButton ID="sortButton" runat="server" Visible="false" CssClass="btn btn-primary" OnClick="sortButton_Click">
<i class="mdi mdi-sort"></i> 排序選項</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False">
<i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇分類</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8 label-sm-right">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal" role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">* 分類名稱</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入分類名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">備註</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">* 狀態</label>
<div class="col-sm-10 col-lg-9">
<label class="col-form-control">
<input type="checkbox" id="status" runat="server"
data-toggle="toggle" data-on="啟用" data-off="停用" data-onstyle="success" />
</label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+310
View File
@@ -0,0 +1,310 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_activity_itemKind : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.activity.ItemLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的分類名稱";
item_name.Text = prod.kind;
demo.Text = prod.demo;
status.Checked = ValString(prod.status).Equals("Y");
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
status.Checked = true;
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的分類】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM actItem_kind ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>分類下,新增次分類";
item_name.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增主分類</span>";
table.Visible = true;
item_name.Text = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
status.Checked = true;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.actItem_kind actItem_kind = _db.actItem_kind.Where(q => q.num == _num).FirstOrDefault();//修改
if (actItem_kind != null)
{
actItem_kind.kind = item_name.Text;
actItem_kind.demo = demo.Text;
actItem_kind.status = status.Checked ? "Y" : "N";
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Update, "分類:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.actItem_kind actItem_kind = new Model.actItem_kind();//新增
actItem_kind.kind = item_name.Text;
actItem_kind.root = root;
actItem_kind.range = range;
actItem_kind.demo = demo.Text;
actItem_kind.status = status.Checked ? "Y" : "N";
_db.actItem_kind.Add(actItem_kind);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Update, "分類:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.actItem_kind.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Update, "分類:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.actItem_kind.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.actItems.AsEnumerable().Where(q => q.kind == num).ToList();
if (prod.Count > 0)
{
//清空分類
foreach (var item in prod)
item.kind = null;
_db.SaveChanges();
}
}
#endregion
protected void sortButton_Click(object sender, EventArgs e)
{
Response.Redirect("range.aspx");
}
}
+877
View File
@@ -0,0 +1,877 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="item_reg.aspx.cs" Inherits="admin_activity_item_reg" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
<!--編緝器-->
<script type="text/javascript" src="<%=ResolveUrl("~/admin/ckeditor/ckeditor.js") %>"></script>
<script type="text/javascript">
CKEDITOR.config.toolbar = 'Default';
</script>
<script>
var prod_bom_num = <%= prod_bom_num %>;
</script>
<!--編緝器-->
<script>
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
this_id: '<%= Request["num"] %>',
options: {},
optionsDetail: {
multiSort: false,
itemsPerPage: -1,
},
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '項目分類',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '分類名稱' },
],
api_url: HTTP_HOST + 'api/actItem_kind/GetList',
columns: [
{ id: 'kind', title: '分類名稱' },
],
selected: {},
select(item,t) {
console.log("select search1", t);
}
},
search2: {
id: 'search2',
title: '相關文件',
text_prop: 'subject',
value_prop: 'num',
keys: [
{ id: 'subject', title: '文件名稱', value: '' },
],
api_url: HTTP_HOST + 'api/FilesSet/GetList',
columns: [
{ id: 'subject', title: '文件名稱' },
],
selected: {},
select(item,t) {
console.log("select search2", t);
item.files_num_selected.text = t.subject //=====?
item.files_num_selected.val = t.num //=====?
}
},
search3: {
id: 'search3',
title: '子項目',
text_prop: 'subject',
value_prop: 'num',
keys: [
{ id: 'subject', title: '項目名稱', value: '' },
{ id: 'kindTxt', title: '項目分類' },
],
api_url: HTTP_HOST + 'api/activity/GetItemList',
columns: [
{ id: 'subject', title: '項目名稱', value: '' },
{ id: 'kindTxt', title: '項目分類' },
],
selected: {},
select(item,t) {
console.log("select search3", item, t);
//debugger;
item.actItem.subject = t.subject
item.actItem.num = t.num
item.item_num_selected={
text: t.subject,
val : t.num
}
// item.bom_editedItem.actItem.subject = t.subject
// item.bom_editedItem.actItem.num = t.num
// item.bom_editedItem.item_num_selected={
// text : t.subject,
// val = t.num
// }
}
////新增/修改+關閉時, 會清空/還原
},
},
show: false,
current: {},
list: [],
count: 0,
page: 1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
},
snackbar: {
show: false,
text: "",
},
//相關文件
searchDetail: '',
headersDetail: [
{ text: '文件名稱', value: 'files_num_selected.text', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "200px" },
],
footersDetail: {
showFirstLastPage: false,
disableItemsPerPage: false,
itemsPerPageAllText: '',
itemsPerPageText: '',
'prev-icon': null,
'next-icon': null,
'disable-pagination': true,
'items-per-page-options': []
},
desserts: [],
desserts_count: 0,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
actItem_num: 0,
files_num_selected: {
text: '',
val: 0
},
},
defaultItem: {
id: 0,
num: 0,
actItem_num: 0,
files_num_selected: {
text: '',
val: 0
},
},
//BOM
prod_bom_num: prod_bom_num,
bom_searchDetail: '',
bom_headersDetail: [
{ text: '品項', value: 'item_num_selected.text', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "200px" },
],
bom_footersDetail: {
showFirstLastPage: false,
disableItemsPerPage: false,
itemsPerPageAllText: '',
itemsPerPageText: '',
'prev-icon': null,
'next-icon': null,
'disable-pagination': true,
'items-per-page-options': []
},
bom_list: [],
bom_count: 0,
bom_editedIndex: -1,
bom_editedItem: {
id: 0,
num: 0,
package_num: 0,
//item_num: 0,
item_num_selected: {
text: '',
val: 0
},
},
bom_defaultItem: {
id: 0,
num: 0,
package_num: 0,
//item_num: 0,
item_num_selected: {
text: '',
val: 0
},
},
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
//console.log("mounted");
},
watch: {
options: {
handler() {
//console.log("watch1", this.search_dialog, this.search_dialog.page);
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
optionsDetail: {
handler() {
this.initialize();
},
deep: true,
},
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
this.search_dialog.page = this.options.page ?? 1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
//necessary parameter===
if (this.search_dialog.current.id == 'search1') {
if (this.this_id=="")
search['status'] = "Y";//啟用
}
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show = true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
var editem = this.editedItem;
if (curr.id == 'search3') {
editem = this.bom_editedItem;
}
else {
}
console.log("search_select", row, editem);
//debugger;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(editem,row);
}
this.search_dialog.show = false;
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
},//文件
initialize() {
if (this.this_id != '') {
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
};
//取得相關文件項目
var searchItemDetail = {
actItem_num: this.this_id,
}
axios
.post(HTTP_HOST + 'api/activity/GetItemFiles',
searchItemDetail, { params: params })
.then(response => {
this.desserts = response.data.list
this.desserts_count = response.data.count
})
.catch(
error => console.log(error)
)
//取得BOM子項目
var searchItemBom = {
item_num: this.this_id,
}
axios
.post(HTTP_HOST + 'api/activity/GetItemBomList',
searchItemBom, { params: params })
.then(response => {
this.bom_list = response.data.list
this.bom_count = response.data.count
})
.catch(
error => console.log(error)
)
}
},
editItem(item) {
this.editedIndex = this.desserts.indexOf(item);
this.editedItem = $.extend(true, {}, item);
},
deleteItem(item) {
//confirm('確定要刪除此筆資料嗎?') && this.desserts.splice(index, 1);
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/activity/DeleteFilesItem/' + item.num)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
this.desserts_count = this.desserts_count - 1;
})
.catch(error => console.log(error))
}
} else {
this.desserts.splice(index, 1)
}
}
},
cancel() {
this.spliceNullData();
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
}
}
}
},
close() {
setTimeout(() => {
this.editedItem = $.extend(true, {}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
addNew() {
this.spliceNullData();
//addObj.id = this.desserts.length + 1;
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
const addObj = $.extend(true, {}, this.defaultItem);
addObj.id = (isFinite(_c) ? _c : 0) + 1;
this.desserts.unshift(addObj);
this.editItem(addObj);
},
save() {
if (this.editedIndex > -1) {
if (this.this_id != '') {
//chcck necessary params
if (this.editedItem.files_num_selected.val != 0 ) {
//insert or update data
var pro_order_detail =
{
num: this.editedItem.num,
actItem_num: this.this_id,
files_num: this.editedItem.files_num_selected.val,
}
axios
.post(HTTP_HOST + 'api/activity/SaveDetailData', pro_order_detail)
.then(response => {
this.editedItem.num = response.data;
Object.assign(this.desserts[this.editedIndex], this.editedItem)
this.close()
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "單號錯誤";
this.snackbar.show = true
}
}
},
titleword() {
var e = document.getElementById("<%= category.ClientID%>");
const strUser = e.options[e.selectedIndex].text;
const _kind_txt = $('#<%= kind_txt.ClientID%>').val();
const _subject = $('#<%= subject.ClientID%>').val();
return "" + strUser + "" + " " + _kind_txt + " " + _subject;
},
bom_editItem(item){
this.bom_editedIndex = this.bom_list.indexOf(item);
this.bom_editedItem = $.extend(true, {}, item);
console.log("bom_editItem:", this.bom_editedIndex, this.bom_editedItem);
//debugger;
},
bom_deleteItem(item){
confirm('確定要刪除此筆資料嗎?') && this.bom_list.splice(index, 1);
},
bom_cancel(){
this.bom_spliceNullData();
this.bom_close();
},
bom_spliceNullData() {
//if new data ,then splice it
if (this.bom_list.num == 0) {
for (var i = 0; i < this.bom_list.map(x => x.id).length; i++) {
if (this.bom_list[i].id == this.bom_list.id) {
this.bom_list.splice(i, 1); break;
}
}
}
},
bom_close() {
setTimeout(() => {
this.bom_editedItem = $.extend(true, {}, this.bom_defaultItem);
this.bom_editedItem = -1;
}, 300)
},
bom_addNew(){
this.spliceNullData();
//addObj.id = this.desserts.length + 1;
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
const addObj = $.extend(true, {}, this.bom_defaultItem);
addObj.id = (isFinite(_c) ? _c : 0) + 1;
addObj.package_num = this.prod_bom_num; ////取得主項目的package_num
addObj.actItem = { subject: '', num: 0 };
if (!!this.bom_list) this.bom_list?.unshift(addObj);
this.bom_editItem(addObj);
},
bom_save(){
if (this.bom_editedIndex > -1) {
if (this.this_id != '') {
//chcck necessary params
if (this.bom_editedItem.item_num_selected.val != 0 ) {
//insert or update data
var package_num = $(".packageNum input[type=hidden]").val();
var bom_detail =
{
num: this.bom_editedItem.num,
package_num: package_num,
item_num: this.bom_editedItem.actItem.num,
};
axios
.post(HTTP_HOST + 'api/activity/SaveDetailBomList', bom_detail)
.then(response => {
this.bom_editedItem.num = response.data;
Object.assign(this.bom_list[this.bom_editedIndex], this.bom_editedItem)
this.bom_close();
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "單號錯誤";
this.snackbar.show = true
}
}
},
},
computed: {
},
})
$(document).ready(function () {
setCss();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
});
function EndRequestHandler(sender, args) {
setCss();
}
function setCss() {
$(".cyclePanel input").addClass("form-check-input");
}
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
<template v-if="this_id !='' "> {{titleword()}} </template>
</div>
<div class="">
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
</div>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<div class="card shadow-sm my-2" id="sec2">
<div class="card-header py-0">
<nav class="navbar py-0">
<div class="nav nav-tabs">
<button class="nav-link active" id="sec2-tab1" data-bs-toggle="tab" data-bs-target="#sec2-page1"
type="button" role="tab" aria-controls="home" aria-selected="true">
基本資料</button>
<button class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2"
type="button" role="tab" aria-controls="profile" aria-selected="false">
相關文件</button>
<button class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
type="button" role="tab" aria-controls="bom" aria-selected="false">
功德項目</button>
</div>
</nav>
</div>
<div class="card-body">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active " id="sec2-page1" role="tabpanel" aria-labelledby="sec2-tab1">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">項目類別 *</label>
<div class="col-sm-4">
<asp:DropDownList ID="category" runat="server" CssClass="form-select">
<asp:ListItem Value="">請選擇</asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" ControlToValidate="category" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-form-label">項目分類 *</label>
<div class="col-sm-4">
<div class="input-group mb-3" data-search-control="search1" @click=" search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
id="kind_txt" runat="server" placeholder="請選擇" value="">
<asp:HiddenField ID="kind" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="kind_txt" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">料號</label>
<div class="col-sm-4">
<asp:TextBox ID="PARTNO" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入料號"></asp:TextBox>
</div>
<label class="col-sm-2 col-form-label">項目名稱 *</label>
<div class="col-sm-4">
<asp:TextBox ID="subject" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入品項名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="subject" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">牌位編號開頭</label>
<div class="col-sm-4">
<asp:TextBox ID="print_init" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入牌位編號開頭"></asp:TextBox>
</div>
<label class="col-sm-2 col-form-label">預設金額</label>
<div class="col-sm-4">
<asp:TextBox ID="price" MaxLength="7" runat="server" CssClass="form-control" placeholder="請輸入預設金額"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="price" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
</div>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" class="row mb-1 label-sm-right">
<ContentTemplate>
<label class="col-sm-2 col-form-label"></label>
<div class="col-sm-4">
<asp:CheckBox ID="extend" runat="server" CssClass="cyclePanel" AutoPostBack="true" OnCheckedChanged="CheckBox1_CheckedChanged" />
<label class="form-check-label me-2" for='<%= extend.ClientID %>'>
應延續
</label>
<asp:CheckBox ID="is_reconcile_item" runat="server" CssClass="cyclePanel" />
<label class="form-check-label me-2" for='<%= is_reconcile_item.ClientID %>'>
核銷項目
</label>
</div>
<asp:PlaceHolder ID="cyclePlaceHolder" runat="server" Visible="false">
<label class="col-sm-2 col-form-label">收費週期 *</label>
<div class="col-sm-4">
<div class="input-group">
<asp:TextBox ID="cycle" MaxLength="3" runat="server" CssClass="form-control"></asp:TextBox>
<span class="input-group-text">月</span>
<asp:RegularExpressionValidator ControlToValidate="cycle" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ID="RegularExpressionValidator1" runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" ControlToValidate="cycle" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
</asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">備註</label>
<div class="col-sm-10">
<asp:TextBox ID="demo" runat="server" CssClass="ckeditor" TextMode="MultiLine"></asp:TextBox>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">自定義欄位預設值</label>
<div class="col-sm-10">
<asp:TextBox ID="customize_data" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="一行輸入一個定義欄位預設值,如:&#10;$品名:醬油&#10;$金額:100" ToolTip="一行輸入一個定義欄位預設值,格式: $變數名稱:值"></asp:TextBox>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">狀態 *</label>
<div class="col-sm-2">
<label class="col-form-control">
<input type="checkbox" id="status" runat="server"
data-toggle="toggle" data-on="啟用" data-off="停用" data-onstyle="success" />
</label>
</div>
</div>
</div>
<div class="tab-pane fade giftItems label-sm-right" id="sec2-page2" role="tabpanel" aria-labelledby="sec2-tab2">
<v-card class="mx-auto mt-10" outlined v-if="this_id!=''">
<v-data-table
:headers="headersDetail"
:items="desserts"
:footer-props="footersDetail"
:search="searchDetail"
:options.sync="optionsDetail" class="elevation-1" fixed-header height="350px"
<%-- :server-items-length="desserts_count"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<v-text-field v-model="searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text"
@click="addNew">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.files_num_selected.text="{ item }">
<div class="input-group mb-3" data-search-control="search2"
@click="search_show(search_dialog.controls.search2)"
v-if="item.id === editedItem.id">
<input class="form-control search-text" type="text" readonly
placeholder="文件名稱" v-model="editedItem.files_num_selected.text" >
<input type="hidden" v-model="editedItem.files_num_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.files_num_selected.text}}</span>
<span v-if="item.num==0" class="text-danger">(預設資料,未存檔)</span>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-3" @click="cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="green" class="mr-3" @click="editItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<div class="mx-auto" v-else >
<p class="lead">請先儲存基本資料後再新增相關文件</p>
</div>
</div>
<div class="tab-pane fade giftItems label-sm-right" id="sec2-page3" role="tabpanel" aria-labelledby="sec2-tab3">
<asp:Panel ID="bom_panel" runat="server">
<div class="row mb-1">
<label class="col-sm-2 col-form-label">牌位數量</label>
<div class="col-sm-6">
<asp:TextBox CssClass="form-control" ID="bom_qty" runat="server"></asp:TextBox>
</div>
<div class="col-md-4">
<asp:button class="btn btn-primary" id="setBom" runat="server"
Text="設定子項目" OnClick="setBom_Click" Visible="true"></asp:button>
<asp:button class="btn btn-primary" id="saveBom" runat="server"
Text="儲存子項目" OnClick="saveBom_Click" Visible="true"></asp:button>
</div>
<div class="packageNum">
<asp:HiddenField ID="packageNum" runat="server"/>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">備註</label>
<div class="col-sm-10">
<asp:TextBox ID="bom_memo" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="輸入備註" ToolTip=""></asp:TextBox>
</div>
</div>
<v-card class="mx-auto mt-10" outlined v-if="this_id!=''">
<v-data-table class="elevation-1" fixed-header height="350px"
:headers="bom_headersDetail"
:items="bom_list"
:footer-props="bom_footersDetail"
:search="bom_searchDetail"
:options.sync="optionsDetail"
<%-- :server-items-length="desserts_count"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<v-text-field v-model="bom_searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text"
@click="bom_addNew">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.item_num_selected.text="{ item }">
<div class="input-group my-3" data-search-control="search3"
@click="search_show(search_dialog.controls.search3)"
v-if="item.num === bom_editedItem.num">
<input class="form-control search-text" type="text" readonly
placeholder="名稱" v-model="bom_editedItem.actItem.subject" >
<input type="hidden" v-model="bom_editedItem.actItem.num">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.actItem.subject}}</span>
<span v-if="item.num==0" class="text-danger">(預設資料,未存檔)</span>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.num === bom_editedItem.num">
<v-icon color="red" class="mr-3" @click="bom_cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="bom_save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="green" class="mr-3" @click="bom_editItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="bom_deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<div class="mx-auto" v-else >
<p class="lead">請先儲存基本資料後再新增相關文件</p>
</div>
</asp:Panel>
</div>
</div>
</div>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title" v-if="item.visible===undefined || item.visible==true "></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+249
View File
@@ -0,0 +1,249 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Globalization;
using static publicFun;
public partial class admin_activity_item_reg : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
public int prod_bom_num = 0;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
InitEnumsOptions<Model.activity.category>(category);
if (isStrNull(Request["num"]))
{
BuildKind();
status.Checked = true;
bom_panel.Visible = false;
}
else
{
int _num = Val(Request["num"]);
//var qry = _db.actItems.AsEnumerable();
var prod = _db.actItems.Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
BuildKind();
subject.Text = prod.subject;
print_init.Text = prod.print_init;
PARTNO.Text = prod.partno;
//kind.SelectedValue = prod.kind.ToString();
if (prod.kind.HasValue)
{
kind_txt.Value = prod.actItem_kind.kind;
kind.Value = prod.kind.ToString();
}
if (prod.category.HasValue) category.SelectedValue = prod.category.ToString();
if(!isStrNull(prod.demo))
demo.Text = prod.demo.ToString();
status.Checked = ValString(prod.status).Equals("Y");
extend.Checked = ValString(prod.extend).Equals("Y");
is_reconcile_item.Checked = ValString(prod.is_reconcile).Equals("Y");
setCycle();
if (prod.price.HasValue)
price.Text = prod.price.Value.ToString();
if (prod.cycle.HasValue)
cycle.Text = prod.cycle.Value.ToString();
customize_data.Text = prod.customize_data?.ToString();
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
//檢查prod有沒有對應的act_bom項目
var prodBom = prod.act_bom.FirstOrDefault();
setBom.Visible = prodBom == null;//沒有對應的act_bom項目才能新增
saveBom.Visible = prodBom != null;//有對應的act_bom項目才能儲存
//bom_qty.Enabled = prodBom != null;//有對應的act_bom項目..
bom_qty.Text = (prodBom?.qty??0).ToString();
bom_memo.Text = (prodBom?.memo ?? "");
packageNum.Value=(prodBom?.num.ToString());
prod_bom_num = prodBom?.num ?? 0;
}
else
{
Response.Redirect("index2.aspx");
}
}
}
}
protected void goback_Click(object sender, EventArgs e)
{
Response.Redirect("index2.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
public void BuildKind()
{
//kind.Items.Clear();
//kind.Items.Add(new ListItem("請選擇", ""));
//buildMultiKind(kind, "actItem_kind", 0, "", 1, Model.activity.ItemLevelMax,null ,true);
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
L_msg.Text = "";
Model.actItem actItem = new Model.actItem();//新增
actItem.subject = subject.Text;
actItem.print_init = print_init.Text;
actItem.partno = PARTNO.Text;
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
if (!isStrNull(price.Text)) { actItem.price = ValFloat(price.Text); } else { actItem.price = null; }
if (extend.Checked && !isStrNull(cycle.Text)) { actItem.cycle = Val(cycle.Text); } else { actItem.cycle = null; }
actItem.status = status.Checked ? "Y" : "N";
actItem.extend = extend.Checked ? "Y" : "N";
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
actItem.demo = demo.Text;
actItem.customize_data = customize_data.Text;
_db.actItems.Add(actItem);
_db.SaveChanges();
int _id = actItem.num;
if( _id > 0)
{
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Insert, subject.Text);
Response.Redirect("index2.aspx");
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
}
}
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
Model.actItem actItem = _db.actItems.Where(q => q.num == _num).FirstOrDefault();//修改
if (actItem != null)
{
actItem.subject = subject.Text;
actItem.print_init = print_init.Text;
actItem.partno = PARTNO.Text;
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
if (!isStrNull(price.Text)) { actItem.price = ValFloat(price.Text); } else { actItem.price = null; }
if (extend.Checked && !isStrNull(cycle.Text)) { actItem.cycle = Val(cycle.Text); } else { actItem.cycle = null; }
actItem.status = status.Checked ? "Y" : "N";
actItem.extend = extend.Checked ? "Y" : "N";
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
actItem.demo = demo.Text;
actItem.customize_data = customize_data.Text;
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Item, (int)Model.admin_log.Status.Update, subject.Text);
Response.Redirect("index2.aspx?page=" + Convert.ToString(Request["page"]));
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "查無資料";
}
}
}
#endregion
#region
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
setCycle();
}
protected void setCycle()
{
cyclePlaceHolder.Visible = extend.Checked;
}
#endregion
protected void setBom_Click(object sender, EventArgs e)
{
//新增本頁品項, 對應的actItem
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.actItems.Where(q => q.num == _num).FirstOrDefault();
var prodBom = prod.act_bom.FirstOrDefault();
if (prod != null && prodBom == null)
{
Model.act_bom actBom = new Model.act_bom();
actBom.item_num = _num;
actBom.qty = Val(bom_qty.Text);
actBom.memo = bom_memo.Text;
_db.act_bom.Add(actBom);
_db.SaveChanges();
Response.Redirect("item_reg.aspx?num=" + _num);
}
}
}
protected void saveBom_Click(object sender, EventArgs e)
{
//儲存本頁品項, 對應的actItem
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.actItems.Where(q => q.num == _num).FirstOrDefault();
var prodBom = prod.act_bom.FirstOrDefault();
if (prod != null && prodBom != null)
{
prodBom.qty = Val(bom_qty.Text);
prodBom.memo = bom_memo.Text;
_db.SaveChanges();
//Response.Redirect("item_reg.aspx?num=" + _num);
}
}
}
}
+554
View File
@@ -0,0 +1,554 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg.aspx.cs" Inherits="admin_activity_kind_reg" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<script>
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
this_id: '<%= _this_id %>',
options: {},
optionsDetail: { multiSort: false },
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '活動品項',
text_prop: 'subject',
value_prop: 'num',
keys: [
{ id: 'subject', title: '項目名稱', value: '' },
{ id: 'kindTxt', title: '項目分類' },
],
api_url: HTTP_HOST + 'api/activity/GetItemList',
columns: [
{ id: 'subject', title: '項目名稱' },
{ id: 'kindTxt', title: '項目分類' },
],
selected: {},
select(item,t) {
console.log("select search1", t);
item.actItem_num.text = t.subject
item.actItem_num.val = t.num
item.price = t.price
}
},
},
show: false,
current: {},
list: [],
count: 0,
page: 1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
},
snackbar: {
show: false,
text: "",
}//相關項目
, searchDetail: '',
headersDetail: [
{ text: '* 品項名稱', value: 'actitem_num.text', sortable: false },
{ text: '預設金額', value: 'price', sortable: false },
{ text: '數量', value: 'qty', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "200px" },
],
footersDetail: {
showFirstLastPage: false,
disableItemsPerPage: false,
itemsPerPageAllText: '',
itemsPerPageText: '',
'prev-icon': null,
'next-icon': null,
'disable-pagination': true,
'items-per-page-options': []
},
desserts: [],
desserts_count: 0,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
activity_kind_num: 0,
actItem_num: {
text: '',
val: 0
},
price: 0,
qty :0,
},
defaultItem: {
id: 0,
num: 0,
activity_kind_num: 0,
actItem_num: {
text: '',
val: 0
},
price: 0,
qty: 0,
},
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
//console.log("mounted");
},
watch: {
options: {
handler() {
//console.log("watch1", this.search_dialog, this.search_dialog.page);
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
optionsDetail: {
handler() {
this.initialize();
},
deep: true,
},
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
this.search_dialog.page = this.options.page ?? 1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
//necessary parameter===
if (this.search_dialog.current.id == 'search1') {
search['categorys'] = "1,2,4";//報名,掛單,贊助
}
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show = true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(this.editedItem,row);
}
this.search_dialog.show = false;
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
},//文件
initialize() {
if (this.this_id != '') {
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page,
//pageSize: itemsPerPage == -1 ? this.desserts.length : itemsPerPage,
pageSize: itemsPerPage,
};
var searchItemDetail = {
activity_kind_num: this.this_id,
}
axios
.post(HTTP_HOST + 'api/activity/GetKindDetail',
searchItemDetail, { params: params })
.then(response => {
this.desserts = response.data.list
this.desserts_count = response.data.count
})
.catch(
error => console.log(error)
)
}
},
editItem(item) {
this.editedIndex = this.desserts.indexOf(item);
this.editedItem = $.extend(true, {}, item);
},
deleteItem(item) {
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/activity/DeleteActKindDetail/' + item.num)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
this.desserts_count = this.desserts_count - 1;
})
.catch(error => console.log(error))
}
} else {
this.desserts.splice(index, 1)
}
}
},
cancel() {
//data-search-control need to return to the original value
this.spliceNullData();
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
}
}
}
},
close() {
setTimeout(() => {
this.editedItem = $.extend(true, {}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
addNew() {
this.spliceNullData();
//addObj.id = this.desserts.length + 1;
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
const addObj = $.extend(true, {}, this.defaultItem);
addObj.id = (isFinite(_c) ? _c : 0) + 1;
this.desserts.unshift(addObj);
this.editItem(addObj);
},
save() {
if (this.editedIndex > -1) {
if (this.this_id != '') {
//chcck necessary params
if (this.editedItem.actItem_num.val != 0 ) {
//insert or update data
var pro_order_detail =
{
num: this.editedItem.num,
activity_kind_num: this.this_id,
actItem_num: this.editedItem.actItem_num.val,
price: this.editedItem.price,
qty: this.editedItem.qty,
}
axios
.post(HTTP_HOST + 'api/activity/SaveActKindDetail', pro_order_detail)
.then(response => {
this.editedItem.num = response.data;
Object.assign(this.desserts[this.editedIndex], this.editedItem)
this.close()
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "單號錯誤";
this.snackbar.show = true
}
}
}, customSearch(value, item) {
console.log(value, item)
},
searchData(event) {
this.desserts = this.desserts.filter(item => item.actItem_num.text.toLowerCase().includes(event));
}
},
computed: {
},
filters: {
currency: function (value) {
return value == null || value === "" ? "" :
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
},
}
})
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增主分類</asp:LinkButton>
<asp:LinkButton ID="sortButton" runat="server" Visible="false" CssClass="btn btn-primary" OnClick="sortButton_Click">
<i class="mdi mdi-sort"></i> 排序選項</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4 col-lg-3">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇分類</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8 col-lg-9">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal" role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-md-3 col-form-label">* 分類名稱</label>
<div class="col-sm-10 col-md-9">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入分類名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-md-3 col-form-label">預設起始日期 </label>
<div class="col-sm-10 col-md-9 col-lg-6">
<div class="input-group">
<asp:DropDownList ID="calendar" runat="server" CssClass="form-select">
<asp:ListItem Value="">請選擇</asp:ListItem>
<asp:ListItem Value="國曆">國曆</asp:ListItem>
<asp:ListItem Value="農曆">農曆</asp:ListItem>
</asp:DropDownList>
<input type="text" class="form-control" placeholder="月" aria-label="月" id="month" runat="server">
<span class="input-group-text">月</span>
<input type="text" class="form-control" placeholder="日" aria-label="日" id="day" runat="server">
<span class="input-group-text">日</span>
</div>
</div>
<div class="col-md-3"></div>
<div class="col-sm-2 col-md-3"></div>
<div class="col-sm-10 col-md-9">
<asp:RangeValidator ID="monthRV" runat="server" SetFocusOnError="true" Display="Dynamic" ControlToValidate="month" MinimumValue="1" MaximumValue="12" Type="Integer"
ErrorMessage="月份應為1~12的數字!"></asp:RangeValidator>
<asp:RangeValidator ID="dayRV" runat="server" SetFocusOnError="true" Display="Dynamic" ControlToValidate="day" MinimumValue="1" MaximumValue="31" Type="Integer"
ErrorMessage="日期應為1~31的數字!"></asp:RangeValidator>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="col-sm-12">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<v-card class="mx-auto mt-10" outlined v-if="this_id!=''">
<v-data-table
:headers="headersDetail"
:items="desserts"
:footer-props="footersDetail"
:search="searchDetail"
<%-- :footer-props="{'items-per-page-options':[5,10,15,-1]}"每頁列數--%>
:options.sync="optionsDetail" class="elevation-1" fixed-header height="350px"
<%-- :server-items-length="desserts_count"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<v-text-field v-model="searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details @input="searchData"></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text"
@click="addNew">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.actitem_num.text="{ item }" >
<div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)" v-if="item.id === editedItem.id">
<input class="form-control search-text" type="text" readonly
placeholder="品項名稱" v-model="editedItem.actItem_num.text" >
<input type="hidden" v-model="editedItem.actItem_num.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.actItem_num.text}}</span>
</template>
<template v-slot:item.price="{ item }">
<v-text-field v-model="editedItem.price" :hide-details="true" dense single-line v-if="item.id === editedItem.id" ></v-text-field>
<span v-else>{{item.price | currency }}</span>
</template>
<template v-slot:item.qty="{ item }">
<v-text-field v-model="editedItem.qty" :hide-details="true" dense single-line v-if="item.id === editedItem.id" ></v-text-field>
<span v-else>{{item.qty}}</span>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-3" @click="cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="green" class="mr-3" @click="editItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title" v-if="item.visible===undefined || item.visible==true "></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+343
View File
@@ -0,0 +1,343 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
using System.Collections;
using System.Collections.Generic;
public partial class admin_activity_kind_reg : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.activity.KindLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
public string _this_id = "";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
_this_id = ValString(Request["num"]);
int _num = Val(Request["num"]);
var prod = _db.activity_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q=>q.kind).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的分類名稱";
item_name.Text = prod.kind;
demo.Text = prod.demo;
calendar.SelectedValue = prod.calendar;
month.Value = prod.month.HasValue? prod.month.Value.ToString():"";
day.Value = prod.day.HasValue ? prod.day.Value.ToString() : "";
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的分類】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM activity_kind ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>分類下,新增次分類";
item_name.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
calendar.SelectedValue = "";
demo.Text = "";
month.Value = "";
day.Value = "";
_this_id = ValString(Request["num"]);
_this_id = "";
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增主分類</span>";
table.Visible = true;
item_name.Text = "";
calendar.SelectedValue = "";
demo.Text = "";
month.Value = "";
day.Value = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
_this_id = "";
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.activity_kind activity_kind = _db.activity_kind.Where(q => q.num == _num).FirstOrDefault();//修改
if (activity_kind != null)
{
activity_kind.kind = item_name.Text;
activity_kind.demo = demo.Text;
if (!isStrNull(calendar.SelectedValue)) { activity_kind.calendar = calendar.SelectedValue; } else { activity_kind.calendar = null; };
if (!isStrNull(month.Value)) { activity_kind.month = Val(month.Value); } else { activity_kind.month = null; };
if (!isStrNull(day.Value)) { activity_kind.day = Val(day.Value); } else { activity_kind.day = null; };
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Update, "詳細分類:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.activity_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.activity_kind activity_kind = new Model.activity_kind();//新增
activity_kind.kind = item_name.Text;
activity_kind.demo = demo.Text;
activity_kind.root = root;
activity_kind.range = range;
if (!isStrNull(calendar.SelectedValue)) { activity_kind.calendar = calendar.SelectedValue; } else { activity_kind.calendar = null; };
if (!isStrNull(month.Value)) { activity_kind.month = Val(month.Value); } else { activity_kind.month = null; };
if (!isStrNull(day.Value)) { activity_kind.day = Val(day.Value); } else { activity_kind.day = null; };
_db.activity_kind.Add(activity_kind);
_db.SaveChanges();
int _id = activity_kind.num;
if (_id > 0)
{
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Insert, "詳細分類:" + item_name.Text);
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
}
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.activity_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.activity_kind.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Delete, "詳細分類:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.activity_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.activity_kind.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
var prod = _db.activities.AsEnumerable().Where(q => q.kind == num).ToList();
if (prod.Count > 0)
{
//清空分類
foreach (var item in prod)
item.kind = null;
_db.SaveChanges();
}
}
#endregion
protected void sortButton_Click(object sender, EventArgs e)
{
Response.Redirect("range.aspx");
}
}
+75
View File
@@ -0,0 +1,75 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg2.aspx.cs" Inherits="admin_activity_kind_reg2" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="footer_script" runat="Server">
<link href="../../App_Script/bootstrap_toggle/css/bootstrap-toggle.min.css" rel="stylesheet" />
<script src="../../App_Script/bootstrap_toggle/js/bootstrap-toggle.min.js"></script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增主類型</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立下一層選項</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇類型</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal label-sm-right " role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1">
<label class="col-sm-2 col-lg-3 col-form-label">* 類型名稱</label>
<div class="col-sm-10 col-lg-9">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入類型名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
</div>
</asp:Content>
+307
View File
@@ -0,0 +1,307 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
public partial class admin_activity_kind_reg2 : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.news.KindLevelMax; //類型層數
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
if (!isStrNull(Request["num"]))
{
int _num = Val(Request["num"]);
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.num == _num).Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的類型名稱";
item_name.Text = prod.kind;
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的類型】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM activity_category_kind ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>類型下,新增次類型";
item_name.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增主類型</span>";
table.Visible = true;
item_name.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.activity_category_kind activity_category_kind = _db.activity_category_kind.Where(q => q.num == _num).FirstOrDefault();//修改
if (activity_category_kind != null)
{
activity_category_kind.kind = item_name.Text;
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Update, "主類型:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.activity_category_kind activity_category_kind = new Model.activity_category_kind();//新增
activity_category_kind.kind = item_name.Text;
activity_category_kind.root = root;
activity_category_kind.range = range;
_db.activity_category_kind.Add(activity_category_kind);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Insert, "主類型:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.activity_category_kind.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Delete, "主類型:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.activity_category_kind.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num) //刪除訊息
{
//EF Model 資料庫拉關聯 , 故刪除類型前,一定要先刪除訊息,否則關聯會出錯
var prod = _db.activities.AsEnumerable().Where(q => q.category_kind == num).ToList();
if (prod.Count > 0)
{
//改為清空類型
foreach (var item in prod)
item.kind = null;
_db.SaveChanges();
}
}
#endregion
protected void sortButton_Click(object sender, EventArgs e)
{
Response.Redirect("range.aspx");
}
}
File diff suppressed because it is too large Load Diff
+393
View File
@@ -0,0 +1,393 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Globalization;
public partial class admin_activity_reg : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
public string _category_kindTxt = "相關";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (isStrNull(Request["num"]))
{
BuildKind();
}
else
{
int _num = Val(Request["num"]);
//var qry = _db.activities.AsEnumerable();
var prod = _db.activities.Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
BuildKind();
try
{
foreach (Control obj in cardBodyPanel.Controls)
{
if (obj is TextBox)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var textBox = (TextBox)obj;
if (textBox.TextMode == TextBoxMode.Date)
{
textBox.Text = Convert.ToDateTime(ObjValue).ToString("yyyy-MM-dd");
}
else
{
textBox.Text = ObjValue.ToString();
}
}
}
else if (obj is DropDownList && ((DropDownList)obj).SelectedIndex == 0)
{
var ObjValue = prod.GetType().GetProperty(obj.ID).GetValue(prod, null);
if (!isStrNull(ObjValue))
{
var dropDown = (DropDownList)obj;
dropDown.SelectedValue = ObjValue.ToString();
}
}
}
}
catch (Exception)
{
}
if (prod.kind.HasValue)
{
kind_txt.Value = prod.activity_kind.kind;
kind.Value = prod.kind.Value.ToString();
kind_txt2.Text = "<div class='pt-2'>" + prod.activity_kind.kind + "</div>";
}
if (prod.category_kind.HasValue)
{
_category_kindTxt = prod.activity_category_kind.kind;
category_kind_txt.Value = prod.activity_category_kind.kind;
category_kind.Value = prod.category_kind.Value.ToString();
}
if (prod.startDate_solar.HasValue)
{
startDate_lunar.Text= publicFun.chagenDate(prod.startDate_solar);
}
if (prod.endDate_solar.HasValue)
{
endDate_lunar.Text = publicFun.chagenDate(prod.endDate_solar);
}
if (prod.reg_time.HasValue)
{
timePanel1.Visible = true;
reg_time.Text = prod.reg_time.Value.ToString("yyyy/MM/dd HH:mm:ss");
}
kindPH.Visible = false;
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
}
else
{
Response.Redirect("index.aspx");
}
}
}
}
protected void goback_Click(object sender, EventArgs e)
{
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
public void BuildKind()
{
}
protected void kind_SelectedIndexChanged(object sender, EventArgs e)
{
//if (isStrNull(Request["num"])) // 只有新增時帶入預設
//{
// if (!isStrNull(kind.SelectedValue))
// {
// int _kind = Val(kind.SelectedValue);
// //日期
// var prop3 = _db.activity_kind.Where(q => q.num == _kind).FirstOrDefault();
// if (prop3 != null)
// {
// ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
// string _calendar = prop3.calendar;
// DateTime _today = DateTime.Now;
// if (_calendar == "國曆")
// {
// DateTime _newDay = Convert.ToDateTime(DateTime.Now.Year + "/" + prop3.month + "/" + prop3.day);
// if (_today.Month >= prop3.month && _today.Day >= prop3.day)
// {
// //過期->預設明年
// _newDay = Convert.ToDateTime(DateTime.Now.AddYears(1).Year + "/" + prop3.month + "/" + prop3.day);
// }
// else
// {
// //未過期->預設今年
// }
// startDate_solar.Text = _newDay.ToString("yyyy-MM-dd");
// endDate_solar.Text = _newDay.ToString("yyyy-MM-dd");
// DateTime _newDay2 = Convert.ToDateTime(chineseDate.GetYear(_newDay) + "/" + chineseDate.GetMonth(_newDay) + "/" + chineseDate.GetDayOfMonth(_newDay));
// startDate_lunar.Text = _newDay2.ToString("yyyy-MM-dd");
// endDate_lunar.Text = _newDay2.ToString("yyyy-MM-dd");
// //TaiwanLunisolarCalendar tlc = new TaiwanLunisolarCalendar();
// //DateTime _newDay3 = Convert.ToDateTime(tlc.GetYear(_newDay) + "/" + tlc.GetMonth(_newDay) + "/" + tlc.GetDayOfMonth(_newDay));
// // -> TaiwanLunisolarCalendar 民國年農曆
// }
// else if (_calendar == "農曆")
// {
// }
// }
// //項目
// DataTable dt = createNewDt();
// var qry = _db.activity_kind_detail.AsEnumerable().Where(q => q.activity_kind_num == _kind && q.actItem.status == "Y");
// var prop = qry.OrderBy(q => q.reg_time).ToList();
// if (prop.Count > 0)
// {
// foreach (var item in prop)
// {
// DataRow dr = dt.NewRow();
// //dr["num"] = item.actItem_num;
// dr["num"] = ""; //新增時為空
// dr["actItem_num"] = item.actItem_num;
// dr["price"] = item.price.HasValue ? item.price.Value.ToString() : "";
// dr["qty"] = item.qty.HasValue ? item.qty.Value.ToString() : "";
// dt.Rows.Add(dr);
// }
// }
// Repeater1.DataSource = dt;
// Repeater1.DataBind();
// //var query =
// //from c in _db.actItems.AsEnumerable()
// //where ((from o in _db.activity_kind_detail.AsEnumerable()
// // where o.activity_kind_num == _kind
// // select o.actItem_num)
// // .Contains(c.num) && c.status=="Y")
// //select c;
// dt = createNewDt2();
// var prop2 = qry.Where(q=>q.actItem.spares=="Y").OrderBy(q => q.reg_time).ToList();
// if (prop2.Count > 0)
// {
// foreach (var item in prop2)
// {
// DataRow dr = dt.NewRow();
// dr["num"] = "";
// dr["actItem_num"] = item.actItem_num;
// dr["qty1"] = item.qty.HasValue ? item.qty.Value.ToString() : "";
// dr["qty2"] = "";
// dr["demo"] = "";
// dt.Rows.Add(dr);
// }
// }
// Repeater2.DataSource = dt;
// Repeater2.DataBind();
// }
// else
// {
// Repeater1.DataSource = null;
// Repeater1.DataBind();
// Repeater2.DataSource = null;
// Repeater2.DataBind();
// }
//}
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
L_msg.Text = "";
Model.activity activity = new Model.activity();
try
{
foreach (Control obj in cardBodyPanel.Controls)
{
if (obj is TextBox)
{
var ObjValue = activity.GetType().GetProperty(obj.ID);
var textBox = (TextBox)obj;
if (!isStrNull(textBox.Text))
{
if (textBox.TextMode == TextBoxMode.Date)
ObjValue.SetValue(activity, selectDate(textBox));
else
ObjValue.SetValue(activity, ((TextBox)obj).Text.Trim());
}
else
ObjValue.SetValue(activity, null);
}
else if (obj is DropDownList)
{
var ObjValue = activity.GetType().GetProperty(obj.ID);
var dropDown = (DropDownList)obj;
if (!isStrNull(dropDown.SelectedValue))
{
if (!isStrNull(dropDown.Attributes["data-int"]) && ValString(dropDown.Attributes["data-int"]).Equals("Y"))
ObjValue.SetValue(activity, Val(dropDown.SelectedValue));
else
ObjValue.SetValue(activity, dropDown.SelectedValue);
}
else
ObjValue.SetValue(activity, null);
}
}
// printInit 欄位
//var printInitValue = printInit.Text.Trim();
//activity.print_init = !string.IsNullOrEmpty(printInitValue) ? printInitValue : null;
activity.kind = Val(kind.Value);
activity.category_kind = Val(category_kind.Value);
activity.reg_time = DateTime.Now;
_db.activities.Add(activity);
_db.SaveChanges();
int _id = activity.num;
if (_id > 0)
{
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Insert, subject.Text);
Response.Redirect("index.aspx");
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
}
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "操作失敗";
}
}
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
Model.activity activity = _db.activities.Where(q => q.num == _num).FirstOrDefault(); // 修改
if (activity != null)
{
try
{
foreach (Control obj in cardBodyPanel.Controls)
{
if (obj is TextBox)
{
var ObjValue = activity.GetType().GetProperty(obj.ID);
var textBox = (TextBox)obj;
if (!isStrNull(textBox.Text))
{
if (textBox.TextMode == TextBoxMode.Date)
ObjValue.SetValue(activity, selectDate(textBox));
else
ObjValue.SetValue(activity, ((TextBox)obj).Text.Trim());
}
else
ObjValue.SetValue(activity, null);
}
else if (obj is DropDownList)
{
var ObjValue = activity.GetType().GetProperty(obj.ID);
var dropDown = (DropDownList)obj;
if (!isStrNull(dropDown.SelectedValue))
{
if (!isStrNull(dropDown.Attributes["data-int"]) && ValString(dropDown.Attributes["data-int"]).Equals("Y"))
ObjValue.SetValue(activity, Val(dropDown.SelectedValue));
else
ObjValue.SetValue(activity, dropDown.SelectedValue);
}
else
ObjValue.SetValue(activity, null);
}
}
// printInit 欄位
//var printInitValue = printInit.Text.Trim();
//activity.print_init = !string.IsNullOrEmpty(printInitValue) ? printInitValue : null;
activity.category_kind = Val(category_kind.Value);
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Update, subject.Text);
}
catch (Exception ex)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "操作失敗";
}
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "查無資料";
}
}
}
#endregion
}
+230
View File
@@ -0,0 +1,230 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="activity.aspx.cs" Inherits="admin_activity_statistics_activity" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server" />
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server" />
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div class="container mt-1" id="app">
<v-container fluid>
<v-card class="elevation-2 pa-4 rounded-lg">
<!-- 標題 -->
<v-row justify="center">
<v-col cols="12" class="text-center">
<v-icon size="36" color="primary">mdi-account-group</v-icon>
<h2 class="font-weight-bold mt-2">參加活動信眾統計表</h2>
<v-divider class="my-4"></v-divider>
</v-col>
</v-row>
<!-- 匯出按鈕 -->
<v-row class="align-center mb-4">
<v-col cols="12" class="text-right">
<v-btn color="green darken-2" class="white--text" @click="exportToExcel">
<v-icon left>mdi-microsoft-excel</v-icon> 匯出 Excel
</v-btn>
</v-col>
</v-row>
<!-- 全選/取消 -->
<v-row class="mb-3" justify="start" align="center" dense>
<v-col cols="auto" class="pr-1">
<v-btn small color="primary" @click="selectAll">全選</v-btn>
</v-col>
<v-col cols="auto" class="pl-1">
<v-btn small color="primary" @click="deselectAll">取消全選</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="statistics.summary_headers"
:items="statistics.summary_rows"
class="elevation-1 rounded-lg"
dense
hide-default-footer
disable-sort
>
<!-- 勾選欄:主項名稱(對齊左邊) -->
<template #item.label="{ item }">
<div>
<v-checkbox
v-model="exportSettings.selectedItems"
:value="item.label"
hide-details
dense
class="mr-2 text-center"
></v-checkbox>
<span class="font-weight-medium">{{ item.label }}</span>
</div>
</template>
<!-- 數量欄:對齊右邊 -->
<template #item.value="{ item }">
<div class="text-center font-weight-bold pr-2">
{{ item.value }}
</div>
</template>
<!-- 名單勾選欄:置中 -->
<template #item.include_followers="{ item }">
<div>
<v-checkbox
v-if="item.canHaveFollowers"
v-model="exportSettings.itemFollowers[item.label]"
hide-details
dense
class="ma-0"
color="primary"
label="含名單"
></v-checkbox>
</div>
</template>
</v-data-table>
</v-card>
</v-container>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<!-- 匯出套件 -->
<script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js"></script>
<script>
let VueApp = new Vue({
el: "#app",
vuetify: new Vuetify(vuetify_options),
data() {
return {
this_id: '<%= Request["num"] %>',
exportSettings: {
selectedItems: [],
itemFollowers: {}
},
statistics: {
summary_rows: [],
summary_headers: [
{ text: '項目(勾選匯出)', value: 'label', align: 'center' },
{ text: '數量', value: 'value', align: 'center' },
{ text: '名單', value: 'include_followers', align: 'center' }
]
},
raw_gdz_items: []
};
},
mounted() {
this.getGDZCount();
},
methods: {
getGDZCount() {
axios.post(HTTP_HOST + 'api/statistics/GDZCount', null, {
params: { activity_num: this.this_id }
}).then(res => {
const raw = res.data;
this.raw_gdz_items = raw.gdz_item_counts;
this.statistics.summary_rows = [
{ label: "報名總人數", value: raw.all_count },
{ label: "功德主人數", value: raw.all_gdz_count }
];
raw.gdz_item_counts.forEach(item => {
this.statistics.summary_rows.push({
label: item.item_name,
value: item.count,
canHaveFollowers: true
});
this.$set(this.exportSettings.itemFollowers, item.item_name, false);
});
});
},
exportToExcel() {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hour = now.getHours().toString().padStart(2, '0');
const minute = now.getMinutes().toString().padStart(2, '0');
const dateStr = `${year}-${month}-${day} ${hour}:${minute}`;
const filename = `活動統計明細_${dateStr.replace(/[: ]/g, '_')}.xlsx`;
const selectedLabels = this.exportSettings.selectedItems;
const selectedItems = this.raw_gdz_items.filter(item =>
selectedLabels.includes(item.item_name)
);
const aoa = [];
// 統計時間
aoa.push([`統計時間:`, `${dateStr}`]);
const totalRow = this.statistics.summary_rows.find(r => r.label === '報名總人數');
const gdzRow = this.statistics.summary_rows.find(r => r.label === '功德主人數');
if (totalRow) aoa.push([totalRow.label, totalRow.value + '人']);
if (gdzRow) aoa.push([gdzRow.label, gdzRow.value + '人']);
aoa.push([])
aoa.push(['牌位功德項目', '數量', '供花果,供齋', '數量', '金額']);
selectedItems.forEach(item => {
if (!item.item_name.includes('供') && !item.item_name.includes('齋')) {
aoa.push([item.item_name, `${item.count}`]);
const includeFollowers = this.exportSettings.itemFollowers[item.item_name];
if (includeFollowers && Array.isArray(item.followers)) {
item.followers.forEach((name, index) => {
aoa.push(['', index + 1 + '.' + name]);
});
}
}
});
var row = 5
selectedItems.forEach(item => {
if (item.item_name.includes('供') || item.item_name.includes('齋')) {
if (!aoa[row]) aoa[row] = []; // 防止該行不存在
//aoa.push([item.item_name + ' 總計金額:' + item.total_price, `${item.count}`]);
aoa[row][2] = item.item_name;
aoa[row][3] = `${item.count}`;
aoa[row][4] = '$' + item.total_price;
row++;
const includeFollowers = this.exportSettings.itemFollowers[item.item_name];
if (includeFollowers && Array.isArray(item.followers)) {
item.followers.forEach((name, index) => {
//aoa.push(['', index + 1 + '.' + name]);
aoa[row][2] = index + 1 + '.' + name
const gk = item.amountsByFollower.find(x => x.follower === name);
const amount = '$' + gk.amount; // 找不到就回傳 0 或其他預設值
aoa[row][4] = amount
row++;
});
}
}
})
const sheet = XLSX.utils.aoa_to_sheet(aoa);
const range = XLSX.utils.decode_range(sheet['!ref']);
for (let R = range.s.r; R <= range.e.r; ++R) {
for (let C = range.s.c; C <= range.e.c; ++C) {
const cell_address = XLSX.utils.encode_cell({ r: R, c: C });
if (!sheet[cell_address]) continue;
if (!sheet[cell_address].s) sheet[cell_address].s = {};
sheet[cell_address].s.alignment = { horizontal: 'center', vertical: 'center' };
}
}
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, sheet, '統計資料');
const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'array', cellStyles: true });
const blob = new Blob([wbout], { type: 'application/octet-stream' });
saveAs(blob, filename);
},
selectAll() {
this.exportSettings.selectedItems = this.statistics.summary_rows
.map(row => row.label);
},
deselectAll() {
this.exportSettings.selectedItems = [];
}
}
});
</script>
</asp:Content>
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_activity_statistics_activity : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
+144
View File
@@ -0,0 +1,144 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_statistics_index" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
<div class="col-2">
<select class="form-select" v-model="selected_activity">
<option disabled value="">請選擇活動</option>
<option v-for="(item, index) in activity_list" :key="index" :value="item.num">
{{item.subject}}
</option>
</select>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div class="container-fluid mt-1">
<div class="text-center text-h5 font-weight-bold my-4">
活動統計報表
</div>
<v-data-table
multi-sort
:headers="activity_statistics.headers"
item-key="id"
:loading="activity_statistics.loading"
:loading-text="activity_statistics.loadingtext"
:options.sync="activity_statistics.options"
:items-per-page="activity_statistics.options.itemsPerPage"
:server-items-length="activity_statistics.totalItems"
:items="activity_statistics.items">
<template #item.detail_btn="{item}">
<a :href="'activity.aspx?num='+item.id" class="btn btn-outline-secondary btn-sm" target="_blank">詳細統計</a>
</template>
<template #item.duetime="{item}">
{{item.startdate|timeString("YYYY/MM/DD")}}-{{item.enddate|timeString("YYYY/MM/DD")}}
</template>
</v-data-table>
</div>
<div class="container-fluid mt-1">
<div class="text-center text-h5 font-weight-bold my-4">信眾統計表</div>
<p>
{{activity_statistics.allGDZCount}}
</p>
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
activity_list: [],
selected_activity: '',
activity_statistics: {
loading: false,
loadingtext: "資料載入中...",
headers: [
{ text: '活動名稱', value: 'activity_name' },
{ text: '報名人數', value: 'order_count' },
{ text: '應收功德金', value: 'receivable' },
{ text: '實收功德金', value: 'received' },
{ text: '牌位總數', value: 'pw_count' },
{ text: '新增信眾人數', value: '' },//針對當前活動
{ text: '流失信眾人數', value: '' },//針對當前活動
{ text: '回歸信眾人數', value: '' },//針對當前活動
{ text: '連續多次參加信眾人數', value: '' },//針對當前活動
{ text: '功德主人數', value: 'gdz_peoples' },
{ text: '活動時間', value: 'duetime' },
{ text: '活動狀態', value: 'activity_status' },
{ text: '', value: 'detail_btn' }
],
items: [],
totalItems: 0,
options: {
page: 1,
itemsPerPage: 5,
sortBy: [],
sortDesc: [],
},
allGDZCount: 0,
}
}
},
mounted() {
this.getActivityList();
//this.getActivityStatistics();
},
methods: {
getActivityList() {
axios
.post(HTTP_HOST + 'api/statistics/activitylist')
.then(res => {
this.activity_list = res.data
})
.catch(error => {
})
},
getActivityStatistics() {
this.activity_statistics.loading = true;
const { page, itemsPerPage } = this.activity_statistics.options;
axios
.post(HTTP_HOST + 'api/statistics/activitycountlist', null, { params:{ page: page, pagesize: itemsPerPage }})
.then(res => {
this.activity_statistics.items = res.data.items;
this.activity_statistics.totalItems = res.data.count;
console.log(this.activity_statistics.options)
})
.catch(error => {
})
.finally(() => {
this.activity_statistics.loading = false;
})
},
},
watch: {
selected_activity: {
handler(newvalue, oldvalue) {
console.log('新值:', newvalue);
console.log('舊值:', oldvalue);
},
deep: true
},
'activity_statistics.options': {
handler() {
this.getActivityStatistics();
},
deep: true
}
},
computed: {
}
})
</script>
</asp:Content>
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_statistics_index : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
+397
View File
@@ -0,0 +1,397 @@
<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="kind_reg.aspx.cs" Inherits="admin_bed_kind_reg" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<script>
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
this_id: '<%= _this_id %>',
this_root: '<%= _this_root %>',
options: {},
optionsDetail: { multiSort: false },
snackbar: {
show: false,
text: "",
}//床位
, searchDetail: '',
headersDetail: [
{ text: '* 床位編號', value: 'bed_name', sortable: false },
{ text: '* 床位型態', value: 'bed_type_txt', sortable: false },
{ text: '備註', value: 'demo', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "120px" },
],
desserts: [],
desserts_count: 0,
desserts_page: 1,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
bed_name: '',
bed_type: 0,
bed_type_txt: '',
demo: '',
},
defaultItem: {
id: 0,
num: 0,
bed_name: '',
bed_type: 0,
bed_type_txt: '',
demo: '',
},
bed_type_items: [{ //床位下單選項
text: "請選擇",
val: 0
},],
}
},
mounted() {
//console.log("mounted");
this.bedTypeArray();
},
watch: {
options: {
handler() {
},
deep: true,
},
optionsDetail: {
handler() {
this.initialize();
},
deep: true,
},
},
methods: {
bedTypeArray() {
var getArray = <%=Newtonsoft.Json.JsonConvert.SerializeObject(_bedType, Newtonsoft.Json.Formatting.Indented) %>;
if (getArray != undefined && getArray != null ) {
var keys = Object.keys(getArray);
for (let i = 0; i < keys.length; i++) {
console.log(`${keys[i]}:${getArray[keys[i]]}`); //value : text
var _tmp = {
text: getArray[keys[i]],
val: parseInt(keys[i]),
}
this.bed_type_items.push(_tmp);
}
}
},
initialize() {
if (this.this_id != '' && this.this_root != '' && this.this_root != '0') {
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
//this.desserts_page = this.options.page ?? 1
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
//page: this.desserts_page, pageSize: 10,
page: 1,
pageSize: itemsPerPage,
//page: page, pageSize: itemsPerPage == -1 ? 9999 : itemsPerPage,
};
var searchBedDetail = {
bed_kind_id: this.this_id,
}
axios
.post(HTTP_HOST + 'api/bed_kind/GetDetailList', searchBedDetail, { params: params })
.then(response => {
this.desserts = response.data.list
this.desserts_count = response.data.count
})
.catch(
error => console.log(error)
)
}
},
editItem(item) {
this.editedIndex = this.desserts.indexOf(item);
this.editedItem = Object.assign({}, item);
},
deleteItem(item) {
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/bed_kind/DeleteBedKindDetail/' + item.num)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
this.desserts_count = this.desserts_count - 1;
})
.catch(error => console.log(error))
}
} else {
this.desserts.splice(index, 1)
}
}
},
cancel() {
this.spliceNullData();
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
}
}
}
},
close() {
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
addNew() {
this.spliceNullData();
//addObj.id = this.desserts.length + 1;
this.editedIndex = -1;
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
const addObj = Object.assign({}, this.defaultItem);
addObj.id = (isFinite(_c) ? _c : 0) + 1;
this.desserts.unshift(addObj);
this.editItem(addObj);
},
save() {
if (this.editedIndex > -1) {
if (this.this_id != '') {
//chcck necessary params
if (this.editedItem.bed_name != '' && this.editedItem.bed_type >0 ) {
//insert or update data
var kind_detail =
{
num: this.editedItem.num,
bed_kind_id: this.this_id,
bed_name: this.editedItem.bed_name,
bed_type: this.editedItem.bed_type,
demo: this.editedItem.demo,
}
axios
.post(HTTP_HOST + 'api/bed_kind/SaveBedKindDetail', kind_detail)
.then(response => {
this.editedItem.num = response.data;
//處理下拉文字
this.editedItem.bed_type_txt = this.bed_type_items[this.editedItem.bed_type].text;
Object.assign(this.desserts[this.editedIndex], this.editedItem)
this.close()
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "房號錯誤";
this.snackbar.show = true
}
}
},
},
computed: {
},
})
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<nav class="mb-1">
<asp:LinkButton ID="ImageButton4" runat="server" CausesValidation="False" OnClick="ImageButton4_Click" CssClass="btn btn-primary"><i class="mdi mdi-plus"></i> 新增樓層</asp:LinkButton>
<asp:LinkButton ID="sortButton" runat="server" Visible="false" CssClass="btn btn-primary" OnClick="sortButton_Click">
<i class="mdi mdi-sort"></i> 排序選項</asp:LinkButton>
</nav>
<nav class="mb-1">
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="add" runat="server" Text="新增" Visible="false" OnClick="add_Click" CssClass="btn btn-primary" />
<asp:PlaceHolder ID="down_table" runat="server">
<asp:LinkButton ID="ImageButton5" runat="server" OnClick="ImageButton5_Click" CssClass="btn btn-outline-secondary" CausesValidation="False"><i class="mdi mdi-arrow-down-right"></i> 建立房號</asp:LinkButton>
<asp:LinkButton ID="ImageButton6" runat="server" OnClientClick="return msgconfirm('是否確定刪除這筆資料?<br>注意!資料刪除後將一併刪除此資料的子選項!',this);" OnClick="ImageButton6_Click" CssClass="btn btn-outline-secondary"><i class="mdi mdi-trash-can"></i> 刪除</asp:LinkButton>
</asp:PlaceHolder>
</nav>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid pb-4">
<div class="row">
<div class="col-sm-4 col-lg-3">
<div class="card shadow-sm my-2" id="sec1">
<div class="card-header">選擇分類</div>
<div class="card-body">
<asp:TreeView ID="TreeView2" runat="server" CssClass="aspxTree" ImageSet="Arrows"
SkipLinkText="" ShowLines="false" EnableTheming="False" ShowExpandCollapse="True">
</asp:TreeView>
</div>
</div>
</div>
<div class="col-sm-8 col-lg-9">
<asp:Panel ID="table" runat="server" CssClass="card shadow-sm my-2">
<div class="card-header">
<div>
<asp:Label ID="start" runat="server" CssClass="text-danger" Display="Dynamic"></asp:Label>
</div>
<div>
<asp:Label ID="title_msg" runat="server" CssClass="" ForeColor=""></asp:Label>
</div>
</div>
<div class="card-body form-horizontal" role="form">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-md-2 col-form-label">* <asp:Literal ID="Literal1" runat="server" Text="樓層名稱"></asp:Literal></label>
<div class="col-sm-10 " v-bind:class="[this_root !='' && this_root !='0' ? ' col-md-10' : ' col-md-4']">
<asp:TextBox ID="item_name" runat="server" CssClass="form-control" MaxLength="100" placeholder="請輸入樓層名稱"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="item_name" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<asp:PlaceHolder ID="sexPlaceHolder" runat="server">
<label class="col-sm-2 col-md-2 col-form-label">* 樓層類型</label>
<div class="col-sm-10 col-md-4">
<asp:DropDownList ID="sex" CssClass="form-select" runat="server">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
<asp:ListItem Value="男眾" Text="男眾"></asp:ListItem>
<asp:ListItem Value="女眾" Text="女眾"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="sex" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</asp:PlaceHolder>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="col-sm-12">
<asp:TextBox ID="demo" runat="server" CssClass="form-control" TextMode="MultiLine" Rows="3" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<v-card class="mx-auto mt-10" outlined v-if="this_id!='' && this_root !='' && this_root !='0'">
<v-data-table
:headers="headersDetail"
:items="desserts"
:search="searchDetail"
:options.sync="optionsDetail" class="elevation-1" fixed-header height="350px"
<%-- :server-items-length="desserts_count"
:page.sync="desserts_page"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<v-text-field v-model="searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text"
@click="addNew">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.bed_name="{ item }">
<v-text-field v-model="editedItem.bed_name" :hide-details="true" dense single-line v-if="item.id === editedItem.id" :maxlength=50 ></v-text-field>
<span v-else>{{item.bed_name}}</span>
<span v-if="item.num==0" class="text-danger">(預設資料,未存檔)</span>
</template>
<template v-slot:item.bed_type_txt="{ item }">
<v-select
item-text="text"
item-value="val"
v-model="editedItem.bed_type"
:items="bed_type_items"
v-if="item.id === editedItem.id"
></v-select>
<span v-else>{{item.bed_type_txt}}</span>
</template>
<template v-slot:item.demo="{ item }">
<v-text-field v-model="editedItem.demo" :hide-details="true" dense single-line v-if="item.id === editedItem.id" ></v-text-field>
<span v-else>{{item.demo}}</span>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-3" @click="cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="green" class="mr-3" @click="editItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<div class="form-group">
<div class="col-sm-offset-3 col-md-offset-2 col-sm-9 col-md-10">
<asp:HiddenField ID="HiddenField1" runat="server" />
</div>
</div>
</div>
</asp:Panel>
</div>
</div>
<v-snackbar
v-model="snackbar.show"
timeout="2000"
>
{{ snackbar.text }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>
+379
View File
@@ -0,0 +1,379 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using System.Data.Entity.Infrastructure;
using System.Collections;
using System.Collections.Generic;
public partial class admin_bed_kind_reg : MyWeb.config
{
DataTable treeDt = new DataTable();
const int LevelMax = Model.bed_order.KindLevelMax; //分類層數
private Model.ezEntities _db = new Model.ezEntities();
public string _this_id = "";
public string _this_root = "";
public Dictionary<int, string> _bedType = null;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
BuildTreeView();
_bedType = publicFun.enum_desc<Model.bed_kind.bed_type>(); //床位型態
if (!isStrNull(Request["num"]))
{
_this_id = ValString(Request["num"]);
int _num = Val(Request["num"]);
var prod = _db.bed_kind.AsEnumerable().Where(q => q.num == _num).FirstOrDefault();
if (prod != null)
{
title_msg.Text = "修改<span class=\"text-primary\">【" + prod.kind + "】</span>的分類名稱";
item_name.Text = prod.kind;
sex.SelectedValue = prod.sex;
demo.Text = prod.demo;
_this_root = prod.root.ToString();
if (prod.root > 0)
{
sexPlaceHolder.Visible = false;
}
HiddenField1.Value = prod.kind;
}
else
{
Response.Redirect(Request.Url.AbsolutePath );
}
edit.Visible = true;
add.Visible = false;
down_table.Visible = true;
start.Visible = false;
}
else
{
table.Visible = false;
down_table.Visible = false;
if (Convert.ToString(Request["msg"]) == "A") { start.Text = "【資料修改成功】"; }
else if (Convert.ToString(Request["msg"]) == "B") { start.Text = "【資料新增成功】"; }
else if (Convert.ToString(Request["msg"]) == "C") { start.Text = "【資料刪除成功】"; }
else { start.Text = "【請點選下方欲新增、修改或刪除的分類】"; }
}
}
}
#region
protected void TreeTopology()
{
MyWeb.sql sql = new MyWeb.sql();
OleDbConnection sqlConn = sql.conn(db, p_name);
try
{
sqlConn.Open();
OleDbCommand sqlCmd = new OleDbCommand("", sqlConn);
sqlCmd.CommandText = "SELECT num,kind,root FROM bed_kind ORDER BY kind,root, range";
treeDt = sql.dataTable(sqlCmd);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
sqlConn.Close();
sqlConn.Dispose();
}
}
public void BuildTreeView()
{
TreeView2.Nodes.Clear();
TreeTopology();
BuildChild(0, TreeView2.Nodes);
treeDt.Dispose();
}
public void BuildChild(int RootUid, TreeNodeCollection Nodes, int Level=1)
{
DataTable dt = treeDt;
foreach (DataRow row in dt.Rows)
{
if (row["root"].ToString() == RootUid.ToString())
{
TreeNode NewNode = new TreeNode();
if (Convert.ToString(Request["num"]) == row["num"].ToString() & HiddenField1.Value != "AddMainItem")
{
NewNode.Text = "<b><span style=\"color:blue\">" + row["kind"].ToString() + "</span></b>";
if (Level +1 > LevelMax)
{
ImageButton5.Visible = false;
}
}
else
{
NewNode.Text = row["kind"].ToString();
}
NewNode.NavigateUrl = Request.Url.AbsolutePath + "?num=" + row["num"].ToString() ;
NewNode.Expand();
Nodes.Add(NewNode);
if (Level + 1 <= LevelMax)
{
BuildChild((int)row["num"], NewNode.ChildNodes, Level + 1);
}
}
}
}
#endregion
#region
protected void ImageButton5_Click(object sender, EventArgs e)
{
title_msg.Text = "於<span class=\"text-primary\">【" + HiddenField1.Value + "】</span>樓層下,新增房號";
item_name.Text = "";
sex.SelectedValue = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
demo.Text = "";
_this_id = "";
_this_root = Request["num"];
Literal1.Text = "房號/房名";
sexPlaceHolder.Visible = false;
}
protected void ImageButton4_Click(object sender, EventArgs e)
{
title_msg.Text = "<span class=\"text-primary\">於根目錄下,新增樓層</span>";
table.Visible = true;
item_name.Text = "";
sex.SelectedValue = "";
demo.Text = "";
add.Visible = true;
edit.Visible = false;
down_table.Visible = false;
start.Visible = false;
HiddenField1.Value = "AddMainItem";
BuildTreeView();
_this_id = "";
_this_root = "";
Literal1.Text = "樓層名稱";
sexPlaceHolder.Visible = true;
}
#endregion
#region
protected void edit_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int _num = Val(Request["num"]);
try
{
Model.bed_kind bed_kind = _db.bed_kind.Where(q => q.num == _num).FirstOrDefault();//修改
if (bed_kind != null)
{
bed_kind.kind = item_name.Text;
bed_kind.sex = sex.SelectedValue;
bed_kind.demo = demo.Text;
_db.SaveChanges();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Bed, (int)Model.admin_log.Status.Update, "分類:" + item_name.Text);
//for postback
_this_id = _num.ToString();
_this_root = bed_kind.root.ToString();
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "無此資料";
}
}
catch (DbUpdateConcurrencyException)
{
L_msg.Type = alert_type.danger;
L_msg.Text = "Error";
throw;
}
BuildTreeView();
}
#endregion
#region
protected void add_Click(object sender, EventArgs e)
{
L_msg.Text = "";
int range = 1;
int root = 0;
if (HiddenField1.Value != "AddMainItem")
{
root = Convert.ToInt32(Request["num"]);
}
try
{
var prod = _db.bed_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
if (prod != null)
if (prod.range.HasValue)
range = prod.range.Value + 1;
Model.bed_kind bed_kind = new Model.bed_kind();//新增
bed_kind.kind = item_name.Text;
bed_kind.demo = demo.Text;
bed_kind.root = root;
bed_kind.range = range;
bed_kind.sex = sex.SelectedValue;
_db.bed_kind.Add(bed_kind);
_db.SaveChanges();
int _id = bed_kind.num;
_this_root = root.ToString();
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Bed, (int)Model.admin_log.Status.Insert, "分類:" + item_name.Text);
L_msg.Type = alert_type.success;
L_msg.Text = "操作成功";
}
catch (DbUpdateConcurrencyException)
{
throw;
}
BuildTreeView();
}
#endregion
#region
protected void ImageButton6_Click(object sender, EventArgs e)
{
int num = Val(Request["num"]);
del_product(num);
var prod = _db.bed_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
if (prod != null)
{
_db.bed_kind.Remove(prod);
_db.SaveChanges(); //執行
}
Del_Ohter_Items(Val(Request["num"]));
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Bed, (int)Model.admin_log.Status.Delete, "分類:" + item_name.Text);
Response.Redirect(Request.Url.AbsolutePath + "?msg=C");
}
public void Del_Ohter_Items(int d_num)
{
var prod = _db.bed_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
if (prod.Count > 0)
{
foreach (var row in prod)
{
del_product(row.num);
Del_Ohter_Items(row.num);
}
//查詢結果全部刪除
_db.bed_kind.RemoveRange(prod);
_db.SaveChanges();
}
}
public void del_product(int num)
{
//床位資料
var prod = _db.bed_kind_detail.AsEnumerable().Where(q => q.bed_kind_id == num).ToList();
if (prod.Count > 0)
{
//清空分類
foreach (var item in prod)
{
//掛單資料
var prod2 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_kind_detail_id == item.num).ToList();
if (prod2.Count > 0)
{
//清空分類
foreach (var item2 in prod2)
item2.bed_kind_detail_id = null;
}
item.bed_kind_id = null;
}
_db.SaveChanges();
}
//掛單資料
var prod3 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_kind1 == num || q.bed_kind2 == num).ToList();
if (prod3.Count > 0)
{
//清空分類
foreach (var item in prod3)
{
if(item.bed_kind1 == num) item.bed_kind1 = null;
if(item.bed_kind2 == num) item.bed_kind2 = null;
}
_db.SaveChanges();
}
}
#endregion
protected void sortButton_Click(object sender, EventArgs e)
{
Response.Redirect("range.aspx");
}
}
+422
View File
@@ -0,0 +1,422 @@
<%@ Page Title="17168-CheckOut" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="checkOut.aspx.cs" Inherits="admin_checkOut" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<nav class="navbar bg-light navbar-light border-top border-bottom px-2">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item navitem1" data-class="light" href="#">Light</a></li>
<li><a class="dropdown-item navitem2" data-class="dark" href="#">Dark</a></li>
<li><a class="dropdown-item navitem3" data-class="info" href="#">Info</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Separated link</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
</nav>
<div class="p-2">
<div class="g-5">
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Form</button>
<button class="nav-link" id="nav-profile-tab" data-bs-toggle="tab" data-bs-target="#nav-profile" type="button" role="tab" aria-controls="nav-profile" aria-selected="false">Table</button>
<button class="nav-link" id="nav-contact-tab" data-bs-toggle="tab" data-bs-target="#nav-contact" type="button" role="tab" aria-controls="nav-contact" aria-selected="false">Card/Buttons</button>
</div>
</nav>
</div>
<div class="tab-content mt-2" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
<div class="container">
<div class="row">
<div class="col-md-5 col-lg-4 order-md-last">
<h4 class="d-flex justify-content-between align-items-center mb-3">
<span class="text-primary">Your cart</span>
<span class="badge bg-primary rounded-pill">3</span>
</h4>
<ul class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between lh-sm">
<div>
<h6 class="my-0">Product name</h6>
<small class="text-muted">Brief description</small>
</div>
<span class="text-muted">$12</span>
</li>
<li class="list-group-item d-flex justify-content-between lh-sm">
<div>
<h6 class="my-0">Second product</h6>
<small class="text-muted">Brief description</small>
</div>
<span class="text-muted">$8</span>
</li>
<li class="list-group-item d-flex justify-content-between lh-sm">
<div>
<h6 class="my-0">Third item</h6>
<small class="text-muted">Brief description</small>
</div>
<span class="text-muted">$5</span>
</li>
<li class="list-group-item d-flex justify-content-between bg-light">
<div class="text-success">
<h6 class="my-0">Promo code</h6>
<small>EXAMPLECODE</small>
</div>
<span class="text-success">$5</span>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Total (USD)</span>
<strong>$20</strong>
</li>
</ul>
<form class="card p-2">
<div class="input-group">
<input type="text" class="form-control" placeholder="Promo code">
<button type="submit" class="btn btn-secondary">Redeem</button>
</div>
</form>
</div>
<div class="col-md-7 col-lg-8">
<h4 class="mb-3">Billing address</h4>
<form class="needs-validation" novalidate>
<div class="row g-3">
<div class="col-sm-6">
<label for="firstName" class="form-label">First name</label>
<input type="text" class="form-control" id="firstName" placeholder="" value="" required>
<div class="invalid-feedback">
Valid first name is required.
</div>
</div>
<div class="col-sm-6">
<label for="lastName" class="form-label">Last name</label>
<input type="text" class="form-control" id="lastName" placeholder="" value="" required>
<div class="invalid-feedback">
Valid last name is required.
</div>
</div>
<div class="col-12">
<label for="username" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text">@</span>
<input type="text" class="form-control" id="username" placeholder="Username" required>
<div class="invalid-feedback">
Your username is required.
</div>
</div>
</div>
<div class="col-12">
<label for="email" class="form-label">Email <span class="text-muted">(Optional)</span></label>
<input type="email" class="form-control" id="email" placeholder="you@example.com">
<div class="invalid-feedback">
Please enter a valid email address for shipping updates.
</div>
</div>
<div class="col-12">
<label for="address" class="form-label">Address</label>
<input type="text" class="form-control" id="address" placeholder="1234 Main St" required>
<div class="invalid-feedback">
Please enter your shipping address.
</div>
</div>
<div class="col-12">
<label for="address2" class="form-label">Address 2 <span class="text-muted">(Optional)</span></label>
<input type="text" class="form-control" id="address2" placeholder="Apartment or suite">
</div>
<div class="col-md-5">
<label for="country" class="form-label">Country</label>
<select class="form-select" id="country" required>
<option value="">Choose...</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
<option>United States</option>
</select>
<div class="invalid-feedback">
Please select a valid country.
</div>
</div>
<div class="col-md-4">
<label for="state" class="form-label">State</label>
<select class="form-select" id="state" required>
<option value="">Choose...</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
<option>California</option>
</select>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div>
<div class="col-md-3">
<label for="zip" class="form-label">Zip</label>
<input type="text" class="form-control" id="zip" placeholder="" required>
<div class="invalid-feedback">
Zip code required.
</div>
</div>
</div>
<hr class="my-4">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="same-address">
<label class="form-check-label" for="same-address">Shipping address is the same as my billing address</label>
</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="save-info">
<label class="form-check-label" for="save-info">Save this information for next time</label>
</div>
<hr class="my-4">
<h4 class="mb-3">Payment</h4>
<div class="my-3">
<div class="form-check">
<input id="credit" name="paymentMethod" type="radio" class="form-check-input" checked required>
<label class="form-check-label" for="credit">Credit card</label>
</div>
<div class="form-check">
<input id="debit" name="paymentMethod" type="radio" class="form-check-input" required>
<label class="form-check-label" for="debit">Debit card</label>
</div>
<div class="form-check">
<input id="paypal" name="paymentMethod" type="radio" class="form-check-input" required>
<label class="form-check-label" for="paypal">PayPal</label>
</div>
</div>
<div class="row gy-3">
<div class="col-md-6">
<label for="cc-name" class="form-label">Name on card</label>
<input type="text" class="form-control" id="cc-name" placeholder="" required>
<small class="text-muted">Full name as displayed on card</small>
<div class="invalid-feedback">
Name on card is required
</div>
</div>
<div class="col-md-6">
<label for="cc-number" class="form-label">Credit card number</label>
<input type="text" class="form-control" id="cc-number" placeholder="" required>
<div class="invalid-feedback">
Credit card number is required
</div>
</div>
<div class="col-md-3">
<label for="cc-expiration" class="form-label">Expiration</label>
<input type="text" class="form-control" id="cc-expiration" placeholder="" required>
<div class="invalid-feedback">
Expiration date required
</div>
</div>
<div class="col-md-3">
<label for="cc-cvv" class="form-label">CVV</label>
<input type="text" class="form-control" id="cc-cvv" placeholder="" required>
<div class="invalid-feedback">
Security code required
</div>
</div>
</div>
<hr class="my-4">
<button class="w-100 btn btn-primary btn-lg" type="submit">Continue to checkout</button>
</form>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">
<table class="table caption-top table-striped">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
</div>
<div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">
<div class="my-2">
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-light">Light</button>
<button type="button" class="btn btn-dark">Dark</button>
<button type="button" class="btn btn-link">Link</button>
</div>
<div class="my-2">
<button type="button" class="btn btn-outline-primary">Primary</button>
<button type="button" class="btn btn-outline-secondary">Secondary</button>
<button type="button" class="btn btn-outline-success">Success</button>
<button type="button" class="btn btn-outline-danger">Danger</button>
<button type="button" class="btn btn-outline-warning">Warning</button>
<button type="button" class="btn btn-outline-info">Info</button>
<button type="button" class="btn btn-outline-light">Light</button>
<button type="button" class="btn btn-outline-dark">Dark</button>
</div>
<div class="my-2">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
Featured
</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="footer_script" runat="Server">
<script>
$(".navitem1,.navitem2,.navitem3").click(function (e) {
e.preventDefault();
var c1 = $(this).data("class");
var c2 = `navbar-${c1} bg-${c1}`;
var c3 = `sb-sidenav-${c1}`;
$("#layoutSidenav_nav .nav-link").removeClass("text-info");
if (c1 == "info") {
c2 = `navbar-dark bg-${c1}`;
$("#layoutSidenav_nav .nav-link").addClass("text-info");
}
$(".sb-topnav")
.removeClass("navbar-dark bg-dark navbar-light bg-light")
.addClass(c2);
$(".sb-sidenav").removeClass("sb-sidenav-dark sb-sidenav-light")
.addClass(c3);
});
</script>
</asp:Content>
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_checkOut : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
+378
View File
@@ -0,0 +1,378 @@
CKEditor 4 Changelog
====================
## CKEditor 4.3.1
**Important Notes:**
* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)).
* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)).
Fixed Issues:
* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event.
* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method.
* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder.
* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu.
* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option.
* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor.
* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions.
* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes.
* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image.
* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image.
* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading.
* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget.
* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details.
* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer.
* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode.
* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item.
* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back.
* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more.
* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked.
* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle.
* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements.
* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors.
* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word.
* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the `<textarea>` element are not encoded.
* [#11260](http://dev.ckeditor.com/ticket/11260): Fixed: Initially disabled buttons are not read by JAWS as disabled.
* [#11200](http://dev.ckeditor.com/ticket/11200): Added [Clipboard](http://ckeditor.com/addon/clipboard) plugin as a dependency for [Widget](http://ckeditor.com/addon/widget) to fix drag and drop.
## CKEditor 4.3
New Features:
* [#10612](http://dev.ckeditor.com/ticket/10612): Internet Explorer 11 support.
* [#10869](http://dev.ckeditor.com/ticket/10869): Widgets: Added better integration with the [Elements Path](http://ckeditor.com/addon/elementspath) plugin.
* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: Added tooltip to the drag handle.
* [#10933](http://dev.ckeditor.com/ticket/10933): Widgets: Introduced drag and drop of block widgets with the [Line Utilities](http://ckeditor.com/addon/lineutils) plugin.
* [#10936](http://dev.ckeditor.com/ticket/10936): Widget System changes for easier integration with other dialog systems.
* [#10895](http://dev.ckeditor.com/ticket/10895): [Enhanced Image](http://ckeditor.com/addon/image2): Added file browser integration.
* [#11002](http://dev.ckeditor.com/ticket/11002): Added the [`draggable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-draggable) option to disable drag and drop support for widgets.
* [#10937](http://dev.ckeditor.com/ticket/10937): [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget improvements:
* loading indicator ([#10948](http://dev.ckeditor.com/ticket/10948)),
* applying paragraph changes (like font color change) to iframe ([#10841](http://dev.ckeditor.com/ticket/10841)),
* Firefox and IE9 clipboard fixes ([#10857](http://dev.ckeditor.com/ticket/10857)),
* fixing same origin policy issue ([#10840](http://dev.ckeditor.com/ticket/10840)),
* fixing undo bugs ([#10842](http://dev.ckeditor.com/ticket/10842), [#10930](http://dev.ckeditor.com/ticket/10930)),
* fixing other minor bugs.
* [#10862](http://dev.ckeditor.com/ticket/10862): [Placeholder](http://ckeditor.com/addon/placeholder) plugin was rewritten as a widget.
* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.
* [#10856](http://dev.ckeditor.com/ticket/10856): Menu buttons will now toggle the visibility of their panels when clicked multiple times. [Language](http://ckeditor.com/addon/language) plugin fixes: Added active language highlighting, added an option to remove the language.
* [#10028](http://dev.ckeditor.com/ticket/10028): New [`config.dialog_noConfirmCancel`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-dialog_noConfirmCancel) configuration option that eliminates the need to confirm closing of a dialog window when the user changed any of its fields.
* [#10848](http://dev.ckeditor.com/ticket/10848): Integrate remaining plugins ([Styles](http://ckeditor.com/addon/stylescombo), [Format](http://ckeditor.com/addon/format), [Font](http://ckeditor.com/addon/font), [Color Button](http://ckeditor.com/addon/colorbutton), [Language](http://ckeditor.com/addon/language) and [Indent](http://ckeditor.com/addon/indent)) with [active filter](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter).
* [#10855](http://dev.ckeditor.com/ticket/10855): Change the extension of emoticons in the [BBCode](http://ckeditor.com/addon/bbcode) sample from GIF to PNG.
Fixed Issues:
* [#10831](http://dev.ckeditor.com/ticket/10831): [Enhanced Image](http://ckeditor.com/addon/image2): Merged `image2inline` and `image2block` into one `image2` widget.
* [#10835](http://dev.ckeditor.com/ticket/10835): [Enhanced Image](http://ckeditor.com/addon/image2): Improved visibility of the resize handle.
* [#10836](http://dev.ckeditor.com/ticket/10836): [Enhanced Image](http://ckeditor.com/addon/image2): Preserve custom mouse cursor while resizing the image.
* [#10939](http://dev.ckeditor.com/ticket/10939): [Firefox] [Enhanced Image](http://ckeditor.com/addon/image2): hovering the image causes it to change.
* [#10866](http://dev.ckeditor.com/ticket/10866): Fixed: Broken *Tab* key navigation in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
* [#10833](http://dev.ckeditor.com/ticket/10833): Fixed: *Lock ratio* option should be on by default in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
* [#10881](http://dev.ckeditor.com/ticket/10881): Various improvements to *Enter* key behavior in nested editables.
* [#10879](http://dev.ckeditor.com/ticket/10879): [Remove Format](http://ckeditor.com/addon/removeformat) should not leak from a nested editable.
* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [WebSpellChecker](http://ckeditor.com/addon/wsc) fails to apply changes if a nested editable was focused.
* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [SCAYT](http://ckeditor.com/addon/wsc) blocks typing in nested editables.
* [#11079](http://dev.ckeditor.com/ticket/11079): Add button icons to the [Placeholder](http://ckeditor.com/addon/placeholder) sample.
* [#10870](http://dev.ckeditor.com/ticket/10870): The `paste` command is no longer being disabled when the clipboard is empty.
* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.
* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: [Link](http://ckeditor.com/addon/link) plugin does not work with non-editable content.
* [#10828](http://dev.ckeditor.com/ticket/10828): [Magic Line](http://ckeditor.com/addon/magicline) integration with the Widget System.
* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.
* [#11066](http://dev.ckeditor.com/ticket/11066): Widget's private parts use CSS reset.
* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed: Block commands break on widgets; added the [`contentDomInvalidated`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDomInvalidated) event.
* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of the [Image](http://ckeditor.com/addon/image) plugin on the [Form Elements](http://ckeditor.com/addon/forms) plugin.
* [#10911](http://dev.ckeditor.com/ticket/10911): Fixed: Browser *Alt* hotkeys will no longer be blocked while a widget is focused.
* [#11082](http://dev.ckeditor.com/ticket/11082): Fixed: Selected widget is not copied or cut when using toolbar buttons or context menu.
* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed list and div element application to block widgets.
* [#10887](http://dev.ckeditor.com/ticket/10887): Internet Explorer 8 compatibility issues related to the Widget System.
* [#11074](http://dev.ckeditor.com/ticket/11074): Temporarily disabled inline widget drag and drop, because of seriously buggy native `range#moveToPoint` method.
* [#11098](http://dev.ckeditor.com/ticket/11098): Fixed: Wrong selection position after undoing widget drag and drop.
* [#11110](http://dev.ckeditor.com/ticket/11110): Fixed: IFrame and Flash objects are being incorrectly pasted in certain conditions.
* [#11129](http://dev.ckeditor.com/ticket/11129): Page break is lost when loading data.
* [#11123](http://dev.ckeditor.com/ticket/11123): [Firefox] Widget is destroyed after being dragged outside of `<body>`.
* [#11124](http://dev.ckeditor.com/ticket/11124): Fixed the [Elements Path](http://ckeditor.com/addon/elementspath) in an editor using the [Div Editing Area](http://ckeditor.com/addon/divarea).
## CKEditor 4.3 Beta
New Features:
* [#9764](http://dev.ckeditor.com/ticket/9764): Widget System.
* [Widget plugin](http://ckeditor.com/addon/widget) introducing the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget).
* New [`editor.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) and [`editor.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-shiftEnterMode) properties &ndash; normalized versions of [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) and [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
* Dynamic editor settings. Starting from CKEditor 4.3 Beta, *Enter* mode values and [content filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) instances may be changed dynamically (for example when the caret was placed in an element in which editor features should be adjusted). When you are implementing a new editor feature, you should base its behavior on [dynamic](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) or [static](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) *Enter* mode values depending on whether this feature works in selection context or globally on editor content.
* Dynamic *Enter* mode values &ndash; [`editor.setActiveEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveEnterMode) method, [`editor.activeEnterModeChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeEnterModeChange) event, and two properties: [`editor.activeEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) and [`editor.activeShiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeShiftEnterMode).
* Dynamic content filter instances &ndash; [`editor.setActiveFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveFilter) method, [`editor.activeFilterChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeFilterChange) event, and [`editor.activeFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter) property.
* "Fake" selection was introduced. It makes it possible to virtually select any element when the real selection remains hidden. See the [`selection.fake`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-fake) method.
* Default [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied to non-editable elements (elements with `contenteditable` attribute set to `false` and their descendants) anymore. To add a rule which will be applied to all elements you need to pass an additional argument to the [`filter.addRules`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter-method-addRules) method.
* Dozens of new methods were introduced &ndash; most interesting ones:
* [`document.find`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-find),
* [`document.findOne`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-findOne),
* [`editable.insertElementIntoRange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange),
* [`range.moveToClosestEditablePosition`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-moveToClosestEditablePosition),
* New methods for [`htmlParser.node`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.node) and [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element).
* [#10659](http://dev.ckeditor.com/ticket/10659): New [Enhanced Image](http://ckeditor.com/addon/image2) plugin that introduces a widget with integrated image captions, an option to center images, and dynamic "click and drag" resizing.
* [#10664](http://dev.ckeditor.com/ticket/10664): New [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin that introduces the MathJax widget.
* [#7987](https://dev.ckeditor.com/ticket/7987): New [Language](http://ckeditor.com/addon/language) plugin that implements Language toolbar button to support [WCAG 3.1.2 Language of Parts](http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html).
* [#10708](http://dev.ckeditor.com/ticket/10708): New [smileys](http://ckeditor.com/addon/smiley).
## CKEditor 4.2.3
Fixed Issues:
* [#10994](http://dev.ckeditor.com/ticket/10994): Fixed: Loading external jQuery library when opening the [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) sample directly from file.
* [#10975](http://dev.ckeditor.com/ticket/10975): [IE] Fixed: Error thrown while opening the color palette.
* [#9929](http://dev.ckeditor.com/ticket/9929): [Blink/WebKit] Fixed: A non-breaking space is created once a character is deleted and a regular space is typed.
* [#10963](http://dev.ckeditor.com/ticket/10963): Fixed: JAWS issue with the keyboard shortcut for [Magic Line](http://ckeditor.com/addon/magicline).
* [#11096](http://dev.ckeditor.com/ticket/11096): Fixed: TypeError: Object has no method 'is'.
## CKEditor 4.2.2
Fixed Issues:
* [#9314](http://dev.ckeditor.com/ticket/9314): Fixed: Incorrect error message on closing a dialog window without saving changs.
* [#10308](http://dev.ckeditor.com/ticket/10308): [IE10] Fixed: Unspecified error when deleting a row.
* [#10945](http://dev.ckeditor.com/ticket/10945): [Chrome] Fixed: Clicking with a mouse inside the editor does not show the caret.
* [#10912](http://dev.ckeditor.com/ticket/10912): Prevent default action when content of a non-editable link is clicked.
* [#10913](http://dev.ckeditor.com/ticket/10913): Fixed [`CKEDITOR.plugins.addExternal`](http://docs.ckeditor.com/#!/api/CKEDITOR.resourceManager-method-addExternal) not handling paths including file name specified.
* [#10666](http://dev.ckeditor.com/ticket/10666): Fixed [`CKEDITOR.tools.isArray`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-isArray) not working cross frame.
* [#10910](http://dev.ckeditor.com/ticket/10910): [IE9] Fixed JavaScript error thrown in Compatibility Mode when clicking and/or typing in the editing area.
* [#10868](http://dev.ckeditor.com/ticket/10868): [IE8] Prevent the browser from crashing when applying the Inline Quotation style.
* [#10915](http://dev.ckeditor.com/ticket/10915): Fixed: Invalid CSS filter in the Kama skin.
* [#10914](http://dev.ckeditor.com/ticket/10914): Plugins [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock) are now included in the build configuration.
* [#10812](http://dev.ckeditor.com/ticket/10812): Fixed [`range#createBookmark2`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-createBookmark2) incorrectly normalizing offsets. This bug was causing many issues: [#10850](http://dev.ckeditor.com/ticket/10850), [#10842](http://dev.ckeditor.com/ticket/10842).
* [#10951](http://dev.ckeditor.com/ticket/10951): Reviewed and optimized focus handling on panels (combo, menu buttons, color buttons, and context menu) to enhance accessibility. Fixed [#10705](http://dev.ckeditor.com/ticket/10705), [#10706](http://dev.ckeditor.com/ticket/10706) and [#10707](http://dev.ckeditor.com/ticket/10707).
* [#10704](http://dev.ckeditor.com/ticket/10704): Fixed a JAWS issue with the Select Color dialog window title not being announced.
* [#10753](http://dev.ckeditor.com/ticket/10753): The floating toolbar in inline instances now has a dedicated accessibility label.
## CKEditor 4.2.1
Fixed Issues:
* [#10301](http://dev.ckeditor.com/ticket/10301): [IE9-10] Undo fails after 3+ consecutive paste actions with a JavaScript error.
* [#10689](http://dev.ckeditor.com/ticket/10689): Save toolbar button saves only the first editor instance.
* [#10368](http://dev.ckeditor.com/ticket/10368): Move language reading direction definition (`dir`) from main language file to core.
* [#9330](http://dev.ckeditor.com/ticket/9330): Fixed pasting anchors from MS Word.
* [#8103](http://dev.ckeditor.com/ticket/8103): Fixed pasting nested lists from MS Word.
* [#9958](http://dev.ckeditor.com/ticket/9958): [IE9] Pressing the "OK" button will trigger the `onbeforeunload` event in the popup dialog.
* [#10662](http://dev.ckeditor.com/ticket/10662): Fixed styles from the Styles drop-down list not registering to the ACF in case when the [Shared Spaces plugin](http://ckeditor.com/addon/sharedspace) is used.
* [#9654](http://dev.ckeditor.com/ticket/9654): Problems with Internet Explorer 10 Quirks Mode.
* [#9816](http://dev.ckeditor.com/ticket/9816): Floating toolbar does not reposition vertically in several cases.
* [#10646](http://dev.ckeditor.com/ticket/10646): Removing a selected sublist or nested table with *Backspace/Delete* removes the parent element.
* [#10623](http://dev.ckeditor.com/ticket/10623): [WebKit] Page is scrolled when opening a drop-down list.
* [#10004](http://dev.ckeditor.com/ticket/10004): [ChromeVox] Button names are not announced.
* [#10731](http://dev.ckeditor.com/ticket/10731): [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin breaks cloning of editor configuration.
* It is now possible to set per instance [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin configuration instead of setting the configuration globally.
## CKEditor 4.2
**Important Notes:**
* Dropped compatibility support for Internet Explorer 7 and Firefox 3.6.
* Both the Basic and the Standard distribution packages will not contain the new [Indent Block](http://ckeditor.com/addon/indentblock) plugin. Because of this the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) might remove block indentations from existing contents. If you want to prevent this, either [add an appropriate ACF rule to your filter](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) or create a custom build based on the Basic/Standard package and add the Indent Block plugin in [CKBuilder](http://ckeditor.com/builder).
New Features:
* [#10027](http://dev.ckeditor.com/ticket/10027): Separated list and block indentation into two plugins: [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock).
* [#8244](http://dev.ckeditor.com/ticket/8244): Use *(Shift+)Tab* to indent and outdent lists.
* [#10281](http://dev.ckeditor.com/ticket/10281): The [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) is now available. Several jQuery-related issues fixed: [#8261](http://dev.ckeditor.com/ticket/8261), [#9077](http://dev.ckeditor.com/ticket/9077), [#8710](http://dev.ckeditor.com/ticket/8710), [#8530](http://dev.ckeditor.com/ticket/8530), [#9019](http://dev.ckeditor.com/ticket/9019), [#6181](http://dev.ckeditor.com/ticket/6181), [#7876](http://dev.ckeditor.com/ticket/7876), [#6906](http://dev.ckeditor.com/ticket/6906).
* [#10042](http://dev.ckeditor.com/ticket/10042): Introduced [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title) setting to change the human-readable title of the editor.
* [#9794](http://dev.ckeditor.com/ticket/9794): Added [`editor.onChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.
* [#9923](http://dev.ckeditor.com/ticket/9923): HiDPI support in the editor UI. HiDPI icons for [Moono skin](http://ckeditor.com/addon/moono) added.
* [#8031](http://dev.ckeditor.com/ticket/8031): Handle `required` attributes on `<textarea>` elements &mdash; introduced [`editor.required`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-required) event.
* [#10280](http://dev.ckeditor.com/ticket/10280): Ability to replace `<textarea>` elements with the inline editor.
Fixed Issues:
* [#10599](http://dev.ckeditor.com/ticket/10599): [Indent](http://ckeditor.com/addon/indent) plugin is no longer required by the [List](http://ckeditor.com/addon/list) plugin.
* [#10370](http://dev.ckeditor.com/ticket/10370): Inconsistency in data events between framed and inline editors.
* [#10438](http://dev.ckeditor.com/ticket/10438): [FF, IE] No selection is done on an editable element on executing [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData).
## CKEditor 4.1.3
New Features:
* Added new translation: Indonesian.
Fixed Issues:
* [#10644](http://dev.ckeditor.com/ticket/10644): Fixed a critical bug when pasting plain text in Blink-based browsers.
* [#5189](http://dev.ckeditor.com/ticket/5189): [Find/Replace](http://ckeditor.com/addon/find) dialog window: rename "Cancel" button to "Close".
* [#10562](http://dev.ckeditor.com/ticket/10562): [Housekeeping] Unified CSS gradient filter formats in the [Moono](http://ckeditor.com/addon/moono) skin.
* [#10537](http://dev.ckeditor.com/ticket/10537): Advanced Content Filter should register a default rule for [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
* [#10610](http://dev.ckeditor.com/ticket/10610): [`CKEDITOR.dialog.addIframe()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-static-method-addIframe) incorrectly sets the iframe size in dialog windows.
## CKEditor 4.1.2
New Features:
* Added new translation: Sinhala.
Fixed Issues:
* [#10339](http://dev.ckeditor.com/ticket/10339): Fixed: Error thrown when inserted data was totally stripped out after filtering and processing.
* [#10298](http://dev.ckeditor.com/ticket/10298): Fixed: Data processor breaks attributes containing protected parts.
* [#10367](http://dev.ckeditor.com/ticket/10367): Fixed: [`editable.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertText) loses characters when `RegExp` replace controls are being inserted.
* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error when `document.domain` has been altered.
* [#9761](http://dev.ckeditor.com/ticket/9761): Update the *Backspace* key state in [`keystrokeHandler.blockedKeystrokes`](http://docs.ckeditor.com/#!/api/CKEDITOR.keystrokeHandler-property-blockedKeystrokes) when calling [`editor.setReadOnly()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly).
* [#6504](http://dev.ckeditor.com/ticket/6504): Fixed: Race condition while loading several [`config.customConfig`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig) files.
* [#10146](http://dev.ckeditor.com/ticket/10146): [Firefox] Empty lines are being removed while [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).
* [#10360](http://dev.ckeditor.com/ticket/10360): Fixed: ARIA `role="application"` should not be used for dialog windows.
* [#10361](http://dev.ckeditor.com/ticket/10361): Fixed: ARIA `role="application"` should not be used for floating panels.
* [#10510](http://dev.ckeditor.com/ticket/10510): Introduced unique voice labels to differentiate between different editor instances.
* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.
* [#10389](http://dev.ckeditor.com/ticket/10389): Fixed: Invalid HTML in the "Text and Table" template.
* [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin user interface was changed to match CKEditor 4 style.
## CKEditor 4.1.1
New Features:
* Added new translation: Albanian.
Fixed Issues:
* [#10172](http://dev.ckeditor.com/ticket/10172): Pressing *Delete* or *Backspace* in an empty table cell moves the cursor to the next/previous cell.
* [#10219](http://dev.ckeditor.com/ticket/10219): Error thrown when destroying an editor instance in parallel with a `mouseup` event.
* [#10265](http://dev.ckeditor.com/ticket/10265): Wrong loop type in the [File Browser](http://ckeditor.com/addon/filebrowser) plugin.
* [#10249](http://dev.ckeditor.com/ticket/10249): Wrong undo/redo states at start.
* [#10268](http://dev.ckeditor.com/ticket/10268): [Show Blocks](http://ckeditor.com/addon/showblocks) does not recover after switching to Source view.
* [#9995](http://dev.ckeditor.com/ticket/9995): HTML code in the `<textarea>` should not be modified by the [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor).
* [#10320](http://dev.ckeditor.com/ticket/10320): [Justify](http://ckeditor.com/addon/justify) plugin should add elements to Advanced Content Filter based on current [Enter mode](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode).
* [#10260](http://dev.ckeditor.com/ticket/10260): Fixed: Advanced Content Filter blocks [`tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces). Unified `data-cke-*` attributes filtering.
* [#10315](http://dev.ckeditor.com/ticket/10315): [WebKit] [Undo manager](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager) should not record snapshots after a filling character was added/removed.
* [#10291](http://dev.ckeditor.com/ticket/10291): [WebKit] Space after a filling character should be secured.
* [#10330](http://dev.ckeditor.com/ticket/10330): [WebKit] The filling character is not removed on `keydown` in specific cases.
* [#10285](http://dev.ckeditor.com/ticket/10285): Fixed: Styled text pasted from MS Word causes an infinite loop.
* [#10131](http://dev.ckeditor.com/ticket/10131): Fixed: [`undoManager.update()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-method-update) does not refresh the command state.
* [#10337](http://dev.ckeditor.com/ticket/10337): Fixed: Unable to remove `<s>` using [Remove Format](http://ckeditor.com/addon/removeformat).
## CKEditor 4.1
Fixed Issues:
* [#10192](http://dev.ckeditor.com/ticket/10192): Closing lists with the *Enter* key does not work with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) in several cases.
* [#10191](http://dev.ckeditor.com/ticket/10191): Fixed allowed content rules unification, so the [`filter.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-allowedContent) property always contains rules in the same format.
* [#10224](http://dev.ckeditor.com/ticket/10224): Advanced Content Filter does not remove non-empty `<a>` elements anymore.
* Minor issues in plugin integration with Advanced Content Filter:
* [#10166](http://dev.ckeditor.com/ticket/10166): Added transformation from the `align` attribute to `float` style to preserve backward compatibility after the introduction of Advanced Content Filter.
* [#10195](http://dev.ckeditor.com/ticket/10195): [Image](http://ckeditor.com/addon/image) plugin no longer registers rules for links to Advanced Content Filter.
* [#10213](http://dev.ckeditor.com/ticket/10213): [Justify](http://ckeditor.com/addon/justify) plugin is now correctly registering rules to Advanced Content Filter when [`config.justifyClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-justifyClasses) is defined.
## CKEditor 4.1 RC
New Features:
* [#9829](http://dev.ckeditor.com/ticket/9829): Advanced Content Filter - data and features activation based on editor configuration.
Brand new data filtering system that works in 2 modes:
* Based on loaded features (toolbar items, plugins) - the data will be filtered according to what the editor in its
current configuration can handle.
* Based on [`config.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent) rules - the data
will be filtered and the editor features (toolbar items, commands, keystrokes) will be enabled if they are allowed.
See the `datafiltering.html` sample, [guides](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) and [`CKEDITOR.filter` API documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).
* [#9387](http://dev.ckeditor.com/ticket/9387): Reintroduced [Shared Spaces](http://ckeditor.com/addon/sharedspace) - the ability to display toolbar and bottom editor space in selected locations and to share them by different editor instances.
* [#9907](http://dev.ckeditor.com/ticket/9907): Added the [`contentPreview`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-contentPreview) event for preview data manipulation.
* [#9713](http://dev.ckeditor.com/ticket/9713): Introduced the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin that brings raw HTML editing for inline editor instances.
* Included in [#9829](http://dev.ckeditor.com/ticket/9829): Introduced new events, [`toHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toHtml) and [`toDataFormat`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toDataFormat), allowing for better integration with data processing.
* [#9981](http://dev.ckeditor.com/ticket/9981): Added ability to filter [`htmlParser.fragment`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.fragment), [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element) etc. by many [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter)s before writing structure to an HTML string.
* Included in [#10103](http://dev.ckeditor.com/ticket/10103):
* Introduced the [`editor.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-status) property to make it easier to check the current status of the editor.
* Default [`command`](http://docs.ckeditor.com/#!/api/CKEDITOR.command) state is now [`CKEDITOR.TRISTATE_DISABLE`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-TRISTATE_DISABLED). It will be activated on [`editor.instanceReady`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-instanceReady) or immediately after being added if the editor is already initialized.
* [#9796](http://dev.ckeditor.com/ticket/9796): Introduced `<s>` as a default tag for strikethrough, which replaces obsolete `<strike>` in HTML5.
## CKEditor 4.0.3
Fixed Issues:
* [#10196](http://dev.ckeditor.com/ticket/10196): Fixed context menus not opening with keyboard shortcuts when [Autogrow](http://ckeditor.com/addon/autogrow) is enabled.
* [#10212](http://dev.ckeditor.com/ticket/10212): [IE7-10] Undo command throws errors after multiple switches between Source and WYSIWYG view.
* [#10219](http://dev.ckeditor.com/ticket/10219): [Inline editor] Error thrown after calling [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy).
## CKEditor 4.0.2
Fixed Issues:
* [#9779](http://dev.ckeditor.com/ticket/9779): Fixed overriding [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl) with `CKEDITOR_GETURL`.
* [#9772](http://dev.ckeditor.com/ticket/9772): Custom buttons in the dialog window footer have different look and size ([Moono](http://ckeditor.com/addon/moono), [Kama](http://ckeditor.com/addon/kama) skins).
* [#9029](http://dev.ckeditor.com/ticket/9029): Custom styles added with the [`stylesSet.add()`](http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet-method-add) are displayed in the wrong order.
* [#9887](http://dev.ckeditor.com/ticket/9887): Disable [Magic Line](http://ckeditor.com/addon/magicline) when [`editor.readOnly`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) is set.
* [#9882](http://dev.ckeditor.com/ticket/9882): Fixed empty document title on [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) if set via the Document Properties dialog window.
* [#9773](http://dev.ckeditor.com/ticket/9773): Fixed rendering problems with selection fields in the Kama skin.
* [#9851](http://dev.ckeditor.com/ticket/9851): The [`selectionChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-selectionChange) event is not fired when mouse selection ended outside editable.
* [#9903](http://dev.ckeditor.com/ticket/9903): [Inline editor] Bad positioning of floating space with page horizontal scroll.
* [#9872](http://dev.ckeditor.com/ticket/9872): [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) returns `true` when called onload. Removed the obsolete `editor.mayBeDirty` flag.
* [#9893](http://dev.ckeditor.com/ticket/9893): [IE] Fixed broken toolbar when editing mixed direction content in Quirks mode.
* [#9845](http://dev.ckeditor.com/ticket/9845): Fixed TAB navigation in the [Link](http://ckeditor.com/addon/link) dialog window when the Anchor option is used and no anchors are available.
* [#9883](http://dev.ckeditor.com/ticket/9883): Maximizing was making the entire page editable with [divarea](http://ckeditor.com/addon/divarea)-based editors.
* [#9940](http://dev.ckeditor.com/ticket/9940): [Firefox] Navigating back to a page with the editor was making the entire page editable.
* [#9966](http://dev.ckeditor.com/ticket/9966): Fixed: Unable to type square brackets with French keyboard layout. Changed [Magic Line](http://ckeditor.com/addon/magicline) keystrokes.
* [#9507](http://dev.ckeditor.com/ticket/9507): [Firefox] Selection is moved before editable position when the editor is focused for the first time.
* [#9947](http://dev.ckeditor.com/ticket/9947): [WebKit] Editor overflows parent container in some edge cases.
* [#10105](http://dev.ckeditor.com/ticket/10105): Fixed: Broken [sourcearea](http://ckeditor.com/addon/sourcearea) view when an RTL language is set.
* [#10123](http://dev.ckeditor.com/ticket/10123): [WebKit] Fixed: Several dialog windows have broken layout since the latest WebKit release.
* [#10152](http://dev.ckeditor.com/ticket/10152): Fixed: Invalid ARIA property used on menu items.
## CKEditor 4.0.1.1
Fixed Issues:
* Security update: Added protection against XSS attack and possible path disclosure in the PHP sample.
## CKEditor 4.0.1
Fixed Issues:
* [#9655](http://dev.ckeditor.com/ticket/9655): Support for IE Quirks Mode in the new [Moono skin](http://ckeditor.com/addon/moono).
* Accessibility issues (mainly in inline editor): [#9364](http://dev.ckeditor.com/ticket/9364), [#9368](http://dev.ckeditor.com/ticket/9368), [#9369](http://dev.ckeditor.com/ticket/9369), [#9370](http://dev.ckeditor.com/ticket/9370), [#9541](http://dev.ckeditor.com/ticket/9541), [#9543](http://dev.ckeditor.com/ticket/9543), [#9841](http://dev.ckeditor.com/ticket/9841), [#9844](http://dev.ckeditor.com/ticket/9844).
* [Magic Line](http://ckeditor.com/addon/magicline) plugin:
* [#9481](http://dev.ckeditor.com/ticket/9481): Added accessibility support for Magic Line.
* [#9509](http://dev.ckeditor.com/ticket/9509): Added Magic Line support for forms.
* [#9573](http://dev.ckeditor.com/ticket/9573): Magic Line does not disappear on `mouseout` in a specific case.
* [#9754](http://dev.ckeditor.com/ticket/9754): [WebKit] Cutting & pasting simple unformatted text generates an inline wrapper in WebKit browsers.
* [#9456](http://dev.ckeditor.com/ticket/9456): [Chrome] Properly paste bullet list style from MS Word.
* [#9699](http://dev.ckeditor.com/ticket/9699), [#9758](http://dev.ckeditor.com/ticket/9758): Improved selection locking when selecting by dragging.
* Context menu:
* [#9712](http://dev.ckeditor.com/ticket/9712): Opening the context menu destroys editor focus.
* [#9366](http://dev.ckeditor.com/ticket/9366): Context menu should be displayed over the floating toolbar.
* [#9706](http://dev.ckeditor.com/ticket/9706): Context menu generates a JavaScript error in inline mode when the editor is attached to a header element.
* [#9800](http://dev.ckeditor.com/ticket/9800): Hide float panel when resizing the window.
* [#9721](http://dev.ckeditor.com/ticket/9721): Padding in content of div-based editor puts the editing area under the bottom UI space.
* [#9528](http://dev.ckeditor.com/ticket/9528): Host page `box-sizing` style should not influence the editor UI elements.
* [#9503](http://dev.ckeditor.com/ticket/9503): [Form Elements](http://ckeditor.com/addon/forms) plugin adds context menu listeners only on supported input types. Added support for `tel`, `email`, `search` and `url` input types.
* [#9769](http://dev.ckeditor.com/ticket/9769): Improved floating toolbar positioning in a narrow window.
* [#9875](http://dev.ckeditor.com/ticket/9875): Table dialog window does not populate width correctly.
* [#8675](http://dev.ckeditor.com/ticket/8675): Deleting cells in a nested table removes the outer table cell.
* [#9815](http://dev.ckeditor.com/ticket/9815): Cannot edit dialog window fields in an editor initialized in the jQuery UI modal dialog.
* [#8888](http://dev.ckeditor.com/ticket/8888): CKEditor dialog windows do not show completely in a small window.
* [#9360](http://dev.ckeditor.com/ticket/9360): [Inline editor] Blocks shown for a `<div>` element stay permanently even after the user exits editing the `<div>`.
* [#9531](http://dev.ckeditor.com/ticket/9531): [Firefox & Inline editor] Toolbar is lost when closing the Format drop-down list by clicking its button.
* [#9553](http://dev.ckeditor.com/ticket/9553): Table width incorrectly set when the `border-width` style is specified.
* [#9594](http://dev.ckeditor.com/ticket/9594): Cannot tab past CKEditor when it is in read-only mode.
* [#9658](http://dev.ckeditor.com/ticket/9658): [IE9] Justify not working on selected images.
* [#9686](http://dev.ckeditor.com/ticket/9686): Added missing contents styles for `<pre>` elements.
* [#9709](http://dev.ckeditor.com/ticket/9709): [Paste from Word](http://ckeditor.com/addon/pastefromword) should not depend on configuration from other styles.
* [#9726](http://dev.ckeditor.com/ticket/9726): Removed [Color Dialog](http://ckeditor.com/addon/colordialog) plugin dependency from [Table Tools](http://ckeditor.com/addon/tabletools).
* [#9765](http://dev.ckeditor.com/ticket/9765): Toolbar Collapse command documented incorrectly in the [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp) dialog window.
* [#9771](http://dev.ckeditor.com/ticket/9771): [WebKit & Opera] Fixed scrolling issues when pasting.
* [#9787](http://dev.ckeditor.com/ticket/9787): [IE9] `onChange` is not fired for checkboxes in dialogs.
* [#9842](http://dev.ckeditor.com/ticket/9842): [Firefox 17] When opening a toolbar menu for the first time and pressing the *Down Arrow* key, focus goes to the next toolbar button instead of the menu options.
* [#9847](http://dev.ckeditor.com/ticket/9847): [Elements Path](http://ckeditor.com/addon/elementspath) should not be initialized in the inline editor.
* [#9853](http://dev.ckeditor.com/ticket/9853): [`editor.addRemoveFormatFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addRemoveFormatFilter) is exposed before it really works.
* [#8893](http://dev.ckeditor.com/ticket/8893): Value of the [`pasteFromWordCleanupFile`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordCleanupFile) configuration option is now taken from the instance configuration.
* [#9693](http://dev.ckeditor.com/ticket/9693): Removed "Live Preview" checkbox from UI color picker.
## CKEditor 4.0
The first stable release of the new CKEditor 4 code line.
The CKEditor JavaScript API has been kept compatible with CKEditor 4, whenever
possible. The list of relevant changes can be found in the [API Changes page of
the CKEditor 4 documentation][1].
[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes "API Changes"
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
CKEditor 4
==========
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
http://ckeditor.com - See LICENSE.md for license information.
CKEditor is a text editor to be used inside web pages. It's not a replacement
for desktop text editors like Word or OpenOffice, but a component to be used as
part of web applications and websites.
## Documentation
The full editor documentation is available online at the following address:
http://docs.ckeditor.com
## Installation
Installing CKEditor is an easy task. Just follow these simple steps:
1. **Download** the latest version from the CKEditor website:
http://ckeditor.com. You should have already completed this step, but be
sure you have the very latest version.
2. **Extract** (decompress) the downloaded file into the root of your website.
**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
place the files in whichever you want though.
## Checking Your Installation
The editor comes with a few sample pages that can be used to verify that
installation proceeded properly. Take a look at the `samples` directory.
To test your installation, just call the following page at your website:
http://<your site>/<CKEditor installation path>/samples/index.html
For example:
http://www.example.com/ckeditor/samples/index.html
+10
View File
@@ -0,0 +1,10 @@
/*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
(function(a){CKEDITOR.config.jqueryOverrideVal="undefined"==typeof CKEDITOR.config.jqueryOverrideVal?!0:CKEDITOR.config.jqueryOverrideVal;"undefined"!=typeof a&&(a.extend(a.fn,{ckeditorGet:function(){var a=this.eq(0).data("ckeditorInstance");if(!a)throw"CKEditor is not initialized yet, use ckeditor() with a callback.";return a},ckeditor:function(g,d){if(!CKEDITOR.env.isCompatible)throw Error("The environment is incompatible.");if(!a.isFunction(g))var k=d,d=g,g=k;var i=[],d=d||{};this.each(function(){var b=
a(this),c=b.data("ckeditorInstance"),f=b.data("_ckeditorInstanceLock"),h=this,j=new a.Deferred;i.push(j.promise());if(c&&!f)g&&g.apply(c,[this]),j.resolve();else if(f)c.once("instanceReady",function(){setTimeout(function(){c.element?(c.element.$==h&&g&&g.apply(c,[h]),j.resolve()):setTimeout(arguments.callee,100)},0)},null,null,9999);else{if(d.autoUpdateElement||"undefined"==typeof d.autoUpdateElement&&CKEDITOR.config.autoUpdateElement)d.autoUpdateElementJquery=!0;d.autoUpdateElement=!1;b.data("_ckeditorInstanceLock",
!0);c=a(this).is("textarea")?CKEDITOR.replace(h,d):CKEDITOR.inline(h,d);b.data("ckeditorInstance",c);c.on("instanceReady",function(d){var e=d.editor;setTimeout(function(){if(e.element){d.removeListener();e.on("dataReady",function(){b.trigger("dataReady.ckeditor",[e])});e.on("setData",function(a){b.trigger("setData.ckeditor",[e,a.data])});e.on("getData",function(a){b.trigger("getData.ckeditor",[e,a.data])},999);e.on("destroy",function(){b.trigger("destroy.ckeditor",[e])});e.on("save",function(){a(h.form).submit();
return!1},null,null,20);if(e.config.autoUpdateElementJquery&&b.is("textarea")&&a(h.form).length){var c=function(){b.ckeditor(function(){e.updateElement()})};a(h.form).submit(c);a(h.form).bind("form-pre-serialize",c);b.bind("destroy.ckeditor",function(){a(h.form).unbind("submit",c);a(h.form).unbind("form-pre-serialize",c)})}e.on("destroy",function(){b.removeData("ckeditorInstance")});b.removeData("_ckeditorInstanceLock");b.trigger("instanceReady.ckeditor",[e]);g&&g.apply(e,[h]);j.resolve()}else setTimeout(arguments.callee,
100)},0)},null,null,9999)}});var f=new a.Deferred;this.promise=f.promise();a.when.apply(this,i).then(function(){f.resolve()});this.editor=this.eq(0).data("ckeditorInstance");return this}}),CKEDITOR.config.jqueryOverrideVal&&(a.fn.val=CKEDITOR.tools.override(a.fn.val,function(g){return function(d){if(arguments.length){var k=this,i=[],f=this.each(function(){var b=a(this),c=b.data("ckeditorInstance");if(b.is("textarea")&&c){var f=new a.Deferred;c.setData(d,function(){f.resolve()});i.push(f.promise());
return!0}return g.call(b,d)});if(i.length){var b=new a.Deferred;a.when.apply(this,i).done(function(){b.resolveWith(k)});return b.promise()}return f}var f=a(this).eq(0),c=f.data("ckeditorInstance");return f.is("textarea")&&c?c.getData():g.call(f)}})))})(window.jQuery);
+182
View File
@@ -0,0 +1,182 @@
/**
* @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
/**
* This file was added automatically by CKEditor builder.
* You may re-use it at any time to build CKEditor again.
*
* If you would like to build CKEditor online again
* (for example to upgrade), visit one the following links:
*
* (1) http://ckeditor.com/builder
* Visit online builder to build CKEditor from scratch.
*
* (2) http://ckeditor.com/builder/9112f95de78a7f2c3576c61a29c8fc5b
* Visit online builder to build CKEditor, starting with the same setup as before.
*
* (3) http://ckeditor.com/builder/download/9112f95de78a7f2c3576c61a29c8fc5b
* Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
*
* NOTE:
* This file is not used by CKEditor, you may remove it.
* Changing this file will not change your CKEditor configuration.
*/
var CKBUILDER_CONFIG = {
skin: 'moono',
preset: 'full',
ignore: [
'.bender',
'bender.js',
'bender-err.log',
'bender-out.log',
'dev',
'.DS_Store',
'.editorconfig',
'.gitattributes',
'.gitignore',
'gruntfile.js',
'.idea',
'.jscsrc',
'.jshintignore',
'.jshintrc',
'less',
'.mailmap',
'node_modules',
'package.json',
'README.md',
'tests'
],
plugins : {
'a11yhelp' : 1,
'about' : 1,
'basicstyles' : 1,
'bidi' : 1,
'blockquote' : 1,
'clipboard' : 1,
'colorbutton' : 1,
'colordialog' : 1,
'contextmenu' : 1,
'dialogadvtab' : 1,
'div' : 1,
'elementspath' : 1,
'enterkey' : 1,
'entities' : 1,
'filebrowser' : 1,
'find' : 1,
'flash' : 1,
'floatingspace' : 1,
'font' : 1,
'format' : 1,
'forms' : 1,
'horizontalrule' : 1,
'htmlwriter' : 1,
'iframe' : 1,
'image' : 1,
'indentblock' : 1,
'indentlist' : 1,
'justify' : 1,
'language' : 1,
'link' : 1,
'list' : 1,
'liststyle' : 1,
'magicline' : 1,
'maximize' : 1,
'newpage' : 1,
'pagebreak' : 1,
'pastefromword' : 1,
'pastetext' : 1,
'preview' : 1,
'print' : 1,
'removeformat' : 1,
'resize' : 1,
'save' : 1,
'scayt' : 1,
'selectall' : 1,
'showblocks' : 1,
'showborders' : 1,
'smiley' : 1,
'sourcearea' : 1,
'specialchar' : 1,
'stylescombo' : 1,
'tab' : 1,
'table' : 1,
'tabletools' : 1,
'templates' : 1,
'toolbar' : 1,
'undo' : 1,
'wsc' : 1,
'wysiwygarea' : 1
},
languages : {
'af' : 1,
'ar' : 1,
'bg' : 1,
'bn' : 1,
'bs' : 1,
'ca' : 1,
'cs' : 1,
'cy' : 1,
'da' : 1,
'de' : 1,
'de-ch' : 1,
'el' : 1,
'en' : 1,
'en-au' : 1,
'en-ca' : 1,
'en-gb' : 1,
'eo' : 1,
'es' : 1,
'et' : 1,
'eu' : 1,
'fa' : 1,
'fi' : 1,
'fo' : 1,
'fr' : 1,
'fr-ca' : 1,
'gl' : 1,
'gu' : 1,
'he' : 1,
'hi' : 1,
'hr' : 1,
'hu' : 1,
'id' : 1,
'is' : 1,
'it' : 1,
'ja' : 1,
'ka' : 1,
'km' : 1,
'ko' : 1,
'ku' : 1,
'lt' : 1,
'lv' : 1,
'mk' : 1,
'mn' : 1,
'ms' : 1,
'nb' : 1,
'nl' : 1,
'no' : 1,
'pl' : 1,
'pt' : 1,
'pt-br' : 1,
'ro' : 1,
'ru' : 1,
'si' : 1,
'sk' : 1,
'sl' : 1,
'sq' : 1,
'sr' : 1,
'sr-latn' : 1,
'sv' : 1,
'th' : 1,
'tr' : 1,
'tt' : 1,
'ug' : 1,
'uk' : 1,
'vi' : 1,
'zh' : 1,
'zh-cn' : 1
}
};
+1091
View File
File diff suppressed because it is too large Load Diff
+108
View File
@@ -0,0 +1,108 @@
/**
* @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function (config) {
// config.uiColor = '#AADC6E'; //設定背景色
config.language = 'zh'; //語系中文
config.skin = 'bootstrapck'; //佈景主題
config.resize_enabled = false; //設定不能resize TEXTAREA
config.height = 300; //設定高度
config.enterMode = CKEDITOR.ENTER_BR; //換行使用br,不使用p tag
config.image_prefillDimensions = false; //插入圖片時,不自動帶寬高
config.allowedContent = true;
config.extraPlugins = 'ContentBuilder,blockimagepaste,tliyoutube,googlemap,qrc,lineheight,photos,EzTemplates';
//可指定css
//config.contentsCss = ['../../webc/css/layout.css', '../../webc/css/module.css', '../../webc/css/style.css', '../../webc/css/type.css'];
//為加入額外字體
config.font_names = 'Arial/Arial, Helvetica, sans-serif;Comic Sans MS/Comic Sans MS, cursive;Courier New/Courier New, Courier, monospace;Georgia/Georgia, serif;Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;Tahoma/Tahoma, Geneva, sans-serif;Times New Roman/Times New Roman, Times, serif;Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;Verdana/Verdana, Geneva, sans-serif;新細明體;標楷體;微軟正黑體';
//功能列設定
config.toolbar_Default =
[
['Source', '-', 'EzTemplates', 'ContentBuilder'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'],
['Find', 'Replace', '-', 'SelectAll'],
['Maximize', 'ShowBlocks', '-', 'About'],
['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'photos', 'Flash', 'tliyoutube', 'googlemap', 'qrc', 'Table', 'CreateDiv', 'Iframe', 'HorizontalRule', 'Smiley', 'SpecialChar'], ['TextColor', 'BGColor'],
['Styles', 'Format', 'Font', 'FontSize', 'LineHeight']
];
config.toolbar_Full =
[
['Source', '-', 'Save', 'NewPage', 'DocProps', 'Preview', 'Print', '-', 'EzTemplates'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'],
['Find', 'Replace', '-', 'SelectAll', '-', 'SpellChecker', 'Scayt'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', 'Iframe', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'],
['Link', 'Unlink', 'Anchor'],
['Image', 'photos', 'Flash', 'tliyoutube', 'googlemap', 'qrc', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'],
['Styles', 'Format', 'Font', 'FontSize', 'LineHeight'],
['TextColor', 'BGColor'],
['Maximize', 'ShowBlocks', '-', 'About']
];
config.toolbar_Basic =
[
['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
['Maximize', 'ShowBlocks', 'Smiley', '-', 'About'],
['Cut', '-', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'],
['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor']
];
//config.toolbar = 'Default'; //指定要使用哪一個功能列設定
//檔案管理器串接(不使用將設定註解掉即可)
config.filebrowserImageBrowseUrl = '../filemanager/index.aspx'; //圖片用
config.filebrowserFlashBrowseUrl = '../filemanager/index.aspx'; //Flash用
config.filebrowserBrowseUrl = '../filemanager/index.aspx'; //超連結用
//編輯器樣板
config.bodyClass = 'editor';
config.templates = 'ez_default';
config.contentsCss = [
'../../js/bootstrap5/css/bootstrap.min.css',
//'../../css/base.min.css',
//'../../css/bootstrap-col10.css',
//'../../css/base_rwd.min.css',
'../../css/contentbuilder/editor_content.css',
'../../App_Script/ContentBuilder/contentbuilder/contentbuilder.css'];
//更多設定請參閱http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
};
//編輯器內文 允許 a div , a p
CKEDITOR.dtd.a.div = 1;
CKEDITOR.dtd.a.p = 1;
CKEDITOR.dtd.a.h1 = 1;
CKEDITOR.dtd.a.h2 = 1;
CKEDITOR.dtd.a.h3 = 1;
CKEDITOR.dtd.a.h4 = 1;
CKEDITOR.dtd.a.h5 = 1;
CKEDITOR.dtd.a.h6 = 1;
CKEDITOR.dtd.a.ul = 1;
CKEDITOR.dtd.a.ol = 1;
CKEDITOR.dtd.a.li = 1;
//編輯器內文 允許 span , i 為空值
CKEDITOR.dtd.$removeEmpty.span = 0;
CKEDITOR.dtd.$removeEmpty.i = 0;
//插入範本 允許 link 在 div 內
CKEDITOR.dtd.div.link = 1;
CKEDITOR.dtd.li.i = 1;
+135
View File
@@ -0,0 +1,135 @@
/*
Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
body
{
/* Font */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
font-size: 12px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent */
background-color: #fff;
margin: 20px;
}
.cke_editable
{
font-size: 13px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
border: solid 1px #ccc;
border-radius: 2px;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More