update
This commit is contained in:
parent
b927c6d1ac
commit
b632da39e8
16
b/product/homepage_category_tree_delete.dspy
Normal file
16
b/product/homepage_category_tree_delete.dspy
Normal file
@ -0,0 +1,16 @@
|
||||
async def homepage_category_tree_delete(ns={}):
|
||||
if not ns.get('id'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '请传递分类ID'
|
||||
}
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
await sor.U('homepage_category_tree', {'id': ns.get('id'), 'del_flg': '1'})
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'product category deleted successfully'
|
||||
}
|
||||
|
||||
ret = await homepage_category_tree_delete(params_kw)
|
||||
return ret
|
||||
@ -1,3 +1,121 @@
|
||||
async def publish_product_to_excel(ns={}):
|
||||
if not ns.get('ids') and (not ns.get('result_from_search')):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '请传递产品ID'
|
||||
}
|
||||
result = []
|
||||
if ns.get('ids'):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
ids = json.loads(ns.get('ids')) if isinstance(ns.get('ids'), str) else ns.get('ids')
|
||||
# 根据ids查询user_publish_product表
|
||||
find_sql = """SELECT * FROM user_publish_product WHERE id IN (%s) AND del_flg = '0';""" % ','.join(["'%s'" % id for id in ids])
|
||||
result = await sor.sqlExe(find_sql, {})
|
||||
if not result:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': '没有找到匹配的产品'
|
||||
}
|
||||
if ns.get('result_from_search'):
|
||||
result = ns.get('result_from_search')
|
||||
|
||||
# 结果转换成 中文名称:值 的字典列表
|
||||
field_mapping = {
|
||||
# 'id': 'id',
|
||||
# 'publish_type': '类型',
|
||||
'img': '图片链接',
|
||||
# 'cart_flag': '是否支持显卡',
|
||||
# 'domain_name': '所属域名',
|
||||
# 'orgid': '所属机构',
|
||||
'product_name': '商品名称',
|
||||
# 'product_category': '所属类别',
|
||||
'company_name': '企业名称',
|
||||
# 'company_type': '公司类别',
|
||||
'contact_person': '联系人',
|
||||
'job_title': '职务',
|
||||
'phone_number': '手机号码',
|
||||
'email': '邮箱',
|
||||
'cpu': 'cpu',
|
||||
'memory': '内存',
|
||||
'gpu': 'gpu',
|
||||
'sys_disk': '系统盘',
|
||||
'data_disk': '数据盘',
|
||||
'net_card': '网卡',
|
||||
'price': '价格',
|
||||
'unit': '价格单位',
|
||||
'discount': '价格折扣',
|
||||
'discount_price': '折扣后价格',
|
||||
'service_charge': '服务费',
|
||||
'short_term': '是否短租',
|
||||
# 'priority': '排序优先级',
|
||||
'status': '上架状态',
|
||||
# 'title': '主题',
|
||||
# 'label': '标签',
|
||||
# 'first_page': '是否推送到首页',
|
||||
# 'admin_push': '是否是运营人员提交',
|
||||
'requirement_summary': '需求概述',
|
||||
'related_parameters': '相关参数',
|
||||
'application_scenario': '应用场景',
|
||||
'audit_status': '审核状态',
|
||||
'listing_status': '上架状态',
|
||||
'reject_reason': '驳回原因',
|
||||
'update_time': '更新时间',
|
||||
'create_at': '创建时间',
|
||||
# 'publish_time': '发布日期',
|
||||
# 'del_flg': '删除标志'
|
||||
}
|
||||
# 转换字典键为中文
|
||||
for data_dic in result:
|
||||
# 如果有图片路径 则转换为完整的图片链接
|
||||
if data_dic.get('img') and data_dic['img'] != 'null':
|
||||
data_dic['img'] = 'https://' + data_dic['domain_name'] + '/idfile?path=' + data_dic['img']
|
||||
else:
|
||||
data_dic['img'] = None
|
||||
# 转换字典键为中文 对应的值要有映射
|
||||
# 拆分后:显式循环结构(便于后续处理)
|
||||
new_data_dic = {}
|
||||
for key, value in data_dic.items():
|
||||
if key == 'publish_type':
|
||||
# 显示类型映射
|
||||
if value == '1':
|
||||
value = '产品'
|
||||
elif value == '2':
|
||||
value = '需求'
|
||||
if key == 'audit_status':
|
||||
# 显示审核状态映射
|
||||
if value == 'pending':
|
||||
value = '待审'
|
||||
elif value == 'approved':
|
||||
value = '通过'
|
||||
elif value == 'rejected':
|
||||
value = '拒绝'
|
||||
if key == 'listing_status':
|
||||
# 显示上架状态映射
|
||||
if value == 'listing':
|
||||
value = '上架'
|
||||
elif value == 'delisting':
|
||||
value = '下架'
|
||||
if key == 'short_term':
|
||||
# 显示短租状态映射
|
||||
if value == '1':
|
||||
value = '是'
|
||||
elif value == '0':
|
||||
value = '否'
|
||||
# 获取中文映射键
|
||||
chinese_key = field_mapping.get(key)
|
||||
# 仅保留有映射关系的字段
|
||||
if chinese_key is not None:
|
||||
new_data_dic[chinese_key] = value
|
||||
data_dic.clear()
|
||||
data_dic.update(new_data_dic)
|
||||
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'export to excel success',
|
||||
'data': result
|
||||
}
|
||||
|
||||
async def get_user_role(ns={}):
|
||||
sor = ns['sor']
|
||||
# get role
|
||||
@ -48,6 +166,12 @@ async def publish_product_search(ns={}):
|
||||
'status': False,
|
||||
'msg': 'url_link is required'
|
||||
}
|
||||
if not ns.get('publish_type'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'publish_type is required'
|
||||
}
|
||||
|
||||
|
||||
domain_name = ns.get('url_link').split("//")[1].split("/")[0]
|
||||
if 'localhost' in domain_name:
|
||||
|
||||
@ -23,6 +23,57 @@ async def get_user_role(ns={}):
|
||||
|
||||
return role
|
||||
|
||||
async def user_browse_history_add(ns={}):
|
||||
# ns = {
|
||||
# 'userid': '9KVhsVCJsW_29q3hRhMAr', # 用户ID
|
||||
# 'product_id': 'p2s2YPPU7uquza3gGw9k2', # 产品ID
|
||||
# 'ip_address': '192.168.1.1', # IP地址
|
||||
# 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102' # 用户代理
|
||||
# }
|
||||
# 必要参数校验
|
||||
if not ns.get('userid') or not ns.get('product_id'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'userid and product_id are required'
|
||||
}
|
||||
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
try:
|
||||
# 根据timestamp时间字段:browse_time去重 查找10个小时内是否存在
|
||||
browse_time = datetime.datetime.now() - datetime.timedelta(hours=10)
|
||||
check_sql = """
|
||||
SELECT * FROM user_browse_history
|
||||
WHERE userid = '%s' AND product_id = '%s' AND del_flg = '0' AND browse_time >= '%s';
|
||||
""" % (ns.get('userid'), ns.get('product_id'), browse_time)
|
||||
check_result = await sor.sqlExe(check_sql, {})
|
||||
if check_result:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'The user has browsed this product within the last 10 hours'
|
||||
}
|
||||
|
||||
# 生成记录ID
|
||||
record_id = uuid()
|
||||
# 插入浏览记录
|
||||
insert_sql = """
|
||||
INSERT INTO user_browse_history (
|
||||
id, userid, product_id, ip_address, user_agent, del_flg
|
||||
) VALUES ('%s', '%s', '%s', '%s', '%s', '0');
|
||||
""" % (record_id, ns.get('userid'), ns.get('product_id'),
|
||||
ns.get('ip_address', ''), ns.get('user_agent', ''))
|
||||
await sor.sqlExe(insert_sql, {})
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Browse history recorded successfully',
|
||||
'data': {'record_id': record_id}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'Failed to record browse history, %s' % str(e)
|
||||
}
|
||||
|
||||
async def publish_product_search_detail(ns={}):
|
||||
"""
|
||||
:param ns:
|
||||
@ -36,6 +87,7 @@ async def publish_product_search_detail(ns={}):
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
user_role = None
|
||||
orgid = None
|
||||
# 区分运营和普通客户
|
||||
if userid:
|
||||
user_list = await sor.R('users', {'id': userid})
|
||||
@ -61,6 +113,10 @@ async def publish_product_search_detail(ns={}):
|
||||
else:
|
||||
product['email'] = 'kawa@****.com'
|
||||
|
||||
# 保存浏览记录
|
||||
if userid:
|
||||
await user_browse_history_add({'userid': userid, 'product_id': ns.get('id')})
|
||||
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Product retrieved successfully',
|
||||
|
||||
@ -12,6 +12,42 @@ async def search_user_inquiry(ns={}):
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
search_sql = """select * from product_inquiry where domain_name = '%s' and del_flg = '0' order by update_time desc;""" % domain_name
|
||||
result = await sor.sqlExe(search_sql, {})
|
||||
if ns.get('to_excel') == '1':
|
||||
# 创建映射字段 导出execl
|
||||
# 结果转换成 中文名称:值 的字典列表
|
||||
field_mapping = {
|
||||
'name': '联系人姓名',
|
||||
'custom_type': '客户类型',
|
||||
'phone': '联系人电话',
|
||||
'email': '邮箱',
|
||||
'company': '公司名称',
|
||||
'content': '咨询内容',
|
||||
'feedback': '反馈状态',
|
||||
}
|
||||
# 新增值映射字典,集中管理各字段的数值转换规则
|
||||
value_mapping = {
|
||||
'custom_type': {'0': '个人', '1': '企业'},
|
||||
'feedback': {'0': '未反馈', '1': '已反馈'} # 根据表结构补充反馈状态映射
|
||||
}
|
||||
# 转换字典键为中文
|
||||
for data_dic in result:
|
||||
# 拆分后:显式循环结构(便于后续处理)
|
||||
new_data_dic = {}
|
||||
# 按field_mapping定义的顺序处理字段,确保输出顺序一致
|
||||
for key in field_mapping.keys():
|
||||
# 跳过数据中不存在的字段
|
||||
if key not in data_dic:
|
||||
continue
|
||||
value = data_dic[key]
|
||||
chinese_key = field_mapping[key]
|
||||
if key in value_mapping:
|
||||
mapped_value = value_mapping[key].get(str(value), value) # 若未找到对应映射,保留原始值
|
||||
new_data_dic[chinese_key] = mapped_value
|
||||
else:
|
||||
new_data_dic[chinese_key] = value
|
||||
data_dic.clear()
|
||||
data_dic.update(new_data_dic)
|
||||
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'search success',
|
||||
|
||||
@ -29,6 +29,14 @@ async def enterprise_audit_info_search(ns={}):
|
||||
'status': False,
|
||||
'msg': '请传递url_link'
|
||||
}
|
||||
|
||||
# 分页
|
||||
current_page = int(ns['current_page']) if ns.get('current_page') else 1
|
||||
page_size = int(ns['page_size']) if ns.get('page_size') else 10
|
||||
offset = (current_page - 1) * page_size
|
||||
|
||||
audit_status = ns.get('audit_status')
|
||||
|
||||
domain_name = ns.get('url_link').split("//")[1].split("/")[0]
|
||||
if 'localhost' in domain_name:
|
||||
domain_name = 'dev.opencomputing.cn'
|
||||
@ -50,10 +58,36 @@ async def enterprise_audit_info_search(ns={}):
|
||||
user_role = await get_user_role({'userid': userid, 'sor': sor})
|
||||
try:
|
||||
if user_role == '客户': # 客户查询
|
||||
count_sql = """SELECT COUNT(*) AS total_count FROM enterprise_audit_info WHERE orgid = '%s' AND del_flg = '0';""" % orgid
|
||||
find_sql = """SELECT * FROM enterprise_audit_info WHERE orgid = '%s' AND del_flg = '0';""" % orgid
|
||||
else: # 运营查询 enterprise_audit_info和organization表关联查询 enterprise_audit_info中的orgid和organization表中的id关联查询
|
||||
find_sql = """SELECT eai.* FROM enterprise_audit_info AS eai LEFT JOIN organization as org ON eai.orgid = org.id WHERE org.parentid = '%s' AND eai.del_flg = '0' ORDER BY eai.update_time DESC;""" % orgid
|
||||
# 执行查询
|
||||
count_sql = """SELECT COUNT(*) AS total_count FROM enterprise_audit_info AS eai LEFT JOIN organization as org ON eai.orgid = org.id WHERE org.parentid = '%s' AND eai.del_flg = '0';""" % orgid
|
||||
find_sql = """SELECT eai.* FROM enterprise_audit_info AS eai LEFT JOIN organization as org ON eai.orgid = org.id WHERE org.parentid = '%s' AND eai.del_flg = '0' ORDER BY eai.update_time DESC LIMIT %s OFFSET %s;""" % (orgid, page_size, offset)
|
||||
# 拆分find_sql 增加audit_status条件筛选
|
||||
if audit_status:
|
||||
# Split the audit_status string into individual statuses
|
||||
statuses = [status.strip() for status in audit_status.split(',') if status.strip()]
|
||||
if statuses:
|
||||
# Create a properly escaped list of statuses for SQL
|
||||
escaped_statuses = []
|
||||
for status in statuses:
|
||||
# Escape single quotes by doubling them (SQL standard)
|
||||
escaped_status = status.replace("'", "''")
|
||||
escaped_statuses.append(f"'{escaped_status}'")
|
||||
|
||||
# Join the escaped statuses for the IN clause
|
||||
statuses_str = ','.join(escaped_statuses)
|
||||
|
||||
if statuses_str:
|
||||
count_sql = count_sql.split("WHERE")[0] + f"WHERE eai.audit_status IN ({statuses_str}) AND " + count_sql.split("WHERE")[1]
|
||||
find_sql = find_sql.split("WHERE")[0] + f"WHERE eai.audit_status IN ({statuses_str}) AND " + find_sql.split("WHERE")[1]
|
||||
# 非pending
|
||||
else:
|
||||
count_sql = count_sql.split("WHERE")[0] + "WHERE eai.audit_status != 'pending' AND " + count_sql.split("WHERE")[1]
|
||||
find_sql = find_sql.split("WHERE")[0] + "WHERE eai.audit_status != 'pending' AND " + find_sql.split("WHERE")[1]
|
||||
|
||||
# 执行查询
|
||||
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
||||
res = await sor.sqlExe(find_sql, {})
|
||||
|
||||
# 处理结果中的图片路径 增加前缀
|
||||
@ -66,7 +100,12 @@ async def enterprise_audit_info_search(ns={}):
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'enterprise audit info search successfully',
|
||||
'data': res
|
||||
'data': {
|
||||
'total_count': total_count,
|
||||
'current_page': current_page,
|
||||
'page_size': page_size,
|
||||
'data': res
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
|
||||
53
b/user/user_browse_history_add.dspy
Normal file
53
b/user/user_browse_history_add.dspy
Normal file
@ -0,0 +1,53 @@
|
||||
async def user_browse_history_add(ns={}):
|
||||
# ns = {
|
||||
# 'userid': '9KVhsVCJsW_29q3hRhMAr', # 用户ID
|
||||
# 'product_id': 'p2s2YPPU7uquza3gGw9k2', # 产品ID
|
||||
# 'ip_address': '192.168.1.1', # IP地址
|
||||
# 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102' # 用户代理
|
||||
# }
|
||||
# 必要参数校验
|
||||
if not ns.get('userid') or not ns.get('product_id'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'userid and product_id are required'
|
||||
}
|
||||
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
try:
|
||||
# 根据timestamp时间字段:browse_time去重 查找10个小时内是否存在
|
||||
browse_time = datetime.datetime.now() - datetime.timedelta(hours=10)
|
||||
check_sql = """
|
||||
SELECT * FROM user_browse_history
|
||||
WHERE userid = '%s' AND product_id = '%s' AND del_flg = '0' AND browse_time >= '%s';
|
||||
""" % (ns.get('userid'), ns.get('product_id'), browse_time)
|
||||
check_result = await sor.sqlExe(check_sql, {})
|
||||
if check_result:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'The user has browsed this product within the last 10 hours'
|
||||
}
|
||||
|
||||
# 生成记录ID
|
||||
record_id = uuid()
|
||||
# 插入浏览记录
|
||||
insert_sql = """
|
||||
INSERT INTO user_browse_history (
|
||||
id, userid, product_id, ip_address, user_agent, del_flg
|
||||
) VALUES ('%s', '%s', '%s', '%s', '%s', '0');
|
||||
""" % (record_id, ns.get('userid'), ns.get('product_id'),
|
||||
ns.get('ip_address', ''), ns.get('user_agent', ''))
|
||||
await sor.sqlExe(insert_sql, {})
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Browse history recorded successfully',
|
||||
'data': {'record_id': record_id}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'Failed to record browse history, %s' % str(e)
|
||||
}
|
||||
|
||||
ret = await user_browse_history_add(params_kw)
|
||||
return ret
|
||||
29
b/user/user_browse_history_delete.dspy
Normal file
29
b/user/user_browse_history_delete.dspy
Normal file
@ -0,0 +1,29 @@
|
||||
async def user_browse_history_delete(ns={}):
|
||||
if not ns.get('id'):
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'record id is required'
|
||||
}
|
||||
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
try:
|
||||
# 逻辑删除(更新删除标志)
|
||||
update_sql = """
|
||||
UPDATE user_browse_history
|
||||
SET del_flg = '1'
|
||||
WHERE id = '%s';
|
||||
""" % ns.get('id')
|
||||
await sor.sqlExe(update_sql, {})
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Browse history deleted successfully'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'Failed to delete browse history, %s' % str(e)
|
||||
}
|
||||
|
||||
ret = await user_browse_history_delete(params_kw)
|
||||
return ret
|
||||
72
b/user/user_browse_history_search.dspy
Normal file
72
b/user/user_browse_history_search.dspy
Normal file
@ -0,0 +1,72 @@
|
||||
async def user_browse_history_search(ns={}):
|
||||
# 处理userid
|
||||
if ns.get('userid'):
|
||||
userid = ns.get('userid')
|
||||
else:
|
||||
userid = await get_user()
|
||||
if not userid:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'no match user'
|
||||
}
|
||||
|
||||
# 参数处理
|
||||
product_id = ns.get('product_id')
|
||||
start_time = ns.get('start_time')
|
||||
end_time = ns.get('end_time')
|
||||
page_size = int(ns.get('page_size', 10))
|
||||
current_page = int(ns.get('current_page', 1))
|
||||
offset = (current_page - 1) * page_size
|
||||
|
||||
db = DBPools()
|
||||
async with db.sqlorContext('kboss') as sor:
|
||||
try:
|
||||
# 基础查询条件
|
||||
base_conditions = ["del_flg = '0'"]
|
||||
if userid:
|
||||
base_conditions.append(f"userid = '{userid}'")
|
||||
if product_id:
|
||||
base_conditions.append(f"product_id = '{product_id}'")
|
||||
if start_time and end_time:
|
||||
end_time += ' 23:59:59'
|
||||
base_conditions.append(f"browse_time BETWEEN '{start_time}' AND '{end_time}'")
|
||||
|
||||
# 构建查询SQL
|
||||
where_clause = " AND ".join(base_conditions)
|
||||
|
||||
# 根据product_id查询product_info
|
||||
|
||||
find_sql = f"""
|
||||
SELECT * FROM user_browse_history
|
||||
WHERE {where_clause}
|
||||
ORDER BY browse_time DESC
|
||||
LIMIT {page_size} OFFSET {offset};
|
||||
"""
|
||||
# 总数查询SQL
|
||||
count_sql = f"""
|
||||
SELECT COUNT(*) AS total_count FROM user_browse_history
|
||||
WHERE {where_clause};
|
||||
"""
|
||||
|
||||
# 执行查询
|
||||
result = await sor.sqlExe(find_sql, {})
|
||||
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
||||
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Browse history retrieved successfully',
|
||||
'data': {
|
||||
'total_count': total_count,
|
||||
'page_size': page_size,
|
||||
'current_page': current_page,
|
||||
'history_list': result
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': False,
|
||||
'msg': 'Failed to retrieve browse history, %s' % str(e)
|
||||
}
|
||||
|
||||
ret = await user_browse_history_search(params_kw)
|
||||
return ret
|
||||
Loading…
x
Reference in New Issue
Block a user