CheckPinyin.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <template>
  2. <div v-loading="loading" class="check-article">
  3. <HeaderPage />
  4. <div class="main">
  5. <div class="main-top">
  6. <div style="display: flex">
  7. <a class="go-back" @click="$router.go(-1)">
  8. <i class="el-icon-arrow-left"></i>
  9. 返回
  10. </a>
  11. <b>校对拼音</b>
  12. </div>
  13. <div class="btn-box">
  14. <el-button type="info" @click="$router.go(-1)">取消</el-button>
  15. <el-button type="primary" @click="savePinyin(id)">保存</el-button>
  16. </div>
  17. </div>
  18. <div class="article">
  19. <div class="paragraph" v-for="(item, index) in indexArr" :key="index + 'paragraph'" >
  20. <div class="sentence-box" v-for="(items, indexs) in item" :key="indexs + 'words'">
  21. <div class="sentence" @click="selectItem(items,index)" :style="{marginRight:items.marginRight?'8px':'',color: activeIndex === index+'_'+items.sentenceIndex+'_'+items.wordIndex?'#F2555A':''}">
  22. <span class="pinyin">{{items.pinyin_lt?items.pinyin_lt:items.pinyin}}</span>
  23. <span class="words" :class="[/^[0-9]*$/.test(items.text)]?/^[\u4e00-\u9fa5]/.test(items.text)?'hanzi':'en':''">
  24. {{items.text}}
  25. </span>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. <el-dialog
  32. :visible.sync="dialogFlag"
  33. :show-close="false"
  34. :close-on-click-modal="false"
  35. :modal-append-to-body="false"
  36. :modal="false"
  37. width="250px"
  38. class="login-dialog"
  39. v-if="dialogFlag">
  40. <div class="check-box">
  41. <div class="content">
  42. <template v-if="itemActive.pinyin_lt">
  43. <div class="words-box">
  44. <span class="pinyin">
  45. {{itemActive.pinyin_lt}}
  46. </span>
  47. <span class="words">
  48. {{itemActive.text}}
  49. </span>
  50. </div>
  51. </template>
  52. <template v-else>
  53. <div class="words-box">
  54. <span class="pinyin">
  55. {{itemActive.pinyin}}
  56. </span>
  57. <span class="words">
  58. {{itemActive.text}}
  59. </span>
  60. </div>
  61. </template>
  62. </div>
  63. <el-input v-model="checkPinyinInput" type="text" class="checkPinyinInput" />
  64. <p class="tips">
  65. 一到四声分别用数字1-4表示,轻声用0表示。拼音间用空格隔开,例如“北语社”,输入“bei3 yu3 she4”;若需要连在一起显示,用_隔开,例如“哪儿”,输入“na3_er”
  66. </p>
  67. <div class="btn-box">
  68. <el-button type="info" size="small" @click="cancleDialog">取消</el-button>
  69. <el-button type="primary" size="small" @click="surePinyin">保存</el-button>
  70. </div>
  71. </div>
  72. </el-dialog>
  73. </div>
  74. </template>
  75. <script>
  76. import HeaderPage from '@/components/Header.vue';
  77. import { publicMethods, reparse } from '@/api/api';
  78. import th from 'element-ui/lib/locale/lang/th';
  79. export default {
  80. components: {
  81. HeaderPage,
  82. },
  83. data() {
  84. return {
  85. loading: false,
  86. id: '',
  87. ArticelData: null,
  88. indexArr: [], // 索引数组
  89. activeIndex: null,
  90. itemActive: null,
  91. dialogFlag: false,
  92. checkPinyinInput: '',
  93. oldInput: '',
  94. tableData: [
  95. ["ā", "á", "ǎ", "à", "a"],
  96. ["ō", "ó", "ǒ", "ò", "o"],
  97. ["ē", "é", "ě", "è", "e"],
  98. ["ī", "í", "ǐ", "ì", "i"],
  99. ["ū", "ú", "ǔ", "ù", "u"],
  100. ["ǖ", "ǘ", "ǚ", "ǜ", "ü"],
  101. ["Ā", "Á", "Â", "À", "A"],
  102. ["Ō", "Ó", "Ô", "Ò", "O"],
  103. ["Ē", "É", "Ê", "È", "E"],
  104. ["Ī", "Í", "Î", "Ì", "I"],
  105. ["Ū", "Ú", "Û", "Ù", "U"],
  106. ],
  107. };
  108. },
  109. // 生命周期 - 创建完成(可以访问当前this实例)
  110. created() {
  111. this.routerData = JSON.parse(JSON.stringify(this.$route.query));
  112. this.id = this.routerData.id
  113. this.getArticleData()
  114. },
  115. methods: {
  116. // 获取分析结果
  117. getArticleData() {
  118. this.loading = true;
  119. publicMethods('/TeachingServer/TextAnalyser/GetParsedTextInfo',{
  120. analyse_record_id: this.id,
  121. }
  122. )
  123. .then((res) => {
  124. if(res.status===1){
  125. let newdata = [];
  126. res.parsed_text.paragraph_list.forEach((item) => {
  127. if (item.length !== 0) {
  128. newdata.push(item);
  129. }
  130. });
  131. // this.ArticelData = JSON.parse(JSON.stringify(newdata));
  132. let saveArr = []
  133. let arr = []
  134. let saveIndex = 0
  135. // 添加索引
  136. newdata.forEach((item,index) => {
  137. arr.push([])
  138. item.forEach((items,indexs) => {
  139. items.forEach((itemss,indexss)=>{
  140. let str = ''
  141. let pinyinStr = ''
  142. let pinyinNo = ''
  143. itemss.text.forEach((itemT,indexT)=>{
  144. str += itemT.word
  145. pinyinStr += itemT.pinyin + ','
  146. pinyinNo += itemT.pinyin
  147. })
  148. let obj = {
  149. text: str,
  150. pinyin: pinyinNo,
  151. paraIndex: index,
  152. sentenceIndex: indexs,
  153. wordIndex: indexss,
  154. wordArr: itemss.text,
  155. marginRight: true,
  156. saveIndex: saveIndex,
  157. pinyin_lt: itemss.pinyin_lt
  158. }
  159. arr[index].push(obj)
  160. let saveObj = {
  161. word: str,
  162. pinyin: pinyinStr.substring(0,pinyinStr.length-1),
  163. // pinyin_lt: itemss.pinyin_lt?itemss.pinyin_lt:''
  164. }
  165. saveArr.push(saveObj)
  166. saveIndex++
  167. })
  168. });
  169. });
  170. this.indexArr = arr
  171. this.ArticelData = saveArr
  172. this.loading = false;
  173. }
  174. })
  175. .catch(() => {
  176. this.loading = false;
  177. });
  178. },
  179. selectItem(item,index){
  180. this.activeIndex = index+'_'+item.sentenceIndex+'_'+item.wordIndex
  181. this.itemActive = item
  182. this.dialogFlag = true
  183. },
  184. cancleDialog(){
  185. this.activeIndex = null
  186. this.itemActive = null
  187. this.checkPinyinInput = ''
  188. this.oldInput = ''
  189. this.dialogFlag = false
  190. },
  191. surePinyin(){
  192. this.oldInput = JSON.parse(JSON.stringify(this.checkPinyinInput.trim()))
  193. this.handleReplaceTone(this.checkPinyinInput.trim())
  194. },
  195. handleReplaceTone(e) {
  196. let _this = this;
  197. _this.$nextTick(() => {
  198. let value = e;
  199. _this.resArr = [];
  200. if (value) {
  201. let valueArr = []
  202. if(value.indexOf('_')>-1){
  203. value.replace(/_{1,}/g,'_')
  204. valueArr = value.split('_')
  205. }else{
  206. value.replace(/\s+/g, " ")
  207. valueArr = value.split(' ')
  208. }
  209. // let reg = /\s+/g;
  210. // valueArr = value.split(reg);
  211. valueArr.forEach((item, index) => {
  212. this.handleValue(item);
  213. });
  214. let str = "";
  215. setTimeout(() => {
  216. _this.resArr.forEach((item) => {
  217. str += " ";
  218. item.forEach((sItem) => {
  219. if (sItem.number && sItem.con) {
  220. let number = Number(sItem.number);
  221. let con = sItem.con;
  222. let word = _this.addTone(number, con);
  223. str += word;
  224. } else {
  225. if (sItem.number) {
  226. str += sItem.number;
  227. } else if (sItem.con) {
  228. str += " " + sItem.con + " ";
  229. }
  230. }
  231. });
  232. });
  233. this.checkPinyinInput = str.trim();
  234. if(this.oldInput.indexOf('_')>-1){
  235. this.ArticelData[this.itemActive.saveIndex].pinyin = this.checkPinyinInput.replace(/\s+/g, " ").split(/\s+/).join('_')
  236. this.checkPinyinInput = this.checkPinyinInput.replace(/\s+/g, " ").split(/\s+/).join('_').replace('_e','').replace('_ē','').replace('_é','').replace('_ě','').replace('_è','')
  237. this.itemActive.pinyin_lt = this.checkPinyinInput.replace(/\s+/g, "")
  238. }else{
  239. this.ArticelData[this.itemActive.saveIndex].pinyin = this.checkPinyinInput.replace(/\s+/g, " ").split(/\s+/).join(',')
  240. this.itemActive.pinyin = this.checkPinyinInput.replace(/\s+/g, "")
  241. }
  242. // this.ArticelData[this.itemActive.saveIndex].pinyin = this.checkPinyinInput
  243. this.loading = true;
  244. publicMethods('/TeachingServer/TextAnalyser/AddMyPinyinProofread',{
  245. analyse_record_id: this.id,
  246. word_list: [this.ArticelData[this.itemActive.saveIndex]]
  247. }
  248. )
  249. .then((res) => {
  250. this.loading = false;
  251. if(res.status===1){
  252. this.$message.success('保存成功')
  253. this.activeIndex = null
  254. this.itemActive = null
  255. this.checkPinyinInput = ''
  256. this.oldInput = ''
  257. this.dialogFlag = false
  258. // this.getArticleData()
  259. }
  260. })
  261. .catch(() => {
  262. this.loading = false;
  263. });
  264. }, 10);
  265. }
  266. });
  267. },
  268. handleValue(valItem) {
  269. let reg = /\d/;
  270. let reg2 = /[A-Za-z]+\d/g;
  271. let numList = [];
  272. let valArr = valItem.split("");
  273. if (reg2.test(valItem)) {
  274. for (let i = 0; i < valArr.length; i++) {
  275. let item = valItem[i];
  276. if (reg.test(item)) {
  277. let numIndex =
  278. numList.length == 0 ? 0 : numList[numList.length - 1].index;
  279. let con = valItem.substring(numIndex, i);
  280. con = con.replace(/\d/g, "");
  281. let obj = {
  282. index: i,
  283. number: item,
  284. con: con,
  285. isTran: true,
  286. };
  287. numList.push(obj);
  288. }
  289. }
  290. } else {
  291. numList = [];
  292. }
  293. if (numList.length == 0) {
  294. this.resArr.push([{ con: valItem }]);
  295. } else {
  296. this.resArr.push(numList);
  297. }
  298. },
  299. addTone(number, con) {
  300. let _this = this;
  301. let zmList = ["a", "o", "e", "i", "u", "v", "A", "O", "E", "I", "U"];
  302. if (number) {
  303. for (let i = 0; i < zmList.length; i++) {
  304. let zm = zmList[i];
  305. if (con.indexOf(zm) > -1) {
  306. let zm2 = _this.tableData[i][number - 1];
  307. if (con.indexOf("iu") > -1) {
  308. zm2 = _this.tableData[4][number - 1];
  309. con = con.replace("u", zm2);
  310. } else if (con.indexOf("ui") > -1) {
  311. zm2 = _this.tableData[3][number - 1];
  312. con = con.replace("i", zm2);
  313. } else if (
  314. con.indexOf("yv") > -1 ||
  315. con.indexOf("jv") > -1 ||
  316. con.indexOf("qv") > -1 ||
  317. con.indexOf("xv") > -1
  318. ) {
  319. zm2 = _this.tableData[4][number - 1];
  320. con = con.replace("v", zm2);
  321. } else {
  322. con = con.replace(zm, zm2);
  323. }
  324. break;
  325. }
  326. }
  327. }
  328. return con;
  329. },
  330. savePinyin(analyse_record_id){
  331. this.loading = true;
  332. reparse({ analyse_record_id })
  333. .then(({ record }) => {
  334. this.getArticleData()
  335. })
  336. .finally(() => {
  337. this.loading = false;
  338. });
  339. }
  340. },
  341. };
  342. </script>
  343. <style lang="scss" scoped>
  344. .check-article {
  345. min-height: 100%;
  346. background: #f6f6f6;
  347. .wheader {
  348. background: #fff;
  349. }
  350. .el-button{
  351. padding: 5px 16px;
  352. border-radius: 2px;
  353. border: 1px solid #F2F3F5;
  354. color: #4E5969;
  355. font-size: 14px;
  356. font-weight: 400;
  357. line-height: 22px;
  358. background: #F2F3F5;
  359. &.el-button--primary{
  360. background: #165DFF;
  361. border: 1px solid #165DFF;
  362. color: #FFF;
  363. }
  364. }
  365. .main {
  366. width: 1200px;
  367. margin: 23px auto;
  368. background: #FFF;
  369. padding: 24px;
  370. &-top{
  371. display: flex;
  372. align-items: center;
  373. justify-content: space-between;
  374. margin-bottom: 24px;
  375. position: relative;
  376. b{
  377. color: #000;
  378. font-size: 24px;
  379. font-weight: 500;
  380. line-height: 34px;
  381. margin-left: 16px;
  382. }
  383. }
  384. .go-back{
  385. border-radius: 4px;
  386. border: 1px solid #D9D9D9;
  387. background: #FFF;
  388. box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.02);
  389. display: flex;
  390. width: 60px;
  391. color: #333;
  392. font-size: 14px;
  393. font-weight: 400;
  394. line-height: 22px;
  395. padding: 5px 8px;
  396. align-items: center;
  397. cursor: pointer;
  398. .el-icon-arrow-left{
  399. font-size: 16px;
  400. margin-right: 8px;
  401. }
  402. }
  403. .article{
  404. border-radius: 2px;
  405. border: 1px solid rgba(0, 0, 0, 0.08);
  406. background: #FCFCFC;
  407. padding: 8px;
  408. }
  409. .paragraph{
  410. margin-bottom: 24px;
  411. text-align: center;
  412. display: flex;
  413. flex-flow: wrap;
  414. width: 100%;
  415. .sentence-box{
  416. display: flex;
  417. flex-flow: wrap;
  418. float: left;
  419. .sentence{
  420. margin-top: 8px;
  421. text-align: center;
  422. cursor: pointer;
  423. color: #000;
  424. .words{
  425. display: block;
  426. font-size: 20px;
  427. line-height: 28px;
  428. font-weight: 400;
  429. }
  430. .pinyin{
  431. font-family: 'League';
  432. font-size: 14px;
  433. font-weight: 400;
  434. line-height: 1;
  435. height: 14px;
  436. display: block;
  437. }
  438. }
  439. }
  440. }
  441. }
  442. }
  443. .check-box{
  444. padding: 24px;
  445. border-radius: 4px;
  446. background: #FFF;
  447. box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
  448. .content{
  449. display: flex;
  450. align-items: center;
  451. justify-content: center;
  452. .words-box{
  453. text-align: center;
  454. color: #000;
  455. .words{
  456. display: block;
  457. font-size: 28px;
  458. line-height: 40px;
  459. font-weight: 400;
  460. }
  461. .pinyin{
  462. font-family: 'League';
  463. font-size: 20px;
  464. font-weight: 400;
  465. line-height: 1;
  466. height: 20px;
  467. display: block;
  468. }
  469. }
  470. }
  471. .checkPinyinInput{
  472. margin: 16px 0 8px 0;
  473. }
  474. .tips{
  475. color: #A0A0A0;
  476. font-size: 12px;
  477. font-weight: 400;
  478. line-height: 18px;
  479. margin: 0 0 24px 0;
  480. }
  481. .btn-box{
  482. text-align: right;
  483. .el-button{
  484. font-size: 12px;
  485. padding: 2px 12px;
  486. line-height: 20px;
  487. }
  488. }
  489. }
  490. </style>
  491. <style lang="scss">
  492. .check-article{
  493. .login-dialog{
  494. .el-dialog__header{
  495. padding: 0;
  496. }
  497. .el-dialog__body{
  498. padding: 0;
  499. }
  500. .el-input__inner{
  501. background: #F3F3F3;
  502. text-align: center;
  503. }
  504. }
  505. }
  506. </style>