You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
10 KiB

9 months ago
  1. <template>
  2. <div class="common-layout">
  3. <el-container>
  4. <el-header class="header">
  5. <el-text class="header-text">抢点班作业后台管理</el-text>
  6. <el-button class="header-button" type="primary" text style="float: right;">退出登录</el-button>
  7. </el-header>
  8. <el-main class="main">
  9. <div class="main-title">
  10. <div class="main-title-text" style="float: left;">
  11. 新建作业
  12. </div>
  13. <div>
  14. <el-button class="main-button" @click="back">返回上一页</el-button>
  15. </div>
  16. </div>
  17. <div class="main-back">
  18. <el-form :model="form" label-width="auto" style="max-width: 700px" size="large">
  19. <el-form-item label="作业名称">
  20. <el-input v-model="form.Name" placeholder="请输入"></el-input>
  21. </el-form-item>
  22. <el-form-item label="提交时间" style="width: 70%">
  23. <el-date-picker v-model="form.picker" type="daterange" range-separator="" start-placeholder="开始日期"
  24. end-placeholder="结束日期" />
  25. </el-form-item>
  26. <el-form-item label="作业归属">
  27. <el-select v-model="form.ClubType" placeholder="请选择" style="width: 100%">
  28. <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item label="关联文章">
  32. <el-autocomplete v-model="articleTitle" :fetch-suggestions="queryArticleList" placeholder="请输入"
  33. @select="handleSelectArticle" />
  34. </el-form-item>
  35. <el-form-item label="关联直播">
  36. <el-select v-model="form.LiveId" placeholder="请选择" style="width: 100%">
  37. <el-option v-for="item in live" :key="item.id" :label="item.name" :value="item.id" />
  38. </el-select>
  39. </el-form-item>
  40. <el-form-item label="选择类型">
  41. <div>
  42. <el-button type="primary" @click="addSingleChoice">添加单选</el-button>
  43. <el-button type="primary" @click="addMultipleChoice">添加多选</el-button>
  44. <el-button type="primary" @click="addBlank">添加单选填空</el-button>
  45. </div>
  46. </el-form-item>
  47. <div class="question-container" v-for="(question, index) in questions" :key="index"
  48. :class="{ 'bg-change': isHovered[index] }" @mouseenter="handleMouseEnter(index)"
  49. @mouseleave="handleMouseLeave(index)">
  50. <div class="question-title">
  51. {{ questionPrefix(index) }} {{ getQuestionTypeText(question.type) }}
  52. </div>
  53. <div style="width: 600px;">
  54. <el-input v-model="question.description" />
  55. </div>
  56. <div class="add" v-if="question.type !== 'blank'">
  57. <div class="question-option">
  58. <span>设置选项:</span>
  59. <el-button type="primary" text @click="addOption(index)">添加</el-button>
  60. </div>
  61. <div v-for="(option, optionIndex) in question.content" :key="optionIndex">
  62. <div class="select" style="display: flex;">
  63. <div class="selection-item" style="display: flex;">
  64. <div style="width: 550px;">
  65. <el-input v-model="question.content[optionIndex].text" />
  66. </div>
  67. <div>
  68. <el-button type="primary" text @click="removeOption(index, optionIndex)">删除</el-button>
  69. </div>
  70. </div>
  71. </div>
  72. </div>
  73. <div class="delete" style="margin-left: 50px;">
  74. <el-button type="info" plain @click="removeQuestion(index)">删除</el-button>
  75. </div>
  76. </div>
  77. </div>
  78. <div class="submit">
  79. <el-button type="primary" :disabled="!form.Name||!form.picker" @click="onSubmit">确认</el-button>
  80. </div>
  81. </el-form>
  82. </div>
  83. </el-main>
  84. </el-container>
  85. </div>
  86. </template>
  87. <script lang="ts" setup>
  88. import { ref, onMounted, computed } from 'vue'
  89. import AddWorkApi from '../api/AddWorkApi';
  90. import _ from 'lodash';
  91. import dayjs from 'dayjs';
  92. const options = ref([
  93. { id: 1, name: '牧民俱乐部' },
  94. { id: 2, name: '博古论坛' },
  95. { id: 3, name: '神枪手俱乐部' },
  96. { id: 4, name: '环球俱乐部' },
  97. { id: 5, name: '价值投资' },
  98. { id: 6, name: '波段行情' },
  99. { id: 7, name: '抄底卖顶' },
  100. { id: 8, name: '资金及仓位管理' },
  101. { id: 9, name: '财富的游戏' },
  102. ]);
  103. // do not use same name with ref
  104. const form = ref({
  105. Name: '',
  106. ClubType: '',
  107. ArticleId: '',
  108. LiveId: '',
  109. picker: [],
  110. StartDate: '',
  111. EndDate: '',
  112. Questions: []
  113. });
  114. const articleTitle = ref('');
  115. // 问题列表数据
  116. const questions = ref([]);
  117. const onSubmit = () => {
  118. // 从picker中获取日期数据并进行格式转换
  119. if (form.value.picker && form.value.picker.length === 2) {
  120. const startDate = dayjs(form.value.picker[0]).format('YYYY-MM-DD HH:mm:00');
  121. const endDate = dayjs(form.value.picker[1]).format('YYYY-MM-DD HH:mm:00');
  122. form.value.StartDate = startDate;
  123. form.value.EndDate = endDate;
  124. }
  125. form.value.Questions = questions.value;
  126. AddWorkApi.addWork(form.value)
  127. console.log(questions.value+'--------------')
  128. }
  129. const back = () => {
  130. window.history.back()
  131. }
  132. // 存储根据文章输入内容查询到的关联文章结果列表
  133. const articleSearchResults = ref([]);
  134. // 根据文章输入内容查询关联文章的函数
  135. const queryArticleList = async (queryString: string) => {
  136. try {
  137. const response = await AddWorkApi.getArticleList(queryString);
  138. const formattedResults = response.data.map(article => ({
  139. value: article.title,
  140. label: article.id
  141. }));
  142. articleSearchResults.value = formattedResults;
  143. return formattedResults;
  144. } catch (error) {
  145. console.error('查询关联文章失败', error);
  146. return [];
  147. }
  148. };
  149. // 处理选择文章的函数
  150. const handleSelectArticle = (article: { label: string }) => {
  151. // 这里可以根据业务需求,比如将选中的文章id(article.label)传递给其他地方使用等
  152. console.log('选中的文章id', article.label);
  153. form.value.ArticleId = article.label; // 将选中文章的id赋值给对应表单字段,用于传递给后端
  154. const selectedArticle = articleSearchResults.value.find(a => a.label === article.label);
  155. if (selectedArticle) {
  156. articleTitle.value = selectedArticle.value; // 更新显示的文章题目
  157. }
  158. };
  159. //获取直播列表
  160. const live = ref([]);
  161. function getLive() {
  162. AddWorkApi.getLiveList()
  163. .then(res => {
  164. live.value = res.data;
  165. console.log(live.value);
  166. })
  167. .catch(error => {
  168. console.error('获取直播列表失败', error)
  169. })
  170. }
  171. getLive();
  172. // 根据类型获取对应的题目类型文本显示
  173. const getQuestionTypeText = (type) => {
  174. switch (type) {
  175. case 1:
  176. return '作业题目(单选)';
  177. case 2:
  178. return '作业题目(多选)';
  179. case 3:
  180. return '作业题目(简答题)';
  181. default:
  182. return '未知类型题目';
  183. }
  184. };
  185. // 从content字符串中解析出选项数组
  186. // const getOptionsFromContent = (content) => {
  187. // return JSON.parse(content);
  188. // };
  189. const addSingleChoice = () => {
  190. questions.value.push({
  191. type: 1, // 假设1代表单选,和后端格式对应起来
  192. description: '',
  193. content: [{ "id": "", "text": "" },{ "id": "", "text": "" }]
  194. });
  195. };
  196. const addMultipleChoice = () => {
  197. questions.value.push({
  198. type: 2, // 假设2代表多选,和后端格式对应起来
  199. description: '',
  200. content: [{ "id": "", "text": "" },{ "id": "", "text": "" }]
  201. });
  202. };
  203. const addBlank = () => {
  204. questions.value.push({
  205. type: 3, // 假设3代表简答题,和后端格式对应起来
  206. description: '',
  207. content: [{ "id": "", "text": "" }]
  208. });
  209. };
  210. const addOption = (questionIndex) => {
  211. const currentQuestion = questions.value[questionIndex];
  212. const currentContent = JSON.parse(currentQuestion.content);
  213. currentContent.push({ "id": "", "text": "" });
  214. currentQuestion.content = JSON.stringify(currentContent);
  215. };
  216. const removeOption = (questionIndex, optionIndex) => {
  217. const currentQuestion = questions.value[questionIndex];
  218. const currentContent = JSON.parse(currentQuestion.content);
  219. currentContent.splice(optionIndex, 1);
  220. currentQuestion.content = JSON.stringify(currentContent);
  221. };
  222. const removeQuestion = (questionIndex) => {
  223. questions.value.splice(questionIndex, 1);
  224. };
  225. // 计算属性,用于生成序号前缀
  226. const questionPrefix = computed(() => {
  227. return (index) => {
  228. return `${index + 1}`;
  229. };
  230. })
  231. // 用于存储每个问题标题是否被鼠标悬停的状态,初始化为false
  232. const isHovered = ref(Array(questions.value.length).fill(false));
  233. const handleMouseEnter = (index) => {
  234. isHovered.value[index] = true;
  235. };
  236. const handleMouseLeave = (index) => {
  237. isHovered.value[index] = false;
  238. };
  239. // 在组件挂载后初始化 `isHovered` 数组长度与 `questions` 数组长度一致
  240. onMounted(() => {
  241. isHovered.value = Array(questions.value.length).fill(false);
  242. });
  243. </script>
  244. <style scoped>
  245. .submit {
  246. margin: 100px 212px;
  247. }
  248. .submit .el-button {
  249. padding: 25px 150px;
  250. }
  251. .question-title {
  252. transition: background-color 0.3s ease;
  253. }
  254. .bg-change {
  255. background-color: rgba(200, 200, 200, 0.3);
  256. }
  257. .question-title {
  258. margin-bottom: 10px;
  259. }
  260. .select {
  261. margin: 10px 0px 0px;
  262. }
  263. .delete {
  264. position: absolute;
  265. right: 10px;
  266. bottom: 0px;
  267. }
  268. .add {
  269. position: relative;
  270. }
  271. .question-container {
  272. margin: 20px 0;
  273. padding: 10px 20px;
  274. width: 750px;
  275. border-bottom: 1px solid #e5e5e5;
  276. }
  277. .header {
  278. height: 100px;
  279. line-height: 100px;
  280. padding: 0 80px;
  281. }
  282. .header-text {
  283. font-size: 22px;
  284. font-weight: 500;
  285. color: black;
  286. float: left;
  287. }
  288. .header-button {
  289. margin-top: 30px;
  290. }
  291. .main {
  292. padding: 30px 212px;
  293. background-color: #F8F8F8;
  294. }
  295. .main-title {
  296. font-size: 16px;
  297. background-color: white;
  298. font-weight: bold;
  299. height: 60px;
  300. border-bottom: 2px solid #ececec;
  301. padding: 0 15px;
  302. line-height: 52px;
  303. }
  304. .main-button {
  305. margin: 10px 15px 0 0;
  306. padding: 12px 20px;
  307. height: 40px;
  308. float: right;
  309. }
  310. .el-form {
  311. padding: 30px 78.5px;
  312. margin: auto;
  313. }
  314. .el-form-item {
  315. --font-size: 16px;
  316. margin: 0 0 25px;
  317. }
  318. .main-back {
  319. background-color: white;
  320. }
  321. </style>