Explorar o código

update 完善页面

YueYunyun hai 4 meses
pai
achega
363d64bfc6

+ 3 - 1
SourceCode/DataMiddleware/app/routes/route_log.py

@@ -15,6 +15,8 @@ def get_page_list():
         username = data.get('username')
         operation_type = data.get('operationType')
         operation_module = data.get('operationModule')
+        operation_result = data.get('operationResult')
+        operation_result = int(operation_result) if operation_result else None
         start_date = None
         end_date = None
         date = data.get('date')
@@ -23,7 +25,7 @@ def get_page_list():
             start_date = date[0]+' 00:00:00'
             end_date = date[1]+" 23:59:59"
 
-        logs, total_count = LogService.get_logs_paginated(page, per_page, username, operation_type, operation_module,
+        logs, total_count = LogService.get_logs_paginated(page, per_page, username, operation_type, operation_module,operation_result,
                                                           start_date, end_date)
         return jsonify(TableResponse.success(logs, total_count))
     except Exception as e:

+ 52 - 2
SourceCode/DataMiddleware/app/routes/route_sub_project.py

@@ -1,4 +1,5 @@
-from flask import Blueprint, request, jsonify
+import os
+from flask import Blueprint, request, jsonify, send_from_directory
 
 from models.project_data import SubProjectModel
 from routes.route_base import ResponseBase,TableResponse
@@ -51,4 +52,53 @@ def delete_sub_project(sub_id:int):
         ProjectService.delete_sub_project(sub_id)
         return jsonify(ResponseBase.success())
     except Exception as e:
-        return jsonify(ResponseBase.error(f'删除工程失败:{str(e)}'))
+        return jsonify(ResponseBase.error(f'删除工程失败:{str(e)}'))
+
+@sub_project_api.route('/download', methods=['GET'])
+@BaseView.login_required
+def download_file():
+    filename = request.args.get('filename', type=str)
+    if not filename:
+        return jsonify(ResponseBase.error('文件名不能为空')),400
+    try:
+        # 安全处理文件名
+        pure_filename = os.path.basename(filename)
+        safe_filename = os.path.basename(pure_filename)
+        path = filename.replace(safe_filename, '')
+        upload_folder = os.path.abspath(os.path.join(os.getcwd(), path))
+        if not os.path.exists(upload_folder):
+            return jsonify(ResponseBase.error('项目目录不存在')),400
+        full_path = os.path.join(upload_folder, safe_filename)
+        if not os.path.exists(full_path):
+            return jsonify(ResponseBase.error('文件不存在')),400
+    except Exception as e:
+        utils.get_logger().error(f'路径构建失败:{str(e)}')
+        return jsonify(ResponseBase.error( f'非法文件路径{str(e)}')),400
+    return send_from_directory(upload_folder.replace('\\', '/'), safe_filename, as_attachment=True)
+
+@sub_project_api.route('/start_task/<int:sub_id>', methods=['POST'])
+@BaseView.login_required
+def start_task(sub_id:int):
+    try:
+        result, err_msg = ProjectService.start_sub_project_task(sub_id)
+        return jsonify(ResponseBase.json_response(result, err_msg))
+    except Exception as e:
+        return jsonify(ResponseBase.error(f'启动任务失败:{str(e)}'))
+
+@sub_project_api.route('/start_process/<int:sub_id>', methods=['POST'])
+@BaseView.login_required
+def start_process(sub_id:int):
+    try:
+        result, err_msg = ProjectService.start_process_sub_project(sub_id)
+        return jsonify(ResponseBase.json_response(result, err_msg))
+    except Exception as e:
+        return jsonify(ResponseBase.error(f'处理数据失败:{str(e)}'))
+
+@sub_project_api.route('/start_send/<int:sub_id>', methods=['POST'])
+@BaseView.login_required
+def start_send(sub_id:int):
+    try:
+        result, err_msg = ProjectService.start_send_sub_project(sub_id)
+        return jsonify(ResponseBase.json_response(result, err_msg))
+    except Exception as e:
+        return jsonify(ResponseBase.error(f'发送数据失败:{str(e)}'))

+ 45 - 4
SourceCode/DataMiddleware/app/routes/route_sub_project_item.py

@@ -39,12 +39,53 @@ def get(item_id:int):
 def save_sub_project_item(sub_id:int,item_id):
     try:
         data = request.get_json()
+        device_name = data.get('device_name')
+        device_model = data.get('device_model')
+        device_unit = data.get('device_unit')
+        device_count = data.get('device_count')
+        device_count = float(device_count) if device_count else 0
+        standard_no = data.get('standard_no')
+        is_query = data.get("is_query") == "true"
+
         if item_id == 0:
-            item = SubProjectItemModel(**data)
+            item = SubProjectItemModel(
+                device_name=device_name,
+                device_model=device_model,
+                device_unit=device_unit,
+                device_count=device_count,
+                standard_no=standard_no
+            )
             item.sub_project_id = sub_id
-            ProjectService.add_sub_project_item(item)
+            new_id = ProjectService.add_sub_project_item(item)
+            item.id = new_id
         else:
-            ProjectService.get_sub_project_item_by_id(item_id)
+            item = ProjectService.get_sub_project_item_by_id(item_id)
+            item.device_name = device_name
+            item.device_model = device_model
+            item.device_unit = device_unit
+            item.device_count = device_count
+            item.standard_no = standard_no
+            ProjectService.update_sub_project_item(item)
+        if is_query and item.id:
+            ProjectService.start_process_item(item.id)
         return jsonify(ResponseBase.success())
     except Exception as e:
-        return jsonify(ResponseBase.error(f'保存工程明细失败:{str(e)}'))
+        return jsonify(ResponseBase.error(f'保存工程明细失败:{str(e)}'))
+
+@sub_project_item_api.route('/process/<int:item_id>', methods=['POST'])
+@BaseView.login_required
+def start_process(item_id:int):
+    try:
+        result, err_msg = ProjectService.start_process_item(item_id)
+        return jsonify(ResponseBase.json_response(result, err_msg))
+    except Exception as e:
+        return jsonify(ResponseBase.error(f'处理数据失败:{str(e)}'))
+
+@sub_project_item_api.route('/send/<int:item_id>', methods=['POST'])
+@BaseView.login_required
+def start_send(item_id:int):
+    try:
+        result, err_msg = ProjectService.start_send_item(item_id)
+        return jsonify(ResponseBase.json_response(result, err_msg))
+    except Exception as e:
+        return jsonify(ResponseBase.error(f'发送数据失败:{str(e)}'))

+ 5 - 2
SourceCode/DataMiddleware/app/services/service_log.py

@@ -44,16 +44,19 @@ class LogService:
 
 
 
-    def get_logs_paginated(self, page: int, per_page: int, username: str = None, operation_type: str =None, operation_module: str =None,
+    def get_logs_paginated(self, page: int, per_page: int, username: str = None, operation_type: str =None, operation_module: str =None, operation_result: int =None,
                           start_date: datetime = None, end_date: datetime = None) :
         """
         分页获取日志列表
         :param page: 页码
         :param per_page: 每页数量
         :param username: 用户名筛选
+        :param operation_type:
+        :param operation_module:
+        :param operation_result:
         :param start_date: 开始时间
         :param end_date: 结束时间
         :return: 日志列表和总数
         """
-        data,total = self._log_store.query_logs_paginated(page, per_page, username, operation_type,operation_module,start_date, end_date)
+        data,total = self._log_store.query_logs_paginated(page, per_page, username, operation_type,operation_module,operation_result,start_date, end_date)
         return [log.to_dict() for log in data],total

+ 1 - 1
SourceCode/DataMiddleware/app/services/service_project.py

@@ -166,7 +166,7 @@ class ProjectService:
             data_send.send_project_data(sub_project)
             self._project_store.update_sub_project_status(sub_project.id, SubProjectStatus.COMPLETE)
 
-    def process_sub_project(self, sub_project_id:int):
+    def start_process_sub_project(self, sub_project_id:int):
         data = self._project_store.query_sub_project(sub_project_id)
         if data:
             LogHelper.log_success(OperationType.PROCESS, OperationModule.SUB_PROJECT, f"处理工程数据", utils.to_str(data.to_dict()))

+ 9 - 3
SourceCode/DataMiddleware/app/stores/log_store.py

@@ -23,7 +23,7 @@ class LogStore:
         with self._db_helper:
             self._db_helper.execute_non_query(sql, params)
 
-    def query_logs_paginated(self, page: int, per_page: int, username: str = None, operation_type: str = None, operation_module: str = None, start_date: datetime = None, end_date: datetime = None) -> Tuple[List[LogModel], int]:
+    def query_logs_paginated(self, page: int, per_page: int, username: str = None, operation_type: str = None, operation_module: str = None, operation_result: int =None, start_date: datetime = None, end_date: datetime = None) -> Tuple[List[LogModel], int]:
         offset = (page - 1) * per_page
         sql_count = "SELECT COUNT(*) as count FROM sys_log WHERE 1=%s"
         sql = "SELECT id, username, operation_type, operation_desc, operation_result, operation_data, operation_ip, operation_module, data_changes, created_at FROM sys_log WHERE 1=%s"
@@ -31,8 +31,8 @@ class LogStore:
         params = (1,)
 
         if username:
-            sql_count += " AND username = %s"
-            sql += " AND username = %s"
+            sql_count += " AND username LIKE %s"
+            sql += " AND username LIKE %s"
             params_count += (f'%{username}%',)
             params += (f'%{username}%',)
 
@@ -48,6 +48,12 @@ class LogStore:
             params_count += (operation_module,)
             params += (operation_module,)
 
+        if operation_result is not None:
+            sql_count += " AND operation_result = %s"
+            sql += " AND operation_result = %s"
+            params_count += (operation_result,)
+            params += (operation_result,)
+
         if start_date:
             sql_count += " AND created_at >= %s"
             sql += " AND created_at >= %s"

+ 1 - 1
SourceCode/DataMiddleware/app/ui/views_project.py

@@ -136,7 +136,7 @@ def start_sub_project_task(project_id:int):
 @BaseView.login_required
 def start_process_sub_project(project_id:int):
     try:
-        result, err_msg = ProjectService.process_sub_project(project_id)
+        result, err_msg = ProjectService.start_process_sub_project(project_id)
         return jsonify({'success': result, 'error': err_msg})
     except Exception as e:
         return jsonify({'success': False, 'error': str(e)})

+ 3 - 3
SourceCode/DataMiddleware/app/views/log.py

@@ -6,6 +6,6 @@ log_bp = Blueprint('log', __name__, template_folder='templates')
 @log_bp.route('/log', methods=['GET'])
 @BaseView.login_required
 def index():
-    operator_type_list = [op.value for op in OperationType]
-    operator_module_list = [op.value for op in OperationModule]
-    return render_template('log/index.html',page_active='log',operator_type_list=operator_type_list,operator_module_list=operator_module_list)
+    operation_type_list = [op.value for op in OperationType]
+    operation_module_list = [op.value for op in OperationModule]
+    return render_template('log/index.html',page_active='log',operation_type_list=operation_type_list,operation_module_list=operation_module_list)

+ 2 - 2
SourceCode/DataMiddleware/app/views/static/layout.css

@@ -1,5 +1,5 @@
 :root {
-    --bs-app-header-height: 54px;
-    --bs-app-header-height-actual: 54px;
+    --bs-app-header-height: 64px;
+    --bs-app-header-height-actual: 64px;
 }
 

+ 10 - 3
SourceCode/DataMiddleware/app/views/static/styles.css

@@ -29,17 +29,24 @@ body > .container, body > .container-fluid{
 .table-box th,.table-box td{
     text-align: center;
     vertical-align: middle;
-    padding: 8px;
+    height: 40px;
+    padding: 0;
 }
 .table-box th{
     font-weight: 600;
     font-size: 16px;
-    height: 40px;
+    height: 45px;
 }
 .table-box td > .btn{
-    padding: calc(.3rem + 1px) calc(1rem + 1px)!important;
+    padding: calc(.2rem + 1px) calc(.6rem + 1px)!important;
     margin: 0 5px;
+    font-size: 12px;
+    --bs-btn-border-radius: .3rem;
 }
+.table-box td > .link:hover{
+    border-bottom: 2px solid;
+}
+
 .table-box .table-loading{
     position: absolute;
     top:0;

+ 41 - 2
SourceCode/DataMiddleware/app/views/static/utils.js

@@ -65,7 +65,7 @@ function IwbTable(table, opts) {
 	if (table.length === 0) return
 	const options = $table.data('options')
 	const defaultOptions = {
-		pageSize: 10,
+		pageSize: 15,
 		pageNum: 1,
 		search: {
 			keyword: '',
@@ -148,7 +148,7 @@ function IwbTable(table, opts) {
 		let str = '<div class=" d-flex align-items-center justify-content-center justify-content-md-start dt-toolbar">'
 		// 每页显示条数选择
 		str += `<div><select class="form-select form-select-solid form-select-sm" onchange="IwbTableChangePageSize(this)">`
-		;[10, 25, 50, 100].forEach((size) => {
+		;[15, 25, 50, 100].forEach((size) => {
 			str += `<option value="${size}" ${pageSize === size ? ' selected' : ''}>${size}</option>`
 		})
 		str += '</select></div>'
@@ -254,4 +254,43 @@ function Confirm(title, callback) {
 	if(confirm(title)){
 		callback && callback()
 	}
+}
+
+function ConfirmUrl(title, url, table){
+	if(confirm(title)){
+		IwbAjax({
+			url:url,
+			table: table||'#table'
+		})
+	}
+}
+
+function ChangeHeadMenu(menu){
+	$('#header_menu .menu-item').removeClass('here')
+	$('#header_menu '+menu).addClass('here')
+}
+
+function DownloadFile(url, fileName) {
+    fetch(url)
+        .then(response => {
+            if (!response.ok) {
+                return response.json().then(err => {
+                    throw new Error(err.message || '下载失败')
+                })
+            }
+            return response.blob()
+        })
+        .then(blob => {
+            const downloadUrl = window.URL.createObjectURL(blob)
+            const a = document.createElement('a')
+            a.href = downloadUrl
+            a.download = fileName
+            document.body.appendChild(a)
+            a.click()
+            window.URL.revokeObjectURL(downloadUrl)
+            document.body.removeChild(a)
+        })
+        .catch(error => {
+            alert(error.message)
+        })
 }

+ 9 - 7
SourceCode/DataMiddleware/app/views/templates/base/layout.html

@@ -13,24 +13,26 @@
             <div class="app-container container-fluid d-flex align-items-stretch justify-content-between">
                 <div class="d-flex align-items-center flex-grow-1 flex-lg-grow-0 me-5">
                     <a href="{{ url_for('project.index') }}">
-                        <img alt="Logo" src="{{ url_for('static', filename='/media/logo.png') }}" class="h-30px" />
+                        <img alt="Logo" src="{{ url_for('static', filename='/media/logo.png') }}" class="h-45px" />
                     </a>
                 </div>
                 <div class="d-flex align-items-stretch justify-content-between flex-lg-grow-1">
                     <div class="app-header-menu app-header-mobile-drawer align-items-stretch" >
+                        <div class="title mx-10 d-flex align-items-center flex-nowrap" style="white-space: nowrap">
+                           <h2 class="d-flex text-white fs-2 mb-0">数据转换推送系统</h2>
+                        </div>
                         <div id="header_menu" class="menu menu-rounded menu-column menu-lg-row my-5 my-lg-0 align-items-stretch fw-semibold px-2 px-lg-0">
-                            <div class="menu-item here">
+                            <div class="menu-item here" id="project_menu">
                                 <a href="{{ url_for('project.index') }}" class="menu-link">
-                                    <span class="menu-title">项目</span>
+                                    <span class="menu-title">项目管理</span>
                                 </a>
                             </div>
-
                             {% if current_user.is_admin %}
-                            <div class="menu-item">
+                             <div class="menu-item here" id="log_menu">
                                 <a href="{{ url_for('log.index') }}" class="menu-link">
-                                    <span class="menu-title">日志</span>
+                                    <span class="menu-title">日志管理</span>
                                 </a>
-                             </div>
+                            </div>
                             {% endif %}
                         </div>
                     </div>

+ 6 - 0
SourceCode/DataMiddleware/app/views/templates/base/user_info.html

@@ -22,6 +22,12 @@
         <div class="menu-item px-5 my-1">
             <a href="#"  class="menu-link px-5" data-bs-toggle="modal" data-bs-target="#changePasswordModal">修改密码</a>
         </div>
+        {% if current_user.is_admin %}
+        <div class="menu-item px-5 my-1">
+            <a href="{{ url_for('log.index') }}" class="menu-link px-5">操作日志</a>
+        </div>
+        {% endif %}
+        <div class="separator my-2"></div>
         <div class="menu-item px-5">
             <a href="{{ url_for('auth.login') }}" class="menu-link px-5">注销登录</a>
         </div>

+ 12 - 3
SourceCode/DataMiddleware/app/views/templates/log/index.html

@@ -15,7 +15,7 @@
         </div>
         <form class="search-box d-flex">
             <div class="d-flex">
-                <input type="text" class="form-control form-control-sm w-200px me-5" placeholder="请输入关键字" name="username" />
+                <input type="text" class="form-control form-control-sm w-200px me-5" placeholder="请输入用户名" name="username" />
                 <select class="form-select form-select-sm w-100 me-5" name="operationType" >
                     <option value="">全部类型</option>
                     {% for op in operation_type_list %}
@@ -28,10 +28,15 @@
                         <option value="{{ op }}">{{ op }}</option>
                     {% endfor %}
                 </select>
+                <select class="form-select form-select-sm w-100 me-5" name="operationResult" >
+                    <option value="">全部结果</option>
+                    <option value="1">成功</option>
+                    <option value="0">失败</option>
+                </select>
                 <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>
+                <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>
@@ -79,8 +84,10 @@
     <script>
         const table = '#table',
         $modal = $("#modal");
+        ChangeHeadMenu("#log_menu")
         $(function () {
 
+
             const start = moment().subtract(29, "days");
             const end = moment();
             function cb(start, end) {
@@ -155,7 +162,9 @@
                         data: 'description',
                         width: 'auto',
                         render: function (row) {
-                            return `<span class="w-100" title="${row.operation_data ? row.operation_data:''} ${row.data_changes ? ('\n'+row.data_changes):''}">${row.operation_desc}</span>`;
+                            const operation_data = row.operation_data ? row.operation_data : "";
+                            const data_changes = row.data_changes ? (operation_data? '\n': '')+ row.data_changes : "";
+                            return `<span class="w-100" title='${operation_data ? operation_data:""}${data_changes ? data_changes:""}'>${row.operation_desc}</span>`;
                         }
                     },
                     {

+ 3 - 1
SourceCode/DataMiddleware/app/views/templates/project/index.html

@@ -19,7 +19,7 @@
                 <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-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
                 <button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
             </div>
         </form>
@@ -65,6 +65,8 @@
 {% endblock %}
 {% block page_scripts %}
     <script>
+        ChangeHeadMenu("#project_menu")
+
         const table = '#table',
         $modal = $("#modal");
         $(function () {

+ 38 - 8
SourceCode/DataMiddleware/app/views/templates/project/sub_project.html

@@ -22,7 +22,7 @@
 				<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-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
 				<button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
 			</div>
 		</form>
@@ -54,9 +54,11 @@
 							<label for="project_desc" class="form-label">上传数据</label>
 							<textarea type="text" class="form-control" name="project_desc" id="project_desc" placeholder="请输入"></textarea>
 						</div>
-						<div class="fv-row form-group mb-3">
-							<label for="project_desc" class="form-label">删除原数据文件</label>
-							<input type="checkbox" class="form-check-input" name="delete_file" id="delete_file" />
+						<div class="form-check mb-3">
+						 	<input class="form-check-input" type="checkbox" value="" id="delete_file" name="delete_file"/>
+							<label class="form-check-label" for="delete_file">
+								删除原数据文件
+							</label>
 						</div>
 					</div>
 				</form>
@@ -70,6 +72,7 @@
 </div>
 {% endblock %} {% block page_scripts %}
 <script>
+	ChangeHeadMenu("#project_menu")
 	const project_id = '{{project.id}}'
 	const table = '#table',
 		$modal = $('#modal')
@@ -98,7 +101,7 @@
 							const path = file_paths[i]
 							const names = path.split('/')
 							const file_name = names[names.length - 1]
-							str += `<a href="${path}"  class="link link-info mx-2" download>${file_name}</a>`
+							str += `<a href="#"  onclick="DownloadFile('/api/sub_project/download?filename=${encodeURIComponent(path)}','${file_name}')"  class="link link-info px-2">${file_name}</a>`
 						}
 						return str
 					},
@@ -125,9 +128,21 @@
 					title: '操作',
 					width: '280px',
 					render: function (row) {
-						let str = `<span class="btn btn-light-primary" onclick="GoTo('/sub-item/${row.id}')">工程明细</span>`
-						str += `<span class="btn btn-light-success" onclick="Edit('${row.id}')">编辑</span>`
-						str += `<span class="btn btn-light-danger" onclick="Delete('${row.id}')">删除</span>`
+						let str = ``
+						if (row.status === 0) {
+							str += `<span class="btn btn-light-success" onclick="StartSubProjectTask('${row.id}')">开始任务</span>`
+						} else if (row.status === 11) {
+							str += `<span class="btn btn-light-warning" onclick="ReStartSubProjectTask('${row.id}')">重新采集</span>`
+						} else if (row.status === 12) {
+							str += `<span class="btn btn-light-warning" onclick="ReStartProcessSubProjectTask('${row.id}')">重新处理</span>`
+						} else if (row.status === 13) {
+							str += `<span class="btn btn-light-warning" onclick="ReStartSendSubProjectTask('${row.id}')">重新发送</span>`
+						}
+						str += `<span class="btn btn-light-primary" onClick="GoTo('/sub-item/${row.id}')">工程明细</span>`
+						if (row.status !== 21 && row.status !== 22){
+							str += `<span class="btn btn-light-success" onclick="Edit('${row.id}')">编辑</span>`
+							str += `<span class="btn btn-light-danger" onclick="Delete('${row.id}')">删除</span>`
+						}
 						return str
 					},
 				},
@@ -161,6 +176,8 @@
 				project_id: project_id,
 				sub_project_name: projectName,
 			},
+			table: table,
+			modal: $modal,
 		})
 	}
 	function Delete(id) {
@@ -171,6 +188,19 @@
 			})
 		})
 	}
+
+	function StartSubProjectTask(id){
+		ConfirmUrl('确定开始任务吗?',`/api/sub_project/start_task/${id}`,table)
+	}
+	function ReStartSubProjectTask(id){
+		ConfirmUrl('确定重新采集吗?',`/api/sub_project/start_task/${id}`,table)
+	}
+	function ReStartProcessSubProjectTask(id){
+		ConfirmUrl('确定重新处理吗?',`/api/sub_project/start_process/${id}`,table)
+	}
+	function ReStartSendSubProjectTask(id){
+		ConfirmUrl('确定重新发送吗?',`/api/sub_project/start_send/${id}`,table)
+	}
 </script>
 
 {% endblock %}

+ 64 - 10
SourceCode/DataMiddleware/app/views/templates/project/sub_project_item.html

@@ -33,7 +33,7 @@
                 <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-primary btn-sm" onclick="IwbTableSearch(this)">查询</button>
                 <button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this)">重置</button>
             </div>
         </form>
@@ -59,17 +59,31 @@
                     <div class="form-group">
                         <input type="hidden" id="sub_id" />
                         <div class="fv-row form-group mb-3">
-                            <label for="sub_project_name" class="form-label required">工程名称</label>
-                            <input type="text" class="form-control" name="sub_project_name" id="sub_project_name" placeholder="请输入" required />
+                            <label for="device_name" class="form-label required">设备名称</label>
+                            <input type="text" class="form-control" name="device_name" id="device_name" placeholder="请输入设备名称" required />
                         </div>
                         <div class="fv-row form-group mb-3">
-                            <label for="project_desc" class="form-label">上传数据</label>
-                            <textarea type="text" class="form-control" name="project_desc" id="project_desc" placeholder="请输入" ></textarea>
+                            <label for="device_model" class="form-label required">规格型号</label>
+                            <input type="text" class="form-control" name="device_model" id="device_model" placeholder="请输入规格型号" required />
                         </div>
                         <div class="fv-row form-group mb-3">
-                            <label for="project_desc" class="form-label">删除原数据文件</label>
-                            <input type="checkbox" class="form-check-input" name="delete_file" id="delete_file"/>
+                            <label for="device_count" class="form-label required">数量</label>
+                            <input type="text" class="form-control" name="device_count" id="device_count" placeholder="请输入数量" required />
                         </div>
+                        <div class="fv-row form-group mb-3">
+                            <label for="device_unit" class="form-label required">单位</label>
+                            <input type="text" class="form-control" name="device_unit" id="device_unit" placeholder="请输入单位" required />
+                        </div>
+                        <div class="fv-row form-group mb-3">
+                            <label for="standard_no" class="form-label ">定额编号</label>
+                            <input type="text" class="form-control" name="standard_no" id="standard_no" placeholder="请输入定额编号"  />
+                        </div>
+                        <div class="form-check mb-3">
+						 	<input class="form-check-input" type="checkbox" value="" id="is_query" name="delete_file"/>
+							<label class="form-check-label" for="is_query">
+								是否查询知识库
+							</label>
+						</div>
                     </div>
                 </form>
             </div>
@@ -83,6 +97,7 @@
 {% endblock %}
 {% block page_scripts %}
     <script>
+        ChangeHeadMenu("#project_menu")
         const projectId='{{sub_project.project_id}}',subId = '{{sub_project.id}}';
         const table = '#table',
         $modal = $("#modal");
@@ -115,7 +130,6 @@
                         data:'standard_no',
                         width:'120px'
                     },
-
                     {
                         title:'处理状态',
                         data:'process_status',
@@ -157,6 +171,20 @@
                         width:'280px',
                         render:function (row) {
                             let str = '';
+                            if (row.process_status === 0){
+                                str += `<span class="btn btn-light-success" onclick="StartProcessItem('${row.id}')">开始处理</span>`;
+                            }else if(row.process_status === 2){
+                                str += `<span class="btn btn-light-warning" onclick="ReStartProcessItem('${row.id}')">重新处理</span>`;
+                            }else if(row.process_status === 3){
+                                str+= `<span class="btn btn-light-danger" onclick="ReStartProcessItem('${row.id}')">重新处理</span>`;
+                            }
+                            if (row.send_status === 0 && row.process_status !== 1){
+                                str += `<span class="btn btn-light-success" onclick="StartSendItem('${row.id}')">开始发送</span>`;
+                            }else if(row.send_status === 2 && row.process_status !== 1){
+                                str += `<span class="btn btn-light-warning" onclick="ReStartSendItem('${row.id}')">重新发送</span>`;
+                            }else if(row.send_status === 3 && row.process_status !== 1){
+                                str += `<span class="btn btn-light-danger" onclick="ReStartSendItem('${row.id}')">重新发送</span>`;
+                            }
                             str+=`<span class="btn btn-light-success" onclick="Edit('${row.id}')">编辑</span>`;
                             str+=`<span class="btn btn-light-danger" onclick="Delete('${row.id}')">删除</span>`;
                             return str
@@ -184,14 +212,27 @@
 
         function SaveProject() {
             const subId = $('#sub_id').val();
-            const projectName= $('#sub_project_name').val();
+
+            const deviceName = $modal.find('#device_name').val(),
+            deviceModel =  $modal.find('#device_model').val(),
+            deviceUnit = $modal.find('#device_unit').val(),
+            deviceCount = $modal.find('#device_count').val(),
+            standardNo = $modal.find('#standard_no').val(),
+            isQuery = $modal.find('#is_query').is(':checked')?'true':'false'
             IwbAjax_2({
                 url:`/api/sub_item/save/${projectId}/${subId}`,
                 data:{
                     id: subId,
                     project_id: project_id,
-                    sub_project_name: projectName,
+                    device_name: deviceName,
+                    device_model: deviceModel,
+                    device_unit: deviceUnit,
+                    device_count: deviceCount,
+                    standard_no: standardNo,
+                    is_query: isQuery,
                 },
+                table:table,
+                modal:$modal,
             })
         }
 
@@ -203,6 +244,19 @@
                 })
             })
         }
+
+        function StartProcessItem(id){
+            ConfirmUrl('确定开始处理吗?',`/api/sub_item/start_process/${id}`,table)
+        }
+        function ReStartProcessItem(id){
+            ConfirmUrl('确定重新处理吗?',`/api/sub_item/start_process/${id}`,table)
+        }
+        function StartSendItem(id){
+            ConfirmUrl('确定开始发送吗?',`/api/sub_item/start_send/${id}`,table)
+        }
+        function ReStartSendItem(id){
+            ConfirmUrl('确定重新发送吗?',`/api/sub_item/start_send/${id}`,table)
+        }
     </script>
 
 {% endblock %}