assessment_form.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. package services
  2. import (
  3. "eta/eta_api/models"
  4. "eta/eta_api/models/system"
  5. "eta/eta_api/services/alarm_msg"
  6. "eta/eta_api/utils"
  7. "fmt"
  8. "math"
  9. "sync"
  10. "time"
  11. )
  12. // 填报单单号锁
  13. var (
  14. formCodeMutex sync.Mutex
  15. formCodeUnique sync.Map
  16. formCodeLastDate string
  17. )
  18. // GenerateAssessmentFormCode 生成单号
  19. func GenerateAssessmentFormCode() (formCode string, err error) {
  20. formCodeMutex.Lock()
  21. defer formCodeMutex.Unlock()
  22. currentDate := time.Now().Format("20060102")
  23. maxAttempts := 1000
  24. baseNumber := 1
  25. // 检查日期变化,清空map
  26. if formCodeLastDate != "" && formCodeLastDate != currentDate {
  27. formCodeUnique = sync.Map{}
  28. }
  29. formCodeLastDate = currentDate
  30. // 获取单号最大ID
  31. formOb := new(models.AssessmentForm)
  32. maxForm, e := formOb.GetItemByCondition(``, make([]interface{}, 0), fmt.Sprintf("%s DESC", formOb.Cols().PrimaryId))
  33. if e != nil && !utils.IsErrNoRow(e) {
  34. err = fmt.Errorf("获取最大单号失败, %v", e)
  35. return
  36. }
  37. if maxForm != nil && maxForm.AssessmentFormId > 0 {
  38. baseNumber = maxForm.AssessmentFormId + 1
  39. }
  40. // 尝试生成自增ID
  41. for i := 0; i < maxAttempts; i++ {
  42. serialNumber := fmt.Sprintf("%06d", baseNumber+i)
  43. uniqueCode := fmt.Sprintf("GDKH%s%s", currentDate, serialNumber)
  44. if _, loaded := formCodeUnique.LoadOrStore(uniqueCode, true); loaded {
  45. continue
  46. }
  47. // 检查单号是否已存在
  48. cond := fmt.Sprintf(` AND %s = ?`, formOb.Cols().FormCode)
  49. pars := make([]interface{}, 0)
  50. pars = append(pars, uniqueCode)
  51. exists, e := formOb.GetCountByCondition(cond, pars)
  52. if e != nil {
  53. formCodeUnique.Delete(uniqueCode)
  54. err = fmt.Errorf("检查单号是否存在失败, %v", e)
  55. return
  56. }
  57. if exists <= 0 {
  58. formCode = uniqueCode
  59. return
  60. }
  61. }
  62. err = fmt.Errorf("生成单号失败, 尝试次数超过%d次", maxAttempts)
  63. return
  64. }
  65. // GetAssessmentWeekAndFriday 获取给定日期的周数,以及所在周的周五
  66. // 规则:某年的第一个周五所在周为该年的第一周
  67. // 返回:格式化字符串(如"202504")、周数(如4)和所在周的周五日期
  68. func GetAssessmentWeekAndFriday(t time.Time) (string, int, time.Time) {
  69. year := t.Year()
  70. // 找到该年第一个周五的日期
  71. firstFriday := findFirstFriday(year)
  72. // 计算当前日期与该年第一个周五所在周的第一天(周一)的天数差
  73. daysSinceFirstWeek := t.YearDay() - firstFriday.YearDay() + int(firstFriday.Weekday()) - int(time.Monday)
  74. weekNum := 1
  75. if daysSinceFirstWeek > 0 {
  76. weekNum += daysSinceFirstWeek / 7
  77. if daysSinceFirstWeek%7 != 0 {
  78. weekNum++
  79. }
  80. } else {
  81. // 如果当前日期在第一个周五所在周之前,则属于上一年的最后一周
  82. prevYear := year - 1
  83. prevFirstFriday := findFirstFriday(prevYear)
  84. daysInPrevYear := daysInYear(prevYear)
  85. daysSincePrevFirstWeek := t.YearDay() + (daysInPrevYear - prevFirstFriday.YearDay()) + int(prevFirstFriday.Weekday()) - int(time.Monday)
  86. weekNum = daysSincePrevFirstWeek / 7
  87. if daysSincePrevFirstWeek%7 != 0 {
  88. weekNum++
  89. }
  90. year = prevYear
  91. }
  92. // 计算当前日期所在周的周五
  93. currentWeekFriday := findFridayOfWeek(t)
  94. // 格式化输出
  95. formatted := fmt.Sprintf("%04d%02d", year, weekNum)
  96. return formatted, weekNum, currentWeekFriday
  97. }
  98. // findFirstFriday 找到某年的第一个周五
  99. func findFirstFriday(year int) time.Time {
  100. // 从1月1日开始找
  101. date := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)
  102. // 找到第一个周五
  103. for date.Weekday() != time.Friday {
  104. date = date.AddDate(0, 0, 1)
  105. }
  106. return date
  107. }
  108. // findFridayOfWeek 找到给定日期所在周的周五
  109. func findFridayOfWeek(t time.Time) time.Time {
  110. // 获取当前日期是周几 (0=周日, 1=周一, ..., 6=周六)
  111. weekday := int(t.Weekday())
  112. // 计算到周五的天数差 (周五是5)
  113. daysToFriday := (5 - weekday + 7) % 7
  114. // 如果当前就是周五,daysToFriday会是0
  115. if daysToFriday < 0 {
  116. daysToFriday += 7
  117. }
  118. return t.AddDate(0, 0, daysToFriday)
  119. }
  120. // daysInYear 计算某年有多少天
  121. func daysInYear(year int) int {
  122. first := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)
  123. last := time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
  124. return last.YearDay() - first.YearDay() + 1
  125. }
  126. // CheckAssessmentFormButton 校验填报单按钮
  127. func CheckAssessmentFormButton(item *models.AssessmentForm, sysAdminId int, authResearcherIds []int) (button models.AssessmentFormButton) {
  128. if item == nil || sysAdminId <= 0 {
  129. return
  130. }
  131. // 已提交状态
  132. if item.Status == models.AssessmentFormStatusSubmitted {
  133. if sysAdminId == item.ResearcherAdminId || utils.InArrayByInt(authResearcherIds, item.ResearcherId) {
  134. button.ViewButton = true
  135. }
  136. // 本周结束前可撤销(TODO:这里象屿会有一个外部条件:当周周报未提交,暂不处理视作true)
  137. if sysAdminId == item.ResearcherAdminId && !item.WeekEnd.IsZero() && time.Now().Local().Before(item.WeekEnd) {
  138. button.CancelButton = true
  139. }
  140. }
  141. // 待提交状态(仅自己有操作按钮)
  142. if item.Status == models.AssessmentFormStatusDraft && sysAdminId == item.ResearcherAdminId {
  143. button.EditButton = true
  144. button.RemoveButton = true
  145. // 本周结束前可提交
  146. if !item.WeekEnd.IsZero() && time.Now().Local().Before(item.WeekEnd) {
  147. button.SubmitButton = true
  148. }
  149. }
  150. return
  151. }
  152. // GetVarietyPriceAndForecastComment 获取品种价格详情及观点评价
  153. func GetVarietyPriceAndForecastComment(forms []*models.AssessmentForm) (varietyPrice []*models.AssessmentFormVarietyPrice, forecastComment []*models.AssessmentFormForecastComment, err error) {
  154. if len(forms) == 0 {
  155. return
  156. }
  157. baseDate := forms[0].BaseDate
  158. var varietyIds []int
  159. for _, v := range forms {
  160. varietyIds = append(varietyIds, v.VarietyId)
  161. }
  162. if len(varietyIds) == 0 || baseDate.IsZero() {
  163. return
  164. }
  165. // 获取品种信息
  166. varietyOb := new(models.AssessmentVariety)
  167. varietyMatch := make(map[int]*models.AssessmentVariety)
  168. {
  169. cond := fmt.Sprintf(` AND %s IN (?)`, varietyOb.Cols().PrimaryId)
  170. pars := make([]interface{}, 0)
  171. pars = append(pars, varietyIds)
  172. list, e := varietyOb.GetItemsByCondition(cond, pars, []string{}, "")
  173. if e != nil {
  174. err = fmt.Errorf("获取品种信息失败, %v", e)
  175. return
  176. }
  177. for _, v := range list {
  178. varietyMatch[v.AssessmentVarietyId] = v
  179. }
  180. }
  181. varietyLatestData := make(map[int]*models.AssessmentVarietyData)
  182. varietyBaseDateData := make(map[int]*models.AssessmentVarietyData)
  183. varietyNextWeekData := make(map[int]*models.AssessmentVarietyData)
  184. varietyNextMonthData := make(map[int]*models.AssessmentVarietyData)
  185. // 获取最新日期和数据
  186. dataOb := new(models.AssessmentVarietyData)
  187. latestData, e := dataOb.GetVarietyMaxDateData(varietyIds)
  188. if e != nil {
  189. err = fmt.Errorf("获取品种最新数据失败, %v", e)
  190. return
  191. }
  192. for _, v := range latestData {
  193. varietyLatestData[v.VarietyId] = v
  194. }
  195. // 获取基准日期N至N+4周的数据
  196. var dateArr []string
  197. nextWeek := baseDate.AddDate(0, 0, 7)
  198. nextMonth := baseDate.AddDate(0, 0, 28)
  199. dateArr = append(dateArr, baseDate.Format(utils.FormatDate), nextWeek.Format(utils.FormatDate), nextMonth.Format(utils.FormatDate))
  200. {
  201. cond := fmt.Sprintf(` AND %s IN (?) AND %s IN (?)`, dataOb.Cols().VarietyId, dataOb.Cols().WeekDate)
  202. pars := make([]interface{}, 0)
  203. pars = append(pars, varietyIds, dateArr)
  204. list, e := dataOb.GetItemsByCondition(cond, pars, []string{}, "")
  205. if e != nil {
  206. err = fmt.Errorf("获取基准日至N+4周数据失败, %v", e)
  207. return
  208. }
  209. for _, v := range list {
  210. if varietyMatch[v.VarietyId] == nil {
  211. continue
  212. }
  213. if baseDate.Equal(v.WeekDate) {
  214. varietyBaseDateData[v.VarietyId] = v
  215. continue
  216. }
  217. if baseDate.AddDate(0, 0, 7).Equal(v.WeekDate) {
  218. varietyNextWeekData[v.VarietyId] = v
  219. continue
  220. }
  221. if baseDate.AddDate(0, 0, 28).Equal(v.WeekDate) {
  222. varietyNextMonthData[v.VarietyId] = v
  223. continue
  224. }
  225. }
  226. }
  227. varietyPrice = make([]*models.AssessmentFormVarietyPrice, 0)
  228. forecastComment = make([]*models.AssessmentFormForecastComment, 0)
  229. for _, v := range forms {
  230. vat := varietyMatch[v.VarietyId]
  231. if vat == nil {
  232. utils.FileLog.Info(fmt.Sprintf("GetVarietyPriceAndForecastComment, 品种不存在: %d", v.VarietyId))
  233. continue
  234. }
  235. // 品种价格评价
  236. vp := new(models.AssessmentFormVarietyPrice)
  237. vp.VarietyId = v.VarietyId
  238. vp.VarietyCode = v.VarietyCode
  239. vp.VarietyName = v.VarietyName
  240. if varietyLatestData[v.VarietyId] != nil {
  241. vp.EndDate = varietyLatestData[v.VarietyId].WeekDate.Format(utils.FormatDate)
  242. vp.LatestValue = fmt.Sprint(varietyLatestData[v.VarietyId].CloseValue)
  243. }
  244. var (
  245. baseDataPrice *float64
  246. nextMonthPrice *float64
  247. nextWeekHighPrice *float64
  248. nextWeekLowPrice *float64
  249. )
  250. if varietyBaseDateData[v.VarietyId] != nil {
  251. baseDataPrice = &varietyBaseDateData[v.VarietyId].CloseValue
  252. vp.BaseDatePrice = fmt.Sprint(varietyBaseDateData[v.VarietyId].CloseValue)
  253. }
  254. if varietyNextWeekData[v.VarietyId] != nil {
  255. nextWeekHighPrice = &varietyNextWeekData[v.VarietyId].HighValue
  256. nextWeekLowPrice = &varietyNextWeekData[v.VarietyId].LowValue
  257. vp.NextWeekPrice = fmt.Sprint(varietyNextWeekData[v.VarietyId].CloseValue)
  258. }
  259. if varietyNextMonthData[v.VarietyId] != nil {
  260. nextMonthPrice = &varietyNextMonthData[v.VarietyId].CloseValue
  261. vp.NextMonthPrice = fmt.Sprint(varietyNextMonthData[v.VarietyId].CloseValue)
  262. }
  263. varietyPrice = append(varietyPrice, vp)
  264. // 观点评价
  265. fc := new(models.AssessmentFormForecastComment)
  266. fc.VarietyId = v.VarietyId
  267. fc.VarietyCode = v.VarietyCode
  268. fc.VarietyName = v.VarietyName
  269. fc.WeekTime = v.WeekTime
  270. if !v.SubmitTime.IsZero() {
  271. fc.SubmitTime = v.SubmitTime.Format(utils.FormatDateUnSpace)
  272. }
  273. // 月度涨跌评价
  274. if baseDataPrice != nil && nextMonthPrice != nil {
  275. _, tips, right := calculateMonthlyPriceTrend(*baseDataPrice, *nextMonthPrice, vat.MonthlyFluctuate, v.MonthlyPriceForecast)
  276. fc.MonthlyPriceComment = tips
  277. fc.MonthlyPriceForecastRight = right
  278. }
  279. // 周度上下行风险
  280. if baseDataPrice != nil && nextWeekHighPrice != nil {
  281. _, tips, right := calculateWeekUpDownTrend(*baseDataPrice, *nextWeekHighPrice, vat.WeeklyFluctuate, v.WeeklyUpForecast, true)
  282. fc.WeeklyUpComment = tips
  283. fc.WeeklyUpForecastRight = right
  284. }
  285. if baseDataPrice != nil && nextWeekLowPrice != nil {
  286. _, tips, right := calculateWeekUpDownTrend(*baseDataPrice, *nextWeekLowPrice, vat.WeeklyFluctuate, v.WeeklyUpForecast, false)
  287. fc.WeeklyDownComment = tips
  288. fc.WeeklyDownForecastRight = right
  289. }
  290. forecastComment = append(forecastComment, fc)
  291. }
  292. return
  293. }
  294. // calculateMonthly 判断月度涨跌趋势
  295. func calculateMonthlyPriceTrend(basePrice, monthPrice, monthlyFluctuate float64, forecast string) (result, tips string, right bool) {
  296. if basePrice <= 0 || monthPrice <= 0 || monthlyFluctuate <= 0 {
  297. return
  298. }
  299. // 计算月度价格变化比例:月度价格/当周价格-1
  300. percent := (monthPrice/basePrice - 1) * 100
  301. // 判断价格趋势
  302. switch {
  303. case percent > monthlyFluctuate:
  304. result = models.AssessmentFormMonthlyPriceUp
  305. case percent < -monthlyFluctuate:
  306. result = models.AssessmentFormMonthlyPriceDown
  307. default:
  308. result = models.AssessmentFormMonthlyPriceShake
  309. }
  310. // 如果有进行预测,判断是否正确,返回提示语句
  311. if forecast == "" {
  312. return
  313. }
  314. tips = fmt.Sprintf("判断 %s,实际 %s", forecast, result)
  315. if forecast == result {
  316. right = true
  317. }
  318. return
  319. }
  320. // calculateWeekUpDownTrend 判断周度上下行风险
  321. func calculateWeekUpDownTrend(basePrice, weekPrice, weekFluctuate float64, forecast string, calculateUp bool) (result, tips string, right bool) {
  322. if basePrice <= 0 || weekPrice <= 0 || weekFluctuate <= 0 {
  323. return
  324. }
  325. percent := (weekPrice/basePrice - 1) * 100
  326. // 上下行
  327. result = models.AssessmentFormWeekUpNo
  328. if calculateUp {
  329. if percent > weekFluctuate {
  330. result = models.AssessmentFormWeekUpYes
  331. }
  332. } else {
  333. if percent < -weekFluctuate {
  334. result = models.AssessmentFormWeekUpYes
  335. }
  336. }
  337. // 如果有进行预测,判断是否正确,返回提示语句
  338. if forecast == "" {
  339. return
  340. }
  341. if forecast == result {
  342. right = true
  343. }
  344. forecastMap := map[string]string{models.AssessmentFormWeekUpYes: "提示风险", models.AssessmentFormWeekUpNo: "未提示风险"}
  345. resultMap := map[string]string{models.AssessmentFormWeekUpYes: "风险发生", models.AssessmentFormWeekUpNo: "风险未发生"}
  346. tips = fmt.Sprint(forecastMap[forecast], " ", resultMap[result])
  347. return
  348. }
  349. // CalculateResultStatistic 计算正确率
  350. func CalculateResultStatistic(forms []*models.AssessmentForm, varietyData []*models.AssessmentVarietyData, results []*models.AssessmentFormResultStatisticItem) (resp []*models.AssessmentFormResultStatisticItem, err error) {
  351. if len(forms) == 0 {
  352. return
  353. }
  354. calculateMappingQ := make(map[string]int) // 月度趋势分子Q(即月度涨跌趋势判断正确的次数)
  355. calculateMappingP := make(map[string]int) // 月度趋势分母P(即月度涨跌趋势判断总次数)
  356. calculateMappingT := make(map[string]int) // 周度风险分子T(即周度上下行风险判断正确的次数)
  357. calculateMappingS := make(map[string]int) // 周度风险分母S(即周度上下行风险判断的总次数)
  358. // 品种数据
  359. varietyDateData := make(map[string]*models.AssessmentVarietyData)
  360. for _, v := range varietyData {
  361. k := fmt.Sprintf("%d-%s", v.VarietyId, v.WeekDate.Format(utils.FormatDate))
  362. varietyDateData[k] = v
  363. }
  364. // 获取品种信息
  365. varietyMatch := make(map[int]*models.AssessmentVariety)
  366. {
  367. varietyOb := new(models.AssessmentVariety)
  368. list, e := varietyOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
  369. if e != nil {
  370. err = fmt.Errorf("获取品种信息失败, %v", e)
  371. return
  372. }
  373. for _, v := range list {
  374. varietyMatch[v.AssessmentVarietyId] = v
  375. }
  376. }
  377. // 对填报单的[研究员ID-品种ID]进行QPTS的计数
  378. for _, v := range forms {
  379. vat := varietyMatch[v.VarietyId]
  380. if vat == nil {
  381. utils.FileLog.Info(fmt.Sprintf("CalculateResultStatistic, 品种不存在: %d", v.VarietyId))
  382. continue
  383. }
  384. key := fmt.Sprintf("%d-%d", v.ResearcherId, v.VarietyId)
  385. // 找出填报单品种对应的基准日期数据、N+1周的最高最低价格、N+4周的价格
  386. var (
  387. baseDataPrice *float64
  388. nextMonthPrice *float64
  389. nextWeekHighPrice *float64
  390. nextWeekLowPrice *float64
  391. )
  392. kb := fmt.Sprintf("%d-%s", v.VarietyId, v.BaseDate.Format(utils.FormatDate))
  393. if varietyDateData[kb] != nil {
  394. baseDataPrice = &varietyDateData[kb].CloseValue
  395. }
  396. kw := fmt.Sprintf("%d-%s", v.VarietyId, v.BaseDate.AddDate(0, 0, 7).Format(utils.FormatDate))
  397. if varietyDateData[kw] != nil {
  398. nextWeekHighPrice = &varietyDateData[kw].HighValue
  399. nextWeekLowPrice = &varietyDateData[kw].LowValue
  400. }
  401. km := fmt.Sprintf("%d-%s", v.VarietyId, v.BaseDate.AddDate(0, 0, 28).Format(utils.FormatDate))
  402. if varietyDateData[km] != nil {
  403. nextMonthPrice = &varietyDateData[km].CloseValue
  404. }
  405. // 月度涨跌评价
  406. if baseDataPrice != nil && nextMonthPrice != nil {
  407. _, _, right := calculateMonthlyPriceTrend(*baseDataPrice, *nextMonthPrice, vat.MonthlyFluctuate, v.MonthlyPriceForecast)
  408. calculateMappingP[key] += 1
  409. if right {
  410. calculateMappingQ[key] += 1
  411. }
  412. }
  413. // 周度上下行风险
  414. if baseDataPrice != nil && nextWeekHighPrice != nil {
  415. _, _, right := calculateWeekUpDownTrend(*baseDataPrice, *nextWeekHighPrice, vat.WeeklyFluctuate, v.WeeklyUpForecast, true)
  416. calculateMappingS[key] += 1
  417. if right {
  418. calculateMappingT[key] += 1
  419. }
  420. }
  421. if baseDataPrice != nil && nextWeekLowPrice != nil {
  422. _, _, right := calculateWeekUpDownTrend(*baseDataPrice, *nextWeekLowPrice, vat.WeeklyFluctuate, v.WeeklyUpForecast, false)
  423. calculateMappingS[key] += 1
  424. if right {
  425. calculateMappingT[key] += 1
  426. }
  427. }
  428. }
  429. // 计算正确率,结果取整
  430. for _, v := range results {
  431. k := fmt.Sprintf("%d-%d", v.ResearcherId, v.VarietyId)
  432. // 月趋势正确率:Q/P
  433. q := calculateMappingQ[k]
  434. p := calculateMappingP[k]
  435. if p > 0 {
  436. v.MonthlyTrendAccuracy = math.Round(float64(q) / float64(p) * 100)
  437. }
  438. // 周度预警正确率:T/S
  439. t := calculateMappingT[k]
  440. s := calculateMappingS[k]
  441. if s > 0 {
  442. v.WeeklyWarningAccuracy = math.Round(float64(t) / float64(s) * 100)
  443. }
  444. // 综合正确率1:(Q+2T)/(P+2S)
  445. a := q + 2*t
  446. b := p + 2*s
  447. if b > 0 {
  448. v.TotalAccuracyA = math.Round(float64(a) / float64(b) * 100)
  449. }
  450. // 综合正确率2:Q/2P+T/2S
  451. var c, d float64
  452. if p > 0 {
  453. c = math.Round(float64(q) / float64(2*p) * 100)
  454. }
  455. if s > 0 {
  456. d = math.Round(float64(t) / float64(2*s) * 100)
  457. }
  458. v.TotalAccuracyB = c + d
  459. }
  460. resp = results
  461. return
  462. }
  463. // SyncAssessmentResearcher 同步更新研究员表冗余字段
  464. func SyncAssessmentResearcher(adminId int) (err error) {
  465. defer func() {
  466. if err != nil {
  467. tips := fmt.Sprintf("SyncAssessmentResearcher, 同步研究员表姓名/状态失败: %v", err)
  468. utils.FileLog.Info(tips)
  469. alarm_msg.SendAlarmMsg(tips, 3)
  470. }
  471. }()
  472. // 查询是否有对应的研究员
  473. researcherOb := new(models.AssessmentResearcher)
  474. cond := fmt.Sprintf(` AND %s = ?`, researcherOb.Cols().AdminId)
  475. pars := make([]interface{}, 0)
  476. pars = append(pars, adminId)
  477. researcher, e := researcherOb.GetItemByCondition(cond, pars, "")
  478. if e != nil && !utils.IsErrNoRow(e) {
  479. err = fmt.Errorf("获取研究员失败, %v", e)
  480. return
  481. }
  482. if researcher == nil || researcher.AssessmentResearcherId <= 0 {
  483. return
  484. }
  485. // 只有研究员状态是启用状态时,才同步系统用户状态
  486. var updateEnabled bool
  487. if researcher.Enabled == models.AssessmentResearcherEnabled {
  488. updateEnabled = true
  489. }
  490. // 获取系统用户,如果不存在,那么禁用研究员
  491. adminItem, e := system.GetSysAdminById(adminId)
  492. if e != nil && !utils.IsErrNoRow(e) {
  493. err = fmt.Errorf("获取系统用户失败, %v", e)
  494. return
  495. }
  496. var updateCols []string
  497. var updateRealName bool
  498. if adminItem != nil && adminItem.AdminId > 0 {
  499. researcher.RealName = adminItem.RealName
  500. researcher.Enabled = adminItem.Enabled
  501. researcher.ModifyTime = time.Now().Local()
  502. updateCols = append(updateCols, researcherOb.Cols().RealName, researcherOb.Cols().ModifyTime)
  503. updateRealName = true
  504. } else {
  505. researcher.Enabled = models.AssessmentResearcherDisabled
  506. researcher.ModifyTime = time.Now().Local()
  507. updateCols = append(updateCols, researcherOb.Cols().ModifyTime)
  508. }
  509. if updateEnabled {
  510. updateCols = append(updateCols, researcherOb.Cols().Enabled)
  511. }
  512. if e = researcher.Update(updateCols); e != nil {
  513. err = fmt.Errorf("同步研究员失败, %v", e)
  514. return
  515. }
  516. // 更新填报单研究员姓名
  517. if !updateRealName {
  518. return
  519. }
  520. formOb := new(models.AssessmentForm)
  521. if e = formOb.UpdateResearcherName(researcher.AssessmentResearcherId, researcher.RealName); e != nil {
  522. err = fmt.Errorf("更新填报单研究员姓名失败, %v", e)
  523. return
  524. }
  525. return
  526. }