AffairsBackward.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <template>
  2. <div class="affairbackward-all" v-loading="affairbackwardloading">
  3. <div class="affairbackward-hade">
  4. <el-form style="display: flex;justify-content: space-between;align-items: center;" :inline="true" :model="formInline" class="demo-form-inline">
  5. <el-form-item>
  6. <el-select filterable @change="ConferenceProceduresInit" v-model="diid" placeholder="团组名称" style="width: 250px;">
  7. <el-option v-for="(item, index) in AuditStatus" :key="index" :label="item.teamName"
  8. :value="item.id"></el-option>
  9. </el-select>
  10. </el-form-item>
  11. <div>
  12. <el-form-item label="团队名称:">
  13. {{ formInline.name }}
  14. </el-form-item>
  15. <el-form-item label="客户:">
  16. {{ formInline.clientName }}
  17. </el-form-item>
  18. <el-form-item label="出访国家:">
  19. {{ formInline.CountriesVisited }}
  20. </el-form-item>
  21. <el-form-item label="起止日期:">
  22. {{ formInline.StartTime }}
  23. </el-form-item>
  24. <el-form-item label="天数/人数:">
  25. {{ formInline.Days }}天 / {{ formInline.Number }}人
  26. </el-form-item>
  27. </div>
  28. <div>
  29. <el-button @click="ConferenceProceduresSave" type="primary">保存</el-button>
  30. <el-button @click="ConferenceProceduresFileDown" type="primary">下载</el-button>
  31. </div>
  32. </el-form>
  33. </div>
  34. <div style="display: flex;justify-content: space-between;align-items: center;">
  35. <div style="margin-top: 20px;font-size: 15px;font-weight: 600;color: red;">PS:插入行与删除行并未进行保存操作,需要保存请点击保存按钮!!!</div>
  36. <el-button size="mini" @click="pushxiangmu" type="primary">添加项目</el-button>
  37. </div>
  38. <el-table :data="tableDatass" :span-method="objectSpanMethod" border style="width: 100%; ">
  39. <el-table-column prop="title" label="项目" width="180">
  40. <template slot-scope="scope">
  41. <el-input @focus="huodejiaodian(scope.row.title)" @input="titleinput" v-model="scope.row.title" placeholder="请输入内容"></el-input>
  42. </template>
  43. </el-table-column>
  44. <el-table-column prop="date" label="时间" width="180">
  45. <template slot-scope="scope">
  46. <el-input v-model="scope.row.dataDetails" placeholder="请输入内容"></el-input>
  47. </template>
  48. </el-table-column>
  49. <el-table-column prop="content" label="内容">
  50. <template slot-scope="scope">
  51. <el-input v-model="scope.row.details" placeholder="请输入内容"></el-input>
  52. </template>
  53. </el-table-column>
  54. <el-table-column prop="remark" label="备注">
  55. <template slot-scope="scope">
  56. <el-input v-model="scope.row.remark" placeholder="请输入内容"></el-input>
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="remark" label="操作" width="150">
  60. <template slot-scope="scope">
  61. <el-button style="width:80px;" class="czbtn" size="mini" type="primary" @click="insertTaskAbove(scope.$index,scope.row)">插入行↑</el-button>
  62. <br />
  63. <el-button style="margin: 10px 0;width:80px;" size="mini" @click="deleterow(scope.$index,scope.row)" type="danger">删 除</el-button>
  64. <br />
  65. <el-button style="width:80px;" size="mini" @click="insertTaskBelow(scope.$index,scope.row)" type="primary">插入行↓</el-button>
  66. </template>
  67. </el-table-column>
  68. </el-table>
  69. </div>
  70. </template>
  71. <script>
  72. export default {
  73. data() {
  74. return {
  75. tableData: [],
  76. tableDatas:[
  77. {
  78. title:'1',
  79. date:'提前45天',
  80. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  81. Remark:'实际根据项目启动时间,倒推时间是否足够'
  82. },
  83. {
  84. title:'1',
  85. date:'提前45天',
  86. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  87. Remark:'实际根据项目启动时间,倒推时间是否足够'
  88. },
  89. {
  90. title:'2',
  91. date:'提前45天',
  92. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  93. Remark:'实际根据项目启动时间,倒推时间是否足够'
  94. },
  95. {
  96. title:'2',
  97. date:'提前45天',
  98. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  99. Remark:'实际根据项目启动时间,倒推时间是否足够'
  100. },
  101. {
  102. title:'2',
  103. date:'提前45天',
  104. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  105. Remark:'实际根据项目启动时间,倒推时间是否足够'
  106. },
  107. {
  108. title:'3',
  109. date:'提前45天',
  110. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  111. Remark:'实际根据项目启动时间,倒推时间是否足够'
  112. },
  113. {
  114. title:'3',
  115. date:'提前45天',
  116. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  117. Remark:'实际根据项目启动时间,倒推时间是否足够'
  118. },
  119. {
  120. title:'3',
  121. date:'提前45天',
  122. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  123. Remark:'实际根据项目启动时间,倒推时间是否足够'
  124. },
  125. {
  126. title:'3',
  127. date:'提前45天',
  128. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  129. Remark:'实际根据项目启动时间,倒推时间是否足够'
  130. },
  131. {
  132. title:'4',
  133. date:'提前45天',
  134. content:'初筛邀请对象,结合客户需求,梳理邀请名单',
  135. Remark:'实际根据项目启动时间,倒推时间是否足够'
  136. },
  137. ],
  138. tableDatass:[],
  139. rowarr:[],
  140. spanArr: [], // 存储每个项目对应的行数
  141. position: 0, // 存储spanArr的索引位置
  142. diid:'',
  143. AuditStatus:[],
  144. formInline: {
  145. name: '美国团',
  146. clientName: '张三',
  147. CountriesVisited: '美国',
  148. StartTime: '2023-10-01至2023-10-10',
  149. Days: 10,
  150. Number: 8,
  151. Status: '',
  152. },
  153. token:'',
  154. userId:'',
  155. affairbackwardloading:false,
  156. porojectname:[],
  157. porojectindex:[],
  158. }
  159. },
  160. created() {
  161. // this.getSpanArr();
  162. // this.flattenData();
  163. },
  164. methods:{
  165. // 将嵌套的数据结构转换为扁平结构
  166. flattenData() {
  167. this.tableDatass = [];
  168. this.tableData.forEach(item => {
  169. item.itmes.forEach(child => {
  170. this.tableDatass.push({
  171. id:child.id,
  172. title: item.title,
  173. dataDetails: child.dataDetails,
  174. identification:item.title,
  175. details: child.details,
  176. remark: child.remark
  177. });
  178. });
  179. });
  180. },
  181. // 将扁平结构转换为嵌套的数据结构
  182. unflattenData() {
  183. let result = [];
  184. let currentTitle = null;
  185. let currentItem = null;
  186. this.tableDatass.forEach(row => {
  187. if (row.title !== currentTitle) {
  188. if (currentItem) {
  189. result.push(currentItem);
  190. }
  191. currentTitle =row.title;
  192. currentItem = {
  193. title: currentTitle,
  194. itmes: []
  195. };
  196. }
  197. currentItem.itmes.push({
  198. id:row.id,
  199. dataDetails: row.dataDetails,
  200. details: row.details,
  201. remark: row.remark,
  202. identification:row.identification,
  203. });
  204. });
  205. if (currentItem) {
  206. result.push(currentItem);
  207. }
  208. this.tableData = result;
  209. },
  210. // 计算每个项目对应的行数
  211. getSpanArr() {
  212. this.spanArr = [];
  213. this.position = 0;
  214. this.tableData.forEach(item => {
  215. this.spanArr.push(item.itmes.length);
  216. });
  217. },
  218. objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  219. if (columnIndex === 0) {
  220. let currentRowTitle = row.title;
  221. let spanCount = 0;
  222. let pos = 0;
  223. // 找到当前项目在spanArr中的位置
  224. for (let i = 0; i < this.tableData.length; i++) {
  225. if (this.tableData[i].title === currentRowTitle) {
  226. spanCount = this.spanArr[i];
  227. break;
  228. }
  229. pos += this.spanArr[i];
  230. }
  231. // 如果是当前项目的第一个行,返回合并行数
  232. if (rowIndex === pos) {
  233. return {
  234. rowspan: spanCount,
  235. colspan: 1
  236. };
  237. } else {
  238. return {
  239. rowspan: 0,
  240. colspan: 0
  241. };
  242. }
  243. }
  244. },
  245. //数据初始化
  246. ConferenceProceduresInit(){
  247. this.affairbackwardloading=true;
  248. this.AuditStatus=[];
  249. var url = "/api/Groups/ConferenceProceduresInit"
  250. var that = this
  251. this.$axios({
  252. method: 'post',
  253. url: url,
  254. headers: {
  255. Authorization: 'Bearer '
  256. },
  257. data:{
  258. groupId:that.diid==''?0:that.diid,
  259. }
  260. }).then(function (res) {
  261. if(res.data.code==200){
  262. that.AuditStatus=res.data.data.groupList;
  263. if (that.diid==='') {
  264. that.diid=res.data.data.groupInfo.id;
  265. }
  266. that.formInline.name = res.data.data.groupInfo.teamName;
  267. that.formInline.clientName = res.data.data.groupInfo.clientName;
  268. that.formInline.CountriesVisited = res.data.data.groupInfo.visitCountry;
  269. that.formInline.StartTime = res.data.data.groupInfo.visitStartDate.split(' ')[0]+'~'+res.data.data.groupInfo.visitEndDate.split(' ')[0];
  270. that.formInline.Days = res.data.data.groupInfo.visitDays;
  271. that.formInline.Number = res.data.data.groupInfo.visitPNumber;
  272. that.tableData=res.data.data.conferenceProceduresGroupByTitle;
  273. that.getSpanArr();
  274. that.flattenData();
  275. that.affairbackwardloading=false;
  276. }else{
  277. that.affairbackwardloading=false;
  278. that.$message.error(res.data.msg);
  279. }
  280. })
  281. },
  282. //插入行
  283. insertTaskAbove(index,row) {
  284. for (let i = 0; i < this.tableData.length; i++) {
  285. if (this.tableData[i].title === row.title) {
  286. this.tableData[i].itmes.splice(index - this.position, 0, {
  287. "id":0,
  288. "dataDetails":"",
  289. "details": "",
  290. "remark": "",
  291. });
  292. this.getSpanArr();
  293. this.flattenData();
  294. break;
  295. }
  296. this.position += this.spanArr[i];
  297. }
  298. },
  299. //插入行
  300. insertTaskBelow(index,row) {
  301. for (let i = 0; i < this.tableData.length; i++) {
  302. if (this.tableData[i].title === row.title) {
  303. this.tableData[i].itmes.splice((index+1) - this.position, 0, {
  304. "id":0,
  305. "dataDetails":"",
  306. "details": "",
  307. "remark": "",
  308. });
  309. this.getSpanArr();
  310. this.flattenData();
  311. break;
  312. }
  313. this.position += this.spanArr[i];
  314. }
  315. },
  316. //删除行
  317. deleterow(index,row) {
  318. for (let i = 0; i < this.tableData.length; i++) {
  319. if (this.tableData[i].title === row.title) {
  320. this.tableData[i].itmes.splice(index - this.position, 1);
  321. this.getSpanArr();
  322. this.flattenData();
  323. break;
  324. }
  325. this.position += this.spanArr[i];
  326. }
  327. },
  328. //保存
  329. ConferenceProceduresSave(){
  330. this.affairbackwardloading=true;
  331. this.unflattenData();
  332. var url = "/api/Groups/ConferenceProceduresSave"
  333. var that = this
  334. this.$axios({
  335. method: 'post',
  336. url: url,
  337. headers: {
  338. Authorization: 'Bearer ',
  339. },
  340. data:{
  341. groupId:that.diid,
  342. userId: that.userId,
  343. conferenceProceduresSaveItem:that.tableData,
  344. }
  345. }).then(function (res) {
  346. if(res.data.code==200){
  347. that.$message({
  348. type: 'success',
  349. message: res.data.msg
  350. });
  351. that.ConferenceProceduresInit();
  352. }else{
  353. that.$message.error(res.data.msg);
  354. that.progressloading=false;
  355. }
  356. })
  357. },
  358. //下载
  359. ConferenceProceduresFileDown(){
  360. // this.unflattenData();
  361. var url = "/api/Groups/ConferenceProceduresFileDown"
  362. var that = this
  363. this.$axios({
  364. method: 'post',
  365. url: url,
  366. headers: {
  367. Authorization: 'Bearer ',
  368. },
  369. data:{
  370. groupId:that.diid,
  371. }
  372. }).then(function (res) {
  373. if(res.data.code==200){
  374. that.$message({
  375. type: 'success',
  376. message: res.data.msg
  377. });
  378. window.open(res.data.data);
  379. }else{
  380. that.$message.error(res.data.msg);
  381. }
  382. })
  383. },
  384. //标题输入
  385. titleinput(val){
  386. for (let b = 0; b < this.tableDatass.length; b++) {
  387. if(this.tableDatass[b].identification==this.porojectindex){
  388. this.tableDatass[b].title=val;
  389. }
  390. }
  391. this.porojectindex=val;
  392. // for (let b = 0; b < this.porojectindex.length; b++) {
  393. // // this.tableDatass.splice( this.porojectindex,1)
  394. // for (let m = 0; m < this.porojectname.length; m++) {
  395. // this.porojectname[m].title=val;
  396. // this.tableDatass.splice(this.porojectindex[b],1,this.porojectname[m])
  397. // }
  398. // }
  399. // this.tableDatass=this.porojectname.concat(this.tableDatass);
  400. this.unflattenData();
  401. this.flattenData();
  402. this.getSpanArr();
  403. },
  404. //添加项目
  405. pushxiangmu(){
  406. this.unflattenData();
  407. console.log(this.tableData);
  408. var obj={
  409. title:'新项目',
  410. itmes:[{
  411. id:0,
  412. dataDetails:'',
  413. details:'',
  414. remark:'',
  415. identification:'新项目',
  416. }]
  417. }
  418. this.tableData.push(obj);
  419. this.flattenData();
  420. this.getSpanArr();
  421. },
  422. //获得焦点
  423. huodejiaodian(val){
  424. this.porojectname=[];
  425. this.porojectindex=val;
  426. for (let y = 0; y < this.tableDatass.length; y++) {
  427. if (this.tableDatass[y].title==val) {
  428. this.porojectname.push(this.tableDatass[y])
  429. // this.porojectindex.push(y)
  430. }
  431. }
  432. }
  433. },
  434. mounted(){
  435. this.token = JSON.parse(localStorage.getItem('userinif')).token;
  436. this.userId = JSON.parse(localStorage.getItem('userinif')).userInfo.userId;
  437. this.ConferenceProceduresInit();
  438. }
  439. }
  440. </script>
  441. <style>
  442. .affairbackward-all {
  443. background-color: #fff;
  444. padding: 10px;
  445. box-shadow: 0 0 5px #0005;
  446. border-radius: 10px;
  447. min-height: 830px;
  448. }
  449. .affairbackward-hade .el-form-item{
  450. margin-bottom: 0;
  451. }
  452. </style>