Browse Source

first version

rita 3 years ago
commit
2782a2b722
30 changed files with 3859 additions and 0 deletions
  1. 245 0
      Rita/ERP_Rita/ERP.py
  2. BIN
      Rita/ERP_Rita/__pycache__/Coffee.cpython-39.pyc
  3. BIN
      Rita/ERP_Rita/__pycache__/RitaCoffee.cpython-39.pyc
  4. BIN
      Rita/ERP_Rita/__pycache__/mqtt.cpython-39.pyc
  5. 293 0
      Rita/ERP_Rita/app/__init__.py
  6. BIN
      Rita/ERP_Rita/app/__pycache__/__init__.cpython-39.pyc
  7. 5 0
      Rita/ERP_Rita/app/main/__init__.py
  8. BIN
      Rita/ERP_Rita/app/main/__pycache__/__init__.cpython-39.pyc
  9. BIN
      Rita/ERP_Rita/app/main/__pycache__/mqtt.cpython-39.pyc
  10. BIN
      Rita/ERP_Rita/app/main/__pycache__/views.cpython-39.pyc
  11. 1167 0
      Rita/ERP_Rita/app/templates/cargo2_actuator.html
  12. 10 0
      Rita/ERP_Rita/app/templates/hello.html
  13. 11 0
      Rita/ERP_Rita/app/templates/index.html
  14. 6 0
      Rita/ERP_Rita/app/user/__init__.py
  15. BIN
      Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-35.pyc
  16. BIN
      Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-36.pyc
  17. BIN
      Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-37.pyc
  18. BIN
      Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-39.pyc
  19. BIN
      Rita/ERP_Rita/app/user/__pycache__/views.cpython-35.pyc
  20. BIN
      Rita/ERP_Rita/app/user/__pycache__/views.cpython-36.pyc
  21. BIN
      Rita/ERP_Rita/app/user/__pycache__/views.cpython-37.pyc
  22. BIN
      Rita/ERP_Rita/app/user/__pycache__/views.cpython-39.pyc
  23. 6 0
      Rita/ERP_Rita/app/user/views.py
  24. 1167 0
      Rita/ERP_Rita/templates/cargo2_actuator.html
  25. 135 0
      Rita/ERP_Rita/templates/create_component_table_item.html
  26. 300 0
      Rita/ERP_Rita/templates/drop_down_list.html
  27. 10 0
      Rita/ERP_Rita/templates/hello.html
  28. 11 0
      Rita/ERP_Rita/templates/index.html
  29. 358 0
      Rita/ERP_Rita/templates/search.html
  30. 135 0
      Rita/ERP_Rita/templates/server.js

+ 245 - 0
Rita/ERP_Rita/ERP.py

