branchSetting.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 分部管理
  6. </h2>
  7. <div class="m-core">
  8. <save-form
  9. :inline="true"
  10. class="searchForm"
  11. saveKey="contentFlashPage"
  12. @submit="search"
  13. :model="searchForm"
  14. >
  15. <el-form-item prop="search">
  16. <el-input
  17. v-model.trim="searchForm.search"
  18. clearable
  19. @keyup.enter.native="search"
  20. placeholder="分部名称、编号"
  21. ></el-input>
  22. </el-form-item>
  23. <el-form-item>
  24. <el-button native-type="submit" type="danger">搜索</el-button>
  25. <el-button @click="onReSet" type="primary">重置</el-button>
  26. </el-form-item>
  27. </save-form>
  28. <el-button
  29. @click="onBranchOperation('create')"
  30. v-permission="'organization/add'"
  31. type="primary"
  32. style="margin-bottom: 20px"
  33. >
  34. 新建
  35. </el-button>
  36. <!-- 列表 -->
  37. <div class="tableWrap">
  38. <el-table
  39. :data="tableList"
  40. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  41. >
  42. <el-table-column align="center" prop="id" label="分部编号">
  43. </el-table-column>
  44. <el-table-column align="center" prop="name" label="分部名称">
  45. </el-table-column>
  46. <el-table-column align="center" prop="areaName" label="城市">
  47. </el-table-column>
  48. <el-table-column align="center" prop="address" label="分部地址">
  49. </el-table-column>
  50. <el-table-column align="center" label="学年制">
  51. <template slot-scope="scope">
  52. {{ scope.row.gradeType | gradeTypeFormat }}
  53. </template>
  54. </el-table-column>
  55. <el-table-column align="center" label="成立时间">
  56. <template slot-scope="scope">
  57. {{ scope.row.registerDate | formatTimer }}
  58. </template>
  59. </el-table-column>
  60. <el-table-column align="center" label="操作">
  61. <template slot-scope="scope">
  62. <el-button
  63. @click="onBranchOperation('update', scope.row)"
  64. v-permission="'organization/update'"
  65. type="text"
  66. >修改</el-button
  67. >
  68. <el-button
  69. @click="showCode(scope.row)"
  70. v-permission="'organization/update'"
  71. type="text"
  72. >注册二维码</el-button
  73. >
  74. </template>
  75. </el-table-column>
  76. </el-table>
  77. <pagination
  78. sync
  79. :total.sync="pageInfo.total"
  80. :page.sync="pageInfo.page"
  81. :limit.sync="pageInfo.limit"
  82. :page-sizes="pageInfo.page_size"
  83. @pagination="getList"
  84. />
  85. </div>
  86. </div>
  87. <el-dialog
  88. :title="formTitle[formActionTitle]"
  89. :visible.sync="branchStatus"
  90. @close="onFormClose('ruleForm')"
  91. width="600px"
  92. >
  93. <el-form :model="form" :rules="rules" ref="ruleForm">
  94. <!-- <el-alert
  95. style="margin: 20px 0"
  96. title="分部信息"
  97. :closable="false"
  98. type="info"
  99. >
  100. </el-alert> -->
  101. <el-form-item
  102. label="分部名称"
  103. prop="name"
  104. :label-width="formLabelWidth"
  105. >
  106. <el-input
  107. v-model.trim="form.name"
  108. placeholder="请输入分部名称"
  109. autocomplete="off"
  110. ></el-input>
  111. </el-form-item>
  112. <el-form-item label="城市" required :label-width="formLabelWidth">
  113. <el-col :span="12">
  114. <el-form-item prop="province">
  115. <el-select
  116. v-model.trim="form.province"
  117. filterable
  118. placeholder="请选择省"
  119. clearable
  120. @change="onChangeProvince"
  121. >
  122. <el-option
  123. v-for="item in provinceList"
  124. :key="item.value"
  125. :label="item.label"
  126. :value="item.value"
  127. ></el-option>
  128. </el-select>
  129. </el-form-item>
  130. </el-col>
  131. <el-col :span="12">
  132. <el-form-item prop="city">
  133. <el-select
  134. v-model.trim="form.city"
  135. filterable
  136. placeholder="请选择市"
  137. clearable
  138. >
  139. <el-option
  140. v-for="item in cityList"
  141. :key="item.value"
  142. :label="item.label"
  143. :value="item.value"
  144. ></el-option>
  145. </el-select>
  146. </el-form-item>
  147. </el-col>
  148. </el-form-item>
  149. <el-form-item
  150. label="学年制"
  151. prop="gradeType"
  152. :label-width="formLabelWidth"
  153. >
  154. <el-select
  155. v-model.trim="form.gradeType"
  156. filterable
  157. placeholder="请选择学年制"
  158. clearable
  159. >
  160. <el-option label="6+3" value="SIX_PLUS"></el-option>
  161. <el-option label="5+4" value="FIVE_PLUS"></el-option>
  162. </el-select>
  163. </el-form-item>
  164. <el-form-item
  165. label="分部地址"
  166. prop="address"
  167. :label-width="formLabelWidth"
  168. >
  169. <el-input
  170. v-model.trim="form.address"
  171. placeholder="请输入分部地址"
  172. autocomplete="off"
  173. ></el-input>
  174. </el-form-item>
  175. <el-form-item
  176. label="成立时间"
  177. prop="registerDate"
  178. :label-width="formLabelWidth"
  179. >
  180. <el-date-picker
  181. v-model.trim="form.registerDate"
  182. type="date"
  183. value-format="yyyy-MM-dd"
  184. :picker-options="{
  185. firstDayOfWeek: 1,
  186. }"
  187. placeholder="选择成立时间"
  188. ></el-date-picker>
  189. </el-form-item>
  190. <el-form-item
  191. label="公司名称"
  192. prop="corporateName"
  193. :label-width="formLabelWidth"
  194. >
  195. <el-input
  196. v-model.trim="form.corporateName"
  197. placeholder="请输入公司名称"
  198. autocomplete="off"
  199. ></el-input>
  200. </el-form-item>
  201. <el-form-item
  202. label="营业执照编号"
  203. prop="corporateCode"
  204. :label-width="formLabelWidth"
  205. >
  206. <el-input
  207. v-model.trim="form.corporateCode"
  208. placeholder="请输入营业执照编号"
  209. autocomplete="off"
  210. ></el-input>
  211. </el-form-item>
  212. <el-form-item
  213. label="企业公章"
  214. prop="corporateSeal"
  215. :label-width="formLabelWidth"
  216. >
  217. <div style="width: 300px !important" class="ant-upload-preview">
  218. <!-- <el-upload
  219. class="avatar-uploader"
  220. action="/api-web/uploadFile"
  221. accept=".png"
  222. :headers="headers"
  223. :show-file-list="false"
  224. :on-success="handleAvatarSuccess"
  225. :before-upload="beforeAvatarUpload"
  226. >
  227. <i v-if="form.corporateSeal" @click.stop="form.corporateSeal = null" class="el-icon-error" style="position: absolute;right: -14px;font-size: 28px;top: -14px;color: #787878;background: #fff;"></i>
  228. <img
  229. v-if="form.corporateSeal"
  230. :src="form.corporateSeal"
  231. class="avatar"
  232. />
  233. <span v-else>
  234. <i class="el-icon-plus avatar-uploader-icon"></i>
  235. <span class="upload-desc">添加上传图片</span>
  236. </span>
  237. </el-upload> -->
  238. <image-cropper
  239. :options="{
  240. autoCrop: true, //是否默认生成截图框
  241. autoCropWidth: 300, //默认生成截图框宽度
  242. autoCropHeight: 300, //默认生成截图框高度
  243. fixedBox: true, //是否固定截图框大小 不允许改变
  244. previewsCircle: false, //预览图是否是圆形
  245. title: '上传企业公章', //模态框上显示的标题
  246. }"
  247. isDelete
  248. :imgSize="5"
  249. accept=".png"
  250. :acceptArray="['image/png']"
  251. :imageUrl.sync="form.corporateSeal"
  252. @crop-upload-success="cropSuccess1"
  253. />
  254. <div class="tips" style="line-height: 1.3; color: red">
  255. 请上传透明背景PNG格式公章图片;<br />
  256. 仅支持图片格式:png,大小:5MB;
  257. </div>
  258. </div>
  259. </el-form-item>
  260. <el-form-item
  261. label="企业财务公章"
  262. prop="corporateFinancialSeal"
  263. :label-width="formLabelWidth"
  264. >
  265. <div style="width: 300px !important" class="ant-upload-preview">
  266. <!-- <el-upload
  267. class="avatar-uploader"
  268. action="/api-web/uploadFile"
  269. accept=".png"
  270. :headers="headers"
  271. :show-file-list="false"
  272. :on-success="handleAvatarSuccess2"
  273. :before-upload="beforeAvatarUpload"
  274. >
  275. <i v-if="form.corporateFinancialSeal" @click.stop="form.corporateFinancialSeal = null" class="el-icon-error" style="position: absolute;right: -14px;font-size: 28px;top: -14px;color: #787878;background: #fff;"></i>
  276. <img
  277. v-if="form.corporateFinancialSeal"
  278. :src="form.corporateFinancialSeal"
  279. class="avatar"
  280. />
  281. <span v-else>
  282. <i class="el-icon-plus avatar-uploader-icon"></i>
  283. <span class="upload-desc">添加上传图片</span>
  284. </span>
  285. </el-upload> -->
  286. <image-cropper
  287. :options="{
  288. autoCrop: true, //是否默认生成截图框
  289. autoCropWidth: 300, //默认生成截图框宽度
  290. autoCropHeight: 300, //默认生成截图框高度
  291. fixedBox: true, //是否固定截图框大小 不允许改变
  292. previewsCircle: false, //预览图是否是圆形
  293. title: '上传企业财务公章', //模态框上显示的标题
  294. }"
  295. isDelete
  296. :imgSize="5"
  297. accept=".png"
  298. :acceptArray="['image/png']"
  299. :imageUrl.sync="form.corporateFinancialSeal"
  300. @crop-upload-success="cropSuccess2"
  301. />
  302. <div class="tips" style="line-height: 1.3; color: red">
  303. 请上传透明背景PNG格式公章图片;<br />
  304. 仅支持图片格式:png,大小:5MB;
  305. </div>
  306. </div>
  307. </el-form-item>
  308. <!-- <el-alert
  309. style="margin: 20px 0"
  310. title="分部人员配置"
  311. :closable="false"
  312. type="info"
  313. >
  314. </el-alert>
  315. <el-form-item label="分部经理" prop="organManager" :label-width="formLabelWidth">
  316. <el-select
  317. v-model.trim="form.organManager"
  318. filterable
  319. clearable
  320. multiple
  321. >
  322. <el-option
  323. v-for="item in employeeList"
  324. :key="item.id"
  325. :label="item.realName"
  326. :value="item.id+''"
  327. >
  328. <span style="float: left">{{ item.realName }}</span>
  329. <span style="float: right; color: #8492a6; font-size: 13px">{{
  330. String(item.id)
  331. }}</span>
  332. </el-option>
  333. </el-select>
  334. </el-form-item>
  335. <el-form-item label="乐团主管" prop="educationId" :label-width="formLabelWidth">
  336. <el-select
  337. v-model.trim="form.educationId"
  338. filterable
  339. clearable
  340. multiple
  341. >
  342. <el-option
  343. v-for="item in employeeList"
  344. :key="item.id"
  345. :label="item.realName"
  346. :value="item.id+''"
  347. >
  348. <span style="float: left">{{ item.realName }}</span>
  349. <span style="float: right; color: #8492a6; font-size: 13px">{{
  350. String(item.id)
  351. }}</span>
  352. </el-option>
  353. </el-select>
  354. </el-form-item>
  355. <el-form-item label="维修技师" prop="repairId" :label-width="formLabelWidth">
  356. <el-select v-model.trim="form.repairId" filterable clearable multiple>
  357. <el-option
  358. v-for="item in employeeList"
  359. :key="item.id"
  360. :label="item.realName"
  361. :value="item.id+''"
  362. >
  363. <span style="float: left">{{ item.realName }}</span>
  364. <span style="float: right; color: #8492a6; font-size: 13px">{{
  365. String(item.id)
  366. }}</span>
  367. </el-option>
  368. </el-select>
  369. </el-form-item>
  370. <el-form-item label="衔接老师" prop="joinTeacherId" :label-width="formLabelWidth">
  371. <el-select v-model.trim="form.joinTeacherId" filterable clearable multiple>
  372. <el-option
  373. v-for="item in employeeList"
  374. :key="item.id"
  375. :label="item.realName"
  376. :value="item.id+''"
  377. >
  378. <span style="float: left">{{ item.realName }}</span>
  379. <span style="float: right; color: #8492a6; font-size: 13px">{{
  380. String(item.id)
  381. }}</span>
  382. </el-option>
  383. </el-select>
  384. </el-form-item> -->
  385. </el-form>
  386. <span slot="footer" class="dialog-footer">
  387. <el-button @click="branchStatus = false">取 消</el-button>
  388. <el-button @click="onBranchSubmit('ruleForm')" type="primary"
  389. >确 定</el-button
  390. >
  391. </span>
  392. </el-dialog>
  393. <qr-code v-model="codeStatus" :title="codeTitle" :codeUrl="qrCodeUrl" />
  394. </div>
  395. </template>
  396. <script>
  397. import { getToken } from "@/utils/auth";
  398. import pagination from "@/components/Pagination/index";
  399. import qrCode from "@/components/QrCode/index";
  400. import {
  401. branchQueryPage,
  402. areaQueryChild,
  403. branchAdd,
  404. branchUpdate,
  405. getParentArea,
  406. } from "@/api/specialSetting";
  407. import { vaildStudentUrl } from "@/utils/validate";
  408. import { queryEmployByOrganId } from "@/api/systemManage";
  409. import ImageCropper from "@/components/ImageCropper";
  410. export default {
  411. name: "branchSetting",
  412. components: { pagination, qrCode, ImageCropper },
  413. data() {
  414. return {
  415. headers: {
  416. Authorization: getToken(),
  417. },
  418. tableList: [],
  419. pageInfo: {
  420. // 分页规则
  421. limit: 10, // 限制显示条数
  422. page: 1, // 当前页
  423. total: 0, // 总条数
  424. page_size: [10, 20, 40, 50], // 选择限制显示条数
  425. },
  426. organId: null,
  427. formActionTitle: "create",
  428. formTitle: {
  429. create: "添加分部",
  430. update: "修改分部",
  431. },
  432. formLabelWidth: "100px",
  433. branchStatus: false,
  434. provinceList: [], // 省列表
  435. cityList: [], // 市列表
  436. employeeList: [], // 分部下的员工集合
  437. form: {
  438. name: null,
  439. province: null,
  440. city: null,
  441. address: null,
  442. registerDate: null,
  443. gradeType: "SIX_PLUS",
  444. organManager: [],
  445. educationId: [],
  446. repairId: [],
  447. joinTeacherId: [],
  448. corporateName: null,
  449. corporateCode: null,
  450. corporateSeal: null,
  451. corporateFinancialSeal: null,
  452. },
  453. rules: {
  454. name: [{ required: true, message: "请输入分部名称", trigger: "blur" }],
  455. province: [{ required: true, message: "请选择省", trigger: "change" }],
  456. city: [{ required: true, message: "请选择市", trigger: "change" }],
  457. address: [
  458. { required: true, message: "请输入分部地址", trigger: "blur" },
  459. ],
  460. registerDate: [
  461. { required: true, message: "请选择成立时间", trigger: "change" },
  462. ],
  463. gradeType: [
  464. { required: true, message: "请选择学年制", trigger: "change" },
  465. ],
  466. },
  467. codeStatus: false,
  468. qrCodeUrl: null,
  469. codeTitle: "注册二维码",
  470. searchForm: {
  471. search: "",
  472. },
  473. };
  474. },
  475. mounted() {
  476. this.getList();
  477. this.getAreaList();
  478. },
  479. methods: {
  480. cropSuccess1(data) {
  481. this.form.corporateSeal = data.data.url;
  482. },
  483. cropSuccess2(data) {
  484. this.form.corporateFinancialSeal = data.data.url;
  485. },
  486. onReSet(){
  487. this.searchForm.search = ''
  488. this.search();
  489. },
  490. search() {
  491. this.rules.page = 1;
  492. this.getList();
  493. },
  494. beforeAvatarUpload(file) {
  495. const imageType = {
  496. "image/png": true,
  497. };
  498. const isImage = imageType[file.type];
  499. const isLt2M = file.size / 1024 / 1024 < 5;
  500. if (!isImage) {
  501. this.$message.error("只能上传图片格式!");
  502. return false;
  503. }
  504. if (!isLt2M) {
  505. this.$message.error("上传头像图片大小不能超过 5MB!");
  506. return false;
  507. }
  508. return isImage && isLt2M;
  509. },
  510. handleAvatarSuccess(res) {
  511. this.form.corporateSeal = res.data.url;
  512. },
  513. handleAvatarSuccess2(res) {
  514. this.form.corporateFinancialSeal = res.data.url;
  515. },
  516. onBranchSubmit(formName) {
  517. this.$refs[formName].validate((valid) => {
  518. if (!valid) return;
  519. this.form.areaId = this.form.city;
  520. let obj = {
  521. ...this.form,
  522. organManager: this.form.organManager.join(","),
  523. educationId: this.form.educationId.join(","),
  524. repairId: this.form.repairId.join(","),
  525. joinTeacherId: this.form.joinTeacherId.join(","),
  526. };
  527. if (this.formActionTitle == "create") {
  528. if (obj.id) {
  529. // 判断有没有Id,如果有则删除
  530. delete obj.id;
  531. }
  532. branchAdd(obj).then((res) => {
  533. this.messageTips("添加", res);
  534. });
  535. } else if (this.formActionTitle == "update") {
  536. branchUpdate(obj).then((res) => {
  537. this.messageTips("修改", res);
  538. });
  539. }
  540. });
  541. },
  542. messageTips(title, res) {
  543. if (res.code == 200) {
  544. this.$message.success(title + "成功");
  545. this.branchStatus = false;
  546. this.getList();
  547. } else {
  548. this.$message.error(res.msg);
  549. }
  550. },
  551. getList() {
  552. branchQueryPage({
  553. rows: this.pageInfo.limit,
  554. page: this.pageInfo.page,
  555. ...this.searchForm,
  556. }).then((res) => {
  557. if (res.code == 200 && res.data) {
  558. this.tableList = res.data.rows;
  559. this.pageInfo.total = res.data.total;
  560. }
  561. });
  562. },
  563. onFormClose(formName) {
  564. // 关闭弹窗重置验证
  565. this.$refs[formName].resetFields();
  566. this.form.gradeType = "SIX_PLUS";
  567. },
  568. getAreaList(parentId, callback) {
  569. parentId = parentId ? parentId : 0;
  570. areaQueryChild({ parentId: parentId }).then((res) => {
  571. if (res.code == 200 && res.data) {
  572. let tempData = [];
  573. res.data.forEach((item) => {
  574. tempData.push({
  575. label: item.name,
  576. value: item.id,
  577. });
  578. });
  579. if (parentId) {
  580. this.cityList = tempData;
  581. } else {
  582. this.provinceList = tempData;
  583. }
  584. if (callback && typeof callback == "function") {
  585. callback();
  586. }
  587. }
  588. });
  589. },
  590. onChangeProvince(val) {
  591. this.form.city = null;
  592. this.getAreaList(val);
  593. },
  594. async onBranchOperation(type, row) {
  595. // 修改分部信息
  596. // employeeFindEmployeeByRole
  597. if (row) {
  598. try {
  599. const res = await queryEmployByOrganId({
  600. organId: row.id,
  601. rows: 9999,
  602. demissionflag: false,
  603. lockFlag: false,
  604. });
  605. this.$set(this, "employeeList", res.data.rows);
  606. } catch (e) {
  607. console.log(e);
  608. }
  609. }
  610. this.formActionTitle = type;
  611. if (type == "update") {
  612. getParentArea({ id: row.areaId }).then((res) => {
  613. if (res.code == 200 && res.data) {
  614. this.getAreaList(res.data.id, () => {
  615. this.form = {
  616. id: row.id,
  617. name: row.name,
  618. province: res.data.id,
  619. city: row.areaId,
  620. address: row.address,
  621. registerDate: row.registerDate,
  622. gradeType: row.gradeType == 1 ? "FIVE_PLUS" : "SIX_PLUS",
  623. organManager: row.organManager
  624. ? row.organManager.split(",")
  625. : [],
  626. repairId: row.repairId ? row.repairId.split(",") : [],
  627. joinTeacherId: row.joinTeacherId
  628. ? row.joinTeacherId.split(",")
  629. : [],
  630. educationId: row.educationId ? row.educationId.split(",") : [],
  631. corporateName: row.corporateName,
  632. corporateCode: row.corporateCode,
  633. corporateSeal: row.corporateSeal,
  634. corporateFinancialSeal: row.corporateFinancialSeal,
  635. };
  636. });
  637. this.branchStatus = true;
  638. }
  639. });
  640. } else {
  641. this.branchStatus = true;
  642. }
  643. },
  644. showCode(row) {
  645. this.qrCodeUrl =
  646. vaildStudentUrl() + "/project/register/index.html?organId=" + row.id;
  647. this.codeStatus = true;
  648. // qrCodeUrl:null,
  649. },
  650. },
  651. };
  652. </script>
  653. <style lang="scss" scoped>
  654. .ant-upload-preview {
  655. background-color: #fff;
  656. .avatar-uploader {
  657. .upload-desc {
  658. position: absolute;
  659. bottom: 0;
  660. left: 0;
  661. color: #ccc;
  662. font-size: 8px;
  663. right: 0;
  664. }
  665. }
  666. }
  667. ::v-deep .avatar-uploader .el-upload--text {
  668. border: 1px dashed #d9d9d9;
  669. border-radius: 6px;
  670. margin-right: 20px;
  671. cursor: pointer;
  672. position: relative;
  673. // overflow: hidden;
  674. }
  675. ::v-deep .avatar-uploader.uploadDisabled {
  676. .el-upload--text {
  677. cursor: not-allowed;
  678. background-color: #f7f7f7;
  679. }
  680. .el-upload:hover {
  681. border-color: #d9d9d9;
  682. }
  683. }
  684. ::v-deep .avatar-uploader .el-upload:hover {
  685. border-color: #409eff;
  686. }
  687. ::v-deep .avatar-uploader-icon {
  688. font-size: 22px;
  689. color: #ccc;
  690. width: 108px;
  691. height: 108px;
  692. line-height: 108px;
  693. text-align: center;
  694. }
  695. ::v-deep.avatar {
  696. width: 108px;
  697. height: 108px;
  698. display: block;
  699. }
  700. /deep/.el-date-editor.el-input {
  701. width: 100% !important;
  702. }
  703. /deep/.el-select {
  704. width: 98% !important;
  705. }
  706. </style>