addressManager.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <div class='m-container'>
  3. <h2>
  4. <div class="squrt"></div>教学点管理
  5. </h2>
  6. <div class="m-core">
  7. <div @click="openTeaching('create')"
  8. v-permission="'school/add'"
  9. class='newBand'>新建</div>
  10. <save-form :inline="true"
  11. class="searchForm"
  12. @submit="search"
  13. :model="searchForm">
  14. <el-form-item>
  15. <el-input type="text"
  16. clearable
  17. v-model.trim="searchForm.search"
  18. placeholder="教学点名称"></el-input>
  19. </el-form-item>
  20. <el-form-item>
  21. <el-select v-model.trim="searchForm.organId"
  22. clearable
  23. filterable
  24. placeholder="请选择分部">
  25. <el-option v-for="item in selects.branchs"
  26. :key="item.id"
  27. :label="item.name"
  28. :value="item.id"></el-option>
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item>
  32. <el-button native-type="submit" type="danger">搜索</el-button>
  33. </el-form-item>
  34. </save-form>
  35. <!-- 列表 -->
  36. <div class="tableWrap">
  37. <el-table :data='tableList'
  38. :header-cell-style="{background:'#EDEEF0',color:'#444'}">
  39. <el-table-column align='center'
  40. width="55"
  41. prop="id"
  42. label="编号">
  43. </el-table-column>
  44. <el-table-column align='center'
  45. prop="name"
  46. label="教学点名称">
  47. </el-table-column>
  48. <el-table-column align="center"
  49. prop="organName"
  50. label="所属分部">
  51. </el-table-column>
  52. <el-table-column align='center'
  53. label="教学点来源"
  54. :formatter="filterOrgan"
  55. width="120px">
  56. <!-- <template slot-scope="scope">
  57. {{ scope.row.cooperationOrganId ? scope.row.cooperationOrganId : '租赁' }}
  58. </template> -->
  59. </el-table-column>
  60. <el-table-column align='center'
  61. width="120px"
  62. label="费用">
  63. <template slot-scope="scope">
  64. {{ scope.row.cooperationOrganId ? '免费' : scope.row.remark }}
  65. </template>
  66. </el-table-column>
  67. <el-table-column align='center'
  68. label="上课地点详情">
  69. <template slot-scope="scope">
  70. {{ scope.row.address.split(',').join('') }}
  71. </template>
  72. </el-table-column>
  73. <el-table-column align='center'
  74. prop="delFlag"
  75. label="状态">
  76. <template slot-scope="scope">
  77. {{ scope.row.delFlag == 2 ? '停用' : '启用' }}
  78. </template>
  79. </el-table-column>
  80. <!-- <el-table-column align='center'
  81. label="课酬补贴">
  82. <template slot-scope="scope">
  83. {{ scope.row.subsidy ? scope.row.subsidy : '无' }}
  84. </template>
  85. </el-table-column> -->
  86. <el-table-column align='center'
  87. label="操作">
  88. <template slot-scope="scope">
  89. <el-button @click="openTeaching('update', scope.row)"
  90. v-permission="'school/update'"
  91. type="text">修改</el-button>
  92. <el-button v-if="scope.row.delFlag == 0"
  93. v-permission="'school/update'"
  94. @click="onUpdateSubmit(scope.row, 2)"
  95. type="text">停用</el-button>
  96. <el-button v-if="scope.row.delFlag == 2"
  97. v-permission="'school/update'"
  98. @click="onUpdateSubmit(scope.row, 0)"
  99. type="text">启用</el-button>
  100. <el-button @click="onUpdateSubmit(scope.row, 1)"
  101. v-permission="'school/update'"
  102. type="text">删除</el-button>
  103. </template>
  104. </el-table-column>
  105. </el-table>
  106. <pagination sync :total.sync="pageInfo.total"
  107. :page.sync="pageInfo.page"
  108. :limit.sync="pageInfo.limit"
  109. :page-sizes="pageInfo.page_size"
  110. @pagination="getList" />
  111. </div>
  112. </div>
  113. <el-dialog :title="formTitle[formActionTitle]"
  114. :visible.sync="teachingStatus"
  115. @close="onFormClose('ruleForm')"
  116. width="500px">
  117. <el-form :model="form"
  118. :rules="rules"
  119. ref="ruleForm">
  120. <el-form-item label="教学点名称"
  121. prop="name"
  122. :label-width="formLabelWidth">
  123. <el-input v-model.trim="form.name"
  124. autocomplete="off"></el-input>
  125. </el-form-item>
  126. <el-form-item label="教学点来源"
  127. prop="source"
  128. :label-width="formLabelWidth">
  129. <template v-if="formActionTitle == 'update'">
  130. <el-select v-model.trim="form.source"
  131. style="width: 100% !important;"
  132. filterable
  133. clearable
  134. disabled>
  135. <el-option label="合作单位"
  136. value="1"></el-option>
  137. <el-option label="租赁"
  138. value="2"></el-option>
  139. </el-select>
  140. </template>
  141. <template v-else>
  142. <el-select v-model.trim="form.source"
  143. filterable
  144. style="width: 100% !important;"
  145. clearable>
  146. <el-option label="合作单位"
  147. value="1"></el-option>
  148. <el-option label="租赁"
  149. value="2"></el-option>
  150. </el-select>
  151. </template>
  152. </el-form-item>
  153. <el-form-item v-if="form.source == 1"
  154. prop="cooperationOrganId"
  155. label="合作单位"
  156. :label-width="formLabelWidth">
  157. <el-select v-model.trim="form.cooperationOrganId"
  158. filterable
  159. style="width: 100% !important;"
  160. clearable
  161. @change="onCooperationChange">
  162. <el-option v-for="item in cooperationList"
  163. :key="item.value"
  164. :label="item.label"
  165. :value="item.value"></el-option>
  166. </el-select>
  167. </el-form-item>
  168. <el-form-item v-if="form.source == 2"
  169. prop="remark"
  170. label="费用"
  171. :label-width="formLabelWidth">
  172. <el-input v-model.trim="form.remark"
  173. autocomplete="off"></el-input>
  174. </el-form-item>
  175. <el-form-item v-if="form.source == 2"
  176. prop="organId"
  177. label="所属分部"
  178. :label-width="formLabelWidth">
  179. <el-select v-model.trim="form.organId"
  180. clearable
  181. style="width: 100% !important;"
  182. filterable>
  183. <el-option v-for="item in selects.branchs"
  184. :key="item.id"
  185. :label="item.name"
  186. :value="item.id"></el-option>
  187. </el-select>
  188. </el-form-item>
  189. <el-form-item prop="address"
  190. :show-message="addressMessage"
  191. label="上课地点"
  192. :label-width="formLabelWidth">
  193. <el-input class="text-address"
  194. v-model.trim="form.address"
  195. :disabled="true">
  196. <el-button slot="append"
  197. @click="addMap"
  198. type="primary"
  199. icon="el-icon-plus">选择</el-button>
  200. </el-input>
  201. </el-form-item>
  202. <el-form-item label="课酬补贴"
  203. prop="subsidy"
  204. :label-width="formLabelWidth">
  205. <el-input v-model.trim.number="form.subsidy"
  206. type="number"
  207. autocomplete="off"></el-input>
  208. </el-form-item>
  209. </el-form>
  210. <span slot="footer"
  211. class="dialog-footer">
  212. <el-button @click="onTeachingCancel('ruleForm')">取 消</el-button>
  213. <el-button type="primary"
  214. @click="onTeachingSubmit('ruleForm')">确 定</el-button>
  215. </span>
  216. </el-dialog>
  217. <el-dialog :close-on-click-modal="false"
  218. title="选择地图"
  219. custom-class="map-container"
  220. :visible.sync="mapStatus"
  221. width="800px">
  222. <el-amap-search-box class="search-box"
  223. value="searchValue"
  224. :search-option="searchOption"
  225. :on-search-result="onSearchResult"></el-amap-search-box>
  226. <el-amap :zoom="zoom"
  227. :plugin="plugin"
  228. :center="center">
  229. <el-amap-marker :events="markerEvents()"
  230. v-for="(marker, index) in markers"
  231. :key="index"
  232. :position="marker"></el-amap-marker>
  233. </el-amap>
  234. </el-dialog>
  235. </div>
  236. </template>
  237. <script>
  238. import pagination from '@/components/Pagination/index'
  239. // 地图
  240. (function () {
  241. let func = EventTarget.prototype.addEventListener;
  242. let supportsPassive = false
  243. try {
  244. let opts = Object.defineProperty({}, 'passive', {
  245. get: function () {
  246. supportsPassive = true;
  247. }
  248. })
  249. document.addEventListener("testPassive", null, opts);
  250. document.removeEventListener('testPassive', null, opts);
  251. } catch (e) { }
  252. EventTarget.prototype.addEventListener = function (type, fn, capture) {
  253. this.func = func;
  254. capture = capture instanceof Object ? capture : {};
  255. capture.passive = supportsPassive;
  256. this.func(type, fn, capture);
  257. };
  258. }());
  259. import { schoolQueryPage, schoolAdd, schoolUpdate, queryByOrganId, schoolDel } from '@/api/systemManage'
  260. import { getEmployeeOrgan } from '@/api/buildTeam'
  261. import store from '@/store'
  262. import VueAMap from 'vue-amap'
  263. // Vue.use(VueAMap)
  264. VueAMap.initAMapApiLoader({
  265. key: 'b1e6ac2eb28902ce91a490edf194e000',
  266. plugin: ['AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Geocoder'],
  267. v: '1.4.4'
  268. })
  269. export default {
  270. name: 'addressManager',
  271. components: { pagination },
  272. data () {
  273. let self = this
  274. return {
  275. searchForm: {
  276. search: null,
  277. organId: null
  278. },
  279. searchLsit: [],
  280. tableList: [],
  281. pageInfo: {
  282. // 分页规则
  283. limit: 10, // 限制显示条数
  284. page: 1, // 当前页
  285. total: 0, // 总条数
  286. page_size: [10, 20, 40, 50] // 选择限制显示条数
  287. },
  288. formActionTitle: 'create',
  289. formTitle: {
  290. create: '添加教学点',
  291. update: '修改教学点'
  292. },
  293. teachingStatus: false, // 添加教学点
  294. formLabelWidth: '100px',
  295. addressDetail: {},
  296. form: {
  297. name: null, // 教学点名称
  298. source: null, // 来源
  299. cooperationOrganId: null, // 合作单位
  300. remark: null, // 费用
  301. address: null, // 上课地点
  302. subsidy: null, // 课酬补贴
  303. organId: null, // 分部编号
  304. },
  305. selectOrganId: null, // 选中的分部编号
  306. rules: {
  307. name: [{ required: true, message: '请输入教学点名称', trigger: 'blur' }],
  308. source: [{ required: true, message: '请选择教学点来源', trigger: 'change' }],
  309. remark: [{ required: true, message: '请输入费用', trigger: 'blur' }],
  310. address: [{ required: true, message: '请选择上课地点', trigger: 'blur' }],
  311. cooperationOrganId: [{ required: true, message: '请选择合作单位', trigger: 'change' }],
  312. organId: [{ required: true, message: '请选择所属分部', trigger: 'change' }],
  313. subsidy: [{ type: 'number', message: '课酬补贴只能为数字', trigger: 'blur' }]
  314. },
  315. addressMessage: true,
  316. mapStatus: false,
  317. zoom: 16,
  318. center: [114.34371, 30.55939],
  319. markers: [],
  320. plugin: [],
  321. searchOption: {
  322. city: '',
  323. citylimit: true,
  324. pageSize: 1, // 单页显示结果条数
  325. pageIndex: 1, // 页码
  326. autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  327. },
  328. cooperationList: [], // 合作单位列表
  329. searchValue: '测试'
  330. }
  331. },
  332. mounted () {
  333. this.getList()
  334. this.getBreachList()
  335. },
  336. methods: {
  337. onTeachingSubmit (formName) { // 添加数据
  338. this.$refs[formName].validate((valid) => {
  339. if (valid) {
  340. this.form.address = this.addressDetail.address
  341. this.form.longitudeLatitude = this.addressDetail.poi
  342. // if(this.form.source == 1) { // 判断是租赁还是合作单位
  343. // this.form.organId = this.selectOrganId
  344. // }
  345. if (this.formActionTitle == 'create') {
  346. schoolAdd(this.form).then(res => {
  347. if (res.code == 200) {
  348. this.$message.success('添加成功')
  349. this.teachingStatus = false
  350. this.getList()
  351. } else {
  352. this.$message.error(res.msg)
  353. }
  354. })
  355. } else if (this.formActionTitle == 'update') {
  356. schoolUpdate(this.form).then(res => {
  357. if (res.code == 200) {
  358. this.$message.success('修改成功')
  359. this.teachingStatus = false
  360. this.getList()
  361. } else {
  362. this.$message.error(res.msg)
  363. }
  364. })
  365. }
  366. } else {
  367. return false;
  368. }
  369. })
  370. },
  371. onTeachingCancel (formName) {
  372. this.teachingStatus = false
  373. this.$refs[formName].clearValidate()
  374. },
  375. addMap () { //
  376. this.mapStatus = true
  377. let poi = this.addressDetail.poi
  378. let address = this.addressDetail.address
  379. // 获取经纬度
  380. if (poi) {
  381. this.markers = []
  382. this.center = [poi.split(',')[0], poi.split(',')[1]]
  383. this.markers.push([poi.split(',')[0], poi.split(',')[1]])
  384. } else if (address && poi == '') {
  385. let that = this
  386. //构造地点查询类
  387. let placeSearch = new AMap.PlaceSearch({
  388. pageSize: 1, // 单页显示结果条数
  389. pageIndex: 1, // 页码
  390. })
  391. //关键字查询
  392. placeSearch.search(address, function (status, result) {
  393. if (status === 'complete') {
  394. let pois = result.poiList.pois[0]
  395. poi = pois.location.lng + ',' + pois.location.lat
  396. that.center = [pois.location.lng, pois.location.lat]
  397. that.markers.push([pois.location.lng, pois.location.lat])
  398. }
  399. })
  400. }
  401. },
  402. onCooperationChange (value) {
  403. this.cooperationList.forEach(item => {
  404. if (item.value == value) {
  405. // this.selectOrganId = item.organId
  406. this.form.organId = item.organId
  407. }
  408. })
  409. },
  410. onSearchResult (pois) { // 搜索出来的Marker
  411. this.markers = [] // 搜索时进行数据重置
  412. let latSum = 0
  413. let lngSum = 0
  414. if (pois.length > 0) {
  415. pois.forEach(poi => {
  416. let { lng, lat } = poi;
  417. lngSum += lng;
  418. latSum += lat;
  419. this.markers.push([poi.lng, poi.lat]);
  420. });
  421. let center = {
  422. lng: lngSum / pois.length,
  423. lat: latSum / pois.length
  424. };
  425. this.center = [center.lng, center.lat];
  426. }
  427. },
  428. markerEvents () { // marker 事件添加
  429. let that = this
  430. return {
  431. click: (e) => {
  432. let geocoder = new AMap.Geocoder()
  433. geocoder.getAddress(e.lnglat, function (status, result) {
  434. if (status === 'complete' && result.regeocode) {
  435. result.regeocode.lnglat = e.lnglat
  436. let ct = result.regeocode.addressComponent
  437. that.addressDetail = {
  438. address: ct.province + ',' + ct.city + ',' + ct.district + ',' + ct.township + ct.street + ct.streetNumber,
  439. poi: e.lnglat.lng + ',' + e.lnglat.lat
  440. }
  441. that.form.address = result.regeocode.formattedAddress
  442. that.mapStatus = false
  443. that.addressMessage = false
  444. } else {
  445. that.$message.error('请重新选择地址')
  446. }
  447. })
  448. }
  449. }
  450. },
  451. getList () {
  452. let searchForm = this.searchForm
  453. let params = {
  454. search: searchForm.search ? searchForm.search : null,
  455. organId: searchForm.organId ? searchForm.organId : null,
  456. rows: this.pageInfo.limit,
  457. page: this.pageInfo.page
  458. }
  459. schoolQueryPage(params).then(res => {
  460. if (res.code == 200 && res.data) {
  461. this.tableList = res.data.rows
  462. this.pageInfo.total = res.data.total
  463. }
  464. })
  465. },
  466. async getBreachList () { // 获取分部列表
  467. // 获取当前用户分部
  468. await this.$store.dispatch('setBranchs')
  469. let branchIds = []
  470. this.selects.branchs.forEach(item => {
  471. branchIds.push(item.id)
  472. })
  473. await queryByOrganId({
  474. organId: branchIds.join(',')
  475. }).then(res => {
  476. if (res.code == 200) {
  477. // 判断是否有数据
  478. if (!res.data && res.data.length <= 0) return
  479. res.data.forEach(r => {
  480. this.cooperationList.push({
  481. value: r.id,
  482. organId: r.organId,
  483. label: r.name
  484. })
  485. })
  486. }
  487. })
  488. },
  489. openTeaching (type, row) {
  490. // 重置数据
  491. // this.form = {
  492. // id: null,
  493. // name: null, // 教学点名称
  494. // linkman: null, // 来源
  495. // job: null, // 费用
  496. // mobileNo: null, // 合作单位
  497. // }
  498. this.teachingStatus = true
  499. this.formActionTitle = type
  500. // this.form.organId = ''
  501. // 修改的时候赋值
  502. if (type == 'update') {
  503. this.addressDetail = {
  504. address: row.address,
  505. poi: row.longitudeLatitude
  506. }
  507. this.form = {
  508. id: row.id,
  509. name: row.name, // 教学点名称
  510. source: row.cooperationOrganId ? "1" : "2", // 来源
  511. cooperationOrganId: row.cooperationOrganId, // 合作单位
  512. remark: row.remark, // 费用
  513. address: row.address.split(',').join(''), // 上课地点
  514. subsidy: row.subsidy, // 课酬补贴
  515. organId: row.organId
  516. }
  517. }
  518. },
  519. onFormClose (formName) { // 关闭弹窗重置验证
  520. // this.$refs[formName].clearValidate()
  521. this.form = {
  522. name: null, // 教学点名称
  523. source: null, // 来源
  524. cooperationOrganId: null, // 合作单位
  525. remark: null, // 费用
  526. address: null, // 上课地点
  527. subsidy: null, // 课酬补贴
  528. }
  529. this.$refs[formName].resetFields()
  530. },
  531. filterOrgan (val) {
  532. let result = ''
  533. if (val.cooperationOrganId) {
  534. this.cooperationList.forEach(res => {
  535. if (res.value == val.cooperationOrganId) {
  536. result = res.label
  537. }
  538. })
  539. } else {
  540. result = '租赁'
  541. }
  542. return result
  543. },
  544. onUpdateSubmit (row, type) {
  545. let msg
  546. if (type == 2) {
  547. msg = '停用'
  548. } else if (type == 0) {
  549. msg = '启用'
  550. } else {
  551. msg = '删除'
  552. }
  553. this.$confirm(`您确定${msg}吗?`, '提示', {
  554. confirmButtonText: '确定',
  555. cancelButtonText: '取消',
  556. type: 'warning'
  557. }).then(() => {
  558. schoolUpdate({
  559. id: row.id,
  560. delFlag: type
  561. }).then(res => {
  562. if (res.code == 200) {
  563. this.$message.success('修改成功')
  564. this.teachingStatus = false
  565. if (type == 2 || type == 0) {
  566. row.delFlag = type
  567. } else {
  568. this.getList()
  569. }
  570. } else {
  571. this.$message.error(res.msg)
  572. }
  573. })
  574. })
  575. },
  576. search () {
  577. this.pageInfo.page = 1
  578. this.getList()
  579. }
  580. }
  581. }
  582. </script>
  583. <style lang="scss">
  584. .el-select {
  585. width: auto !important;
  586. }
  587. .el-vue-amap-container {
  588. width: 100%;
  589. height: 50vh !important;
  590. }
  591. * {
  592. // touch-action: pan-y;
  593. touch-action: none;
  594. }
  595. .map-container {
  596. .el-dialog__body {
  597. padding: 0;
  598. }
  599. }
  600. .el-input-group__append,
  601. .el-button--primary {
  602. background: #14928a;
  603. border-color: #14928a;
  604. color: #fff;
  605. &:hover,
  606. &:active,
  607. &:focus {
  608. background: #14928a;
  609. border-color: #14928a;
  610. color: #fff;
  611. }
  612. }
  613. .el-vue-search-box-container {
  614. position: absolute !important;
  615. left: 10px;
  616. margin-top: 10px;
  617. z-index: 99999 !important;
  618. }
  619. </style>