@@ -0,0 +1,245 @@
+# TODO 資料表是否會重複開啟? -> def?
+from logging import info
+from datetime import datetime
+from flask import Flask, render_template, request, jsonify
+import pymysql
+# from flask_sqlalchemy import SQLAlchemy
+# from sqlalchemy.orm import query, session
+from flask_migrate import Migrate
+import time
+from app import create_app
+
+#app, db, mqtt = create_app()
+
+app = Flask(__name__)
+
+# # app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:g53743001@localhost:3306/coffeetest"
+# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+# db = SQLAlchemy(app)
+# # db.init_app(app)
+
+# Migrate(app, db)
+
+
+# 首頁測試
+@app.route('/')
+def index():
+    return render_template('index.html')
+
+# 使用者名稱測試
+@app.route('/user/<name>')
+def user(name):
+    return render_template('hello.html', name=name)
+
+# 新增零件清單項目
+@app.route('/create_component_table_item', methods=['GET', 'POST'])
+def create_component_table_item():
+    # 開啟本機 erp 資料庫
+    mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='erp', charset='utf8')
+    # mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee', password='skyeye', database='Coffee', charset='utf8')
+    mycursor = mydb.cursor()
+
+    # 獲取會計科目欄位
+    AccountingSubjects = "SELECT * FROM 會計科目表"
+    mycursor.execute(AccountingSubjects)
+    AccountingSubjects_data = mycursor.fetchall()
+    # print("AccountingSubjects_data", AccountingSubjects_data)     
+    # # (('01', '成品'), ('02', '系統成品'), ('03', '模組半成品'), ('04', '零件'), ('05', '工具'))
+
+    # 獲取類別欄位
+    Category = "SELECT * FROM 類別表"
+    mycursor.execute(Category)
+    Category_data = mycursor.fetchall()
+
+    # 獲取供應商欄位
+    Supplier = "SELECT * FROM 供應商"
+    mycursor.execute(Supplier)
+    Supplier_data = mycursor.fetchall()
+
+    # 獲取零件名稱
+    Component = "SELECT 名稱 FROM 零件表"
+    mycursor.execute(Component)
+    Component_data = mycursor.fetchall()
+
+
+    return render_template('create_component_table_item.html', title='新增零件', **locals())
+
+
+# ERP 測試 四層下拉式選單關聯
+@app.route('/drop_down_list', methods=['GET', 'POST'])
+def drop_down_list():
+    conn = pymysql.connect(
+        host='52.69.200.169', 
+        port=3306, 
+        user='coffee',
+        password='skyeye', 
+        database='Coffee', 
+        charset='utf8'
+    )
+    cur = conn.cursor()
+    #獲取欄位資料
+    sql = "select * from product_info"
+    cur.execute(sql)
+    content = cur.fetchall()
+    #獲取欄位名稱
+    sql = "SHOW FIELDS FROM product_info"
+    cur.execute(sql)
+    labels = cur.fetchall()
+    # print("labels: ", labels)                   # labels:  (('產品', 'varchar(4)', 'YES', '', None, ''), ('系統', 'varchar(5)', 'YES', '', None, ''), 
+    labels = [g[0] for g in labels]
+    # print("labels: ", labels)                   # labels:  ['產品', '系統', '系統圖號', '狀態', '進貨狀態', '序號', '組序號',
+    return render_template('drop_down_list.html', labels=labels, content=content)
+
+# ERP 測試
+@app.route('/search', methods=['GET', 'POST'])
+def search():
+    # 開啟本機 erp 資料庫
+    mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='erp', charset='utf8')
+    # mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee', password='skyeye', database='Coffee', charset='utf8')
+    mycursor = mydb.cursor()
+    # 獲取欄位資料
+    # sql = '''SELECT * FROM table_component_name'''
+    sql = '''SELECT 內部料號, 會計科目表.會計科目_名稱, 類別表.類別_名稱, 流水號, 供應商.公司, 名稱
+                FROM (
+                        (零件表
+                        INNER JOIN 供應商
+                        ON 供應商.供應商 = 零件表.供應商
+                        )
+                    INNER JOIN 類別表
+                    ON 類別表.類別_編號 = 零件表.類別
+                ) 
+                INNER JOIN 會計科目表 
+                ON 會計科目表.會計科目_編號 = 零件表.會計科目
+                '''
+    mycursor.execute(sql)
+    content = mycursor.fetchall()
+    #獲取欄位名稱
+    sql = "SHOW FIELDS FROM 零件表"
+    mycursor.execute(sql)
+    labels = mycursor.fetchall()
+    # print("labels: ", labels)                   
+    # # labels:  (('產品', 'varchar(4)', 'YES', '', None, ''), ('系統', 'varchar(5)', 'YES', '', None, ''), 
+    labels = [g[0] for g in labels]
+    # print("labels: ", labels)                   
+    # # labels:  ['產品', '系統', '系統圖號', '狀態', '進貨狀態', '序號', '組序號', 
+
+    # 獲取會計科目欄位
+    AccountingSubjects = "SELECT * FROM 會計科目表"
+    mycursor.execute(AccountingSubjects)
+    AccountingSubjects_data = mycursor.fetchall()
+    # print("AccountingSubjects_data", AccountingSubjects_data)     
+    # # (('01', '成品'), ('02', '系統成品'), ('03', '模組半成品'), ('04', '零件'), ('05', '工具'))
+
+    # 獲取類別欄位
+    Category = "SELECT * FROM 類別表"
+    mycursor.execute(Category)
+    Category_data = mycursor.fetchall()
+
+    # 獲取供應商欄位
+    Supplier = "SELECT * FROM 供應商"
+    mycursor.execute(Supplier)
+    Supplier_data = mycursor.fetchall()
+
+    # 獲取零件名稱
+    Component = "SELECT 名稱 FROM 零件表"
+    mycursor.execute(Component)
+    Component_data = mycursor.fetchall()
+    
+    return render_template('search.html', title = 'ERP Search', **locals())
+
+# 找到 serial number 最大值後 +1
+@app.route('/sn_get/<AccountSubject>/<Category>', methods=['GET', 'POST'])
+def zn_get(AccountSubject, Category):
+    # 開啟本機 erp 資料庫
+    mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='erp', charset='utf8')
+    mycursor = mydb.cursor()
+    # 取得流水號最大值
+    sql = 'SELECT 流水號 FROM 零件表 '
+    sql += 'WHERE 會計科目 = "' + AccountSubject + '" AND 類別 = "' + Category + '" ORDER BY 流水號 DESC LIMIT 1'
+    print("sql: ", sql)
+
+    mycursor.execute(sql)
+    content = mycursor.fetchall()
+    try:
+        print("content: ", content[0][0], type(content[0][0]))
+        new_sn = int(content[0][0])+1
+        new_sn = '{0:04d}'.format(new_sn)
+        # new_sn = content[0][0].zfill(4)
+    except IndexError:
+        new_sn = '0001'
+    
+    return jsonify({"new_sn":new_sn})
+
+# 從資料表找出符合篩選條件之資料
+@app.route('/sql_get', methods=['GET'])
+def sql_get():
+    mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='erp', charset='utf8')
+    mycursor = mydb.cursor()
+    # 取得網頁傳回來的 SQL 指令
+    # sql = "SELECT * FROM 零件表 WHERE 會計科目 = 04"
+    info = request.args.to_dict('sql')
+    sql = info['sql']
+    print("sql: ", sql)
+    mycursor.execute(sql)
+    sql_data = mycursor.fetchall()
+    # 獲取欄位名稱
+    # 拆解取得資料表資料
+    # print("sql_data: ", sql_data)
+    # # sql_data:  (('04030001T01', '04', '03', '0001', 'T01', '電阻-18Ω'), ... )
+
+    # Rita 這裡在測試日期格式修改, 優化後調整
+    # if 'INNER JOIN 庫存表' in sql:
+    #     labels = []
+    #     for g in sql_data:
+    #         # timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
+    #         print("g[0]: ", g[0], type(g[0]), g[0].strftime("%Y-%m-%d %H:%M:%S"))
+            
+    #         timeString = g[0].strftime("%Y-%m-%d %H:%M:%S")
+    #         print("timeString: ", timeString, type(timeString))
+    #         labels.append(timeString)
+    #         # labels.append(time.strftime("%Y-%m-%d %H:%M:%S"))
+    #         labels.append(g[1])
+    #         labels.append(g[2])
+    # else:
+    #     labels = [g for g in sql_data]
+    labels = [g for g in sql_data]
+
+    # # labels g[1]~g[5]:  [('04030001T01', '04', '03', '0001', 'T01', '電阻-18Ω'), ...]
+    print("labels: ", labels)
+    # 取得欄位資料
+    if 'INNER JOIN 規格表' in sql:
+        sql_field = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '規格表'"
+    elif 'INNER JOIN 庫存表' in sql:
+        sql_field = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '庫存表' LIMIT 3"
+    elif 'INNER JOIN 銷貨表' in sql:
+        sql_field = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '銷貨表'"
+    elif 'INNER JOIN 進貨表' in sql:
+        sql_field = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '進貨表'"
+    else:
+        sql_field = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '零件表'"
+    mycursor.execute(sql_field)
+    sql_field = mycursor.fetchall()
+
+    mydb.commit()
+     
+    return jsonify({"sql_data":sql_data,
+                    "labels":labels,
+                    "sql_field":sql_field})
+
+
+
+
+
+#自動關閉所有未使用、掛著的連接
+@app.teardown_appcontext
+def shutdown_session(exception=None):
+    # db.session.remove()
+    pass
+
+if __name__ == '__main__':
+    # Rita 測試 Benson 網頁 http://192.168.50.65:5006/login
+    app.run(debug=False, threaded=True, port=5010)
+    #app.run(debug=False, threaded=True, port=5006, host='0.0.0.0')
+    #使用WSGI開關,避免出現WARNING: This is a development server. d not use it in a production deployment.Use a production WSGI server instead.
+    # server = pywsgi.WSGIServer(('0.0.0.0', 5006), app)
+    # server.serve_forever()

BIN
Rita/ERP_Rita/__pycache__/Coffee.cpython-39.pyc


BIN
Rita/ERP_Rita/__pycache__/RitaCoffee.cpython-39.pyc


BIN
Rita/ERP_Rita/__pycache__/mqtt.cpython-39.pyc


+ 293 - 0
Rita/ERP_Rita/app/__init__.py

