feat: 新增住建厅价格计算

This commit is contained in:
han0
2024-07-12 11:11:28 +08:00
parent 44c8e8c096
commit cb0eb54984
26 changed files with 140 additions and 81 deletions

View File

@@ -45,12 +45,19 @@ class Calculator:
price_calculate = 0
price_recommend = 0
fluctuating_recommend = 0
price_fujian = 0
fluctuating_fujian = 0
unit = ""
spec = ''
_previous_prices = None
_fluctuatings = []
def __init__(self, year, month, force=True):
self.year = year
self.month = month
self.force = True # todo-2 已修改的的发布价不在覆盖计算
@property
def previous_prices(self):
if not self._previous_prices:
@@ -78,6 +85,8 @@ class Calculator:
'price_calculate': self.price_calculate,
'price_recommend': self.price_recommend,
'fluctuating_recommend': self.fluctuating_recommend,
'price_fujian': self.price_fujian,
'fluctuating_fujian': self.fluctuating_fujian,
'unit': self.unit,
'spec': self.spec,
}
@@ -91,6 +100,7 @@ class Calculator:
self.price_last_month = self._get_last_month_price()
self.price_calculate = self._get_calculate_price()
self.price_recommend, self.fluctuating_recommend = self._get_recommend_price()
self.price_fujian, self.fluctuating_fujian = self._get_fujian_price()
return self
def _get_ftb_price(self):
@@ -108,6 +118,9 @@ class Calculator:
def _get_survey_price(self):
return 0, 0
def _get_fujian_price(self):
return 0, 0
def _get_last_month_price(self):
return getattr(self.previous_prices, 'price_recommend', 0)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -13,10 +14,6 @@ class AsphaltDomesticCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='石油沥青', spec='国产')
query = query.with_entities(func.avg(FuzhouTransportationBureau.price))
@@ -49,6 +46,13 @@ class AsphaltDomesticCalculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='石油沥青')
data = query.first()
price = data.price * 1000 if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey]
return super()._get_recommend_price()

View File

@@ -1,7 +1,4 @@
from sqlalchemy import func
from calculators import Calculator, Helper
from commons.models.asphalt_modifier import AsphaltModifier
from calculators import Calculator
from commons.models.price_result import PriceResult
@@ -12,10 +9,6 @@ class AsphaltDomesticModifierCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_recommend_price(self):
query = PriceResult.get_query(self.year, self.month, name='国产沥青')
asphalt = query.first()

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -14,10 +15,6 @@ class AsphaltImportedCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='石油沥青', spec='进口')
query = query.with_entities(func.avg(FuzhouTransportationBureau.price))
@@ -49,6 +46,13 @@ class AsphaltImportedCalculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='石油沥青')
data = query.first()
price = data.price * 1000 if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey]
return super()._get_recommend_price()

View File

@@ -1,7 +1,4 @@
from sqlalchemy import func
from calculators import Calculator, Helper
from commons.models.asphalt_modifier import AsphaltModifier
from calculators import Calculator
from commons.models.price_result import PriceResult
@@ -12,10 +9,6 @@ class AsphaltImportedModifierCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_recommend_price(self):
query = PriceResult.get_query(self.year, self.month, name='进口沥青')
asphalt = query.first()

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -15,10 +16,6 @@ class Cement325Calculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='32.5级水泥')
query = query.with_entities(func.avg(FuzhouTransportationBureau.price))
@@ -54,6 +51,13 @@ class Cement325Calculator(Calculator):
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='水泥', spec='32.5')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self, round_by=5):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb]
return super()._get_recommend_price(round_by)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -15,10 +16,6 @@ class Cement425Calculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='42.5级水泥')
data = query.first()
@@ -59,6 +56,13 @@ class Cement425Calculator(Calculator):
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='水泥', spec='42.5')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self, round_by=5):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb]
return super()._get_recommend_price(round_by)

View File

@@ -1,6 +1,6 @@
from sqlalchemy import func
from calculators import Calculator, Helper
from calculators import Calculator
from commons.models.asphalt_modifier import AsphaltModifier
from commons.models.price_result import PriceResult
@@ -12,10 +12,6 @@ class ModifierCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_recommend_price(self):
query = AsphaltModifier.get_query(self.year, self.month)
query = query.with_entities(func.avg(AsphaltModifier.price))

