419 lines
18 KiB
Plaintext
419 lines
18 KiB
Plaintext
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="edit.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletuselist_edit" %>
|
|
|
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
|
</asp:Content>
|
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
|
<nav>
|
|
<a :href="'detail.aspx?registrantCode=' + registrantCode" class="btn btn-secondary">返回詳情</a>
|
|
</nav>
|
|
</asp:Content>
|
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
|
<div>
|
|
<!-- 登記人資料編輯區域 -->
|
|
<div class="card">
|
|
<h2>編輯登記人資訊</h2>
|
|
<label>登記編碼:</label>
|
|
<input type="text" v-model="registrant.registrantCode" class="form-control" disabled />
|
|
|
|
<label>姓名:</label>
|
|
<input type="text" v-model="registrant.name" class="form-control" />
|
|
|
|
<label>電話:</label>
|
|
<input type="text" v-model="registrant.phone" class="form-control" />
|
|
|
|
<label>地址:</label>
|
|
<input type="text" v-model="registrant.address" class="form-control" />
|
|
|
|
<label>登記日期:</label>
|
|
<input type="date" v-model="registrant.registerDate" class="form-control" />
|
|
<div class="mt-4" style="border: 1px solid #007bff; background-color: #f0f8ff; padding: 10px 15px; border-radius: 5px; display: flex; flex-direction: column; gap: 5px; max-width: 400px; margin-bottom: 10px;">
|
|
<div>
|
|
<label style="font-weight: bold; margin-right: 5px;">已選擇位置:</label>
|
|
<span>{{ registrant?.positionName || '未選擇' }}</span>
|
|
</div>
|
|
<div v-if="newPositionId">
|
|
<label style="font-weight: bold; margin-right: 5px;">新選擇位置:</label>
|
|
<span>{{ this.newPositionEntity?.positionName }}</span>
|
|
</div>
|
|
<button type="button" @click="isShowPositionDialog=true"
|
|
style="align-self: flex-start; padding: 5px 10px; background-color: #007bff; color: #fff; border: none; border-radius: 3px; cursor: pointer;"
|
|
>
|
|
{{registrant?.positionId ? '更換位置' : '選擇位置'}}
|
|
</button>
|
|
</div>
|
|
<label>價格:</label>
|
|
<input type="number" v-model="registrant.price" class="form-control" />
|
|
|
|
<label>開始日期:</label>
|
|
<input type="date" v-model="registrant.startDate" class="form-control" />
|
|
|
|
<label>結束日期:</label>
|
|
<input type="date" v-model="registrant.endDate" class="form-control" />
|
|
|
|
<div class="mt-3" style="display:flex; align-items:center; gap:15px; margin-bottom:10px; font-family:Arial, sans-serif;">
|
|
<label style="font-weight:500;">是否長期:</label>
|
|
<input type="checkbox" v-model="registrant.isLongTerm" style="width:16px; height:16px; cursor:pointer;" />
|
|
<span>是</span>
|
|
</div>
|
|
|
|
<div style="display:flex; align-items:center; gap:15px; margin-bottom:10px; font-family:Arial, sans-serif;">
|
|
<label style="font-weight:500;">是否啟用:</label>
|
|
<input type="checkbox" v-model="registrant.isActive" style="width:16px; height:16px; cursor:pointer;" />
|
|
<span>是</span>
|
|
</div>
|
|
|
|
<button type="button" class="btn btn-primary mt-2" @click="updateRegistrant">保存登記資料</button>
|
|
</div>
|
|
|
|
<!-- 牌位資料區域 -->
|
|
<div class="card" v-if="registrant.tabletRecord">
|
|
<h2>編輯牌位資料</h2>
|
|
<label>記錄ID:</label>
|
|
<input type="text" v-model="registrant.tabletRecord.recordId" class="form-control" disabled />
|
|
|
|
<label>登記編碼 (外鍵):</label>
|
|
<input type="text" v-model="registrant.tabletRecord.registrantCode" class="form-control" disabled />
|
|
|
|
|
|
<label>牌位標題:</label>
|
|
<input type="text" v-model="registrant.tabletRecord.npTitle" class="form-control" />
|
|
|
|
<label>立牌日期:</label>
|
|
<input type="date" v-model="registrant.tabletRecord.npStandDate" class="form-control" />
|
|
|
|
<label>陽上:</label>
|
|
<input type="text" v-model="registrant.tabletRecord.npYangShang" class="form-control" />
|
|
|
|
<label>內牌內容:</label>
|
|
<textarea v-model="registrant.tabletRecord.wpContent" class="form-control"></textarea>
|
|
|
|
<button type="button" class="btn btn-success mt-2" @click="updateTabletRecord">保存牌位資料</button>
|
|
</div>
|
|
|
|
<div class="card" v-else>
|
|
<h2>牌位資料</h2>
|
|
<p>暫無牌位資料</p>
|
|
<button type="button" class="btn btn-primary" @click="createTabletRecordForm">新增牌位資料</button>
|
|
|
|
<div v-if="creatingTablet" class="mt-3">
|
|
<label>牌位標題:</label>
|
|
<input type="text" v-model="newTablet.npTitle" class="form-control" />
|
|
|
|
<label>立牌日期:</label>
|
|
<input type="date" v-model="newTablet.npStandDate" class="form-control" />
|
|
|
|
<label>陽上:</label>
|
|
<input type="text" v-model="newTablet.npYangShang" class="form-control" />
|
|
|
|
<label>牌位內容:</label>
|
|
<textarea v-model="newTablet.wpContent" class="form-control"></textarea>
|
|
|
|
<button type="button" class="btn btn-success mt-2" @click="createTabletRecord">保存新增</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<v-dialog v-model="isShowPositionDialog" persistent
|
|
width="80%"
|
|
height="80%">
|
|
<v-card style="
|
|
width: 80vw;
|
|
height: 80vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
">
|
|
<v-card-title
|
|
style="display: flex; align-items: center; font-weight: 600; font-size: 18px;"
|
|
>
|
|
<span>選擇位置:</span>
|
|
|
|
<select
|
|
class="form-control"
|
|
style="
|
|
flex: 0 0 200px;
|
|
padding: 6px 10px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
background-color: #fff;
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
outline: none;
|
|
transition: border-color 0.2s;
|
|
"
|
|
v-model="selectedArea"
|
|
@focus="e => e.target.style.borderColor = '#007bff'"
|
|
@blur="e => e.target.style.borderColor = '#ccc'"
|
|
@change="onAreaChange"
|
|
>
|
|
<option value="">請選擇區域</option>
|
|
<option v-for="area in areaList" :value="area.areaId" :key="area.areaId">{{area.areaName}}</option>
|
|
</select>
|
|
</v-card-title>
|
|
|
|
<v-card-text style="flex: 1; overflow: auto;">
|
|
<div class="grid-container">
|
|
<div
|
|
v-for="pos in positionList"
|
|
:key="pos.positionId"
|
|
class="grid-item"
|
|
:class="'status-' + (pos.isCanUse? 'canuse':'cannotuse')"
|
|
:style="{ gridRow: pos.rowNo, gridColumn: pos.columnNo }"
|
|
>
|
|
<div class="position-name">{{ pos.positionName }}</div>
|
|
<div class="position-content">
|
|
<button type="button" v-if="pos.isCanUse"
|
|
class="btn btn-primary"
|
|
@click="chooseNewPositionMethod(pos)"
|
|
>選擇</button>
|
|
<span v-else>已被使用</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer></v-spacer>
|
|
<div class="me-5">新位置:{{newPositionEntity?.positionName}}</div>
|
|
<v-btn color="primary" @click="saveChoosePositionMethod">確定</v-btn>
|
|
<v-btn color="grey" @click="cancelChoosePositionMethod">取消</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</div>
|
|
</div>
|
|
</asp:Content>
|
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
|
</asp:Content>
|
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
|
<script>
|
|
new Vue({
|
|
el: '#app',
|
|
vuetify: new Vuetify(vuetify_options),
|
|
data() {
|
|
return {
|
|
registrantCode: '<%=Request.QueryString["registrantCode"]%>',
|
|
registrant: {},
|
|
creatingTablet: false,
|
|
newPositionId: null,
|
|
newPositionEntity: null,
|
|
newTablet: {
|
|
//新增牌位登記form
|
|
recordId: null, // 自增主鍵,前端一般不用填
|
|
registrantCode: null, // 外鍵,關聯登記人編號
|
|
npTitle: null,
|
|
npStandDate: null,
|
|
npYangShang: null,
|
|
wpContent: null,
|
|
},
|
|
positionList: [],//選擇神位位置的時候獲取的位置列表
|
|
isShowPositionDialog: false,
|
|
selectedArea: "",
|
|
areaList: [],
|
|
}
|
|
},
|
|
methods: {
|
|
formatDate(dateStr) {
|
|
if (!dateStr) return "";
|
|
return dateStr.split('T')[0];
|
|
},
|
|
getRegistrantByCodeMethod(code) {
|
|
axios.get(HTTP_HOST + 'api/ancestraltablet/registrant/getbycode', {
|
|
params: {
|
|
registrantCode: code
|
|
}
|
|
})
|
|
.then((res => {
|
|
const data = res.data;
|
|
|
|
// 格式化登記日期欄位
|
|
if (data.registerDate) data.registerDate = this.formatDate(data.registerDate);
|
|
if (data.startDate) data.startDate = this.formatDate(data.startDate);
|
|
if (data.endDate) data.endDate = this.formatDate(data.endDate);
|
|
|
|
// 格式化牌位日期欄位
|
|
if (data.tabletRecord && data.tabletRecord.npStandDate)
|
|
data.tabletRecord.npStandDate = this.formatDate(data.tabletRecord.npStandDate);
|
|
|
|
this.registrant = data;
|
|
}))
|
|
.catch((error => {
|
|
|
|
}))
|
|
},
|
|
// 更新登記資料
|
|
updateRegistrant() {
|
|
const newPositionId = this.newPositionId; // 假設 newPositionId 存在組件裡
|
|
|
|
// 如果 newPositionId 不為空,則更新 registrant.PositionId
|
|
if (newPositionId != null && newPositionId !== '') {
|
|
this.registrant.PositionId = newPositionId;
|
|
}
|
|
axios.post(HTTP_HOST + 'api/ancestraltablet/registrant/update', this.registrant)
|
|
.then(() => {
|
|
alert('登記資料已保存!')
|
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
|
this.newPositionId = null;
|
|
}
|
|
)
|
|
.catch(err => {
|
|
console.error(err);
|
|
alert('保存失敗!');
|
|
});
|
|
},
|
|
|
|
// 更新牌位資料
|
|
updateTabletRecord() {
|
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/update', this.registrant.tabletRecord)
|
|
.then(() => alert('牌位資料已更新!'))
|
|
.catch(err => {
|
|
console.error(err);
|
|
alert('保存失敗!');
|
|
});
|
|
},
|
|
|
|
// 顯示新增牌位表單
|
|
createTabletRecordForm() {
|
|
this.creatingTablet = true;
|
|
},
|
|
|
|
// 新增牌位資料
|
|
createTabletRecord() {
|
|
const data = {
|
|
...this.newTablet,
|
|
registrantCode: this.registrant.registrantCode,
|
|
};
|
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/create', data)
|
|
.then(() => {
|
|
alert('牌位資料已新增!');
|
|
this.creatingTablet = false;
|
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
alert('新增失敗!');
|
|
});
|
|
},
|
|
getPositionList(areaId) {
|
|
axios.get(HTTP_HOST + 'api/ancestraltablet/position/shortlist',
|
|
{
|
|
params: {
|
|
areaId: areaId
|
|
}
|
|
})
|
|
.then((res) => {
|
|
this.positionList = res.data
|
|
})
|
|
.catch((error) => {
|
|
|
|
});
|
|
},
|
|
getArea() {
|
|
axios.get(HTTP_HOST + 'api/ancestraltablet/area/getereawithposition')
|
|
.then((res) => {
|
|
this.areaList = res.data;
|
|
})
|
|
.catch();
|
|
},
|
|
onAreaChange() {
|
|
//獲取有神位的區域
|
|
if (!this.selectedArea) {
|
|
this.positionList = [];
|
|
return; // 如果沒有選擇,不請求
|
|
}
|
|
this.getPositionList(this.selectedArea)
|
|
|
|
},
|
|
chooseNewPositionMethod(newPos) {
|
|
this.newPositionEntity = newPos
|
|
},
|
|
closeChoosePositionDialogMethod() {
|
|
this.isShowPositionDialog = false;
|
|
this.selectedArea = "";
|
|
this.positionList = [];
|
|
},
|
|
cancelChoosePositionMethod() {
|
|
this.newPositionEntity = null;
|
|
this.closeChoosePositionDialogMethod()
|
|
},
|
|
saveChoosePositionMethod() {
|
|
this.newPositionId = this.newPositionEntity.positionId
|
|
this.closeChoosePositionDialogMethod()
|
|
},
|
|
},
|
|
mounted() {
|
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
|
this.getArea()
|
|
}
|
|
})
|
|
</script>
|
|
<style>
|
|
.card {
|
|
border: 1px solid #ccc;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
border-radius: 5px;
|
|
background-color: #fafafa;
|
|
width: 90%;
|
|
max-width: 900px;
|
|
min-width: 300px; /* 最小寬度防止太窄 */
|
|
margin: 0 auto; /* 居中 */
|
|
}
|
|
.grid-container {
|
|
display: grid;
|
|
grid-template-columns: repeat(10, 150px); /* 6列 */
|
|
grid-auto-rows: 150px; /* 行高 */
|
|
gap: 10px;
|
|
}
|
|
.status-available {
|
|
background-color: #d4edda;
|
|
border-color: #28a745;
|
|
}
|
|
|
|
/* 維護中(黃色) */
|
|
.status-maintenance {
|
|
background-color: #fff3cd;
|
|
border-color: #ffc107;
|
|
}
|
|
|
|
/* 已使用(灰色) */
|
|
.status-used {
|
|
background-color: #e2e3e5;
|
|
border-color: #6c757d;
|
|
}
|
|
/* 可以使用(綠色) */
|
|
.status-canuse {
|
|
background-color: #d4edda; /* 淺綠色背景 */
|
|
border-color: #28a745; /* 綠色邊框 */
|
|
color: #155724; /* 深綠色文字 */
|
|
}
|
|
|
|
/* 不能使用(紅色) */
|
|
.status-cannotuse {
|
|
background-color: #f8d7da; /* 淺紅色背景 */
|
|
border-color: #dc3545; /* 紅色邊框 */
|
|
color: #721c24; /* 深紅文字 */
|
|
}
|
|
.grid-item {
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.position-name {
|
|
background-color: #f0f0f0;
|
|
padding: 4px 8px;
|
|
font-weight: bold;
|
|
font-size: 14px;
|
|
text-align: center;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
|
|
.position-content {
|
|
flex-grow: 1;
|
|
padding: 3px;
|
|
font-size: 12px;
|
|
color: #666;
|
|
}
|
|
</style>
|
|
</asp:Content> |