@@ -0,0 +1,293 @@
+#對整個應用做初始化操作
+#主要工作:
+# 1.構建Flask的應用以及各種配置
+#2.構建SQLAlchemy的應用
+
+from flask import Flask
+from flask_sqlalchemy import SQLAlchemy
+import pymysql
+import eventlet
+from flask_mqtt import Mqtt
+from flask_migrate import Migrate
+#from flask_migrate import Migrate, MigrateCommand
+
+
+#綠化(綠色線程)所有系統模組,實現IO多路複用
+# eventlet.monkey_patch()
+
+pymysql.install_as_MySQLdb()
+
+# db = SQLAlchemy()
+
+def create_app():
+    app = Flask(__name__)
+    #配置啟動模式為調適模式
+    # app.config['DEBUG'] = True
+    #配置數據庫的連接字符串
+    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://coffee:skyeye@52.69.200.169:3306/Coffee'
+    #配置數據庫內容再更新時自動提交
+    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
+    #配置session所需要的秘鑰
+    app.config['SECRET_KEY'] = 'you guess'
+    # template 有修改後,會自動去更新
+    app.config['TEMPLATES_AUTO_RELOAD'] = True
+    #如果设置成True(默认情况),Flask - SQLAlchemy将会追踪对象的修改并且发送信号。这需要额外的内存, 如果不必要的可以禁用它
+    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
+    #資料库连接池的大小。默认是数据库引擎的默认值 (通常是5)
+    app.config['SQLALCHEMY_POOL_SIZE'] = 100
+    #指定資料库连接池的超时时间。默认是 10
+    app.config['SQLALCHEMY_POOL_TIMEOUT'] = 60 * 60
+    #自动回收连接的秒数。这对 MySQL 是必须的,默认 情况下 MySQL 会自动移除闲置 8 小时或者以上的连接。 需要注意地是如果使用 MySQL 的话, Flask-SQLAlchemy 会自动地设置这个值为 2 小时
+    app.config['SQLALCHEMY_MAX_OVERFLOW'] = 15
+
+    # app.config['SECRET'] = 'my secret key'
+    #MQTT相關設置
+    app.config['MQTT_BROKER_URL'] = '60.250.156.234'
+    app.config['MQTT_BROKER_PORT'] = 1883
+    app.config['MQTT_USERNAME'] = 'aisky-client'
+    app.config['MQTT_PASSWORD'] = 'aiskyc'
+    #將發送ping到代理的時間間隔設置60秒
+    app.config['MQTT_KEEPALIVE'] = 60
+    #出於測試目的將TLS設置為禁用
+    app.config['MQTT_TLS_ENABLED'] = False
+
+    #資料庫的初始化
+    db = SQLAlchemy(app)
+    db.init_app(app)
+    mqtt = Mqtt(app)
+
+    # 初始化Flask-Migrate擴展
+    migrate = Migrate(app, db)
+
+
+
+    #用來使用flask-migrate數據遷移使用,如要用在把下面模型類註釋消掉,並且將main裡的from coffee_manage import mqtt,db註釋掉(因會報導入錯誤)
+    # # 用戶表
+    # class User(db.Model):
+    #     __tablename__ = 'user'
+    #
+    #     userID = db.Column(db.Integer, primary_key=True)
+    #     firstname = db.Column(db.String(30), nullable=False)
+    #     lastname = db.Column(db.String(30), nullable=False)
+    #     mail = db.Column(db.String(50), nullable=False)
+    #     phone = db.Column(db.String(20), nullable=False)
+    #     username = db.Column(db.String(30), nullable=False, unique=True)
+    #     password = db.Column(db.String(40), nullable=False)
+    #     status = db.Column(db.Integer, nullable=False, info='0:admin;1:new;9:disable')
+    #
+    # # 發酵槽溫度感測器表
+    # class TankTemSensor(db.Model):
+    #     __tablename__ = 'tank_tem_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     tem = db.Column(db.Text, nullable=False)
+    #
+    # # 發酵槽二氧化碳感測器表
+    # class TankCO2Sensor(db.Model):
+    #     __tablename__ = 'tank_co2_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     co2 = db.Column(db.Text, nullable=False)
+    #
+    # # 發酵槽酸鹼值感測器表
+    # class TankPHSensor(db.Model):
+    #     __tablename__ = 'tank_ph_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     ph = db.Column(db.Text, nullable=False)
+    #
+    # class BeanValve(db.Model):
+    #     __tablename__ = 'bean_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class WashMachine(db.Model):
+    #     __tablename__ = 'wash_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt1(db.Model):
+    #     __tablename__ = 'conveyor_belt1'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Cargo1Disinfect(db.Model):
+    #     __tablename__ = 'cargo1_disinfect'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ColorMachine(db.Model):
+    #     __tablename__ = 'color_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt2(db.Model):
+    #     __tablename__ = 'conveyor_belt2'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class PeelingMachine(db.Model):
+    #     __tablename__ = 'peeling_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt3(db.Model):
+    #     __tablename__ = 'conveyor_belt3'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Bacteria(db.Model):
+    #     __tablename__ = 'bacteria'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Cargo2Disinfect(db.Model):
+    #     __tablename__ = 'cargo2_disinfect'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Heating(db.Model):
+    #     __tablename__ = 'heating'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Stir(db.Model):
+    #     __tablename__ = 'stir'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class WaterInjection(db.Model):
+    #     __tablename__ = 'water_injection'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class TopValve(db.Model):
+    #     __tablename__ = 'top_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class BottomValve(db.Model):
+    #     __tablename__ = 'bottom_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Temperature(db.Model):
+    #     __tablename__ = 'temperature'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Hoist(db.Model):
+    #     __tablename__ = 'hoist'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Dryer(db.Model):
+    #     __tablename__ = 'dryer'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Relay(db.Model):
+    #     __tablename__ = 'relay'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     status = db.Column(db.Text, nullable=False)
+
+
+
+
+    #將main藍圖程序與app關聯到一起
+    from .main import main as main_blueprint
+    app.register_blueprint(main_blueprint)
+    #將user藍圖程序與app關聯到一起
+    from .user import user as user_blueprint
+    app.register_blueprint(user_blueprint)
+
+    return app, db, mqtt

BIN
Rita/ERP_Rita/app/__pycache__/__init__.cpython-39.pyc


+ 5 - 0
Rita/ERP_Rita/app/main/__init__.py

@@ -0,0 +1,5 @@
+#main 目錄: 包含主要的業務邏輯的路由和視圖
+# __init__.py : 對主業務邏輯程序的初始化操作
+from flask import Blueprint
+main = Blueprint('main',__name__)
+from . import views

BIN
Rita/ERP_Rita/app/main/__pycache__/__init__.cpython-39.pyc


BIN
Rita/ERP_Rita/app/main/__pycache__/mqtt.cpython-39.pyc


BIN
Rita/ERP_Rita/app/main/__pycache__/views.cpython-39.pyc


File diff suppressed because it is too large
+ 1167 - 0
Rita/ERP_Rita/app/templates/cargo2_actuator.html


+ 10 - 0
Rita/ERP_Rita/app/templates/hello.html

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>{{name}}</title>
+</head>
+<body>
+    <h1>{{name}}</h1>
+</body>
+</html>

+ 11 - 0
Rita/ERP_Rita/app/templates/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Coffee Project</title>
+    db connect!
+</head>
+<body>
+    <h1>Hello Coffee!</h1>
+</body>
+</html>

+ 6 - 0
Rita/ERP_Rita/app/user/__init__.py

@@ -0,0 +1,6 @@
+#user目錄:針對用戶業務邏輯處理的目錄
+#針對用戶業務邏輯處理的初始化行為
+
+from flask import Blueprint
+user = Blueprint('user',__name__)
+from . import views

