Yue 3 mēneši atpakaļ
vecāks
revīzija
b6d0144718

+ 20 - 16
SourceCode/IntelligentRailwayCosting/app/routes/excel_test.py

@@ -39,12 +39,18 @@ def test_cancel():
 
 def build_test_data(task_data):
     # 从task_data获取selected_zgs_id,如果没有则从zgs_list随机选择
-   
     selected_zgs_id = task_data.get('selected_zgs_id', None) if task_data else 1
+    zgs_code = ""
     zgs_list = task_data.get('zgs_list', None)
     if not selected_zgs_id and zgs_list:
         selected_zgs = random.choice(zgs_list)
-        selected_zgs_id = selected_zgs.get('id')
+        selected_zgs_id = selected_zgs.get('zgs_id')
+        zgs_code = selected_zgs.get('zgs_code')
+    elif zgs_list:
+        selected_zgs = zgs_list.filter(lambda x: x.get('zgs_id') == selected_zgs_id)
+        if not selected_zgs:
+            selected_zgs = random.choice(zgs_list)
+        zgs_code = selected_zgs.get('zgs_code')
     
     file_excel = task_data.get('file_excel', None)
     # 从file_excel随机选择文件
@@ -52,15 +58,13 @@ def build_test_data(task_data):
     if file_excel:
         file = random.choice(file_excel)
         ex_file_id = file.get('file_id')
-    
-    # 随机生成各种编码和名称
-    zgs_code = f"ZGS_{''.join(random.choices(string.digits, k=3))}"
-    item_id = random.randint(100, 999)
-    item_code = f"ITEM{''.join(random.choices(string.digits, k=3))}"
-    project_types = ['路基工程', '桥梁工程', '隧道工程', '轨道工程', '站场工程']
-    entry_name = f"{random.choice(project_types)}{random.randint(1,100)}号"
-    dinge_code = f"DE{''.join(random.choices(string.digits, k=3))}"
-    
+
+    items = task_data.get('components', [])
+    item = random.choice(items)
+    item_id = item.get('item_id',2)
+    item_code = item.get('item_code',"01")
+    entry_name = item.get('item_name',"001")
+    dinge_code = f"TY-{''.join(random.choices(string.digits, k=3))}"
     # 随机选择单位和数量
     units_list = ['个', '米', '千米', '平方米', '立方米', '吨', '件']
     units = random.choice(units_list)
@@ -104,12 +108,12 @@ def build_result(task_id:int):
         result = 1  # 运行超过5次必定成功
     else:
         rand = random.random()
-        if rand < 0.1:
-            result = -1  # 10%概率失败
-        elif rand < 0.7:
-            result = 0   # 60%概率处理中
+        if rand < 0.05:
+            result = -1  # 5%概率失败
+        elif rand < 0.8:
+            result = 0   # 85%概率处理中
         else:
-            result = 1   # 30%概率成功
+            result = 1   # 10%概率成功
     
     if data and result != -1:
         # 当result为1(成功)时,有80%概率生成数据

+ 2 - 2
SourceCode/IntelligentRailwayCosting/app/routes/log.py

@@ -23,8 +23,8 @@ def get_page_list():
         date = data.get('date')
         if date:
             date = date.split(' - ')
-            start_date = date[0]+' 00:00:00'
-            end_date = date[1]+" 23:59:59"
+            start_date = date[0]
+            end_date = date[1]
 
         logs, total_count = log_service.get_logs_paginated(page, per_page, username, operation_type, operation_module, operation_result,
                                                            start_date, end_date)

+ 2 - 2
SourceCode/IntelligentRailwayCosting/app/routes/project.py

@@ -19,8 +19,8 @@ def get_page_list():
         date = data.get('date')
         if date:
             date = date.split(' - ')
-            start_date = date[0]+' 00:00:00'
-            end_date = date[1]+" 23:59:59"
+            start_date = date[0]
+            end_date = date[1]
 
         projects, total_count = project_srvice.get_projects_paginated(page, per_page, keyword, start_date, end_date)
         return TableResponse.success(projects, total_count)

+ 1 - 1
SourceCode/IntelligentRailwayCosting/app/services/project_task.py

@@ -233,7 +233,7 @@ class ProjectTaskService:
 
         self._logger.info(f"保存处理文件,项目ID:{task.project_id},任务ID:{task.id}")
         delete_old = task.collect_status == 0
-        if delete_old:
+        if delete_old and task.file_path:
             delete_paths=[]
             for file_path in task.file_path.split(','):
                 if os.path.isfile(file_path):

+ 32 - 7
SourceCode/IntelligentRailwayCosting/app/views/static/base/js/utils.js

