猎羽广告

fillBack.ts 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. import { ElMessage } from "element-plus";
  2. import { basicInfoJson, scheduleBid } from './information'
  3. import { specificPositionAll } from './other'
  4. import { scene } from './scene'
  5. import { number, time } from "echarts";
  6. import { getDay } from "@/common/common";
  7. import { JsonInfo } from "../../originalityBasic/ts/information";
  8. import _ from "lodash";
  9. const specificPosition = specificPositionAll()
  10. /**格式化为文字 */
  11. export const formatTime = (data) => {
  12. interface ITimeSlots {
  13. startTime: string,
  14. endTime: string
  15. }
  16. const timeSlots: ITimeSlots[] = [];
  17. let startTime = '';
  18. let endTime = '';
  19. for (let i = 0; i < data.length; i += 1) {
  20. if (data[i] == 1 && startTime == '') {
  21. let timeNum = (Math.floor(i / 2)).toString();
  22. timeNum = Number(timeNum) < 10 ? '0' + timeNum : timeNum
  23. startTime = `${timeNum}:${i % 2 == 0 ? '00' : '30'}`;
  24. }
  25. if (data[i] == 1 && (data[i + 1] == 0 || data[i + 1] === undefined)) {
  26. let timeNum = (Math.floor((i + 1) / 2)).toString();
  27. timeNum = Number(timeNum) < 10 ? '0' + timeNum : timeNum
  28. endTime = `${timeNum}:${(i + 1) % 2 == 0 ? '00' : '30'}`;
  29. timeSlots.push({ startTime, endTime })
  30. startTime = '';
  31. endTime = '';
  32. }
  33. }
  34. return timeSlots
  35. }
  36. export const switchEvent = (v: number) => {
  37. switch (v) {
  38. case 0:
  39. return '星期一';
  40. case 1:
  41. return '星期二';
  42. case 2:
  43. return '星期三';
  44. case 3:
  45. return '星期四';
  46. case 4:
  47. return '星期五';
  48. case 5:
  49. return '星期六';
  50. case 6:
  51. return '星期日';
  52. default:
  53. return '星期';
  54. }
  55. }
  56. /**检验最大值-最小值 是否符合规则 */
  57. const inspectMaxMin = (info, label) => {
  58. let range = info?.split('-')
  59. let arr_min = range && range[0]?.split('.')
  60. let arr_max = range && range[1]?.split('.')
  61. if ((range && isNaN(Number(range[0]))) || (range && isNaN(Number(range[1]))) || (arr_min.length > 1 && arr_min[1].length > 2) || (arr_max.length > 1 && arr_max[1].length > 2)) {
  62. ElMessage.error(`${label}请填写数字,最多支持小数点后2位`)
  63. return false
  64. } else if (Number(arr_min) < 0.01 || Number(arr_max) < 0.01 || Number(arr_min) > 20000000 || Number(arr_max) > 20000000) {
  65. ElMessage.error(`${label}超出范围0.01~20000000元`)
  66. return false
  67. } else if (!arr_min && arr_min != 0) {
  68. ElMessage.error(`请填写${label}最小值`)
  69. return false
  70. } else if (!arr_max && arr_max != 0) {
  71. ElMessage.error(`请填写${label}最大值`)
  72. return false
  73. } else {
  74. return true
  75. }
  76. }
  77. /**检验单个输入框 */
  78. const inspectNumber = (info, label, min = 200, max = 10000000) => {
  79. let arr = String(info).split('.')
  80. if (isNaN(Number(info)) || (arr.length > 1 && arr[1].length > 2)) {
  81. ElMessage.error(`${label}请填写数字,最多支持小数点后2位`)
  82. return false
  83. } else if (Number(info) < min || Number(info) > max) {
  84. ElMessage.error(`${label}超出范围${min}~${max}元`)
  85. return false
  86. } else {
  87. return true
  88. }
  89. }
  90. /**判断一个日期是周几 */
  91. const dayOfWeek = (day) => {
  92. // 创建一个表示特定日期的Date对象
  93. let date = new Date(day); // 这里的日期可以根据你的需求更改
  94. // 使用getDay()方法获取星期几
  95. let dayOfWeek = date.getDay();
  96. return dayOfWeek;
  97. }
  98. /**
  99. * 回显文案
  100. * me自己的 api接口回显的
  101. */
  102. interface IFillBackData {
  103. data: any,
  104. type: 'me' | 'api',
  105. cb?: Function,
  106. updateScene?: any,
  107. }
  108. export const FillBackData = ({ data, type, updateScene = {}, cb }: IFillBackData) => {
  109. let copywriting: string[] = [];
  110. let site_ids: string[] = [];//广告版位
  111. let params: any = {}
  112. let time_series_writ: [][] = [];
  113. if (data) {
  114. if (data.time_series_type == '2') {
  115. time_series_writ = (data.time_series?.split(','))?.map((v) => {
  116. let a = v.split('')
  117. return formatTime(a)
  118. }) || []
  119. }
  120. time_series_writ = time_series_writ.filter((v) => { return v.length > 0 })
  121. if (type == 'me') {
  122. params = {
  123. 'promoted_object_type': 'PROMOTED_OBJECT_TYPE_LEAD_AD',
  124. 'ad_form': data.ad_form,
  125. 'attribution_type': data.attribution_type,
  126. 'automatic_site': data.automatic_site,
  127. 'site_ids': data.automatic_site == '2' ? data.site_ids : '',
  128. 'display_scene': updateScene['display_scene'] ? data.display_scene : '',
  129. 'union_position_enabled': updateScene['union_position_enabled'] ? data.union_position_enabled : '',
  130. 'exclude_union_position_enabled': updateScene['exclude_union_position_enabled'] ? data.exclude_union_position_enabled : '',
  131. 'flow_optimization_enabled': updateScene['flow_optimization_enabled'] ? data.flow_optimization_enabled : '',
  132. 'search_expand_targeting_switch': data.search_scene_expand == 1 ? data.search_expand_targeting_switch : '',
  133. 'search_scene_expand': updateScene['search_scene_expand'] ? data.search_scene_expand : '',
  134. 'wechat_position': updateScene['wechat_position'] ? data.wechat_position ? data.wechat_position : null : '',
  135. 'wechat_scene': updateScene['wechat_scene'] ? data.wechat_scene : '',
  136. 'wechat_scene_official_category': updateScene['wechat_scene'] && data.wechat_scene == '1' ? data.wechat_scene_official_category : '',
  137. 'wechat_scene_mini_program': updateScene['wechat_scene'] && data.wechat_scene == '1' ? data.wechat_scene_mini_program : '',
  138. 'wechat_scene_pay_scene': updateScene['wechat_scene'] && data.wechat_scene == '1' ? data.wechat_scene_pay_scene : '',
  139. 'site_expand': updateScene['site_expand'] ? data.site_expand : '',
  140. 'auto_audience': data.auto_audience,
  141. 'excluded_converted_audience': data.excluded_converted_audience,
  142. 'expand_enabled': data.expand_enabled,
  143. 'expand_targeting': data.expand_enabled == 1 ? data.expand_targeting : '',
  144. 'smart_targeting_switch': data.smart_targeting_switch,
  145. 'unbreakable_targeting': data.unbreakable_targeting,
  146. 'wechat_ad_behaviors': data.wechat_ad_behaviors == '' ? '0' : data.wechat_ad_behaviors,
  147. 'wechat_ad_behavior_actions': data.wechat_ad_behaviors != '' ? data.wechat_ad_behavior_actions : '',
  148. 'wechat_ad_behavior_excluded_actions': data.wechat_ad_behaviors != '' ? data.wechat_ad_behavior_excluded_actions : '',
  149. 'date_model': data.date_model,
  150. 'begin_date': data.begin_date,
  151. 'end_date': data.date_model == '2' ? data.end_date : '',
  152. 'first_day_begin_time': data.first_day_begin_time,
  153. 'time_series_type': data.time_series_type,
  154. 'time_series': data.time_series_type == '2' ? data.time_series : '',
  155. 'daily_budget': data.daily_budget_radio == '1' ? 0 : Number(data.daily_budget),
  156. 'bid_mode': data.bid_mode,
  157. 'bid_way': data.smart_bid_type == 'SMART_BID_TYPE_CUSTOM' ? data.bid_way : '',
  158. 'smart_bid_type': data.bid_scene == 'BID_SCENE_UNKNOWN' ? data.smart_bid_type : '',
  159. 'bid_amount': data.bid_way == '1' ? data.bid_amount : '',
  160. 'bid_range': data.bid_way != '1' ? data.bid_range : '',
  161. 'ad_name': data.ad_name,
  162. 'dynamic_num': data.dynamic_num,
  163. 'bid_site_wechat_enabled': data.automatic_site == '1' ? data.bid_site_wechat_enabled : ''
  164. };
  165. if (data.bid_mode == 'BID_MODE_OCPM' || data.bid_mode == 'BID_MODE_OCPC') { // bid_mode为oCPM 或者oCPC
  166. params['bid_scene'] = data.bid_scene
  167. params['bid_site'] = data.bid_site
  168. params['bid_site_details'] = data.bid_site_details
  169. params['conversion_tracking_enabled'] = data.conversion_tracking_enabled
  170. params['conversion_tracking_report_type'] = data.conversion_tracking_enabled == 1 ? data.conversion_tracking_report_type : ''
  171. params['conversion_tracking_way'] = data.conversion_tracking_enabled == 1 ? data.conversion_tracking_way : ''
  172. params['conversion_tracking_scene'] = data.conversion_tracking_enabled == 1 ? data.conversion_tracking_scene : ''
  173. params['auto_acquisition_enabled'] = data.auto_acquisition_enabled
  174. params['auto_acquisition_amount'] = data.auto_acquisition_amount
  175. params['optimization_goal'] = data.optimization_goal
  176. params['optimization_goal_name'] = data.optimization_goal_name
  177. params['forward_link_assist_enabled'] = data.forward_link_assist_enabled
  178. params['forward_link_assist'] = data.forward_link_assist_enabled == 1 ? data.forward_link_assist : ''
  179. params['bid_strategy'] = data.bid_strategy
  180. params['deep_optimize_type'] = data.deep_optimize_type
  181. params['deep_conversion_type'] = data.deep_conversion_type
  182. params['deep_conversion_behavior_spec'] = data.deep_conversion_behavior_spec
  183. params['deep_conversion_worth_spec'] = data.deep_conversion_worth_spec
  184. params['deep_bid_site'] = data.deep_bid_site
  185. params['deep_bid_site_details'] = data.deep_bid_site_details
  186. params['deep_roi_site'] = data.deep_roi_site
  187. params['deep_roi_site_details'] = data.deep_roi_site_details
  188. } else {
  189. params['bid_scene'] = 'BID_SCENE_UNKNOWN'
  190. }
  191. // console.log('params', params)
  192. // 预存时 - 报错
  193. if (params.automatic_site == '2' && (params.site_ids == '' || !params.site_ids)) {
  194. ElMessage.error('请选择广告版位')
  195. return
  196. }
  197. if (params.begin_date == '' || !params.begin_date) {
  198. ElMessage.error('请选择投放开始日期')
  199. return
  200. }
  201. if(new Date(params.begin_date).getTime() < new Date(getDay(0,false) as string).getTime()) {
  202. ElMessage.error('开始投放日期应该不小于今日!')
  203. return
  204. }
  205. if (params.date_model == '2') {
  206. if((params.end_date == '' || !params.end_date)){
  207. ElMessage.error('请选择投放结束日期')
  208. return
  209. }
  210. if(new Date(params.begin_date).getTime() > new Date(params.end_date).getTime()) {
  211. ElMessage.error('结束投放日期应不小于开始投放日期!')
  212. return
  213. }
  214. }
  215. if (params.time_series_type == '2' && time_series_writ.length == 0) {
  216. ElMessage.error('请选择投放时段')
  217. return
  218. }
  219. if(params.first_day_begin_time && params.first_day_begin_time != ''){
  220. let daysOfWeek = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
  221. let time_series = _.cloneDeep(params.time_series)?.split(',')
  222. for(let i = 0; i < time_series.length; i++){
  223. time_series[i] = time_series[i].split('')
  224. }
  225. let hour = _.cloneDeep(params.first_day_begin_time).split(':')[0]
  226. let week = dayOfWeek(params.begin_date)
  227. if( time_series[week == 0 ? 6 : (week - 1)][Number(hour) * 2] != 1) {
  228. ElMessage.error(`当前投放开始日期为:${params.begin_date},${daysOfWeek[week]}, 投放时间段中应包含${daysOfWeek[week]}的${params.first_day_begin_time.slice(0,5)}`)
  229. return
  230. }
  231. }
  232. if (data.daily_budget_radio == '2') {
  233. if (!inspectNumber(params.daily_budget, '日预算', 50, 20000000)) return
  234. }
  235. if (params.bid_mode == 'BID_MODE_OCPM' || params.bid_mode == 'BID_MODE_OCPC') { // bid_mode为oCPM 或者oCPC
  236. if (!params.optimization_goal || params.optimization_goal == '') {
  237. ElMessage.error('请选择优化目标')
  238. return
  239. }
  240. if (params.forward_link_assist_enabled == 1 && (!params.forward_link_assist || params.forward_link_assist == '')) {
  241. ElMessage.error('请选择助攻行为')
  242. return
  243. }
  244. if (params.deep_optimize_type != 0) {
  245. let obj = '';
  246. let name = ''
  247. if (params.deep_conversion_type == 'DEEP_CONVERSION_BEHAVIOR') {
  248. obj = params.deep_conversion_behavior_spec
  249. name = '深度优化出价'
  250. } else {
  251. obj = params.deep_conversion_worth_spec
  252. name = '期望ROI'
  253. }
  254. if (!obj || obj == '' || JSON.parse(obj).target == '') {
  255. ElMessage.error('请选择深度优化目标')
  256. return
  257. }
  258. if (obj && obj != '') {
  259. let objInfo = JSON.parse(obj)
  260. if (params.bid_way == '1') {
  261. if (!inspectNumber(params.deep_conversion_type == 'DEEP_CONVERSION_BEHAVIOR' ? objInfo.price : objInfo.roi, name, 0.01, 20000000)) return
  262. }
  263. if (params.bid_way != '1') {
  264. if (!inspectMaxMin(`${objInfo.min}-${objInfo.max}`, `${name}范围`)) return
  265. }
  266. }
  267. }
  268. if (data.auto_acquisition_enabled == 1) {
  269. if (!inspectNumber(params.auto_acquisition_amount, '起量预算')) return
  270. }
  271. }
  272. if (params.bid_way == '1') {
  273. if (params.bid_mode == 'BID_MODE_OCPM' || params.bid_mode == 'BID_MODE_OCPC') {
  274. if (!inspectNumber(params.bid_amount, '出价', 0.01, 5000)) return
  275. }
  276. if (params.bid_mode == 'BID_MODE_CPA') {
  277. if (!inspectNumber(params.bid_amount, '出价', 1, 500)) return
  278. }
  279. if (params.bid_mode == 'BID_MODE_CPM') {
  280. if (!inspectNumber(params.bid_amount, '出价', 1.5, 999)) return
  281. }
  282. if (params.bid_mode == 'BID_MODE_CPC') {
  283. if (!inspectNumber(params.bid_amount, '出价', 0.1, 100)) return
  284. }
  285. }
  286. if (params.bid_way != '1') {
  287. if (!inspectMaxMin(params.bid_range, '出价范围')) return;
  288. }
  289. } else {
  290. params = data
  291. }
  292. if (type == 'api') { // 从后端获取数据回显时,把number变为string
  293. for (let i in params) {
  294. let typesOf = typeof params[i]
  295. if (typesOf == 'number') {
  296. params[i] = String(params[i])
  297. }
  298. }
  299. }
  300. //对应展示文案
  301. copywriting.push(`广告形式:${basicInfoJson['广告形式']['ad_form'].data.list.filter((v) => { return v.value == data.ad_form })[0]?.label}`)
  302. copywriting.push(`转化归因:${basicInfoJson['目标详情']['attribution_type'].data.list.filter((v) => { return v.value == data.attribution_type })[0]?.label}`)
  303. if (data.automatic_site == '1') {
  304. site_ids = ['自动版位']
  305. } else {
  306. site_ids = []
  307. data.site_ids.split(',').forEach((item, index) => {
  308. site_ids.push(specificPosition[item].label)
  309. })
  310. }
  311. copywriting.push(`广告版位:${site_ids.join(',')}`)
  312. if ((updateScene['search_scene_expand'] || type == 'api') && data.search_scene_expand == 1 && data.search_expand_targeting_switch == 'SEARCH_EXPAND_TARGETING_SWITCH_OPEN') {
  313. copywriting.push(`搜索场景扩展 - 定向拓展:开启`)
  314. }
  315. if (updateScene['display_scene'] || (type == 'api' && data.display_scene)) {
  316. let arr = data.display_scene == '' ? [] : data.display_scene.split(',').map((item) => {
  317. return scene['display_scene'].data.list.filter((v) => {
  318. return v.value == item
  319. })[0]?.label
  320. })
  321. copywriting.push(`优量汇广告展示场景:${arr.length > 0 ? arr.join(',') : '不限'}`)
  322. }
  323. copywriting.push(`行为兴趣系统优选:${basicInfoJson['定向扩展']['auto_audience'].data.list.filter((v) => { return v.value == data.auto_audience })[0]?.label}`)
  324. copywriting.push(`排除优化目标用户:${basicInfoJson['定向扩展']['excluded_converted_audience'].data.list.filter((v) => { return v.value == data.excluded_converted_audience })[0]?.label}`)
  325. // copywriting.push(`自动扩量:${basicInfoJson['定向扩展']['expand_enabled'].data.list.filter((v) => { return v.value == data.expand_enabled })[0]?.label}`)
  326. copywriting.push(`智能定向:${basicInfoJson['定向扩展']['smart_targeting_switch'].data.list.filter((v) => { return v.value == data.smart_targeting_switch })[0]?.label}`)
  327. copywriting.push(`微信再营销:${data.wechat_ad_behaviors == '' || ((!data.wechat_ad_behavior_actions || data.wechat_ad_behavior_actions == '') && (!data.wechat_ad_behavior_excluded_actions || data.wechat_ad_behavior_excluded_actions == '')) ? '关闭' : '开启'}`)
  328. copywriting.push(`投放日期:${data.date_model == '1' ? `长期投放(开始日期:${data.begin_date})` : `指定日期(开始日期:${data.begin_date} - 结束日期:${data.end_date})`}`)
  329. copywriting.push(`投放时段:${data.time_series_type == '1' ? `不限` : ''}`)
  330. if (data.time_series_type == '2' && time_series_writ.length != 0) {
  331. time_series_writ.forEach((v, idx) => {
  332. copywriting.push(`${switchEvent(idx)}:${v.map((item: { startTime: string, endTime: string }) => `${item.startTime}~${item.endTime}`)?.join('、')}`)
  333. })
  334. }
  335. if (data.first_day_begin_time != '' && data.first_day_begin_time) {
  336. copywriting.push(`投放首日开始时间:${data.first_day_begin_time}`)
  337. }
  338. copywriting.push(`日预算:${data.daily_budget_radio == '1' ? '不限' : `${params.daily_budget}元`}`)
  339. copywriting.push(`出价方式:${scheduleBid.bid_mode.data.otherList.one.filter((v: any) => { return v.value == data.bid_mode })[0]?.label}`)
  340. let bid_scene_writ = ''
  341. if (params.bid_scene == 'BID_SCENE_UNKNOWN') {
  342. bid_scene_writ = '关闭'
  343. } else if (params.bid_scene == 'BID_SCENE_NORMAL_MAX') {
  344. bid_scene_writ = '最大转化量投放'
  345. } else if (params.bid_scene == 'BID_SCENE_NORMAL_TARGET') {
  346. bid_scene_writ = '常规投放-放量投放'
  347. } else if (params.bid_scene == 'BID_SCENE_NORMAL_AVERAGE') {
  348. bid_scene_writ = '常规投放-稳定投放'
  349. }
  350. copywriting.push(`投放场景:${bid_scene_writ}`)
  351. if (data.bid_scene == 'BID_SCENE_UNKNOWN') {
  352. copywriting.push(`出价类型:${scheduleBid.smart_bid_type.data.list.filter((v: any) => { return v.value == data.smart_bid_type })[0]?.label}`)
  353. }
  354. if (data.bid_mode == 'BID_MODE_OCPM' || data.bid_mode == 'BID_MODE_OCPC') {
  355. copywriting.push(`优化目标:${data.optimization_goal_name}`)
  356. if (data.forward_link_assist_enabled == 1) {
  357. // copywriting.push(`助攻行为:${optimizationGoal_1.filter((v: any) => { return v.value == data.forward_link_assist })[0]?.label}`)
  358. }
  359. copywriting.push(`出价策略:${scheduleBid.bid_strategy.data.list.filter((v: any) => { return v.value == data.bid_strategy })[0]?.label}`)
  360. copywriting.push(`深度转化优化:${scheduleBid.deep_optimize_type.data.list.filter((v: any) => { return v.value == data.deep_optimize_type })[0]?.label}`)
  361. if (data.deep_optimize_type != 0) {
  362. copywriting.push(`深度转化类型:${scheduleBid.deep_conversion_type.data.list.filter((v: any) => { return v.value == data.deep_conversion_type })[0]?.label}`)
  363. if (data.deep_conversion_type == 'DEEP_CONVERSION_BEHAVIOR' && data.deep_conversion_behavior_spec && data.deep_conversion_behavior_spec != '') {
  364. let obj = JSON.parse(data.deep_conversion_behavior_spec)
  365. // copywriting.push(`深度优化目标:${optimizationGoal_2.filter((v: any) => { return v.value == obj.target })[0]?.label}`)
  366. if (data.bid_way == '1') {
  367. copywriting.push(`深度优化出价:${obj.price}元`)
  368. } else {
  369. copywriting.push(`深度优化出价范围:${obj.min}元-${obj.max}元`)
  370. }
  371. }
  372. if (data.deep_conversion_type == 'DEEP_CONVERSION_WORTH' && data.deep_conversion_worth_spec && data.deep_conversion_worth_spec != '') {
  373. let obj = JSON.parse(data.deep_conversion_worth_spec)
  374. // copywriting.push(`深度优化目标:${optimizationGoal_2.filter((v: any) => { return v.value == obj.target })[0]?.label}`)
  375. if (data.bid_way == '1') {
  376. copywriting.push(`期望ROI:${obj.roi}元`)
  377. } else {
  378. copywriting.push(`期望ROI范围:${obj.min}元-${obj.max}元`)
  379. }
  380. }
  381. }
  382. copywriting.push(`一键起量:${scheduleBid.auto_acquisition_enabled.data.list.filter((v: any) => { return v.value == data.auto_acquisition_enabled })[0]?.label}`)
  383. if (data.auto_acquisition_enabled == 1) {
  384. copywriting.push(`起量预算:${data.auto_acquisition_amount}元`)
  385. }
  386. }
  387. if (data.smart_bid_type == 'SMART_BID_TYPE_CUSTOM') {//手动出价
  388. if (data.bid_way == '1') {
  389. copywriting.push(`出价:${params.bid_amount}元`)
  390. } else {
  391. let arr = data.bid_range && data.bid_range.split('-') || []
  392. let bid_range_min = ''
  393. let bid_range_max = ''
  394. if (arr.length > 0) bid_range_min = arr[0]
  395. if (arr.length > 1) bid_range_max = arr[1]
  396. copywriting.push(`出价范围:${bid_range_min}元-${bid_range_max}元`)
  397. }
  398. }
  399. copywriting.push(`一方数据跑量加强:${data.ecom_pkam_switch == '1' ? '开启' : '关闭'}`)
  400. copywriting.push(`广告名称:${data.ad_name}`)
  401. copywriting.push(`动态标号起始值:${data.dynamic_num}`)
  402. }
  403. cb ? cb({ 'copywriting': copywriting, 'params': params }) : ''
  404. }