BIN
Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-35.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-36.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-37.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/__init__.cpython-39.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/views.cpython-35.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/views.cpython-36.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/views.cpython-37.pyc


BIN
Rita/ERP_Rita/app/user/__pycache__/views.cpython-39.pyc


+ 6 - 0
Rita/ERP_Rita/app/user/views.py

@@ -0,0 +1,6 @@
+#針對用戶業務邏輯處理的視圖和路由的定義
+from . import user
+
+@user.route('/user')
+def user_index():
+    return "這是user中的首頁"

File diff suppressed because it is too large
+ 1167 - 0
Rita/ERP_Rita/templates/cargo2_actuator.html


+ 135 - 0
Rita/ERP_Rita/templates/create_component_table_item.html

@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>{{ title }}</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+</head>
+
+<body>
+    會計科目:
+    <select id="accountingsubjects" onChange="">
+        <option value="00"></option>
+        {% for data in AccountingSubjects_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select>
+    類別:
+    <select id="category" onChange="renewSN();">
+        <option value="00"></option>
+        {% for data in Category_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select>
+    流水號:
+    <input id="serialnumber" value="—" style="height: 25px; width: 45px;" readonly>
+    供應商:
+    <select id="supplier" onChange="">
+        <option value="00"></option>
+        {% for data in Supplier_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select>
+    零件名稱:
+    <input list="conponents" id="component_name_select">
+        <datalist id="conponents">
+            <option value=""></option>
+            {% for data in Component_data %}
+                <option value="{{data[0]}}">{{data[0]}}</option>
+            {% endfor %}
+        </datalist>
+    </select>
+    <br>
+    
+    <input type="button" id="create_component" value="新增零件" onclick="create_component();">
+
+    <div id="result">
+        <!-- <table>
+        </table> -->
+    </div>
+
+    <script>
+        // 輸入完類別後, 流水號自動帶入
+        function renewSN() {
+            var accountingsubjects_select = $("#accountingsubjects").val();
+            var category_select = $("#category").val();
+            $.get('/sn_get/' + accountingsubjects_select + '/' + category_select, '', function (res) {
+                // console.log(res.new_sn)
+                $('#serialnumber').val(res.new_sn)
+            }, 'json');
+        }
+
+        // 零件表 新增零件
+        function create_component() {
+            // 會計科目
+            var accountingsubjects_select = $("#accountingsubjects").val();
+            // 類別
+            var category_select = $("#category").val();
+            // 流水號 → 從資料庫找到最大的流水號, 然後 +1
+            var serialnumber_select = $("#serialnumber").val();
+            // 放到 renewSN 方法內執行
+            // 供應商
+            var supplier_select = $("#supplier").val();
+            // 零件名稱
+            var component_name_select = $("#component_name_select").val();
+            // 內部料號組合
+            var company_id = accountingsubjects_select + category_select + serialnumber_select + supplier_select;
+            var AND_list = [];
+            // console.log(accountingsubjects_select, category_select, serialnumber_select, supplier_select, component_name_select)
+
+            var sql = '';
+            sql += 'INSERT INTO 零件表 ' +
+                   'VALUES ("' + company_id + '", "' + accountingsubjects_select + '", "' + category_select + '", "' + serialnumber_select + '", "';
+            sql += supplier_select + '", "' + component_name_select + '");';
+            console.log("sql: " + sql)
+
+            var sql_data = {
+                "sql":sql
+            };
+
+            $.ajax({
+                type:"GET",
+                url:"/sql_get",
+                dataType:"JSON",
+                data:sql_data,
+                success:function (res) {
+                    data = '-- 新增成功! --'
+                    var sectorSelect = document.getElementById("result");
+                    sectorSelect.innerHTML = data;
+                },
+                error: function (thrownError) {
+                    if (thrownError.statusText == "INTERNAL SERVER ERROR") {
+                        alert("內部料號 " + company_id + " 已存在, 請重新輸入")
+                    }
+                }
+
+            })
+
+            // $.get('/sql_get', sql_data, function (res) {
+            //     // console.log("res: " + res)
+            //     // console.log("res.labels:" + res.labels)
+            //     // console.log("res.labels[0]:" + res.labels[0])
+            //     // console.log("res.labels[0][0]:" + res.labels[0][0])
+            //     // console.log("res.sql_field:" + res.sql_field)
+            //     // console.log("res.sql_field[0]:" + res.sql_field[0])
+                
+            // }, 'json');
+            
+        }
+        
+    </script>
+</body>
+
+</html>

+ 300 - 0
Rita/ERP_Rita/templates/drop_down_list.html

@@ -0,0 +1,300 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>{{ title }}</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+    <style>
+        .newcondition_css {
+            padding: 10px;
+            margin-top: 10px;
+            background-color: honeydew;
+        }
+
+        hr {
+            margin-top: 5px;
+            margin-bottom: 5px;
+        }
+    </style>
+
+</head>
+
+<body>
+    <!--     
+    <script>
+        // [系統]更新: Array / renew_system function
+        system_object = new Array();
+        system_object[0] = ["   "];
+        system_object[1] = ["   ", "清洗槽組立"];
+        system_object[2] = ["   ", "發酵桶組立"];
+        system_object[3] = ["   ", "乾燥桶組立"];
+        function renew_system(index) {
+            var Value="";
+            for(var i=0; i<system_object[index].length; i++){
+                Value = Value + '<option value=' + system_object[index][i] + '> ' + system_object[index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("system");
+            sectorSelect.innerHTML = Value;
+            $('#product_index').text(index)
+        }
+        // [模組]更新: Array / renew_system function
+        module_object = new Array();
+        module_object[0] = ["   "];
+        module_object[1] = ["   ", "c1上蓋組立", "c2內桶槽組立"];
+        module_object[2] = ["   ", "f1上蓋組立", "f2控制盒組立"];
+        module_object[3] = ["   ", "d1上蓋組立", "d2控制盒組立"];
+        
+        function renew_module(index) {
+            var Value="";
+            for(var i=0; i<module_object[index].length; i++){
+                Value = Value + '<option value=' + module_object[index][i] + '>' + module_object[index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("module");
+            sectorSelect.innerHTML = Value;
+            $('#system_index').text(index)
+        }
+        // // [零件]更新: Array / renew_system function
+        component_object = new Array();
+        component_object[0] = ["   "];
+        component_object[1][1] = ["   ", "c1_M10平墊圈", "c1_M10螺帽"];
+        component_object[1][2] = ["   ", "c2_內桶槽", "c2_內桶槽固定環"];
+        component_object[2][1] = ["   ", "f1_吸料機入料管", "f1_入料斗擋板"];
+        component_object[2][2] = ["   ", "f2_LED指示燈 綠色 TB12LED-G0201", "f2_K3 LED指示燈-主板"];
+        component_object[3][1] = ["   ", "d1_軸心(單邊出軸)", "d1_墊片M18x25x1.5"];
+        component_object[3][2] = ["   ", "d2_M3x5螺絲", "d2_M3x5銅柱 1公1母"];
+        function renew_component(product_index, index) {
+            var Value="";
+            for(var i=0; i<component_object[product_index][index].length; i++){
+                Value = Value + '<option value=' + component_object[product_index][index] + '>' + component_object[index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("component");
+            sectorSelect.innerHTML = Value;
+            $('#module_index').text(index)
+        }
+        // // 輸出零件 index
+        function renew_item(index) {
+            $('#component_index').text(index)
+        }
+
+    </script>
+     -->
+    <br>
+
+    產品:
+    <select id="product" onChange="renew_system(this.selectedIndex);">
+    </select>
+    系統:
+    <select id="system" onChange="renew_module(this.selectedIndex);">
+    </select>
+    模組:
+    <select id="module" onChange="renew_component(this.selectedIndex);">
+    </select>
+    零件:
+    <select id="component" onChange="">
+        <input type="button" id="input_value" value="取值" onclick="printValue();"><br>
+        取值: <span id="span_value"></span>
+    </select><br>
+
+    <script>
+        // 輸出關鍵字
+        function printValue() {
+            // database 取值語法
+            var data = 'select * from teststock1213';
+            // 取得下拉式選單選擇的 value
+            var product_value = $("#product").val();
+            var system_value = $("#system").val();
+            var module_value = $("#module").val();
+            var component_value = $("#component").val();
+            if (product_value != '*' || system_value != '*' || module_value != '*' || component_value != '*') {
+                data += ' WHERE ';
+
+                if (product_value != '*') {
+                    data += '`產品` = ' + product_value;
+                    if (system_value != '*' || module_value != '*' || component_value != '*') {
+                        data += ' AND ';
+                    }
+                }
+                if (system_value != '*') {
+                    data += '`系統` = ' + system_value;
+                    if (module_value != '*' || component_value != '*') {
+                        data += ' AND ';
+                    }
+                }
+                if (module_value != '*') {
+                    data += '`模組` = ' + module_value;
+                    if (component_value != '*') {
+                        data += ' AND ';
+                    }
+                }
+                if (component_value != '*') {
+                    data += '`零件` = ' + component_value;
+                }
+            }
+
+            // if product_value
+            $("#span_value").text(data)
+        }
+
+        // 資料庫中的所有 [產品]
+        var product_item = ["*", "清洗貨櫃", "發酵貨櫃", "乾燥貨櫃"]
+        var inner = '';
+        for (let i = 0; i < product_item.length; i++) {
+            inner += '<option value="' + product_item[i] + '">' + product_item[i] + '</option>';
+        }
+        var sectorSelect = document.getElementById("product");
+        sectorSelect.innerHTML = inner;
+        // 資料庫中的所有 [系統]
+        var system_item = ["*", "清洗槽組立", "發酵桶組立", "乾燥桶組立"]
+        var inner = '';
+        for (let i = 0; i < system_item.length; i++) {
+            inner += '<option value="' + system_item[i] + '">' + system_item[i] + '</option>';
+        }
+        var sectorSelect = document.getElementById("system");
+        sectorSelect.innerHTML = inner;
+        // 資料庫中的所有 [模組]
+        var module_item = ["*", "上蓋組立", "內桶槽組立", "控制盒組立"]
+        var inner = '';
+        for (let i = 0; i < module_item.length; i++) {
+            inner += '<option value="' + module_item[i] + '">' + module_item[i] + '</option>';
+        }
+        var sectorSelect = document.getElementById("module");
+        sectorSelect.innerHTML = inner;
+        // 資料庫中的所有 [零件]
+        var component_item = ["*", "M10平墊圈", "M10螺帽", "內桶槽", "內桶槽固定環", "吸料機入料管",
+            "入料斗擋板", "LED指示燈_綠色 TB12LED-G0201", "K3 LED指示燈-主板",
+            "軸心(單邊出軸)", "墊片M18x25x1.5", "M3x5螺絲", "M3x5銅柱 1公1母"]
+        var inner = '';
+        for (let i = 0; i < component_item.length; i++) {
+            inner += '<option value="' + component_item[i] + '">' + component_item[i] + '</option>';
+        }
+        var sectorSelect = document.getElementById("component");
+        sectorSelect.innerHTML = inner;
+
+
+        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        // 系統的 index
+        var sysIndex;
+        // [系統]更新: Array / renew_system function
+        system_object = new Array();
+        system_object[0] = ["*"];
+        system_object[1] = ["*", "清洗槽組立"];
+        system_object[2] = ["*", "發酵桶組立"];
+        system_object[3] = ["*", "乾燥桶組立"];
+        function renew_system(index) {
+            sysIndex = index
+            var inner = '';
+            for (let i = 0; i < system_object[index].length; i++) {
+                inner += '<option value="' + system_object[index][i] + '">' + system_object[index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("system");
+            sectorSelect.innerHTML = inner;
+        }
+
+        // 模組的 index
+        var moIndex;
+        // [模組]更新: Array / renew_system function
+        module_object = new Array();
+        module_object[0] = ["*"];
+        module_object[1] = ["*", "清洗槽組立"];
+        module_object[2] = ["*", "發酵桶組立"];
+        module_object[3] = ["*", "乾燥桶組立"];
+        module_object[0][0] = ["*"];
+        module_object[1][1] = ["*", "c1上蓋組立", "c2內桶槽組立"];
+        module_object[2][1] = ["*", "f1上蓋組立", "f2控制盒組立"];
+        module_object[3][1] = ["*", "d1上蓋組立", "d2控制盒組立"];
+        function renew_module(index) {
+            moIndex = index
+            var inner = '';
+            for (let i = 0; i < module_object[sysIndex][index].length; i++) {
+                inner += '<option value="' + module_object[sysIndex][index][i] + '">' + module_object[sysIndex][index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("module");
+            sectorSelect.innerHTML = inner;
+        }
+
+        // 零件
+        // // [零件]更新: Array / renew_system function
+        component_object = new Array();
+        component_object[0] = ["*"];
+        component_object[1] = ["*", "清洗槽組立"];
+        component_object[2] = ["*", "發酵桶組立"];
+        component_object[3] = ["*", "乾燥桶組立"];
+        component_object[0][0] = ["*"];
+        component_object[1][1] = ["*", "c1上蓋組立", "c2內桶槽組立"];
+        component_object[2][1] = ["*", "f1上蓋組立", "f2控制盒組立"];
+        component_object[3][1] = ["*", "d1上蓋組立", "d2控制盒組立"];
+        component_object[0][0][0] = ["*"];
+        component_object[1][1][0] = ["*"];
+        component_object[1][1][1] = ["*", "c1_M10平墊圈", "c1_M10螺帽"];
+        component_object[1][1][2] = ["*", "c2_內桶槽", "c2_內桶槽固定環"];
+        component_object[2][1][0] = ["*"];
+        component_object[2][1][1] = ["*", "f1_吸料機入料管", "f1_入料斗擋板"];
+        component_object[2][1][2] = ["*", "f2_LED指示燈 綠色 TB12LED-G0201", "f2_K3 LED指示燈-主板"];
+        component_object[3][1][0] = ["*"];
+        component_object[3][1][1] = ["*", "d1_軸心(單邊出軸)", "d1_墊片M18x25x1.5"];
+        component_object[3][1][2] = ["*", "d2_M3x5螺絲", "d2_M3x5銅柱 1公1母"];
+        function renew_component(index) {
+            var Value = "";
+            for (var i = 0; i < component_object[sysIndex][moIndex][index].length; i++) {
+                Value = Value + '<option value="' + component_object[sysIndex][moIndex][index][i] + '">' + component_object[sysIndex][moIndex][index][i] + '</option>';
+            }
+            var sectorSelect = document.getElementById("component");
+            sectorSelect.innerHTML = Value;
+        }
+    </script>
+    <!-- // 資料庫中的所有 [產品]
+        var product_item = ["*", "清洗貨櫃", "發酵貨櫃", "乾燥貨櫃"]
+        var inner = '';
+        for (let i = 0; i < product_item.length; i++) {
+            inner += '<option value="' + product_item[i] + '">' + product_item[i] + '</option>';
+        }
+        var sectorSelect = document.getElementById("product");
+        sectorSelect.innerHTML = inner; -->
+
+    <table class="table table-bordered">
+        <tr>
+            {% for i1 in labels %}
+            <th>{{i1}}</th>
+            {% endfor %}
+        </tr>
+        {% for i in content %}
+        
+        <tr id="tr_content">
+            
+            <td>{{ i[0] }}</td>
+            <td>{{ i[1] }}</td>
+            <td>{{ i[2] }}</td>
+            <td>{{ i[3] }}</td>
+            <td>{{ i[4] }}</td>
+            <td>{{ i[5] }}</td>
+            <td>{{ i[6] }}</td>
+            <td>{{ i[7] }}</td>
+            <td>{{ i[8] }}</td>
+            <td>{{ i[9] }}</td>
+            <td>{{ i[10] }}</td>
+            <td>{{ i[11] }}</td>
+            <td>{{ i[12] }}</td>
+            <td>{{ i[13] }}</td>
+            <td>{{ i[14] }}</td>
+            <td>{{ i[15] }}</td>
+        </tr>
+        {% endfor %}
+    </table>
+
+
+</body>
+
+</html>

+ 10 - 0
Rita/ERP_Rita/templates/hello.html

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>{{name}}</title>
+</head>
+<body>
+    <h1>{{name}}</h1>
+</body>
+</html>

+ 11 - 0
Rita/ERP_Rita/templates/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Coffee Project</title>
+    db connect!
+</head>
+<body>
+    <h1>Hello Coffee!</h1>
+</body>
+</html>

+ 358 - 0
Rita/ERP_Rita/templates/search.html

@@ -0,0 +1,358 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>{{ title }}</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+</head>
+
+<style>
+    .input-cond-delete {
+        background: #E43030;
+        border: 1px solid #CFCFCF;
+        box-sizing: border-box;
+        border-radius: 5px;
+        margin-left: 5px;
+        width: 65px;
+        height: 33px;
+        font-size: 16px;
+        text-align: center;
+        line-height: 16px;
+        color: #FFFFFF;
+    }
+    .input-cond-add {
+        background: #008CBA;
+        border: 1px solid #CFCFCF;
+        box-sizing: border-box;
+        border-radius: 5px;
+        margin-left: 5px;
+        width: 65px;
+        height: 33px;
+        font-size: 16px;
+        text-align: center;
+        line-height: 16px;
+        color: #FFFFFF;
+    }
+</style>
+
+<body>
+    會計科目:
+    <select id="accountingsubjects" onChange="">
+        <option value="00"></option>
+        {% for data in AccountingSubjects_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select>
+    類別:
+    <select id="category" onChange="">
+        <option value="00"></option>
+        {% for data in Category_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select>
+    流水號:
+    <input id="serialnumber" placeholder="0001" style="height: 25px; width: 45px;">
+    供應商:
+    <select id="supplier" onChange="">
+        <option value="00"></option>
+        {% for data in Supplier_data %}
+            <option value="{{data[0]}}">{{data[0]}}-{{data[1]}}</option>
+        {% endfor %}
+    </select><br>
+    
+    零件名稱:
+    <select id="component_name_select" onChange="">
+        <option value="00"></option>
+        {% for data in Component_data %}
+            <option value="{{data[0]}}">{{data[0]}}</option>
+        {% endfor %}
+    </select>
+    <input id="component_name_input" placeholder="零件關鍵字輸入" style="height: 25px; width: 120px;">
+    <input type="button" id="search_component_table" value="零件表查詢" onclick="search_component_table();">
+    <input type="button" id="search_component_standard_table" value="(零件)規格表查詢" onclick="search_component_standard_table();">
+    <input type="button" id="search_component_stock_table" value="(零件)庫存表查詢" onclick="search_component_stock_table();">
+    <input type="button" id="search_component_import_table" value="(零件)進貨表查詢" onclick="search_component_import_table();">
+    <input type="button" id="search_component_export_table" value="(零件)銷貨表查詢" onclick="search_component_export_table();">
+    <br>
+    <a id="create_component_table_item" href="/create_component_table_item">(零件)新增零件</a>
+
+    <script>
+        // (零件)銷貨表查詢
+        function search_component_export_table() {
+            var sql = 'SELECT 銷貨表.* FROM 零件表';
+            sql += ' INNER JOIN 銷貨表';
+            sql += ' ON 零件表.內部料號 = 銷貨表.內部料號';
+            search_relation_insertdata(sql)
+        }
+
+        // (零件)進貨表查詢
+        function search_component_import_table() {
+            var sql = 'SELECT 進貨表.* FROM 零件表';
+            sql += ' INNER JOIN 進貨表';
+            sql += ' ON 零件表.內部料號 = 進貨表.內部料號';
+            search_relation_insertdata(sql)
+        }
+
+        // (零件)庫存表查詢
+        function search_component_stock_table() {
+            var sql = 'SELECT 庫存表.時間, 庫存表.內部料號, 庫存表.數量 FROM 零件表';
+            sql += ' INNER JOIN 庫存表';
+            sql += ' ON 零件表.內部料號 = 庫存表.內部料號';
+            search_relation_insertdata(sql)
+        }
+
+        // (零件)規格表查詢
+        function search_component_standard_table() {
+            var sql = 'SELECT 規格表.* FROM 零件表';
+            sql += ' INNER JOIN 規格表';
+            sql += ' ON 零件表.內部料號 = 規格表.內部料號';
+            search_relation_insertdata(sql)
+        }
+        // 各資料表←關聯→零件表, 程式
+        function search_relation_insertdata(sql) {
+            var accountingsubjects_select = $("#accountingsubjects").val();
+            var category_select = $("#category").val();
+            var serialnumber_select = $("#serialnumber").val();
+            var supplier_select = $("#supplier").val();
+            var component_name_select = $("#component_name_select").val();
+            var component_name_input = $("#component_name_input").val();
+            var AND_list = [];
+
+            console.log(accountingsubjects_select, category_select, serialnumber_select, supplier_select)
+            var sql = sql;
+            // 篩選 會計科目/類別/供應商 關鍵字
+            if (accountingsubjects_select != '00') {
+                AND_list.push('會計科目 = "' + accountingsubjects_select + '"')
+            }
+            if (category_select != '00') {
+                AND_list.push('類別 = "' + category_select + '"')
+            }
+            if (serialnumber_select != '') {
+                AND_list.push('流水號 = "' + serialnumber_select + '"')
+            }
+            if (supplier_select != '00') {
+                AND_list.push('供應商 = "' + supplier_select + '"')
+            }
+            if (component_name_select != '00') {
+                AND_list.push('零件表.名稱 = "' + component_name_select + '"')
+            } else if (component_name_input != '') {
+                AND_list.push('零件表.名稱 LIKE "%' + component_name_input + '%"')
+            }
+            console.log("AND_list: ", AND_list)
+            if (AND_list != '') {
+                sql += ' WHERE ' + AND_list.join(' AND ');
+            }
+
+            if (sql.match('INNER JOIN 庫存表')) {
+                sql += ' ORDER BY 時間 DESC LIMIT 1'
+            }
+            
+            var sql_data = {
+                "sql":sql
+            };
+            console.log("sql_data: ", sql_data)
+
+            $.get('/sql_get', sql_data, function (res) {
+                // console.log("res: " + res)
+                // console.log("res.labels:" + res.labels)
+                // console.log("res.labels[0]:" + res.labels[0])
+                // console.log("res.labels[0][0]:" + res.labels[0][0])
+                // console.log("res.sql_field:" + res.sql_field)
+                // console.log("res.sql_field[0]:" + res.sql_field[0])
+                var data = " ";
+                if (res.labels == '') {
+                    data += '-- 無符合關鍵字之資料 --'
+                } else {
+                    data += '<table class="table table-bordered" style="margin-top: 10px;">';
+                    data += '<tr>';
+                    for (let fields = 0; fields < res.sql_field.length; fields++) {
+                        data += '<th>' + res.sql_field[fields][0] + '</th>';
+                    }
+                    data += '</tr>';
+                    for (let items = 0; items < res.labels.length; items++) {
+                        data += '<tr>';
+                            for (let item = 0; item < res.labels[items].length; item++) {
+                                console.log("res.labels[items][item]: ", res.labels[items][item], typeof(res.labels[items][item]))
+                                data += '<td>' + res.labels[items][item] + '</td>';
+                            };
+                        data += '</tr>';
+                    };
+                    data += '</table>';
+                }
+                var sectorSelect = document.getElementById("result");
+                sectorSelect.innerHTML = data;
+            }, 'json');
+        }
+        
+        // 修改確認
+        function ComfirmUpdate_component(company_id) {
+            console.log("修改完成: " + company_id)
+            // var new_name = document.getElementById(company_id + '_5_ta');
+            // var new_name_value = new_name.val();
+            var new_name_value = $('#' + company_id + '_5_ta').val();
+            console.log("new_name_value: " + new_name_value)
+
+            sql = '';
+            sql += 'UPDATE 零件表 SET 名稱 = \'' + new_name_value + '\' WHERE 內部料號 = \'' + company_id + '\';'
+            console.log('sql: ' + sql)
+            var sql_data = { "sql":sql };
+
+            $.get('/sql_get', sql_data, function (res) {
+                console.log(res)
+            }, 'json');
+        }
+
+        // 修改
+        function update_component(company_id) {
+            console.log("修改 " + company_id)
+            var old_name = 
+            target_id = company_id + '_5'
+            var target_id = document.getElementById(company_id + '_5');
+            var old_name = target_id.innerText;
+            console.log('old_name: ', old_name)
+            target_id.innerHTML = "";
+            textarea = '';
+            textarea += '<input id="'+ company_id + '_5_ta' + '" value="' + old_name + '" style="height: 25px; width: auto">';
+            textarea += '<input type="button" value="OK" onclick="ComfirmUpdate_component(\'' + company_id + '\')">';
+            target_id.insertAdjacentHTML('beforeend', textarea);
+        }
+        // 刪除
+        function delete_component(company_id) {
+            console.log("刪除 " + company_id)
+        }
+
+        // 零件表查詢
+        function search_component_table(){
+            var accountingsubjects_select = $("#accountingsubjects").val();
+            var category_select = $("#category").val();
+            var serialnumber_select = $("#serialnumber").val();
+            var supplier_select = $("#supplier").val();
+            var component_name_select = $("#component_name_select").val();
+            var component_name_input = $("#component_name_input").val();
+            var AND_list = [];
+
+            console.log(accountingsubjects_select, category_select, serialnumber_select, supplier_select)
+            // sql = 'SELECT * FROM 零件表';
+            sql = 'SELECT 內部料號, 會計科目表.會計科目_名稱, 類別表.類別_名稱, 流水號, 供應商.公司, 名稱' +
+                  ' FROM (' +
+                        '(零件表 ' +
+                        'INNER JOIN 供應商' +
+                        ' ON 供應商.供應商 = 零件表.供應商' +
+                        ')' +
+                    ' INNER JOIN 類別表' +
+                    ' ON 類別表.類別_編號 = 零件表.類別' +
+                ') ' +
+                'INNER JOIN 會計科目表 ' +
+                'ON 會計科目表.會計科目_編號 = 零件表.會計科目' +
+                '' ;
+            // 篩選 會計科目/類別/供應商 關鍵字
+            if (accountingsubjects_select != '00') {
+                AND_list.push('會計科目 = "' + accountingsubjects_select + '"')
+            }
+            if (category_select != '00') {
+                AND_list.push('類別 = "' + category_select + '"')
+            }
+            if (serialnumber_select != '') {
+                AND_list.push('流水號 = "' + serialnumber_select + '"')
+            }
+            if (supplier_select != '00') {
+                AND_list.push('零件表.供應商 = "' + supplier_select + '"')
+            }
+            if (component_name_select != '00') {
+                AND_list.push('名稱 = "' + component_name_select + '"')
+            } else if (component_name_input != '') {
+                AND_list.push('名稱 LIKE "%' + component_name_input + '%"')
+            }
+            console.log("AND_list: ", AND_list)
+            if (AND_list != '') {
+                sql += ' WHERE ' + AND_list.join(' AND ');
+            }
+            
+            var sql_data = {
+                "sql":sql
+            };
+            console.log("sql_data: ", sql_data)
+
+            $.get('/sql_get', sql_data, function (res) {
+                // console.log("res: " + res)
+                // console.log("res.labels:" + res.labels)
+                // console.log("res.labels[0]:" + res.labels[0])
+                // console.log("res.labels[0][0]:" + res.labels[0][0])
+                // console.log("res.sql_field:" + res.sql_field)
+                // console.log("res.sql_field[0]:" + res.sql_field[0])
+                var data = " ";
+                if (res.labels == '') {
+                    data += '-- 無符合關鍵字之資料 --'
+                } else {
+                    data += '<table class="table table-bordered" style="margin-top: 10px;">';
+                    data += '<tr>';
+                    for (let fields = 0; fields < res.sql_field.length; fields++) {
+                        data += '<th>' + res.sql_field[fields][0] + '</th>';
+                    }
+                    data += '</tr>';
+                    for (let items = 0; items < res.labels.length; items++) {
+                        data += '<tr>';
+                            for (let item = 0; item < res.labels[items].length; item++) {
+                                data += '<td id="' + res.labels[items][0] + '_' + item + '">' + res.labels[items][item] + '</td>';
+                            };
+                            data += '<td><input type="button" class="input-cond-add" value="修改" onclick="update_component(\'' + res.labels[items][0] + '\')"></td>';
+                            data += '<td><input type="button" class="input-cond-delete" value="刪除" onclick="delete_component(\'' + res.labels[items][0] + '\')"></td>';
+                        data += '</tr>';
+                    };
+                    data += '</table>';
+                }
+                var sectorSelect = document.getElementById("result");
+                sectorSelect.innerHTML = data;
+            }, 'json');
+        }
+
+        
+
+        
+    </script>
+
+    <div id="result">
+        <!-- <table>
+        </table> -->
+    </div>
+
+    
+        
+            
+        
+    
+    
+    <!-- <table class="table table-bordered" style="margin-top: 20px;">
+        <tr>
+            {% for i1 in labels %}
+            <th>{{i1}}</th>
+            {% endfor %}
+        </tr>
+        {% for i in content %}
+        <tr>
+            <td>{{ i[0] }}</td>
+            <td>{{ i[1] }}</td>
+            <td>{{ i[2] }}</td>
+            <td>{{ i[3] }}</td>
+            <td>{{ i[4] }}</td>
+            <td>{{ i[5] }}</td>
+            <td>{{ i[6] }}</td>
+            <td>{{ i[7] }}</td>
+        </tr>
+        {% endfor %}
+    </table> -->
+</body>
+
+</html>

+ 135 - 0
Rita/ERP_Rita/templates/server.js

@@ -0,0 +1,135 @@
+const path = require('path');
+const express = require('express');
+const WebSocket = require('ws');
+const app = express();
+
+const path1 = require('path');
+const express1 = require('express');
+const WebSocket1 = require('ws');
+
+const path2 = require('path');
+const express2 = require('express');
+const WebSocket2 = require('ws');
+
+const path3 = require('path');
+const express3 = require('express');
+const WebSocket3 = require('ws');
+
+const path4 = require('path');
+const express4 = require('express');
+const WebSocket4 = require('ws');
+
+const path5 = require('path');
+const express5 = require('express');
+const WebSocket5 = require('ws');
+
+
+
+const WS_PORT  = 8088;
+const HTTP_PORT = 8000;
+const WS_PORT1 = 8089;
+const WS_PORT2 = 8090;
+const WS_PORT3 = 8091;
+const WS_PORT4 = 8092;
+const WS_PORT5 = 8093;
+
+const wsServer = new WebSocket.Server({port: WS_PORT}, ()=> console.log(`WS Server is listening at ${WS_PORT}`));
+let connectedClients = [];
+wsServer.on('connection', (ws, req)=>{
+    console.log('Connected');
+    connectedClients.push(ws);
+
+    ws.on('message', data => {
+        connectedClients.forEach((ws,i)=>{
+            if(ws.readyState === ws.OPEN){
+                ws.send(data);
+            }else{
+                connectedClients.splice(i ,1);
+            }
+        })
+    });
+});
+const wsServer1 = new WebSocket.Server({port: WS_PORT1}, ()=> console.log(`WS Server is listening at ${WS_PORT1}`));
+let connectedClients1 = [];
+wsServer1.on('connection', (ws1, req)=>{
+    console.log('Connected');
+    connectedClients1.push(ws1);
+
+    ws1.on('message', data1 => {
+        connectedClients1.forEach((ws1,i)=>{
+            if(ws1.readyState === ws1.OPEN){
+                ws1.send(data1);
+            }else{
+                connectedClients1.splice(i ,1);
+            }
+        })
+    });
+});
+const wsServer2 = new WebSocket.Server({port: WS_PORT2}, ()=> console.log(`WS Server is listening at ${WS_PORT2}`));
+let connectedClients2 = [];
+wsServer2.on('connection', (ws2, req)=>{
+    console.log('Connected');
+    connectedClients2.push(ws2);
+
+    ws2.on('message', data2 => {
+        connectedClients2.forEach((ws2,i)=>{
+            if(ws2.readyState === ws2.OPEN){
+                ws2.send(data2);
+            }else{
+                connectedClients2.splice(i ,1);
+            }
+        })
+    });
+});
+const wsServer3 = new WebSocket.Server({port: WS_PORT3}, ()=> console.log(`WS Server is listening at ${WS_PORT3}`));
+let connectedClients3 = [];
+wsServer3.on('connection', (ws3, req)=>{
+    console.log('Connected');
+    connectedClients3.push(ws3);
+
+    ws3.on('message', data3 => {
+        connectedClients3.forEach((ws3,i)=>{
+            if(ws3.readyState === ws3.OPEN){
+                ws3.send(data3);
+            }else{
+                connectedClients3.splice(i ,1);
+            }
+        })
+    });
+});
+const wsServer4 = new WebSocket.Server({port: WS_PORT4}, ()=> console.log(`WS Server is listening at ${WS_PORT4}`));
+let connectedClients4 = [];
+wsServer4.on('connection', (ws4, req)=>{
+    console.log('Connected');
+    connectedClients4.push(ws4);
+
+    ws4.on('message', data4 => {
+        connectedClients4.forEach((ws4,i)=>{
+            if(ws4.readyState === ws4.OPEN){
+                ws4.send(data4);
+            }else{
+                connectedClients4.splice(i ,1);
+            }
+        })
+    });
+});
+const wsServer5 = new WebSocket.Server({port: WS_PORT5}, ()=> console.log(`WS Server is listening at ${WS_PORT5}`));
+let connectedClients5 = [];
+wsServer5.on('connection', (ws5, req)=>{
+    console.log('Connected');
+    connectedClients5.push(ws5);
+
+    ws5.on('message', data5 => {
+        connectedClients5.forEach((ws5,i)=>{
+            if(ws5.readyState === ws5.OPEN){
+                ws5.send(data5);
+            }else{
+                connectedClients5.splice(i ,1);
+            }
+        })
+    });
+});
+//app.get('/client',(req,res)=>res.sendFile(path.resolve(__dirname, '/home/gs1801/CoffeeProject/app/templates/video.html')));
+app.get('/client',(req,res)=>res.sendFile(path.resolve(__dirname, '/home/gs1801/Rita/Coffee/templates/dry_containter.html')));
+app.listen(HTTP_PORT, ()=> console.log(`HTTP server listening at ${HTTP_PORT}`));
+