fix(admin): 自动记录政策发布人 (bug #24051)
| | |
| | | </script> |
| | | <template> |
| | | <div class="policy-edit-page" v-loading="loading"><section class="news-meta-panel"><h3>发布信息</h3><div class="news-meta-grid"><div><span>发布时间</span><strong>{{ createdAt }}</strong></div><div><span>修改时间</span><strong>{{ updatedAt }}</strong></div></div></section><section class="policy-publish-panel"><h3>政策内容</h3><el-form class="policy-publish-form" :model="form" label-width="88px"> |
| | | <el-form-item label="政策标题"><el-input v-model="form.title" /></el-form-item><el-form-item label="政策摘要"><el-input v-model="form.subtitle" /></el-form-item><el-form-item label="发布人"><el-input v-model="form.author" /></el-form-item><el-form-item label="发布来源"><el-input v-model="form.source" /></el-form-item><el-form-item label="政策详情"><el-input v-model="form.content" type="textarea" :rows="10" /></el-form-item><el-form-item label="封面图 URL"><el-input v-model="form.coverUrl" /></el-form-item><el-form-item label="排序值"><el-input-number v-model="form.sortNo" :min="0" :max="9999" /></el-form-item><el-form-item><el-button type="primary" @click="save">保存</el-button></el-form-item> |
| | | <el-form-item label="政策标题"><el-input v-model="form.title" /></el-form-item><el-form-item label="政策摘要"><el-input v-model="form.subtitle" /></el-form-item><el-form-item label="政策详情"><el-input v-model="form.content" type="textarea" :rows="10" /></el-form-item><el-form-item label="封面图 URL"><el-input v-model="form.coverUrl" /></el-form-item><el-form-item label="排序值"><el-input-number v-model="form.sortNo" :min="0" :max="9999" /></el-form-item><el-form-item><el-button type="primary" @click="save">保存</el-button></el-form-item> |
| | | </el-form></section></div> |
| | | </template> |
| | |
| | | <div class="policy-publish-page"><section class="policy-publish-panel"><h3>政策内容</h3><el-form class="policy-publish-form" :model="form" label-width="88px"> |
| | | <el-form-item label="政策标题"><el-input v-model="form.title" placeholder="请输入政策标题" /></el-form-item> |
| | | <el-form-item label="政策摘要"><el-input v-model="form.subtitle" placeholder="用于小程序列表展示" /></el-form-item> |
| | | <el-form-item label="发布人"><el-input v-model="form.author" /></el-form-item> |
| | | <el-form-item label="发布来源"><el-input v-model="form.source" /></el-form-item> |
| | | <el-form-item label="政策详情"><el-input v-model="form.content" type="textarea" :rows="10" /></el-form-item> |
| | | <el-form-item label="封面图 URL"><el-input v-model="form.coverUrl" placeholder="https://..." /></el-form-item> |
| | | <el-form-item label="排序值"><el-input-number v-model="form.sortNo" :min="0" :max="9999" /></el-form-item> |
| | |
| | | import java.util.Map; |
| | | |
| | | import com.talentcard.server.business.PageResult; |
| | | import com.talentcard.server.business.admin.auth.AdminAuthInterceptor; |
| | | import com.talentcard.server.common.ApiResponse; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.http.HttpStatus; |
| | |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.ResponseStatus; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | |
| | | @RestController |
| | | @RequestMapping("/api/admin/business") |
| | |
| | | |
| | | @PostMapping("/policies") |
| | | @ResponseStatus(HttpStatus.CREATED) |
| | | public ApiResponse<Map<String, Object>> createPolicy(@Valid @RequestBody PolicyArticleRequest request) { |
| | | return ApiResponse.success(adminBusinessService.createPolicy(request)); |
| | | public ApiResponse<Map<String, Object>> createPolicy(@Valid @RequestBody PolicyArticleRequest request, HttpServletRequest servletRequest) { |
| | | String operatorName = String.valueOf(servletRequest.getAttribute(AdminAuthInterceptor.OPERATOR_NAME_ATTRIBUTE)); |
| | | return ApiResponse.success(adminBusinessService.createPolicy(request, operatorName)); |
| | | } |
| | | |
| | | @PutMapping("/policies/{id}") |
| | |
| | | } |
| | | |
| | | @Transactional |
| | | public Map<String, Object> createPolicy(PolicyArticleRequest request) { |
| | | public Map<String, Object> createPolicy(PolicyArticleRequest request, String operatorName) { |
| | | int status = defaultNewsStatus(request.status()); |
| | | jdbcTemplate.update("insert into policy_article(policy_no, title, subtitle, cover_url, author, source, content, is_top, sort_no, publish_time, status) values (?, ?, ?, ?, ?, ?, ?, ?, ?, case when ? = 1 then now() else null end, ?)", |
| | | BusinessIdGenerator.next("POLICY"), request.title().trim(), blankToNull(request.subtitle()), blankToNull(request.coverUrl()), blankToNull(request.author()), blankToNull(request.source()), sanitizeNewsContent(request.content()), Boolean.TRUE.equals(request.isTop()) ? 1 : 0, request.sortNo() == null ? 0 : request.sortNo(), status, status); |
| | | BusinessIdGenerator.next("POLICY"), request.title().trim(), blankToNull(request.subtitle()), blankToNull(request.coverUrl()), blankToNull(operatorName), blankToNull(request.source()), sanitizeNewsContent(request.content()), Boolean.TRUE.equals(request.isTop()) ? 1 : 0, request.sortNo() == null ? 0 : request.sortNo(), status, status); |
| | | return policyDetail(jdbcTemplate.queryForObject("select last_insert_id()", Long.class)); |
| | | } |
| | | |
| | |
| | | @Component |
| | | public class AdminAuthInterceptor implements HandlerInterceptor { |
| | | public static final String OPERATOR_ID_ATTRIBUTE = "authenticatedAdminOperatorId"; |
| | | public static final String OPERATOR_NAME_ATTRIBUTE = "authenticatedAdminOperatorName"; |
| | | |
| | | private final AdminAuthService service; |
| | | |
| | |
| | | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { |
| | | Long operatorId = service.authenticate(request.getHeader(HttpHeaders.AUTHORIZATION)); |
| | | request.setAttribute(OPERATOR_ID_ATTRIBUTE, operatorId); |
| | | request.setAttribute(OPERATOR_NAME_ATTRIBUTE, service.operatorName(operatorId)); |
| | | return true; |
| | | } |
| | | } |
| | |
| | | return number(rows.get(0).get("operatorId")); |
| | | } |
| | | |
| | | @Transactional(readOnly = true) |
| | | public String operatorName(Long operatorId) { |
| | | List<Map<String, Object>> rows = rows("select display_name from admin_operator where id = ? and deleted = 0 limit 1", operatorId); |
| | | if (rows.isEmpty()) throw new BusinessException(ErrorCode.UNAUTHORIZED, "请先登录管理后台"); |
| | | String displayName = String.valueOf(rows.get(0).get("displayName")).trim(); |
| | | return displayName.isBlank() ? "管理员" : displayName; |
| | | } |
| | | |
| | | private Map<String, Object> issueSession(Map<String, Object> operator) { |
| | | String accessToken = token(); |
| | | LocalDateTime now = LocalDateTime.now(); |