meeting.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. <template>
  2. <div class="app-container">
  3. <div class="query-container">
  4. <el-form ref="formInline" v-model="formInline" size="mini" :inline="true">
  5. <el-form-item>
  6. <el-radio-group v-model="formInline.meetingEternal" @input="chooseMeeting()">
  7. <el-radio-button label="0" value="0">内部会议</el-radio-button>
  8. <el-radio-button label="1" value="1">外部会议</el-radio-button>
  9. </el-radio-group>
  10. </el-form-item>
  11. <el-form-item>
  12. <el-input v-model="formInline.meetingName" placeholder="会议主题"></el-input>
  13. </el-form-item>
  14. <el-form-item>
  15. <el-select v-model="formInline.meetingType" placeholder="会议类型" clearable>
  16. <el-option label="周例会" value="1" key="周例会">周例会</el-option>
  17. <el-option label="项目会议" value="2" key="项目会议">项目会议</el-option>
  18. <el-option label="实施会议" value="3" key="实施会议">实施会议</el-option>
  19. <el-option label="其他会议" value="4" key="其他会议">其他会议</el-option>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-select v-model="formInline.status" placeholder="会议状态" clearable>
  24. <el-option label="待开始" value="0"></el-option>
  25. <el-option label="进行中" value="1"></el-option>
  26. <el-option label="已结束" value="2"></el-option>
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item>
  30. <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
  31. <el-button icon="el-icon-refresh" @click="resetSearch()">重置</el-button>
  32. </el-form-item>
  33. </el-form>
  34. <el-row :gutter="10" style="margin-bottom:8px">
  35. <el-col :span="1.5">
  36. <el-button type="success" icon="el-icon-plus" @click="createMeeting">创建会议</el-button>
  37. </el-col>
  38. </el-row>
  39. </div>
  40. <el-table
  41. :data="tableData"
  42. border
  43. stripe
  44. height="calc(100vh - 180px)"
  45. size="mini"
  46. style="width: 100%">
  47. <el-table-column type="index" label="序号" width="60" fixed>
  48. </el-table-column>
  49. <el-table-column label="会议主题" prop="meetingName">
  50. </el-table-column>
  51. <el-table-column label="会议地点" prop="meetingPlace" width="150" :show-overflow-tooltip="true">
  52. </el-table-column>
  53. <el-table-column label="会议内容" prop="meetingContent" width="80">
  54. <scope slot-scope="scope">
  55. <el-popover
  56. placement="bottom"
  57. :title="meetingTitle"
  58. width="600"
  59. trigger="click">
  60. <el-table :data="meetingContents" border stripe>
  61. <el-table-column width="60" type="index" label="序号"></el-table-column>
  62. <el-table-column min-width="300" property="content" label="内容"></el-table-column>
  63. </el-table>
  64. <span style="color: blue" slot="reference" @click="searchMeetingContent(scope.row)">会议内容</span>
  65. </el-popover>
  66. </scope>
  67. </el-table-column>
  68. <el-table-column prop="address" label="参会人员" :show-overflow-tooltip="true">
  69. <template slot-scope="scope">
  70. <span>{{ scope.row.outAttendees }}</span>
  71. <span v-if="scope.row.outAttendees!=''">、</span>
  72. <span v-for="(item,index) in JSON.parse(scope.row.innerAttendees) ">
  73. <template v-if="index > 0">,</template>
  74. <span>{{ item.name }}</span>
  75. </span>
  76. </template>
  77. </el-table-column>
  78. <el-table-column prop="name" label="会议时间" width="240">
  79. <template slot-scope="scope">
  80. <div>{{ parseTime(scope.row.beginTime) }}——{{ parseTime(scope.row.endTime) }}</div>
  81. </template>
  82. </el-table-column>
  83. <el-table-column prop="emcee" label="主持人" width="100"></el-table-column>
  84. <el-table-column prop="recorder" label="记录人" width="100"></el-table-column>
  85. <el-table-column label="会议类型" prop="meetingType" width="80">
  86. <template slot-scope="scope">
  87. <!--会议类型(1-周例会,2-项目会议,3-实施会议,4-其他会议)-->
  88. <div v-if="scope.row.meetingType===1">周例会</div>
  89. <div v-else-if="scope.row.meetingType===2">项目会议</div>
  90. <div v-else-if="scope.row.meetingType===3">实施会议</div>
  91. <div v-else>其他会议</div>
  92. </template>
  93. </el-table-column>
  94. <el-table-column prop="status" label="会议状态" width="80">
  95. <template slot-scope="scope">
  96. <!--会议状态,0待开始,1进行中,2已结束-->
  97. <div v-if="scope.row.status===0" style="color: green">待开始</div>
  98. <div v-else-if="scope.row.status===1" style="color: #3A71A8">进行中</div>
  99. <div v-else>已结束</div>
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="status" label="确认状态" width="80">
  103. <template slot-scope="scope">
  104. <div v-if="scope.row.meetingConfirmStatus===0 && (scope.row.meetingType===1 || scope.row.meetingType===2)">
  105. 未确认
  106. </div>
  107. <div
  108. v-else-if="scope.row.meetingConfirmStatus===1 && (scope.row.meetingType===1 || scope.row.meetingType===2)">
  109. 已确认
  110. </div>
  111. <div v-else>无需确认</div>
  112. </template>
  113. </el-table-column>
  114. <!-- <el-table-column prop="createTime" label="创建时间" width="130" :v-show="false">
  115. <template slot-scope="scope">
  116. <span>{{ parseTime(scope.row.createTime) }}</span>
  117. </template>
  118. </el-table-column>-->
  119. <el-table-column label="操作" prop="op" width="300">
  120. <template slot-scope="scope">
  121. <el-button v-if="scope.row.status!==2" size="mini" type="primary" @click="handleEdit(scope.row)">编辑
  122. </el-button>
  123. <el-button v-if="scope.row.status===0" size="mini" type="danger" @click="deleteMeeting(scope.row)">删除
  124. </el-button>
  125. <el-button v-if="scope.row.status===0" size="mini" type="success" @click="startMeeting(scope.row)">开始会议
  126. </el-button>
  127. <el-button v-if="scope.row.status===1" v-show="true" size="mini" type="warning" @click="endMeetingClick(scope.row)">结束会议
  128. </el-button>
  129. <el-button v-if="scope.row.status!==0 " type="success" size="mini" @click="meetingDetail(scope.row)">会议详情
  130. </el-button>
  131. </template>
  132. </el-table-column>
  133. </el-table>
  134. <div style="margin-top: 10px;text-align: center">
  135. <Pagination v-bind:child-msg="pageparm" @callFather="callFather"></Pagination>
  136. </div>
  137. <!--编辑会议窗体-->
  138. <!-- 编辑界面 -->
  139. <el-dialog :title="title" :visible.sync="editFormVisible" width="70%" @click="closeDialog"
  140. :close-on-click-modal="false">
  141. <el-form label-width="120px" ref="form" size="mini" :model="editForm">
  142. <el-form-item label="会议主题:" prop="meetingName" :rules="[{required:true,message: '请输入会议主题', trigger: 'blur'}]">
  143. <el-input v-model="editForm.meetingName"></el-input>
  144. </el-form-item>
  145. <el-form-item label="会议类别:">
  146. <el-radio-group v-model="editForm.external" @input="changeMeetingExternal">
  147. <el-radio :label="1">外部会议</el-radio>
  148. <el-radio :label="0">内部会议</el-radio>
  149. </el-radio-group>
  150. </el-form-item>
  151. <el-row :gutter="10">
  152. <el-col :span="12">
  153. <el-form-item label="会议类型:" prop="meetingType"
  154. :rules="[{required:true,message: '请选择会议类型', trigger: 'blur'}]">
  155. <el-select v-model="editForm.meetingType" placeholder="会议类型" clearable>
  156. <el-option label="周例会" :value="1" key="周例会" v-if="editForm.external===0">周例会</el-option>
  157. <el-option label="项目会议" :value="2" key="项目会议">项目会议</el-option>
  158. <el-option label="实施会议" :value="3" key="实施会议" v-if="editForm.external===0">实施会议</el-option>
  159. <el-option label="其他会议" :value="4" key="其他会议">其他会议</el-option>
  160. </el-select>
  161. </el-form-item>
  162. </el-col>
  163. <el-col :span="12">
  164. <el-form-item label="关联项目" v-if="editForm.meetingType===2" prop="projectId"
  165. :rules="[{required:true,message: '请选择项目', trigger: 'change'}]">
  166. <el-select
  167. v-model="editForm.projectId"
  168. clearable
  169. style="width: 240px">
  170. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"/>
  171. </el-select>
  172. </el-form-item>
  173. </el-col>
  174. </el-row>
  175. <el-form-item label="会议地点:" prop="meetingPlace" :rules="[{required:true,message: '请输入会议地点', trigger: 'blur'}]">
  176. <el-input size="mini" v-model="editForm.meetingPlace"></el-input>
  177. </el-form-item>
  178. <el-form-item label="会议时间:" prop="time">
  179. <el-date-picker
  180. v-model="editForm.beginTime"
  181. type="datetime"
  182. value-format="yyyy-MM-dd HH:mm:ss"
  183. format="yyyy-MM-dd HH:mm:ss" default-time="12:00:00"
  184. placeholder="选择会议开始时间" @change="chooseMeetingStartTime">
  185. </el-date-picker>
  186. <el-date-picker
  187. v-show="endTimeShow"
  188. v-model="editForm.endTime"
  189. type="datetime"
  190. value-format="yyyy-MM-dd HH:mm:ss"
  191. format="yyyy-MM-dd HH:mm:ss" default-time="12:00:00"
  192. placeholder="选择会议结束时间" @change="chooseMeetingEndTime">
  193. </el-date-picker>
  194. </el-form-item>
  195. <el-form-item label="会议时长:" :rules="[{required:true,message: '请选择会议时长'}]">
  196. <el-select v-model="editForm.duration" placeholder="请选择会议时长" @change="chooseMeetingTime">
  197. <el-option label="15分钟" :value="15" key="15分钟">15分钟</el-option>
  198. <el-option label="30分钟" :value="30" key="30分钟">30分钟</el-option>
  199. <el-option label="45分钟" :value="45" key="45分钟">45分钟</el-option>
  200. <el-option label="1小时" :value="60" key="1小时">1小时</el-option>
  201. <el-option label="2小时" :value="120" key="2小时">2小时</el-option>
  202. <el-option label="3小时" :value="180" key="3小时">3小时</el-option>
  203. <el-option label="其他" :value="0" key="其他">其他</el-option>
  204. </el-select>
  205. </el-form-item>
  206. <el-form-item label="外部参会人员:">
  207. <el-input size="mini" v-model="editForm.outAttendees"></el-input>
  208. </el-form-item>
  209. <el-form-item label="内部参会人员:" prop="innerAttendUsers"
  210. :rules="[{required:true,message: '请选择参会人员', trigger: 'change'}]">
  211. <el-input size="mini" v-model="editForm.innerAttendUsers" :readonly="true" @keyup.enter.native="openUsers()">
  212. <el-button @click="openUsers" icon="el-icon-search" slot="append"></el-button>
  213. </el-input>
  214. </el-form-item>
  215. <el-form-item label="主持人:" prop="emcee" :rules="[{required:true,message: '请选择会议主持人', trigger: 'change'}]">
  216. <el-input size="mini" v-model="editForm.emcee" :readonly="true" @keyup.enter.native="openUsers1('emcee')">
  217. <el-button @click="openUsers1('emcee')" icon="el-icon-search" slot="append"></el-button>
  218. </el-input>
  219. </el-form-item>
  220. <el-form-item label="记录人:" prop="recorder" :rules="[{required:true,message: '请选择会议记录人', trigger: 'change'}]">
  221. <el-input size="mini" v-model="editForm.recorder" :readonly="true"
  222. @keyup.enter.native="openUsers1('recorder')">
  223. <el-button @click="openUsers1('recorder')" icon="el-icon-search" slot="append"></el-button>
  224. </el-input>
  225. </el-form-item>
  226. <el-form-item label="参会情况:" prop="remark" v-if="editForm.status>0">
  227. <el-input type="textarea" :rows="2" size="mini" v-model="editForm.remark"></el-input>
  228. </el-form-item>
  229. <el-form-item label="会议内容:">
  230. <el-table style="width: 100%" border stripe :show-header="false" :data="editForm.meetingContents">
  231. <el-table-column type="index" label="序号" width="40">
  232. </el-table-column>
  233. <el-table-column label="工作内容" prop="content">
  234. <template slot-scope="scope">
  235. <el-input size="mini" v-model="scope.row.content" placeholder="请输入会议内容"></el-input>
  236. </template>
  237. </el-table-column>
  238. <el-table-column label="操作" prop="op" width="150">
  239. <template slot-scope="scope">
  240. <el-button size="mini" type="primary" @click="addRow()">添加</el-button>
  241. <el-button size="mini" type="danger" @click="deleteRow(scope.$index, scope.row)">删除</el-button>
  242. </template>
  243. </el-table-column>
  244. </el-table>
  245. </el-form-item>
  246. <el-form-item label="会议备注:">
  247. <div id="editorElem" style="text-align:left"></div>
  248. </el-form-item>
  249. </el-form>
  250. <div slot="footer" class="dialog-footer">
  251. <el-button size="mini" @click="closeDialog">取消</el-button>
  252. <el-button size="mini" type="primary" class="title" @click="submitForm('editForm')">保存</el-button>
  253. </div>
  254. </el-dialog>
  255. <el-dialog title="选择人员" :visible.sync="usersVisble" width="30%" @click="closeUserDialog"
  256. :close-on-click-modal="false">
  257. <el-input placeholder="输入关键字进行过滤" v-model="filterText">
  258. </el-input>
  259. <el-tree
  260. ref="dept"
  261. :data="userList"
  262. node-key="id"
  263. show-checkbox
  264. :props="{label:'name'}" :default-expand-all="false"
  265. :filter-node-method="filterNode">
  266. </el-tree>
  267. <div slot="footer" class="dialog-footer">
  268. <el-button size="mini" @click="closeUserDialog">取消</el-button>
  269. <el-button size="mini" type="primary" class="title" @click="submitUserForm('editForm')">确定</el-button>
  270. </div>
  271. </el-dialog>
  272. <el-dialog title="选择人员" :visible.sync="users1Visble" width="30%" @click="closeUser1Dialog"
  273. :close-on-click-modal="false">
  274. <el-input placeholder="输入关键字进行过滤" v-model="filterText1">
  275. </el-input>
  276. <el-tree
  277. ref="dept1"
  278. :data="userList"
  279. node-key="id"
  280. :props="{label:'name'}" :default-expand-all="false"
  281. :filter-node-method="filterNode1">
  282. </el-tree>
  283. <div slot="footer" class="dialog-footer">
  284. <el-button size="mini" @click="closeUser1Dialog">取消</el-button>
  285. <el-button size="mini" type="primary" class="title" @click="submitUser1Form('editForm')">确定</el-button>
  286. </div>
  287. </el-dialog>
  288. <el-dialog :visible.sync="projectMeetingDetailVisble" width="95%" @click="closeProjectMeetingDailog" fullscreen
  289. :close-on-click-modal="false">
  290. <el-descriptions title="会议记录详情" border :column="2">
  291. <el-descriptions-item label="会议主题">
  292. {{ pro.meetingName }}
  293. </el-descriptions-item>
  294. <el-descriptions-item label="会议类别">
  295. {{ pro.external }}
  296. </el-descriptions-item>
  297. <el-descriptions-item label="会议类型">
  298. {{ pro.meetingType }}
  299. </el-descriptions-item>
  300. <el-descriptions-item label="会议地点">
  301. {{ pro.meetingPlace }}
  302. </el-descriptions-item>
  303. <el-descriptions-item label="会议时间">
  304. {{ pro.times }}
  305. </el-descriptions-item>
  306. <el-descriptions-item label="外部参会人员" v-if="pro.outAttendees!=''">
  307. {{ pro.outAttendees }}
  308. </el-descriptions-item>
  309. <el-descriptions-item label="记录人员" :span="2">
  310. {{ pro.recorder }}
  311. </el-descriptions-item>
  312. <el-descriptions-item label="内部参会人员">
  313. <span v-if="pro.innerAttendeesNew!==''" v-for="(item,index) in pro.innerAttendeesNew">
  314. <el-badge is-dot v-if="pro.meetingConfirmStatus===1">
  315. &nbsp;&nbsp;&nbsp; {{ item.name }}
  316. </el-badge>
  317. <el-badge is-dot v-else type="info">
  318. &nbsp;&nbsp;&nbsp; {{ item.name }}
  319. </el-badge>
  320. </span>
  321. </el-descriptions-item>
  322. <el-descriptions-item label="参会情况">
  323. {{ pro.remark }}
  324. </el-descriptions-item>
  325. <el-descriptions-item label="会议备注">
  326. <div v-html="pro.remarks"></div>
  327. </el-descriptions-item>
  328. </el-descriptions>
  329. <el-table style="width: 100%;margin: 0" border stripe :data="pro.meetingContents">
  330. <el-table-column label="序号" width="60" type="index"></el-table-column>
  331. <el-table-column label="会议内容" prop="content"></el-table-column>
  332. <el-table-column label="会议问题" prop="question">
  333. <template slot-scope="scope">
  334. <el-input size="mini" v-model="scope.row.question" type="textarea"
  335. :autosize="{ minRows: 4, maxRows: 10}" @input="editMeetingContents(scope.row)"></el-input>
  336. </template>
  337. </el-table-column>
  338. <el-table-column label="会议方案" prop="optionss">
  339. <template slot-scope="scope">
  340. <el-input size="mini" v-model="scope.row.optionss" type="textarea"
  341. :autosize="{ minRows: 4, maxRows: 10}" @input="editMeetingContents(scope.row)"></el-input>
  342. </template>
  343. </el-table-column>
  344. <el-table-column label="执行人" width="180">
  345. <template slot-scope="scope">
  346. <el-input size="mini" v-model="scope.row.executorName" :readonly="true"
  347. @keyup.enter.native="openUsers1('executorName',scope.row)"
  348. @input="editMeetingContents(scope.row)">
  349. <el-button @click="openUsers1('executorName',scope.row)" icon="el-icon-search" slot="append"></el-button>
  350. </el-input>
  351. </template>
  352. </el-table-column>
  353. <el-table-column label="开始日期" width="180" prop="beginTime">
  354. <template slot-scope="scope">
  355. <el-date-picker size="mini"
  356. v-model="scope.row.beginTime" format="yyyy-MM-dd"
  357. type="date" style="width: 150px"
  358. placeholder="选择开始日期" @change="editMeetingContents(scope.row)">
  359. </el-date-picker>
  360. </template>
  361. </el-table-column>
  362. <el-table-column label="结束日期" width="180" prop="endTime">
  363. <template slot-scope="scope">
  364. <el-date-picker size="mini"
  365. v-model="scope.row.endTime" format="yyyy-MM-dd"
  366. type="date" style="width: 150px"
  367. placeholder="选择结束日期" @change="editMeetingContents(scope.row)">
  368. </el-date-picker>
  369. </template>
  370. </el-table-column>
  371. </el-table>
  372. <div slot="footer" class="dialog-footer">
  373. <el-button v-if="pro.status!==0 && pro.meetingConfirmStatus===0" type="success" size="mini"
  374. @click="confirmMeeting(pro)">会议结果确认
  375. </el-button>
  376. <el-button size="mini" @click="closeProjectMeetingDailog">取消</el-button>
  377. <el-button size="mini" v-if="pro.meetingConfirmStatus===0" type="primary" class="title"
  378. @click="submitMeetingOptionsForm(pro,'editForm')">保存
  379. </el-button>
  380. </div>
  381. </el-dialog>
  382. <el-dialog :visible.sync="otherMeetingDetailVisble" width="95%" @click="closeotherMeetingDailog" fullscreen
  383. :close-on-click-modal="false">
  384. <el-descriptions title="会议记录详情" border :column="2">
  385. <el-descriptions-item label="会议主题">
  386. {{ pro.meetingName }}
  387. </el-descriptions-item>
  388. <el-descriptions-item label="会议类别">
  389. {{ pro.external }}
  390. </el-descriptions-item>
  391. <el-descriptions-item label="会议类型">
  392. {{ pro.meetingType }}
  393. </el-descriptions-item>
  394. <el-descriptions-item label="会议地点">
  395. {{ pro.meetingPlace }}
  396. </el-descriptions-item>
  397. <el-descriptions-item label="会议时间">
  398. {{ pro.times }}
  399. </el-descriptions-item>
  400. <el-descriptions-item label="外部参会人员" v-if="pro.outAttendees!=''">
  401. {{ pro.outAttendees }}
  402. </el-descriptions-item>
  403. <el-descriptions-item label="记录人员" :span="2">
  404. {{ pro.recorder }}
  405. </el-descriptions-item>
  406. <el-descriptions-item label="内部参会人员">
  407. {{ pro.innerAttendees }}
  408. </el-descriptions-item>
  409. <el-descriptions-item label="参会情况">
  410. {{ pro.remark }}
  411. </el-descriptions-item>
  412. <el-descriptions-item label="会议备注">
  413. <div v-html="pro.remarks"></div>
  414. </el-descriptions-item>
  415. </el-descriptions>
  416. <el-table style="width: 100%;margin: 0" border stripe :data="pro.meetingContents">
  417. <el-table-column label="序号" width="60" type="index"></el-table-column>
  418. <el-table-column label="会议内容" prop="content"></el-table-column>
  419. </el-table>
  420. <div slot="footer" class="dialog-footer">
  421. <el-button size="mini" @click="closeotherMeetingDailog">取消</el-button>
  422. </div>
  423. </el-dialog>
  424. </div>
  425. </template>
  426. <script>
  427. import Pagination from '../../components/Page/Pagination'
  428. import E from 'wangeditor';
  429. let editor;
  430. import {
  431. addMeeting,
  432. getMeetingsByPage,
  433. deleteMeeting,
  434. getMeetingDetailsById,
  435. deleteMeetingContentById,
  436. saveMeetingOptionss,
  437. confirmMeetings,
  438. startMeetingById,
  439. meetingAuthById,
  440. meetingDeleteAuth,
  441. endMeeting, editMeetingContent, getMeetingContentsByMeetingId
  442. } from '@/api/meeting/meeting'
  443. import {getDeptUserTree} from '@/api/system/user'
  444. import {getProjectList} from "@/api/task/project";
  445. import {getProjects} from '@/api/meeting/work'
  446. import DateUtil from "@/utils/date"
  447. export default {
  448. name: 'Meeting',
  449. watch: {
  450. filterText(val) {
  451. this.$refs.dept.filter(val);
  452. },
  453. filterText1(val) {
  454. this.$refs.dept1.filter(val);
  455. },
  456. },
  457. data() {
  458. return {
  459. filterText: null,
  460. filterText1: null,
  461. projectMeetingDetailVisble: false,
  462. otherMeetingDetailVisble: false,
  463. tableData: [],
  464. pageparm: {
  465. current: 1,
  466. size: 10,
  467. total: 0
  468. },
  469. formInline: {
  470. current: 1,
  471. size: 10,
  472. meetingEternal: '0',
  473. meetingName: '',
  474. meetingType: null,
  475. status: null,
  476. searchAuthFlag: false,
  477. },
  478. editFormVisible: false,
  479. title: '创建会议',
  480. endTimeShow: false,
  481. editForm: {
  482. id: null,
  483. meetingName: '',
  484. external: 0,
  485. meetingType: null,
  486. projectId: null,
  487. meetingPlace: '',
  488. time: null,
  489. beginTime: null,
  490. startTime: null,
  491. endTime: null,
  492. outAttendees: '',
  493. innerAttendees: '',
  494. innerAttendesss: null,
  495. innerAttendUsers: '',
  496. remark: '',
  497. emcee: '',
  498. recorder: '',
  499. duration: null,
  500. meetingContents: [
  501. {content: '会议内容', 'op': ''}
  502. ],
  503. remarks: null,
  504. },
  505. usersVisble: false,
  506. userList: [],
  507. users1Visble: false,
  508. users1Flag: '',
  509. pro: {
  510. id: '',
  511. meetingName: '',
  512. meetingType: '',
  513. external: null,
  514. meetingPlace: '',
  515. times: '',
  516. outAttendees: '',
  517. innerAttendees: '',
  518. innerAttendeesNew: [],
  519. emcee: '',
  520. recorder: '',
  521. remark: '',
  522. status: null,
  523. beginTime: null,
  524. endTime: null,
  525. meetingConfirmStatus: 0,
  526. remarks: null,
  527. meetingContents: [{
  528. id: null,
  529. meetingId: null,
  530. content: '',
  531. question: '',
  532. optionss: '',
  533. executorName: '',
  534. executorId: null,
  535. beginTime: null,
  536. endTime: null,
  537. times: []
  538. }],
  539. row: null
  540. },
  541. meetingContents:[],
  542. meetingTitle:''
  543. }
  544. },
  545. // 注册组件
  546. components: {
  547. Pagination
  548. },
  549. mounted() {
  550. this.getData(this.formInline);
  551. this.getDeptUserTrees();
  552. },
  553. methods: {
  554. getDeptUserTrees() {
  555. getDeptUserTree('1').then(res => {
  556. this.userList = res.data
  557. });
  558. },
  559. // 分页插件事件
  560. callFather(parm) {
  561. this.formInline.current = parm.current
  562. this.formInline.size = parm.size
  563. this.getData(this.formInline)
  564. },
  565. getData(data) {
  566. // 获取会议列表查询权限
  567. let permissions = this.$store.getters.permissions;
  568. for (let i = 0; i < permissions.length; i++) {
  569. if (permissions[i] === 'meeting:meeting:list') {
  570. this.formInline.searchAuthFlag = true
  571. break;
  572. }
  573. }
  574. let searchParams = data
  575. getMeetingsByPage(searchParams).then(response => {
  576. this.tableData = response.data.records;
  577. this.pageparm.total = response.data.total;
  578. });
  579. },
  580. createwangeditor() {
  581. editor = new E('#editorElem');
  582. editor.config.height = 250
  583. editor.create()
  584. editor.txt.html(this.editForm.remarks)
  585. editor.config.onchange = (html) => {
  586. this.editForm.remarks = editor.txt.html()
  587. };
  588. },
  589. createMeeting() {
  590. getProjects().then(res => {
  591. this.projectList = res.data;
  592. this.title = '创建会议'
  593. this.editFormVisible = true
  594. this.$nextTick(() => {
  595. if (editor == null) {
  596. this.createwangeditor()
  597. } else {
  598. editor.destroy();//这里做了一次判断,判断编辑器是否被创建,如果创建了就先销毁。
  599. this.createwangeditor()
  600. }
  601. });
  602. })
  603. this.editForm = {
  604. id: null,
  605. meetingName: '',
  606. external: 0,
  607. meetingType: null,
  608. projectId: null,
  609. meetingPlace: '',
  610. time: null,
  611. outAttendees: '',
  612. innerAttendees: '',
  613. innerAttendesss: null,
  614. innerAttendUsers: '',
  615. remark: '',
  616. emcee: '',
  617. recorder: '',
  618. meetingContents: [
  619. {content: '', 'op': ''}
  620. ],
  621. remarks: null
  622. }
  623. },
  624. closeDialog() {
  625. this.editFormVisible = false
  626. },
  627. addRow() {
  628. let row = {content: '', 'op': ''}
  629. this.editForm.meetingContents.push(row)
  630. },
  631. deleteRow(index, row) {
  632. if (index == 0) {
  633. this.$message({
  634. message: '不能删除会议内容',
  635. type: 'warning'
  636. });
  637. return;
  638. }
  639. this.editForm.meetingContents.splice(index, 1)
  640. if (row.id !== undefined) {
  641. deleteMeetingContentById(row.id).then(res => {
  642. });
  643. }
  644. },
  645. async meetingAuth(id) {
  646. await meetingAuthById(id).then(res => {
  647. let flag = true
  648. if (res.success === false) {
  649. flag = false
  650. this.$message.error(res.data)
  651. }
  652. return flag;
  653. });
  654. },
  655. submitForm(row, str) {
  656. this.$refs["form"].validate((valid) => {
  657. if (valid) {
  658. let data = this.editForm;
  659. let duration = data.duration;
  660. if (duration === undefined || duration === null) {
  661. this.$message.error("请选择会议时长!")
  662. return
  663. } else {
  664. let times = []
  665. times.push(this.editForm.beginTime)
  666. times.push(this.editForm.endTime)
  667. this.editForm.time = times
  668. addMeeting(data).then(response => {
  669. this.$message({
  670. message: '操作成功!',
  671. type: 'success'
  672. });
  673. this.closeDialog();
  674. this.getData(this.formInline);
  675. });
  676. }
  677. } else {
  678. return false;
  679. }
  680. });
  681. },
  682. resetSearch() {
  683. this.formInline = {
  684. current: 1,
  685. size: 10,
  686. meetingEternal: 0,
  687. meetingName: '',
  688. meetingType: null,
  689. status: null,
  690. searchAuthFlag:false
  691. }
  692. this.getData(this.formInline);
  693. },
  694. search() {
  695. let searchParams = this.formInline
  696. this.getData(searchParams);
  697. },
  698. deleteMeeting(row) {
  699. //删除会议
  700. let id = row.id;
  701. //验证会议删除权限--创建者才能删除
  702. meetingAuthById(id).then(res => {
  703. if (res.success === false) {
  704. this.$message.error(res.data)
  705. } else {
  706. deleteMeeting(id).then(() => {
  707. this.$message({
  708. message: '操作成功!',
  709. type: 'success'
  710. });
  711. this.getData(this.formInline);
  712. })
  713. }
  714. });
  715. },
  716. confirmMeeting(row) {
  717. let status = row.status;
  718. if (status !== 2) {
  719. this.$message.warning("会议暂未结束,请会议结束后在确认!");
  720. return
  721. }
  722. let meetingConfirmStatus = row.meetingConfirmStatus
  723. if (meetingConfirmStatus === 1) {
  724. this.$message.warning("会议已经确认,请勿再次操作!")
  725. return
  726. }
  727. let id = row.id;
  728. //点击会议确认时候判断信息是否完整
  729. let data = this.pro.meetingContents;
  730. for (let i = 0; i < data.length; i++) {
  731. let t = data[i];
  732. if (t.question === '' || t.optionss === '' || t.executorName === '' || t.times === null || t.times.length === 0) {
  733. this.$message({
  734. message: '请将信息填写完整!',
  735. type: 'warning'
  736. });
  737. return
  738. }
  739. }
  740. saveMeetingOptionss(data).then(res => {
  741. confirmMeetings(id).then(res => {
  742. this.$message({
  743. message: '操作成功!',
  744. type: 'success'
  745. });
  746. this.getData(this.formInline);
  747. this.projectMeetingDetailVisble = false
  748. });
  749. });
  750. },
  751. meetingDetail(row) {
  752. let meetingType = row.meetingType
  753. if (meetingType !== 1) {
  754. if (row.meetingType == 2) {
  755. //this.projectMeetingDetailVisble = true
  756. } else {
  757. this.otherMeetingDetailVisble = true
  758. }
  759. this.pro.meetingName = row.meetingName
  760. this.pro.outAttendees = row.outAttendees
  761. this.pro.innerAttendees = row.innerAttendees
  762. this.pro.recorder = row.recorder
  763. this.pro.times = row.beginTime + '至' + row.endTime
  764. this.pro.beginTime = row.beginTime
  765. this.pro.endTime = row.endTime
  766. this.pro.meetingPlace = row.meetingPlace
  767. this.pro.meetingConfirmStatus = row.meetingConfirmStatus
  768. this.pro.remarks = row.remarks
  769. let meetingType = row.meetingType
  770. //1-周例会,2-项目会议,3-实施会议,4-其他会议
  771. let meetingTypeNames = '';
  772. if (meetingType === 1) {
  773. meetingTypeNames = '周例会'
  774. } else if (meetingType === 2) {
  775. meetingTypeNames = '项目会议'
  776. } else if (meetingType === 3) {
  777. meetingTypeNames = '实施会议'
  778. } else {
  779. meetingTypeNames = '其他会议'
  780. }
  781. this.pro.meetingType = meetingTypeNames
  782. let external = row.external
  783. if (external === 0) {
  784. this.pro.external = '内部会议'
  785. } else {
  786. this.pro.external = '外部会议'
  787. }
  788. let innerAttendees = JSON.parse(row.innerAttendees);
  789. let innerPeople = '';
  790. for (let i = 0; i < innerAttendees.length; i++) {
  791. innerPeople += innerAttendees[i].name + '、'
  792. }
  793. innerPeople = innerPeople.substring(0, innerPeople.length - 1);
  794. this.pro.innerAttendees = innerPeople
  795. this.pro.remark = row.remark
  796. this.pro.status = row.status
  797. let meetingId = row.id
  798. this.pro.id = row.id
  799. getMeetingDetailsById(meetingId).then(res => {
  800. let data = res.data.meetingContents
  801. let innerAttendess = JSON.parse(res.data.innerAttendees)
  802. let temp = [];
  803. for (let i = 0; i < innerAttendess.length; i++) {
  804. temp.push(innerAttendess[i])
  805. }
  806. this.pro.innerAttendeesNew = temp
  807. this.pro.meetingContents = data
  808. if (row.meetingType === 2) {
  809. this.projectMeetingDetailVisble = true
  810. }
  811. });
  812. }
  813. if (meetingType === 1) {
  814. let params = {
  815. meetingId: row.id,
  816. weeks: row.weeks
  817. }
  818. this.$router.push({path: '/meeting/weeklyRecords', query: params});
  819. }
  820. },
  821. startMeeting(row) {
  822. let id = row.id;
  823. meetingAuthById(id).then(res => {
  824. if (res.success === false) {
  825. this.$message.error(res.data)
  826. } else {
  827. startMeetingById(id).then(res => {
  828. this.$message({
  829. message: '操作成功!',
  830. type: 'success'
  831. });
  832. this.getData(this.formInline);
  833. })
  834. }
  835. })
  836. },
  837. endMeetingClick(row) {
  838. let id = row.id;
  839. meetingAuthById(id).then(res => {
  840. if (res.success === false) {
  841. this.$message.error(res.data)
  842. } else {
  843. endMeeting(id).then(res => {
  844. this.$message({
  845. message: '操作成功!',
  846. type: 'success'
  847. });
  848. this.getData(this.formInline);
  849. })
  850. }
  851. })
  852. },
  853. openUsers() {
  854. this.usersVisble = true
  855. },
  856. closeUserDialog() {
  857. this.usersVisble = false
  858. },
  859. submitUserForm() {
  860. //获取选中的节点
  861. let node = this.$refs.dept.getCheckedNodes();
  862. if (node == undefined || node == null || node.length === 0) {
  863. this.$message({
  864. message: '请选择人员数据!',
  865. type: 'warning'
  866. });
  867. return;
  868. }
  869. let userList = []
  870. let userName = ''
  871. let saveUsers = []
  872. node.forEach(item => {
  873. if (item.type === 'u') {
  874. userList.push(item);
  875. userName += item.name + '、';
  876. saveUsers.push({
  877. id: item.id,
  878. name: item.name
  879. })
  880. }
  881. })
  882. userName = userName.substring(0, userName.length - 1);
  883. if (userList.length === 0) {
  884. this.$message({
  885. message: '请选择人员!',
  886. type: 'warning'
  887. });
  888. return;
  889. }
  890. this.closeUserDialog()
  891. this.editForm.innerAttendUsers = userName
  892. this.editForm.innerAttendesss = saveUsers
  893. },
  894. closeUser1Dialog() {
  895. this.users1Visble = false
  896. },
  897. openUsers1(data, row) {
  898. this.users1Visble = true
  899. this.users1Flag = data
  900. this.pro.row = row
  901. },
  902. submitUser1Form() {
  903. let node = this.$refs.dept1.getCurrentNode();
  904. if (node == undefined || node == null) {
  905. this.$message({
  906. message: '请选择数据!',
  907. type: 'warning'
  908. });
  909. return;
  910. }
  911. if (node.type !== 'u') {
  912. this.$message({
  913. message: '请选择人员!',
  914. type: 'warning'
  915. });
  916. return;
  917. }
  918. let user1Flag = this.users1Flag;
  919. if (user1Flag === 'emcee') {
  920. this.editForm.emcee = node.name
  921. } else if (user1Flag === 'executorName') {
  922. let row = this.pro.row
  923. row.executorName = node.name
  924. row.executorId = node.id
  925. this.pro.meetingContents.executorName = node.name
  926. this.pro.meetingContents.executorId = node.id
  927. } else {
  928. this.editForm.recorder = node.name
  929. }
  930. this.closeUser1Dialog()
  931. },
  932. handleEdit(row) {
  933. let meetingId = row.id
  934. meetingAuthById(meetingId).then(res => {
  935. if (res.success === false) {
  936. this.$message.error(res.data)
  937. } else {
  938. getProjectList("").then(res => {
  939. this.projectList = res.data;
  940. })
  941. getMeetingDetailsById(row.id).then(res => {
  942. let data = res.data
  943. this.editForm = data
  944. let users = JSON.parse(data.innerAttendees)
  945. this.editForm.innerAttendees = ''
  946. for (let i = 0; i < users.length; i++) {
  947. this.editForm.innerAttendees += users[i].name + ','
  948. }
  949. this.editForm.innerAttendees = this.editForm.innerAttendees.substring(0, this.editForm.innerAttendees.length - 1)
  950. this.editForm.innerAttendesss = users;
  951. this.editForm.innerAttendUsers = this.editForm.innerAttendees
  952. this.editForm.meetingType = data.meetingType
  953. let time = [];
  954. time.push(data.beginTime);
  955. time.push(data.endTime);
  956. this.editForm.time = time;
  957. this.editForm.endTime = data.endTime
  958. this.editForm.duration = data.duration
  959. if (this.editForm.duration === 0) {
  960. this.endTimeShow = true
  961. }
  962. this.title = '修改会议'
  963. this.editFormVisible = true
  964. this.$nextTick(() => {
  965. if (editor == null) {
  966. this.createwangeditor()
  967. } else {
  968. editor.destroy();//这里做了一次判断,判断编辑器是否被创建,如果创建了就先销毁。
  969. this.createwangeditor()
  970. }
  971. });
  972. });
  973. }
  974. });
  975. },
  976. chooseMeeting() {
  977. let val = this.formInline.meetingEternal;
  978. let search = this.formInline
  979. search.meetingEternal = val;
  980. this.getData(search)
  981. },
  982. closeProjectMeetingDailog() {
  983. this.projectMeetingDetailVisble = false;
  984. },
  985. submitMeetingOptionsForm(row, str) {
  986. let meetingConfirmStatus = row.meetingConfirmStatus
  987. if (meetingConfirmStatus === 1) {
  988. this.$message.warning("会议已经确认,请勿再次操作!")
  989. return
  990. }
  991. let data = this.pro.meetingContents;
  992. let datas=[]
  993. for (let i = 0; i < data.length; i++) {
  994. let t = data[i];
  995. if (t.question === '' || t.optionss === '' || t.executorName === '' || t.beginTime === null || t.endTime === null) {
  996. this.$message({
  997. message: '请将信息填写完整!',
  998. type: 'warning'
  999. });
  1000. return
  1001. }
  1002. t.beginTime=new Date(t.beginTime).getTime()
  1003. t.endTime=new Date(t.endTime).getTime()
  1004. t.times=[]
  1005. datas.push(t)
  1006. }
  1007. saveMeetingOptionss(datas).then(res => {
  1008. this.$message({
  1009. message: '操作成功!',
  1010. type: 'success'
  1011. });
  1012. this.closeProjectMeetingDailog();
  1013. });
  1014. },
  1015. closeotherMeetingDailog() {
  1016. this.otherMeetingDetailVisble = false;
  1017. },
  1018. changeMeetingExternal() {
  1019. },
  1020. chooseMeetingTime() {
  1021. //选择会议时长
  1022. let duration = this.editForm.duration
  1023. if (duration === 0) {
  1024. this.endTimeShow = true
  1025. } else {
  1026. this.endTimeShow = false
  1027. //计算会议结束日期
  1028. let beginTime = this.editForm.beginTime
  1029. if (beginTime === undefined || beginTime === null) {
  1030. return
  1031. }
  1032. let endTime = DateUtil.afterTime(beginTime, duration)
  1033. this.editForm.endTime = endTime
  1034. }
  1035. },
  1036. addMinutesToCurrentTime(minutes) {
  1037. let currentDate = new Date();
  1038. let newDate = new Date(currentDate.getTime() + minutes * 60000);
  1039. return newDate;
  1040. },
  1041. chooseMeetingStartTime() {
  1042. let beginTime = this.editForm.beginTime
  1043. if (beginTime === undefined || beginTime === null) {
  1044. this.$message.error("请选择会议开始时间!")
  1045. return
  1046. }
  1047. let duration = this.editForm.duration
  1048. if (duration === undefined || duration === null) {
  1049. return;
  1050. }
  1051. let endTime = DateUtil.afterTime(beginTime, duration);
  1052. this.editForm.endTime = endTime
  1053. },
  1054. chooseMeetingEndTime() {
  1055. let startTime = this.editForm.beginTime
  1056. let endTime = this.editForm.endTime
  1057. if (startTime === undefined || startTime === null) {
  1058. this.$message.error("请选择会议开始时间!")
  1059. return
  1060. }
  1061. if (endTime === undefined || endTime === null) {
  1062. this.$message.error("请选择会议结束时间!")
  1063. return
  1064. }
  1065. if (startTime > endTime) {
  1066. this.$message.error("会议开始时间不能大于会议结束时间!")
  1067. this.editForm.endTime = null
  1068. return
  1069. }
  1070. //计算时长
  1071. let calculateTimeDuration = this.calculateTimeDuration(startTime, endTime);
  1072. this.editForm.duration = calculateTimeDuration
  1073. },
  1074. calculateTimeDuration(time1, time2) {
  1075. let date1 = new Date(time1);
  1076. let date2 = new Date(time2);
  1077. let duration = Math.abs(date1.getTime() - date2.getTime());
  1078. let arr = [15, 30, 45, 60, 120, 180]
  1079. if (arr.indexOf(duration) < 0) {
  1080. duration = 0
  1081. }
  1082. return duration;
  1083. },
  1084. editMeetingContents(row) {
  1085. let data = row;
  1086. if(row.beginTime!==undefined && row.beginTime!=null){
  1087. data.beginTime=new Date(row.beginTime).getTime();
  1088. }
  1089. if(row.endTime!==undefined && row.endTime!=null){
  1090. data.endTime=new Date(row.endTime).getTime()
  1091. }
  1092. data.times=[]
  1093. editMeetingContent(data).then(res => {
  1094. // this.$message.success("操作成功!")
  1095. });
  1096. },
  1097. filterNode(value, data) {
  1098. if (!value) {
  1099. return true
  1100. }
  1101. return data.name.indexOf(value) !== -1;
  1102. },
  1103. filterNode1(value, data) {
  1104. if (!value) {
  1105. return true
  1106. }
  1107. return data.name.indexOf(value) !== -1;
  1108. },
  1109. searchMeetingContent(row){
  1110. let id=row.id
  1111. this.meetingTitle=row.meetingName
  1112. getMeetingContentsByMeetingId(id).then(res => {
  1113. let contents=res.data
  1114. this.meetingContents=contents
  1115. })
  1116. }
  1117. }
  1118. }
  1119. </script>
  1120. <style scoped lang="scss">
  1121. .el-form-item--mini.el-form-item, .el-form-item--small.el-form-item {
  1122. margin-bottom: 10px;
  1123. }
  1124. </style>