@@ -17,13 +17,7 @@ function IwbAjax(opt) {
 	if (opt.data === undefined) {
 		opt.data = {}
 	}
-	opt = $.extend(
-		{},
-		{
-			isAlert: true,
-		},
-		opt
-	)
+	opt = $.extend({},{isAlert: true,},opt)
 	fetch(opt.url, {
 		method: opt.method,
 		headers:opt.headers || {
@@ -270,6 +264,37 @@ function EditModal(modal, callback) {
 	$modal.modal('show')
 }
 
+function InitRangeDate($el) {
+	const start = moment().subtract(29, "days");
+	const end = moment();
+	function cb(start, end) {
+	   $el.html(start.format("YYYY-MM-DD") + " - " + end.format("YYYY-MM-DD"));
+	}
+	$el.daterangepicker({
+		startDate: start,
+		endDate: end,
+		locale:{
+			format: "YYYY-MM-DD", //设置显示格式
+			applyLabel: '确定', //确定按钮文本
+			cancelLabel: '取消', //取消按钮文本
+			customRangeLabel: '自定义',
+			daysOfWeek: ['日', '一', '二', '三', '四', '五', '六'],
+			monthNames: ['一月', '二月', '三月', '四月', '五月', '六月',
+				'七月', '八月', '九月', '十月', '十一月', '十二月'
+			],
+			firstDay: 1
+		},
+		ranges: {
+		"今天": [moment(), moment()],
+		"昨天": [moment().subtract(1, "days"), moment().subtract(1, "days")],
+		"近7天": [moment().subtract(6, "days"), moment()],
+		"近30天": [moment().subtract(29, "days"), moment()],
+		"本月": [moment().startOf("month"), moment().endOf("month")],
+		"上月": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
+		}
+	}, cb);
+	cb(start, end);
+}
 function Msg(msg, type){
 	const opts={
         text: msg,

+ 107 - 232
SourceCode/IntelligentRailwayCosting/app/views/static/project/budget_info.js

@@ -1,59 +1,98 @@
+const task_modal_template=`
+<div class="modal fade" id="modal" tabindex="-1" aria-hidden="true">
+  <div class="modal-dialog modal-dialog-centered">
+    <div class="modal-content rounded">
+      <div class="modal-header">
+        <h3 class="modal-title"><span class="prefix"></span>任务</h3>
+        <div class="btn btn-sm btn-icon btn-active-color-primary" data-bs-dismiss="modal">
+          <i class="ki-duotone ki-cross fs-1">
+            <span class="path1"></span>
+            <span class="path2"></span>
+          </i>
+        </div>
+      </div>
+      <div class="modal-body">
+        <form>
+          <div class="form-group">
+<!--            <input type="hidden" name="budget_id" value="">-->
+            <input type="hidden" name="project_id" value="">
+            <input type="hidden" name="item_id" value="">
+            <input type="hidden" name="item_code" value="">
+            <input type="hidden" name="task_id" value="">
+            <div class="fv-row form-group mb-3">
+              <label for="task_name" class="form-label required">任务名称</label>
+              <input type="text" class="form-control" name="task_name" id="task_name" placeholder="请输入任务名称" required />
+            </div>
+            <div class="fv-row form-group mb-3">
+              <label for="budget_id" class="form-label">概算单元</label>
+              <select class="form-select" name="budget_id" id="budget_id"></select>
+            </div>
+            <div class="fv-row form-group mb-3">
+              <label for="task_sort" class="form-label">任务排序</label>
+              <input type="number" class="form-control" name="task_sort" id="task_sort" placeholder="请输入任务排序"/>
+            </div> 
+             <div class="fv-row form-group mb-3">
+              <label for="task_desc" class="form-label">任务描述</label>
+              <textarea type="number" class="form-control" name="task_desc" id="task_desc" placeholder="请输入任务描述"></textarea>
+            </div>
+
+<!--            <div class="form-check mb-3" id="delete_file_box">-->
+<!--               <input class="form-check-input" type="checkbox" value="" id="delete_file" name="delete_file"/>-->
+<!--              <label class="form-check-label ms-5 text-primary " for="delete_file">-->
+<!--                删除原数据文件-->
+<!--              </label>-->
+<!--            </div>-->
+            <div class="fv-row">
+              <div id="file_upload_dropzone">
+                <div class="dropzone">
+                  <div class="dz-message dropzone-select">
+                    <i class="ki-duotone ki-file-up fs-3x text-primary"><span class="path1"></span><span class="path2"></span></i>
+                    <div class="ms-4">
+                      <h3 class="fs-5 fw-bold text-gray-900 mb-1">将文件拖放到此处或单击上传。</h3>
+                      <span class="fs-7 fw-semibold text-gray-500">最多可上传 5 个文件,文件最大10M</span>
+                    </div>
+                  </div>
+                </div>
+                <div class="dropzone dropzone-queue">
+                  <div class="dropzone-items wm-200px">
+                    <div class="dropzone-item" style="display:none">
+                      <div class="dropzone-file">
+                        <div class="dropzone-filename" title="some_image_file_name.jpg">
+                          <span data-dz-name>some_image_file_name.jpg</span>
+                          <strong>(<span data-dz-size>340kb</span>)</strong>
+                        </div>
+                        <div class="dropzone-error" data-dz-errormessage></div>
+                      </div>
+                      <div class="dropzone-toolbar">
+                        <span class="dropzone-delete" data-dz-remove><i class="bi bi-x fs-1"></i></span>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </form>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-light" data-bs-dismiss="modal">取消</button>
+        <button type="button" class="btn btn-success" onclick="SaveProject(true)">提交</button>
+        <button type="button" class="btn btn-primary" onclick="SaveProject()">保存草稿</button>
+      </div>
+    </div>
+  </div>
+</div>`
+$('.app-main .app-container').append(task_modal_template)
+const table_add_task_btn_template = `<button type="button" class="task_add_btn btn btn-primary btn-sm" onclick="Add('{0}')">添加任务</button>`
+
 const table = '#table',
 	$modal = $('#modal')
-InitBody()
+$modal.find('#budget_id').html($('#budget_id_options').html())
 $(function () {
-	BuildChapterInfo()
 	InitFileUpload()
 })
 
 
-
-const nav_template = `<ul id="nav_tab" class="nav nav-tabs nav-line-tabs nav-line-tabs-2x fs-6"></ul><div class="tab-content" id="tab_content" style="height: calc(100% - 80px);"></div>`,
-	nav_tab_template = `
-		<li class="nav-item" data-id="{0}">
-			<button type="button" class="nav-link {2} btn-light-primary btn-active-color-primary" data-id="{0}"  data-bs-toggle="tab" data-bs-target="#iwb_tab_{0}">{1}</button>
-		</li>`,
-	tab_content_template = `<div class="tab-pane h-100" id="iwb_tab_{0}" role="tabpanel">{1}</div>`,
-	table_add_task_btn_template = `<button type="button" class="task_add_btn btn btn-primary btn-sm" onclick="Add('{0}')">添加任务</button>`,
-	table_add_quota_btn_template = `` //`<button type="button" class="quota_add_btn btn btn-primary btn-sm" onclick="Add_Quota('{0}')">添加定额</button>`,
-	table_run_select_template = `<select class="form-select form-select-sm me-5" name="process_status">
-												<option value="">全部运行状态</option>
-												<option value="0">草稿</option>
-												<option value="1">等待运行</option>
-												<option value="2">运行中</option>
-												<option value="200">运行成功</option>
-												<option value="4">取消运行</option>
-												<option value="5">运行失败</option>
-												<!--<option value="4">已修改</option>-->
-											</select>`,
-	table_send_select_template = `<select class="form-select form-select-sm me-5" name="send_status">
-												<option value="">全部发送状态</option>
-												<option value="0">未发送</option>
-												<option value="1">发送中</option>
-												<option value="200">发送成功</option>
-												<option value="2">发送失败</option>
-												<option value="3">数据变更</option>
-											</select>`,
-	table_template = `<div class="table-box table-responsive" data-id="{0}" id="table_box_{0}">
-								<div class="d-flex justify-content-between my-5">
-									<div class="">{1}</div>
-									<form class="search-box d-flex">
-										<div class="d-flex">
-											{2}
-											<input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />
-										</div>
-										<div class="btn-group ms-5">
-											<button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
-											<button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
-										</div>
-									</form>
-								</div>
-								<table class="table table-striped table-bordered table-hover  table-rounded" id="table_{0}">
-								</table>
-								<div class="pagination-row"></div>
-							</div>`
-
-
 let _fileUploadDropzone = null;
 
 function InitFileUpload(){
@@ -102,123 +141,31 @@ function InitFileUpload(){
 	// 	console.log('removedfile', file,_files)
 	// })
 }
-function InitBody(){
-	const h= $('.app-wrapper').height()  - $('#breadcrumb_header').height() - $('.app-footer').height() -5
-	$('#body_box').html(`<div class="d-flex flex-row project-box w-100">
-						<div class="flex-row-auto h-100 left-box">
-							<div class="tree-dom w-300px h-100 overflow-auto" id="js-tree"></div>
-						</div>
-						<div class="flex-row-fluid flex-column right-box" style="display: none">
-							<div class="my-2 d-flex align-items-center box-header mt-5 flex-column-auto">
-								<section class="d-none">
-									<input type="hidden" name="budget_id" value="{0}">
-									<input type="hidden" name="project_id" value="">
-									<input type="hidden" name="item_id" value="">
-									<input type="hidden" name="item_code" value="">
-								</section>
-								<span class="fw-bolder me-5 title fs-2"></span>
-								<span class="badge d-none badge-primary fs-5 me-5"></span>
-								<div class="d-flex">
-									<div class="form-check form-check-custom form-check-primary form-check-solid">
-										<input class="form-check-input" name="table_radio" type="radio" value="task"  id="task_radio"/>
-										<label class="form-check-label fw-bolder text-primary" for="task_radio">
-											任务列表
-										</label>
-									</div>
-									<div class="form-check  form-check-custom form-check-success form-check-solid ms-5">
-										<input class="form-check-input" name="table_radio" type="radio" value="quota"  id="quota_radio"/>
-										<label class="form-check-label fw-bolder text-success" for="quota_radio">
-											定额输入
-										</label>
-									</div>
-								</div>
-							</div>
-							<div class="box-body  flex-column-fluid">
-								<div class="task w-100 h-100" style="display: none"></div>
-								<div class="quota w-100 h-100" style="display: none"></div>
-							</div>
-						</div>
-					</div>`)
-	$('#body_box .project-box').height(h)
-}
-function BuildChapterInfo(){
-	const $tree = $(`#js-tree`)
-	const opt = {
-		core: {
-			themes: {
-				responsive: false,
-			},
-			strings:{
-				'Loading ...': '加载中...',
-			},
-			check_callback: true,
-			data: function (node, callback) {
-				// console.log('TREE_NODE', node)
-				IwbAjax_1({
-					url: `/api/project/chapter/${project_id}?c=${node?.data?.item_code || ''}`,
-					success: res => {
-						if (res.success) {
-							console.log('TREE', res.data)
-							callback(res.data)
-						} else {
-							console.error(res.message)
-						}
-					},
-				})
-			},
-		},
-		types: {
-			default: {
-				icon: 'ki-outline ki-folder text-primary',
-			},
-			file: {
-				icon: 'ki-outline ki-file  text-primary',
-			},
-		},
-		plugins: ['dnd', 'types'],
-	}
-	// $tree.jstree('destroy')
-	$tree.on('loaded.jstree', function(e, data){
-		// console.log('TREE_LOADED', e, data)
-		const inst = data.instance;
-		const obj = inst.get_node(e.target.firstChild.firstChild.firstChild);
-		inst.select_node(obj);
-	})
-	$tree.on('select_node.jstree', function (e, data) {
-		console.log('TREE_SELECTED', e, data)
-		RenderRightBox(data.node?.data)
-	})
-	$tree.jstree(opt)
-}
-function RenderRightBox(data){
-	console.log('RenderRightBox', arguments)
-	const $rightBox= $('#body_box .right-box'),
-		$rightBoxHeader = $('#body_box .right-box .box-header'),
+
+function RenderRightBox_Custom(data){
+	const $rightBoxHeader = $('#body_box .right-box .box-header'),
 		$rightBoxBody = $('#body_box .right-box .box-body'),
 		$taskBox = $rightBoxBody.find('.task'),
 		$quotaBox = $rightBoxBody.find('.quota')
-	$rightBoxBody.data('data',data)
-	$rightBox.find('input[name="budget_id"]').val(data.budget_id);
-	$rightBox.find('input[name="project_id"]').val(project_id);
-	$rightBox.find('input[name="item_id"]').val(data.item_id);
-	$rightBox.find('input[name="item_code"]').val(data.item_code);
-	const title = data.chapter ?`${data.chapter}、${data.project_name}`: data.section ?`${data.section}.${data.project_name}`: data.project_name
-	$rightBoxHeader.find('.title').text(title)
+
 	$rightBoxHeader.find('[name="table_radio"]').prop("disabled",false).off('change.iwb')
 	$rightBoxHeader.find('[name="table_radio"]').on('change.iwb',function(){
-				const val = $(this).val()
-				if (val === 'quota') {
-					_quotaNavTab(data)
-				} else {
-					_taskTable(data)
-				}
-			})
+		const val = $(this).val()
+		if (val === 'quota') {
+			$taskBox.hide()
+			QuotaNavTab(data)
+		} else {
+			_taskTable(data)
+		}
+	})
 	if(data.children_count>0||data.chapter){
 		_renderTask(data)
 	}else{
-		_renderQuota(data)
+		$rightBoxHeader.find('.badge').text('定额输入明细').removeClass('badge-primary').addClass('badge-success')
+		$rightBoxHeader.find('#task_radio').prop("disabled",true)
+		$rightBoxHeader.find('#quota_radio').prop("checked",true)
+		QuotaNavTab(data)
 	}
-	$rightBox.show()
 	function _renderTask(data){
 		$rightBoxHeader.find('.badge').text('任务列表').removeClass('badge-success').addClass('badge-primary')
 		$rightBoxHeader.find('#task_radio').prop("checked",true)
@@ -357,7 +304,7 @@ function RenderRightBox(data){
 							}
 							if (row.process_status === 0) {
 								str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="编辑" onclick="Edit(${row.id})"><i class="ki-duotone ki-message-edit fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
-							} 
+							}
 							str+=`<!--<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="编辑" onclick="Edit(${row.id})"><i class="ki-duotone ki-message-edit fs-1"><span class="path1"></span><span class="path2"></span></i></button>-->`
 							if (row.process_status === 2 || row.process_status ===200) {
 								str+=`<button type="button" class="btn btn-icon btn-sm btn-light-primary"  data-bs-toggle="tooltip" data-bs-placement="top" title="定额输入列表" onclick="GoTo('/quota_info/${project_id}/${row.id}')"><i class="ki-duotone ki-eye fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
@@ -370,81 +317,9 @@ function RenderRightBox(data){
 					},
 				]
 			}, true)
-		setTimeout(function () {$taskBox.show()},500)
-	}
-	function _renderQuota(data){
-		$rightBoxHeader.find('.badge').text('定额输入明细').removeClass('badge-primary').addClass('badge-success')
-		$rightBoxHeader.find('#task_radio').prop("disabled",true)
-		$rightBoxHeader.find('#quota_radio').prop("checked",true)
-		_quotaNavTab(data)
+		$taskBox.find('.table-box').hide()
+		$taskBox.show()
 	}
-	function _quotaNavTab(data){
-		$taskBox.hide()
-		if(!$quotaBox.find('#nav_tab').length){
-			$quotaBox.html(nav_template)
-			BuildBudgetInfo()
-		}else{
-			const data = $quotaBox.find('#nav_tab').data('budget-info') || {}
-			$quotaBox.html(nav_template)
-			RenderTabs(data)
-		}
-		// const $tab = $('#nav_tab li button[data-bs-toggle="tab"]')
-		// if ($tab.length) {
-		// 	const firstTab = new bootstrap.Tab($tab.eq(0))
-		// 	firstTab.show()
-		// }
-		setTimeout(function () {$quotaBox.show()},500)
-	}
-
-}
-
-function BuildBudgetInfo() {
-	IwbAjax_1({
-		url: `/api/project/budget/${project_id}`,
-		success: function (res) {
-			if (res.success) {
-				RenderTabs(res.data)
-			}else{
-				console.error(res.message)
-			}
-		},
-	})
-}
-
-function RenderTabs(data){
-	console.log('RenderTabs', data)
-	let str1 = '',
-		str2 = ''
-	if(data && data.length){
-		for (let i = 0; i < data.length; i++) {
-			const item = data[i]
-			str1 += nav_tab_template.format(item.budget_id, item.budget_code)
-			const tableStr = table_template.format(item.budget_id,table_add_quota_btn_template.format(item.budget_id),table_send_select_template)
-			const tabContent = tab_content_template.format(item.budget_id, tableStr)
-			// console.log('TAB_CONTENT', tabContent)
-			str2 += tabContent
-		}
-	}
-	const $tab = $('#nav_tab'),$content =$('#tab_content')
-	$tab.html(str1).data('budget-info', data)
-	$content.html(str2)
-	const $tab_btn = $tab.find('li button[data-bs-toggle="tab"]')
-	$tab_btn.on('shown.bs.tab',(e)=>{
-		console.log('TAB', e)
-		const tab_id = $(e.target).data('id'),
-			data = $("#body_box .right-box .box-body").data('data')
-		//
-		RenderQuotaTable(tab_id,data)
-	})
-	const firstTab = new bootstrap.Tab($tab_btn.eq(0))
-	firstTab.show()
-}
-
-function RenderQuotaTable(budget_id,data){
-	console.log('RenderQuotaTable', budget_id, data)
-	const $quotaBox = $('#body_box .right-box .box-body .quota')
-	const $table = $quotaBox.find(`#table_${budget_id}`)
-	LoadQuotaTable($table,`/api/quota/list/${budget_id}/${project_id}/${data.item_code}`)
 }
 
 function SetBudgetData($el){

+ 2 - 0
SourceCode/IntelligentRailwayCosting/app/views/static/project/project.js

@@ -2,6 +2,7 @@
 const table = '#table',
 $modal = $("#modal");
 $(function () {
+    InitRangeDate($('#date'))
     IwbTable(table,{
         url:'/api/project/list',
         columns:[
@@ -68,6 +69,7 @@ $(function () {
             }
         ]
     })
+
 });
 function Add(){
     AddModal($modal,()=>{

+ 229 - 2
SourceCode/IntelligentRailwayCosting/app/views/static/project/quota_info.js

@@ -1,4 +1,4 @@
-const modal_template = `
+const quota_modal_template = `
 <div class="modal fade" id="modal_quota" tabindex="-1" aria-hidden="true">
   <div class="modal-dialog modal-lg modal-dialog-centered">
     <div class="modal-content rounded">
@@ -78,9 +78,236 @@ const modal_template = `
     </div>
   </div>
 </div>`
-	$('.app-main .app-container').append(modal_template)
+$('.app-main .app-container').append(quota_modal_template)
+const	nav_template = `<ul id="nav_tab" class="nav nav-tabs nav-line-tabs nav-line-tabs-2x fs-6"></ul><div class="tab-content" id="tab_content" style="height: calc(100% - 80px);"></div>`,
+	nav_tab_template = `
+		<li class="nav-item" data-id="{0}">
+			<button type="button" class="nav-link {2} btn-light-primary btn-active-color-primary" data-id="{0}"  data-bs-toggle="tab" data-bs-target="#iwb_tab_{0}">{1}</button>
+		</li>`,
+	tab_content_template = `<div class="tab-pane h-100" id="iwb_tab_{0}" role="tabpanel">{1}</div>`,
+	table_add_quota_btn_template = `` //`<button type="button" class="quota_add_btn btn btn-primary btn-sm" onclick="Add_Quota('{0}')">添加定额</button>`,
+	table_run_select_template = `<select class="form-select form-select-sm me-5" name="process_status">
+												<option value="">全部运行状态</option>
+												<option value="0">草稿</option>
+												<option value="1">等待运行</option>
+												<option value="2">运行中</option>
+												<option value="200">运行成功</option>
+												<option value="4">取消运行</option>
+												<option value="5">运行失败</option>
+												<!--<option value="4">已修改</option>-->
+											</select>`,
+	table_send_select_template = `<select class="form-select form-select-sm me-5" name="send_status">
+												<option value="">全部发送状态</option>
+												<option value="0">未发送</option>
+												<option value="1">发送中</option>
+												<option value="200">发送成功</option>
+												<option value="2">发送失败</option>
+												<option value="3">数据变更</option>
+											</select>`,
+	table_template = `<div class="table-box table-responsive" data-id="{0}" id="table_box_{0}">
+								<div class="d-flex justify-content-between my-5">
+									<div class="">{1}</div>
+									<form class="search-box d-flex">
+										<div class="d-flex">
+											{2}
+											<input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />
+										</div>
+										<div class="btn-group ms-5">
+											<button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
+											<button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
+										</div>
+									</form>
+								</div>
+								<table class="table table-striped table-bordered table-hover  table-rounded" id="table_{0}">
+								</table>
+								<div class="pagination-row"></div>
+							</div>`
+
 const $modalQuota = $('#modal_quota')
 console.log(`加载项目:${project_id}`)
+InitBody()
+$(function () {
+	BuildChapterInfo()
+	$(window).on('resize', AdjustBoxHeight)
+})
+
+function InitBody(){
+	$('#body_box').html(`<div class="d-flex flex-row project-box w-100">
+						<div class="flex-row-auto h-100 left-box">
+							<div class="tree-dom w-300px h-100 overflow-auto" id="js-tree"></div>
+						</div>
+						<div class="flex-row-fluid flex-column right-box" style="display: none">
+							<div class="my-2 d-flex align-items-center box-header mt-5 flex-column-auto">
+								<section class="d-none">
+									<input type="hidden" name="budget_id" value="{0}">
+									<input type="hidden" name="project_id" value="">
+									<input type="hidden" name="item_id" value="">
+									<input type="hidden" name="item_code" value="">
+								</section>
+								<span class="fw-bolder me-5 title fs-2"></span>
+								<span class="badge d-none badge-primary fs-5 me-5"></span>
+								<div class="d-flex table_radio_box" >
+									<div class="form-check form-check-custom form-check-primary form-check-solid">
+										<input class="form-check-input" name="table_radio" type="radio" value="task"  id="task_radio"/>
+										<label class="form-check-label fw-bolder text-primary" for="task_radio">
+											任务列表
+										</label>
+									</div>
+									<div class="form-check  form-check-custom form-check-success form-check-solid ms-5">
+										<input class="form-check-input" name="table_radio" type="radio" value="quota"  id="quota_radio"/>
+										<label class="form-check-label fw-bolder text-success" for="quota_radio">
+											定额输入
+										</label>
+									</div>
+								</div>
+							</div>
+							<div class="box-body  flex-column-fluid">
+								<div class="task w-100 h-100" style="display: none"></div>
+								<div class="quota w-100 h-100" style="display: none"></div>
+							</div>
+						</div>
+					</div>`)
+	AdjustBoxHeight()
+}
+function  AdjustBoxHeight(){
+	const h= $('.app-wrapper').height()  - $('.app-body-header').height() - $('.app-footer').height() -5
+	$('#body_box .project-box').height(h)
+}
+function BuildChapterInfo(){
+	const $tree = $(`#js-tree`)
+	const opt = {
+		core: {
+			themes: {
+				responsive: false,
+			},
+			strings:{
+				'Loading ...': '加载中...',
+			},
+			check_callback: true,
+			data: function (node, callback) {
+				// console.log('TREE_NODE', node)
+				IwbAjax_1({
+					url: `/api/project/chapter/${project_id}?c=${node?.data?.item_code || ''}`,
+					success: res => {
+						if (res.success) {
+							console.log('TREE', res.data)
+							callback(res.data)
+						} else {
+							console.error(res.message)
+						}
+					},
+				})
+			},
+		},
+		types: {
+			default: {
+				icon: 'ki-outline ki-folder text-primary',
+			},
+			file: {
+				icon: 'ki-outline ki-file  text-primary',
+			},
+		},
+		plugins: ['dnd', 'types'],
+	}
+	// $tree.jstree('destroy')
+	$tree.on('loaded.jstree', function(e, data){
+		// console.log('TREE_LOADED', e, data)
+		const inst = data.instance;
+		const obj = inst.get_node(e.target.firstChild.firstChild.firstChild);
+		inst.select_node(obj);
+	})
+	$tree.on('select_node.jstree', function (e, data) {
+		console.log('TREE_SELECTED', e, data)
+		RenderRightBox(data.node?.data)
+	})
+	$tree.jstree(opt)
+}
+
+function RenderRightBox(data){
+	console.log('RenderRightBox', arguments)
+	const $rightBox= $('#body_box .right-box'),
+		$rightBoxHeader = $('#body_box .right-box .box-header'),
+		$rightBoxBody = $('#body_box .right-box .box-body')
+	$rightBoxBody.data('data',data)
+	$rightBox.find('input[name="budget_id"]').val(data.budget_id);
+	$rightBox.find('input[name="project_id"]').val(project_id);
+	$rightBox.find('input[name="item_id"]').val(data.item_id);
+	$rightBox.find('input[name="item_code"]').val(data.item_code);
+	const title = data.chapter ?`${data.chapter}、${data.project_name}`: data.section ?`${data.section}.${data.project_name}`: data.project_name
+	$rightBoxHeader.find('.title').text(title)
+	RenderRightBox_Custom(data)
+	$rightBox.show()
+}
+function  RenderRightBox_Custom(data){
+	$('.table_radio_box .form-check').hide()
+	QuotaNavTab(data)
+}
+function QuotaNavTab(){
+	const $rightBoxBody = $('#body_box .right-box .box-body'),
+		$taskBox = $rightBoxBody.find('.task'),
+		$quotaBox = $rightBoxBody.find('.quota')
+	$taskBox.hide()
+	if(!$quotaBox.find('#nav_tab').length){
+		$quotaBox.html(nav_template)
+		BuildBudgetInfo()
+	}else{
+		const budget = $quotaBox.find('#nav_tab').data('budget-info') || {}
+		$quotaBox.html(nav_template)
+		RenderTabs(budget)
+	}
+	$quotaBox.find('.table-box').hide()
+	$quotaBox.show()
+}
+
+function BuildBudgetInfo() {
+	IwbAjax_1({
+		url: `/api/project/budget/${project_id}`,
+		success: function (res) {
+			if (res.success) {
+				RenderTabs(res.data)
+			}else{
+				console.error(res.message)
+			}
+		},
+	})
+}
+
+function RenderTabs(data){
+	console.log('RenderTabs', data)
+	let str1 = '',
+		str2 = ''
+	if(data && data.length){
+		for (let i = 0; i < data.length; i++) {
+			const item = data[i]
+			str1 += nav_tab_template.format(item.budget_id, item.budget_code)
+			const tableStr = table_template.format(item.budget_id,table_add_quota_btn_template.format(item.budget_id),table_send_select_template)
+			const tabContent = tab_content_template.format(item.budget_id, tableStr)
+			// console.log('TAB_CONTENT', tabContent)
+			str2 += tabContent
+		}
+	}
+	const $tab = $('#nav_tab'),$content =$('#tab_content')
+	$tab.html(str1).data('budget-info', data)
+	$content.html(str2)
+	const $tab_btn = $tab.find('li button[data-bs-toggle="tab"]')
+	$tab_btn.on('shown.bs.tab',(e)=>{
+		console.log('TAB', e)
+		const tab_id = $(e.target).data('id'),
+			data = $("#body_box .right-box .box-body").data('data')
+		//
+		RenderQuotaTable(tab_id,data)
+	})
+	const firstTab = new bootstrap.Tab($tab_btn.eq(0))
+	firstTab.show()
+}
+
+function RenderQuotaTable(budget_id,data){
+	console.log('RenderQuotaTable', budget_id, data)
+	const $quotaBox = $('#body_box .right-box .box-body .quota')
+	const $table = $quotaBox.find(`#table_${budget_id}`)
+	LoadQuotaTable($table,`/api/quota/list/${budget_id}/${project_id}/${data.item_code}`)
+}
+
 function  LoadQuotaTable(table,url){
     IwbTable(table,{
 		url,

+ 2 - 36
SourceCode/IntelligentRailwayCosting/app/views/templates/log/index.html

@@ -34,7 +34,7 @@
                         <option value="0">成功</option>
                         <option value="1">失败</option>
                     </select>
-                    <input type="text" class="form-control form-control-sm w-200px me-5" placeholder="请输入关键字" name="date" id="date"/>
+                    <input type="text" class="form-control form-control-sm w-200px me-5" placeholder="请输入起始日期" name="date" id="date"/>
                 </div>
                 <div class="btn-group ms-5">
                     <button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
@@ -90,38 +90,7 @@
         $modal = $("#modal");
         ChangeHeadMenu("#{{page_active}}_menu")
         $(function () {
-
-
-            const start = moment().subtract(29, "days");
-            const end = moment();
-            function cb(start, end) {
-                $('#date').html(start.format("YYYY-MM-DD") + " - " + end.format("YYYY-MM-DD"));
-            }
-            $('#date').daterangepicker({
-                startDate: start,
-                endDate: end,
-                locale:{
-                    format: "YYYY-MM-DD", //设置显示格式
-                    applyLabel: '确定', //确定按钮文本
-                    cancelLabel: '取消', //取消按钮文本
-                    customRangeLabel: '自定义',
-                    daysOfWeek: ['日', '一', '二', '三', '四', '五', '六'],
-                    monthNames: ['一月', '二月', '三月', '四月', '五月', '六月',
-                        '七月', '八月', '九月', '十月', '十一月', '十二月'
-                    ],
-                    firstDay: 1
-                },
-                ranges: {
-                "今天": [moment(), moment()],
-                "昨天": [moment().subtract(1, "days"), moment().subtract(1, "days")],
-                "近7天": [moment().subtract(6, "days"), moment()],
-                "近30天": [moment().subtract(29, "days"), moment()],
-                "本月": [moment().startOf("month"), moment().endOf("month")],
-                "上月": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
-                }
-            }, cb);
-            cb(start, end);
-
+            InitRangeDate($('#date'))
             IwbTable(table,{
                 url:'/api/log/list',
                 columns: [
@@ -197,9 +166,6 @@
             })
         });
 
-
-
-
     </script>
 
 {% endblock %}

+ 9 - 85
SourceCode/IntelligentRailwayCosting/app/views/templates/project/budget_info.html

@@ -11,97 +11,21 @@
 	</ol>
 </div>
 <div class="box w-100" id="body_box"></div>
-<div class="modal fade" id="modal" tabindex="-1" aria-hidden="true">
-	<div class="modal-dialog modal-dialog-centered">
-		<div class="modal-content rounded">
-			<div class="modal-header">
-				<h3 class="modal-title"><span class="prefix"></span>任务</h3>
-				<div class="btn btn-sm btn-icon btn-active-color-primary" data-bs-dismiss="modal">
-					<i class="ki-duotone ki-cross fs-1">
-						<span class="path1"></span>
-						<span class="path2"></span>
-					</i>
-				</div>
-			</div>
-			<div class="modal-body">
-				<form>
-					<div class="form-group">
-<!--						<input type="hidden" name="budget_id" value="">-->
-						<input type="hidden" name="project_id" value="">
-						<input type="hidden" name="item_id" value="">
-						<input type="hidden" name="item_code" value="">
-						<input type="hidden" name="task_id" value="">
-						<div class="fv-row form-group mb-3">
-							<label for="task_name" class="form-label required">任务名称</label>
-							<input type="text" class="form-control" name="task_name" id="task_name" placeholder="请输入" required />
-						</div>
-						<div class="fv-row form-group mb-3">
-							<label for="budget_id" class="form-label">概算单元</label>
-							<select class="form-select" name="budget_id" id="budget_id">
-								<option value="0">全部概算单元</option>
-								{% for budget in budgets %}
-								<option value="{{ budget.budget_id }}">{{ budget.budget_code }}</option>
-								{% endfor %}
-							</select>
-						</div>
-						<div class="fv-row form-group mb-3">
-							<label for="task_sort" class="form-label">任务排序</label>
-							<input type="number" class="form-control" name="task_sort" id="task_sort" placeholder="请输入"/>
-						</div>
-
-<!--						<div class="form-check mb-3" id="delete_file_box">-->
-<!--						 	<input class="form-check-input" type="checkbox" value="" id="delete_file" name="delete_file"/>-->
-<!--							<label class="form-check-label ms-5 text-primary " for="delete_file">-->
-<!--								删除原数据文件-->
-<!--							</label>-->
-<!--						</div>-->
-						<div class="fv-row">
-							<div id="file_upload_dropzone">
-								<div class="dropzone">
-									<div class="dz-message dropzone-select">
-										<i class="ki-duotone ki-file-up fs-3x text-primary"><span class="path1"></span><span class="path2"></span></i>
-										<div class="ms-4">
-											<h3 class="fs-5 fw-bold text-gray-900 mb-1">将文件拖放到此处或单击上传。</h3>
-											<span class="fs-7 fw-semibold text-gray-500">最多可上传 5 个文件,文件最大10M</span>
-										</div>
-									</div>
-								</div>
-								<div class="dropzone dropzone-queue">
-									<div class="dropzone-items wm-200px">
-										<div class="dropzone-item" style="display:none">
-											<div class="dropzone-file">
-												<div class="dropzone-filename" title="some_image_file_name.jpg">
-													<span data-dz-name>some_image_file_name.jpg</span>
-													<strong>(<span data-dz-size>340kb</span>)</strong>
-												</div>
-												<div class="dropzone-error" data-dz-errormessage></div>
-											</div>
-											<div class="dropzone-toolbar">
-												<span class="dropzone-delete" data-dz-remove><i class="bi bi-x fs-1"></i></span>
-											</div>
-										</div>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</form>
-			</div>
-			<div class="modal-footer">
-				<button type="button" class="btn btn-light" data-bs-dismiss="modal">取消</button>
-				<button type="button" class="btn btn-success" onclick="SaveProject(true)">提交</button>
-				<button type="button" class="btn btn-primary" onclick="SaveProject()">保存草稿</button>
-			</div>
-		</div>
-	</div>
-</div>
+<section class="d-none">
+	<select class="d-none" id="budget_id_options">
+		<option value="0">全部概算单元</option>
+		{% for budget in budgets %}
+		<option value="{{ budget.budget_id }}">{{ budget.budget_code }}</option>
+		{% endfor %}
+	</select>
+</section>
 
 {% endblock %} {% block page_scripts %}
+<script src="{{ url_for('static', filename='base/plugins/jstree/jstree.bundle.js') }}"></script>
 <script>
 	ChangeHeadMenu('#{{page_active}}_menu')
 	const project_id = '{{project.project_id}}'
 </script>
-<script src="{{ url_for('static', filename='base/plugins/jstree/jstree.bundle.js') }}"></script>
 <script src="/static/project/quota_info.js"></script>
 <script src="/static/project/budget_info.js"></script>
 

+ 1 - 0
SourceCode/IntelligentRailwayCosting/app/views/templates/project/index.html

@@ -18,6 +18,7 @@
             <form class="search-box d-flex">
                 <div class="d-flex">
                     <input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />
+                    <input type="text" class="form-control form-control-sm w-200px ms-5" placeholder="请输入起始日期" name="date" id="date"/>
                 </div>
                 <div class="btn-group ms-5">
                     <button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>

+ 55 - 44
SourceCode/IntelligentRailwayCosting/app/views/templates/project/quota_info.html

@@ -1,7 +1,10 @@
 {% extends "base/layout.html" %}
 
 {% block title %}定额输入管理{% endblock %}
-
+{% block page_head_plugins %}
+<link rel="stylesheet" href="{{ url_for('static', filename='base/plugins/jstree/jstree.bundle.css') }}" />
+<link rel="stylesheet" href="{{ url_for('static', filename='project/budget.css') }}" />
+{% endblock %}
 {% block page_content %}
  <div class="app-body-header h-50px">
     <h3>定额输入({{task.task_name}})</h3>
@@ -11,55 +14,63 @@
 		<li class="breadcrumb-item text-muted">定额输入</li>
     </ol>
 </div>
-<div class="mx-10 my-5">
-    <div class="table-box table-responsive">
-        <section class="d-none">
-            <input type="hidden" name="project_id" value="{{project.project_id}}">
-            <input type="hidden" name="item_id" value="">
-            <input type="hidden" name="item_code" value="">
-        </section>
-        <div class="d-flex justify-content-between mb-5 mx-10">
-            <div>
-<!--                <button class="btn btn-primary btn-sm" onclick="Add()">添加</button>-->
-            </div>
-            <form class="search-box d-flex">
-                <div class="d-flex">
-                    <select class="form-select form-select-sm me-5" name="send_status">
-                        	<option value="">全部发送状态</option>
-                            <option value="0">未发送</option>
-                            <option value="1">发送中</option>
-                            <option value="200">发送成功</option>
-                            <option value="2">发送失败</option>
-                            <option value="3">数据变更</option>
-                    </select>
-                    <select class="form-select form-select-sm me-5" name="budget_id">
-                        	<option value="">全部概算单元</option>
-                            {% for budget in budgets %}
-                            <option value="{{ budget.budget_id }}">{{ budget.budget_code }}</option>
-                            {% endfor %}
-                    </select>
-                    <input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />
-                </div>
-                <div class="btn-group ms-5">
-                    <button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
-                    <button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
-                </div>
-            </form>
-        </div>
-        <table class="table table-striped table-bordered table-hover  table-rounded" id="table">
-        </table>
-        <div class="pagination-row"></div>
-    </div>
-</div>
+<div class="box w-100" id="body_box"></div>
+
+<!--<div class="d-flex flex-row project-box w-100">-->
+<!--    <div class="flex-row-auto h-100 left-box">-->
+<!--        <div class="tree-dom w-300px h-100 overflow-auto" id="js-tree"></div>-->
+<!--    </div>-->
+<!--    <div class="flex-row-fluid flex-column right-box">-->
+<!--        <div class="mx-10 my-5">-->
+<!--            <div class="table-box table-responsive">-->
+<!--                <section class="d-none">-->
+<!--                    <input type="hidden" name="project_id" value="{{project.project_id}}">-->
+<!--                    <input type="hidden" name="item_id" value="">-->
+<!--                    <input type="hidden" name="item_code" value="">-->
+<!--                </section>-->
+<!--                <div class="d-flex justify-content-between mb-5 mx-10">-->
+<!--                    <div>-->
+<!--        &lt;!&ndash;                <button class="btn btn-primary btn-sm" onclick="Add()">添加</button>&ndash;&gt;-->
+<!--                    </div>-->
+<!--                    <form class="search-box d-flex">-->
+<!--                        <div class="d-flex">-->
+<!--                            <select class="form-select form-select-sm me-5" name="send_status">-->
+<!--                                    <option value="">全部发送状态</option>-->
+<!--                                    <option value="0">未发送</option>-->
+<!--                                    <option value="1">发送中</option>-->
+<!--                                    <option value="200">发送成功</option>-->
+<!--                                    <option value="2">发送失败</option>-->
+<!--                                    <option value="3">数据变更</option>-->
+<!--                            </select>-->
+<!--                            <select class="form-select form-select-sm me-5" name="budget_id">-->
+<!--                                    <option value="">全部概算单元</option>-->
+<!--                                    {% for budget in budgets %}-->
+<!--                                    <option value="{{ budget.budget_id }}">{{ budget.budget_code }}</option>-->
+<!--                                    {% endfor %}-->
+<!--                            </select>-->
+<!--                            <input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />-->
+<!--                        </div>-->
+<!--                        <div class="btn-group ms-5">-->
+<!--                            <button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>-->
+<!--                            <button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>-->
+<!--                        </div>-->
+<!--                    </form>-->
+<!--                </div>-->
+<!--                <table class="table table-striped table-bordered table-hover  table-rounded" id="table">-->
+<!--                </table>-->
+<!--                <div class="pagination-row"></div>-->
+<!--            </div>-->
+<!--        </div>-->
+<!--    </div>-->
+<!--</div>-->
 
 {% endblock %}
 {% block page_scripts %}
+    <script src="{{ url_for('static', filename='base/plugins/jstree/jstree.bundle.js') }}"></script>
     <script>
         ChangeHeadMenu("#{{page_active}}_menu")
 	    const project_id = '{{project.project_id}}', task_id = '{{task.id}}'
-        $(function (){
-            LoadQuotaTable($('#table'),`/api/quota/list/task/${task_id}`)
-        })
+
     </script>
     <script src="/static/project/quota_info.js"></script>