View File

@@ -1,6 +1,7 @@
import datetime
from calculators import Calculator, Helper
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -15,10 +16,6 @@ class Oil0Calculator(Calculator):
unit = "kg"
spec = "0#"
def __init__(self, year, month):
self.year = year
self.month = month
def _get_survey_price(self):
query = FujianSurvey.get_query(self.year, self.month, name='柴油', spec='0#')
data = query.first()
@@ -36,6 +33,13 @@ class Oil0Calculator(Calculator):
def _get_calculate_price(self, round_dit=2):
return super()._get_calculate_price(round_dit)
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='柴油', spec='0#')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
return self.price_network, self.fluctuating_network

View File

@@ -1,6 +1,7 @@
import datetime
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
@@ -13,10 +14,6 @@ class Oil89Calculator(Calculator):
unit = "kg"
spec = "89#"
def __init__(self, year, month):
self.year = year
self.month = month
def _get_survey_price(self):
query = FujianSurvey.get_query(self.year, self.month, name='汽油', spec='89#')
data = query.first()
@@ -31,6 +28,13 @@ class Oil89Calculator(Calculator):
fluctuating = self._get_fluctuating('price_network', price)
return round(price, 2), round(fluctuating, 2)
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='汽油', spec='89#')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_calculate_price(self, round_dit=2):
return super()._get_calculate_price(round_dit)

View File

@@ -1,6 +1,7 @@
import datetime
from calculators import Calculator, Helper
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.oil import Oil
@@ -14,10 +15,6 @@ class Oil92Calculator(Calculator):
unit = "kg"
spec = "92#"
def __init__(self, year, month):
self.year = year
self.month = month
def _get_survey_price(self):
query = FujianSurvey.get_query(self.year, self.month, name='汽油', spec='92#')
data = query.first()
@@ -32,6 +29,13 @@ class Oil92Calculator(Calculator):
fluctuating = self._get_fluctuating('price_network', price)
return round(price, 2), round(fluctuating, 2)
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='汽油', spec='92#')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_calculate_price(self, round_dit=2):
return super()._get_calculate_price(round_dit)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -14,10 +15,6 @@ class SteelPlateCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='钢板')
data = query.first()
@@ -53,6 +50,13 @@ class SteelPlateCalculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='钢板', spec='δ14-20')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb]
return super()._get_recommend_price()

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -16,10 +17,6 @@ class Reber300Calculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='光圆钢筋')
data = query.first()
@@ -55,6 +52,13 @@ class Reber300Calculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='圆钢筋', spec='HPB300Φ12')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb, self.fluctuating_ss]
return super()._get_recommend_price()

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
@@ -16,10 +17,6 @@ class Reber400Calculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='带肋钢筋')
data = query.first()
@@ -55,6 +52,13 @@ class Reber400Calculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='圆钢筋', spec='HRB400EΦ20')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb, self.fluctuating_ss]
return super()._get_recommend_price()

View File

@@ -1,12 +1,10 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
from commons.models.price_result import PriceResult
from commons.models.steel_section import SteelSection
class SteelSectionCalculator(Calculator):
@@ -15,10 +13,6 @@ class SteelSectionCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='型钢')
data = query.first()
@@ -50,6 +44,13 @@ class SteelSectionCalculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='型钢')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb]
return super()._get_recommend_price()

View File

@@ -1,12 +1,10 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_fujian import DataFujian
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
from commons.models.price_result import PriceResult
from commons.models.steel_strand import SteelStrand
class SteelStrandCalculator(Calculator):
@@ -15,10 +13,6 @@ class SteelStrandCalculator(Calculator):
unit = "t"
spec = ""
def __init__(self, year, month):
self.year = year
self.month = month
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='钢绞线')
data = query.first()
@@ -50,6 +44,13 @@ class SteelStrandCalculator(Calculator):
fluctuating = int(self._get_fluctuating('price_survey', price))
return price, fluctuating
def _get_fujian_price(self):
query = DataFujian.get_query(self.year, self.month, name='钢绞线')
data = query.first()
price = data.price if data else 0
fluctuating = self._get_fluctuating('price_fujian', price)
return price, fluctuating
def _get_recommend_price(self):
self._fluctuatings = [self.fluctuating_network, self.fluctuating_survey, self.fluctuating_fhb, self.fluctuating_ftb]
return super()._get_recommend_price()

