Files
17168ERP/web/admin/order/bed_reg.aspx
2025-08-29 01:27:25 +08:00

639 lines
33 KiB
Plaintext

<%@ Page Title="後端管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="bed_reg.aspx.cs" Inherits="admin_bed_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>
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 {
this_order_no: '<%= Request["order_no"]%>', //來源訂單編號
this_detail_id: '<%= Request["detail"]%>', //來源明細id
this_id: '<%= _this_id %>', //掛單表單單號bed_order_no
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/bed_kind/GetList',
columns: [
{ id: 'kind', title: '樓層名稱', value: '' },
],
selected: {},
select(item,t) {
console.log("select search1", t);
item.bed_kind1_selected.text = t.kind
item.bed_kind1_selected.val = t.num
//清空下層
item.bed_kind2_selected.text = ''
item.bed_kind2_selected.val = 0
item.bed_kind_detail_id_selected.text = ''
item.bed_kind_detail_id_selected.val = 0
}
},
search2: {
id: 'search2',
title: '房號/房名',
text_prop: 'kind',
value_prop: 'num',
keys: [
{ id: 'kind', title: '房號/房名', value: '' },
],
api_url: HTTP_HOST + 'api/bed_kind/GetList',
columns: [
{ id: 'kind', title: '房號/房名', value: '' },
],
selected: {},
select(item,t) {
console.log("select search2", t);
item.bed_kind2_selected.text = t.kind
item.bed_kind2_selected.val = t.num
//清空下層
item.bed_kind_detail_id_selected.text = ''
item.bed_kind_detail_id_selected.val = 0
}
},
search3: {
id: 'search3',
title: '床位編號',
text_prop: 'bed_name',
value_prop: 'num',
keys: [
{ id: 'bed_name', title: '床位編號', value: '' },
{ id: 'bed_type_txt', title: '床位型態' },
],
api_url: HTTP_HOST + 'api/bed_kind/GetDetailList',
columns: [
{ id: 'bed_name', title: '床位編號' },
{ id: 'bed_type_txt', title: '床位型態' },
],
selected: {},
select(item,t) {
console.log("select search3", t);
item.bed_kind_detail_id_selected.text = t.bed_name
item.bed_kind_detail_id_selected.val = t.num
item.bed_kind_detail_id_selected.bed_type = t.bed_type_txt
}
},
},
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: 'u_name', sortable: false },
{ text: '掛單日期 *', value: 'check_in_date', sortable: false },
{ text: '床位型態', value: 'bed_kind_detail_id_selected.bed_type', sortable: false },
{ text: '樓層', value: 'bed_kind1_selected.text', sortable: false },
{ text: '房號/房名', value: 'bed_kind2_selected.text', sortable: false },
{ text: '床位編號 *', value: 'bed_kind_detail_id_selected.text', sortable: false },
{ text: '車牌號碼', value: 'license', sortable: false },
{ text: '數量', value: 'qty', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "120px" },
],
desserts: [],
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
u_name: '',
checkIn_date: new Date().format("yyyy-MM-dd"),
bed_kind1_selected: {
text: '',
val: 0
},
bed_kind2_selected: {
text: '',
val: 0
},
bed_kind_detail_id_selected: {
text: '',
val: 0,
bed_type: '',
},
license:'',
},
defaultItem: {
id: 0,
num: 0,
u_name: '',
checkIn_date: new Date().format("yyyy-MM-dd"),
bed_kind1_selected: {
text: '',
val: 0
},
bed_kind2_selected: {
text: '',
val: 0
},
bed_kind_detail_id_selected: {
text: '',
val: 0,
bed_type: '',
},
license: '',
},
}
},
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: {
initialize() {
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
};
var searchBedDetail = {
order_no: this.this_order_no,
o_detail_id: this.this_detail_id,
bed_order_no: this.this_id,
}
axios
.post(HTTP_HOST + 'api/bed/GetDetailList', searchBedDetail, { params: params })
.then(response => {
this.desserts = response.data.list
})
.catch(
error => console.log(error)
)
},
editItem(item) {
this.editedIndex = this.desserts.indexOf(item);
//日期處理
let isValidDate = Date.parse(item.checkIn_date);
if (!isNaN(isValidDate))
item.checkIn_date = new Date(item.checkIn_date).format("yyyy-MM-dd")
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/DeleteBedDetail/' + item.num)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
})
.catch(error => console.log(error))
}
} else {
this.desserts.splice(index, 1)
}
}
},
cancel() {
this.close();
if (this.editedItem.num == 0) {
this.desserts.splice(-1, 1)
}
this.initialize(); //or get this.editedItem ?
},
close() {
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
save() {
if (this.editedIndex > -1) {
if (this.this_id != '') {
//chcck necessary params
if (this.editedItem.checkIn_date != null && this.editedItem.checkIn_date != '' && this.editedItem.bed_kind_detail_id_selected.val > 0) {
//insert or update data
var kind_detail =
{
num: this.editedItem.num,
bed_order_no: this.this_id,
checkIn_date: this.editedItem.checkIn_date,
bed_kind1: this.editedItem.bed_kind1_selected.val,
bed_kind2: this.editedItem.bed_kind2_selected.val,
bed_kind_detail_id: this.editedItem.bed_kind_detail_id_selected.val,
license: this.editedItem.license,
}
axios
.post(HTTP_HOST + 'api/bed/SaveBedDetail', kind_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
}
}
},
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===
let goto = true;
if (this.search_dialog.current.id == 'search1') {
search['root'] = 0;
}
if (this.search_dialog.current.id == 'search2') {
if (this.editedItem.bed_kind1_selected.val != '' && this.editedItem.bed_kind1_selected.val > 0)
search['root'] = this.editedItem.bed_kind1_selected.val;
else {
goto = false;
this.snackbar.text = "請先選擇樓層"
this.snackbar.show = true
}
}
if (this.search_dialog.current.id == 'search3') {
if (this.editedItem.bed_kind2_selected.val != '' && this.editedItem.bed_kind2_selected.val > 0) {
if (this.editedItem.checkIn_date != null && this.editedItem.checkIn_date != '') {
search['inTime'] = this.editedItem.checkIn_date;
search['bed_kind_id'] = this.editedItem.bed_kind2_selected.val;
}
else {
goto = false;
this.snackbar.text = "請先選擇掛單日期"
this.snackbar.show = true
}
}
else {
goto = false;
this.snackbar.text = "請先選擇房號/房名"
this.snackbar.show = true
}
}
if (goto) {
console.log("search_get", api_url, search, params, this.options);
this.search_dialog.loading = true
this.search_dialog.show = 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;
},
},
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="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
<asp:Button ID="gobackOrder" runat="server" Text="回報名表單" CausesValidation="false" OnClick="gobackOrder_Click" CssClass="btn btn-outline-secondary" />
<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 mb-1 label-sm-right ">
<label class="col-sm-2 col-lg-1 col-form-label">單號</label>
<div class="col-sm-10 col-lg-3 pt-2">
<asp:Literal ID="bed_order_no" runat="server"></asp:Literal>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">單據日期</label>
<div class="col-sm-10 col-lg-3 pt-2">
<%-- <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>--%>
<asp:Literal ID="uptime" runat="server"></asp:Literal>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">來源單號</label>
<div class="col-sm-10 col-lg-3 pt-2">
<asp:Literal ID="order_no" runat="server"></asp:Literal>
</div>
</div>
<div class="row mb-1 label-sm-right ">
<label class="col-sm-2 col-lg-1 col-form-label">報名活動</label>
<div class="col-sm-10 col-lg-3 pt-2">
<asp:Literal ID="activity_num_Txt" runat="server"></asp:Literal>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">姓名/名稱</label>
<div class="col-sm-10 col-lg-3 pt-2">
<asp:Literal ID="f_num_Txt" runat="server"></asp:Literal>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">聯絡電話</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="phone" MaxLength="15" runat="server" CssClass="form-control"></asp:TextBox>
</div>
</div>
<div class="row mb-1 label-sm-right ">
<label class="col-sm-2 col-lg-1 col-form-label">掛單起始日 *</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="start_date" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="start_date" 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:TextBox ID="end_date" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" ControlToValidate="end_date" 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="keyin1" CssClass="form-select" runat="server" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator9" runat="server" ControlToValidate="keyin1"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</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"></asp:TextBox>
</div>
</div>
<v-card class="mx-auto mt-10" outlined v-if="this_id!=''">
<v-data-table
:headers="headersDetail"
:items="desserts"
:search="searchDetail"
:options.sync="optionsDetail" class="elevation-1" fixed-header height="350px">
<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>
</div>
</v-toolbar>
</template>
<template v-slot:item.u_name="{ item }">
{{item.u_name}} ({{item.sex}})
</template>
<template v-slot:item.check_in_date="{ item }">
<v-text-field v-model="editedItem.checkIn_date" :hide-details="true" dense single-line v-if="item.id === editedItem.id" type="date"></v-text-field>
<span v-else>{{item.checkIn_date|timeString('YYYY/MM/DD')}}</span>
</template>
<template v-slot:item.bed_kind1_selected.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.bed_kind1_selected.text" >
<input type="hidden" v-model="editedItem.bed_kind1_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.bed_kind1_selected.text}}</span>
</template>
<template v-slot:item.bed_kind2_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.bed_kind2_selected.text" >
<input type="hidden" v-model="editedItem.bed_kind2_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.bed_kind2_selected.text}}</span>
</template>
<template v-slot:item.bed_kind_detail_id_selected.text="{ item }">
<div class="input-group mb-3" data-search-control="search3" @click="search_show(search_dialog.controls.search3)" v-if="item.id === editedItem.id">
<input class="form-control search-text" type="text" readonly
placeholder="床位編號" v-model="editedItem.bed_kind_detail_id_selected.text" >
<input type="hidden" v-model="editedItem.bed_kind_detail_id_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.bed_kind_detail_id_selected.text}}</span>
</template>
<template v-slot:item.license="{ item }">
<v-text-field v-model="editedItem.license" :hide-details="true" dense single-line v-if="item.id === editedItem.id" :maxlength=10 ></v-text-field>
<span v-else>{{item.license}}</span>
</template>
<template v-slot:item.qty="{ item }">
1
</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>
</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>