migrate to new git
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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象素 <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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 696 KiB |
|
After Width: | Height: | Size: 420 KiB |
|
After Width: | Height: | Size: 508 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 462 KiB |
@@ -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 © 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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 977 B |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 999 B |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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="一行輸入一個定義欄位預設值,如: $品名:醬油 $金額: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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 – 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 – [`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 – [`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 – 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 — 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"
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||