View File

@@ -9,9 +9,10 @@ from commons.models.price_result import PriceResult
class Collector:
def __init__(self, year, month):
def __init__(self, year, month, force=True):
self.year = year
self.month = month
self.force = True # todo-2 已发布的价格不在覆盖计算
# todo-2 材料id映射
@@ -269,6 +270,7 @@ class Collector:
).upsert()
def run(self):
# 当月价
self.get_from_survey()
self.get_from_result()

View File

@@ -38,3 +38,19 @@ class DataFujian(db.Model, Model, BaseModelMixin):
query = query.filter(DataFujian.spec == self.spec)
result = query.one_or_none()
return result
@classmethod
def get_query(cls, year=None, month=None, name=None, spec=None, name_in=None, region='福州'):
query = cls.query
if year and month:
query = query.filter(cls.year == year)
query = query.filter(cls.month == month)
if name:
query = query.filter(cls.name == name)
if name_in:
query = query.filter(cls.name.in_(name_in))
if spec:
query = query.filter(cls.spec.like(f'%{spec}%'))
if region:
query = query.filter(cls.city.like(f'%{region}%'))
return query

View File

@@ -51,6 +51,7 @@ class PricePublish(db.Model, Model, OperationTrackMixin, BaseModelMixin):
query = query.filter(cls.year == self.year)
query = query.filter(cls.month == self.month)
query = query.filter(cls.name == self.name)
query = query.filter(cls.spec == self.spec)
query = query.filter(cls.type == self.type)
result = query.one_or_none()
return result

View File

@@ -27,6 +27,8 @@ class PriceResult(db.Model, Model, OperationTrackMixin, BaseModelMixin):
price_calculate = Column('PRICE_CALCULATE', Numeric(16, 4), default=0, comment='计算价格')
price_recommend = Column('PRICE_RECOMMEND', Numeric(16, 4), default=0, comment='推荐价格')
fluctuating_recommend = Column('FLUCTUATING_RECOMMEND', Numeric(16, 4), default=0, comment='推荐浮动')
price_fujian = Column('PRICE_FUJIAN', Numeric(16, 4), default=0, comment='住建厅价格')
fluctuating_fujian = Column('FLUCTUATING_FUJIAN', Numeric(16, 4), default=0, comment='住建厅浮动')
spec = Column('SPEC', String(128), default='', comment='规格')
unit = Column('UNIT', String(128), default='', comment='单位')

View File

@@ -26,6 +26,7 @@ def run_spider(spider):
process.start()
return pathlib.Path(filename) # .absolute()
class CookieTools:
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'

View File

@@ -70,7 +70,7 @@ class DataFujianSpider(scrapy.Spider):
'year': response.meta['year'],
'month': response.meta['month'],
'city': response.meta['city'],
'date': datetime.date.today().strftime('%Y-%m-%d')
'date': datetime.datetime(response.meta['year'], response.meta['month'], 1).strftime('%Y-%m-%d')
}

View File

@@ -64,7 +64,8 @@ class DataJiangxiSpider(scrapy.Spider):
'date': date,
}
# todo 江西造价站入库
# todo-2 江西造价站入库
if __name__ == '__main__':
import json

View File

@@ -23,7 +23,7 @@ def create_last_month_publish_data():
# 检查是否生成上月数据
query = PriceResult.get_query(year=year, month=month)
result = PriceResult.get_list(query)
# todo 有修改记录的忽略,其余都重新生成
if not result:
calculate(year=year, month=month)

View File

@@ -15,7 +15,7 @@ if __name__ == '__main__':
with ClientApp().app_context():
for i in range(2, 12):
collect(2022, i + 1)
for i in range(1, 12):
for i in range(0, 12):
collect(2023, i + 1)
for i in range(0, 5):
collect(2024, i + 1)

View File

@@ -24,7 +24,6 @@ class Pylint:
if not self._disable:
self._prepare_hook()
# todo 移入脚本
self._check_code()
return self