consumable.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. <template>
  2. <div class="content-box">
  3. <div class="left">
  4. <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
  5. <span class="cameratxt" @click="getList(1)" :class="themeIndex == 1 ? 'is_active' : ''">耗材管理</span>
  6. <span class="cameratxt" @click="getList(2)" :class="themeIndex == 2 ? 'is_active' : ''">耗材记录</span>
  7. </div>
  8. <div v-if="themeIndex == 1">
  9. <div class="middle">
  10. <div class="filter">
  11. <div class="condition">
  12. <span>关键字 : </span>
  13. <el-input clearable v-model="searchInput.name" @clear="searchBtn" class="w-50 m-2" placeholder="请输入名称"
  14. style="width: 150px" />
  15. </div>
  16. <div class="condition">
  17. <span>创建时间 : </span>
  18. <el-date-picker v-model="searchInput.createTime" type="daterange" range-separator="-" start-placeholder="起始时间"
  19. end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" :prefix-icon="Calendar"
  20. placeholder="请选择日期" />
  21. </div>
  22. <div class="condition">
  23. <span>校区 : </span>
  24. <el-select v-model="searchInput.schoolId" class="m-2" placeholder="请选择校区" @change="selSchool">
  25. <el-option label="全部校区" :value="0" />
  26. <el-option label="黄家湖校区" :value="1" />
  27. <el-option label="墨轩湖校区" :value="2" />
  28. </el-select>
  29. </div>
  30. <el-button style="margin-left: 20px" color="rgba(111, 182, 184, 1)" type="primary" class="search"
  31. @click="searchBtn"><el-icon>
  32. <Search />
  33. </el-icon> <span>查询</span></el-button>
  34. </div>
  35. <!-- 按钮列表 -->
  36. <div class="gongneng">
  37. <el-button type="primary" color="rgba(111, 182, 184, 1)" @click="addlist"><img src="@/assets/add.png"
  38. style="width: 14px; height: 14px; margin-right: 4px" alt="" /><span>添加耗材</span></el-button>
  39. <el-button color="rgba(111, 182, 184, 1)" class="import" type="primary" @click="importFile"><img
  40. src="@/assets/toLead.png" style="width: 24px; height: 22px" alt="" />
  41. <span>导入耗材</span></el-button>
  42. <el-button color="rgba(111, 182, 184, 1)" class="import" type="primary" @click="importExcel1"><img
  43. src="@/assets/import.png" style="width: 14px; height: 14px; margin-right: 4px" alt="" />
  44. <span>导出耗材</span></el-button>
  45. </div>
  46. </div>
  47. <div class="footer" :key="keyIndex">
  48. <el-table :row-class-name="tableRowClassName" :data="tableData.list" style="width: 100%" :header-cell-style="{
  49. background: 'rgba(240, 243, 247, 1)',
  50. height: '50px',
  51. border: 0,
  52. }">
  53. <!-- <el-table-column align="center" type="selection" width="80" /> -->
  54. <el-table-column width="80" align="center" type="index" prop="1" label="序号" />
  55. <el-table-column width="220" align="center" prop="name" label="品名" />
  56. <el-table-column align="center" prop="price" label="单价(元)" />
  57. <el-table-column width="150" align="center " label="校区">
  58. <template #default="{ row }">
  59. <span>{{ row.schoolId == 1 ? "黄家湖校区" : "墨轩湖校区" }}</span>
  60. </template>
  61. </el-table-column>
  62. <!-- <el-table-column width="250" align="center" prop="content" show-overflow-tooltip label="耗材内容" />
  63. <el-table-column align="center" show-overflow-tooltip label="关联物品种类" width="250">
  64. <template #default="{ row }">
  65. <span v-if="row.articleNames">{{
  66. row.articleNames.join(",")
  67. }}</span>
  68. </template>
  69. </el-table-column> -->
  70. <el-table-column align="center" prop="userName" label="录入人" />
  71. <el-table-column align="center" prop="updateTime" label="创建时间" />
  72. <el-table-column align="center" label="操作" width="220">
  73. <template #default="scope">
  74. <div class="edit">
  75. <div class="look" @click="edit(scope.row)">编辑</div>
  76. <el-popconfirm width="220" confirm-button-text="确认" cancel-button-text="取消" :icon="InfoFilled"
  77. icon-color="#f89626" :title="`是否删除 ${scope.row.name} 物品?`" @confirm="del(scope.row)"
  78. @cancel="cancelEvent">
  79. <template #reference>
  80. <div class="look">删除</div>
  81. </template>
  82. </el-popconfirm>
  83. </div>
  84. </template>
  85. </el-table-column>
  86. </el-table>
  87. <!-- 添加耗材弹窗 -->
  88. <el-dialog class="addStaff" v-model="addDialogVisible" :close-on-click-modal="false"
  89. :close-on-press-escape="false" :title="dialongTitle" align-center width="609" :before-close="handleVideoClose">
  90. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
  91. :size="formSize" label-position="left" status-icon>
  92. <el-form-item label="耗材名称 :" prop="name">
  93. <el-input clearable v-model="ruleForm.name" placeholder="请输入耗材名称" />
  94. </el-form-item>
  95. <el-form-item label="校区 :" prop="schoolId">
  96. <el-select v-model="ruleForm.schoolId" class="m-2" placeholder="请选择校区" @change="changeSchool">
  97. <el-option label="黄家湖校区" :value="1" />
  98. <el-option label="墨轩湖校区" :value="2" />
  99. </el-select>
  100. </el-form-item>
  101. <el-form-item label="单价 :" prop="price">
  102. <el-input clearable v-model="ruleForm.price" placeholder="请输入单价" />
  103. </el-form-item>
  104. <el-form-item label="关联物品种类 :" prop="articleIds" class="checkbox">
  105. <el-tree :data="articleIdsList" :props="{ label: 'name', children: 'children', value: 'id' }" node-key="id"
  106. show-checkbox ref="articleIdsRef" @check-change="handleArticleIds" />
  107. <!-- <el-checkbox
  108. v-model="checkAll"
  109. :indeterminate="isIndeterminate"
  110. @change="handleCheckAllChange"
  111. >全选</el-checkbox
  112. >
  113. <el-checkbox-group
  114. v-model="checkedCities"
  115. @change="handleCheckedCitiesChange"
  116. >
  117. <el-checkbox
  118. v-for="item in articleIdsList"
  119. :label="item.name"
  120. >{{ item.name }}</el-checkbox
  121. >
  122. </el-checkbox-group> -->
  123. </el-form-item>
  124. <el-form-item label="报修内容 :">
  125. <el-input v-model="ruleForm.content" :rows="3" type="textarea" show-word-limit :autofocus="true"
  126. placeholder="请输入报修内容" />
  127. </el-form-item>
  128. <!-- <el-form-item
  129. label="关联物品种类 :"
  130. prop="volume"
  131. class="checkbox"
  132. style="
  133. padding-bottom: 40px;
  134. border-bottom: 1px solid rgba(230, 230, 230, 1);
  135. "
  136. >
  137. <el-checkbox
  138. v-model="checkAll"
  139. :indeterminate="isIndeterminate"
  140. @change="handleCheckAllChange"
  141. >全选</el-checkbox
  142. >
  143. <el-checkbox-group
  144. v-model="checkedCities"
  145. @change="handleCheckedCitiesChange"
  146. >
  147. <el-checkbox v-for="city in cities" :key="city" :label="city">{{
  148. city
  149. }}</el-checkbox>
  150. </el-checkbox-group>
  151. </el-form-item> -->
  152. <el-form-item class="options">
  153. <el-button color="rgba(111, 182, 184, 1)" class="queding" type="primary" @click="submitAdd(ruleFormRef)">
  154. 确定
  155. </el-button>
  156. <el-button class="congzhi" @click="cancelAdd(ruleFormRef)">取消</el-button>
  157. </el-form-item>
  158. </el-form>
  159. </el-dialog>
  160. <!-- 导入弹窗 -->
  161. <el-dialog class="importXlsx" v-model="importXlsx" :close-on-click-modal="false" :close-on-press-escape="false"
  162. title="导入文件" align-center width="409" :before-close="closeXlsx">
  163. <div class="el_btn">
  164. <el-button type="primary" color="rgb(243, 144, 122)" @click="importTemp">
  165. <span style="color: #fff">下载文件模板</span></el-button>
  166. <el-upload class="avatar-uploader" action="" ref="upload" :on-preview="handlePreview"
  167. :on-remove="handleRemove" :on-change="handleChange" :http-request="handleUpload"
  168. :before-upload="beforeAvatarUpload" :auto-upload="false" :limit="1" :on-exceed="handleExceed">
  169. <template #trigger>
  170. <el-button type="primary" color="rgba(111, 182, 184, 1)" @click="updateImg">
  171. <img src="@/assets/toLead.png" style="width: 24px; height: 22px" alt="" />
  172. <span style="color: #fff">导入文件</span></el-button>
  173. </template>
  174. <!-- <template #tip>
  175. <div class="el-upload__tip">
  176. (注:图片大小不超过10M,建议按3:2比例)
  177. </div>
  178. </template> -->
  179. </el-upload>
  180. </div>
  181. <div class="options">
  182. <el-button color="rgba(111, 182, 184, 1)" class="queding" type="primary" @click="importSuc()">
  183. 确定
  184. </el-button>
  185. <el-button class="congzhi" @click="closeXlsx()">取消</el-button>
  186. </div>
  187. </el-dialog>
  188. </div>
  189. <!-- 分页组件 -->
  190. <div class="pageSize">
  191. <span></span>
  192. <el-pagination background :current-page="currentPage" :page-size="pageSize"
  193. layout="total, prev, pager, next, jumper, slot" :total="total" @update:current-page="handleCurrentChange" />
  194. </div>
  195. </div>
  196. <div v-else-if="themeIndex == 2">
  197. <div class="middle">
  198. <div class="filter">
  199. <div class="condition">
  200. <span>关键字 : </span>
  201. <el-input clearable v-model="searchInput2.name" @clear="searchBtn" class="w-50 m-2" placeholder="请输入工单或耗材名称"
  202. style="width: 150px" />
  203. </div>
  204. <div class="condition">
  205. <span>维修时间 : </span>
  206. <el-date-picker v-model="searchInput2.createTime" type="daterange" range-separator="-"
  207. start-placeholder="起始时间" end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
  208. :prefix-icon="Calendar" placeholder="请选择日期" />
  209. </div>
  210. <div class="condition">
  211. <span>校区 : </span>
  212. <el-select v-model="searchInput2.schoolId" class="m-2" placeholder="请选择校区" @change="selSchool">
  213. <el-option label="全部校区" :value="0" />
  214. <el-option label="黄家湖校区" :value="1" />
  215. <el-option label="墨轩湖校区" :value="2" />
  216. </el-select>
  217. </div>
  218. <el-button style="margin-left: 20px" color="rgba(111, 182, 184, 1)" type="primary" class="search"
  219. @click="searchBtn"><el-icon>
  220. <Search />
  221. </el-icon> <span>查询</span></el-button>
  222. </div>
  223. <!-- 按钮列表 -->
  224. <div class="gongneng">
  225. <el-button color="rgba(111, 182, 184, 1)" class="import" type="primary" @click="importExcel2"><img
  226. src="@/assets/import.png" style="width: 14px; height: 14px; margin-right: 4px" alt="" />
  227. <span>导出耗材记录</span></el-button>
  228. </div>
  229. </div>
  230. <div class="footer" :key="keyIndex">
  231. <el-table :row-class-name="tableRowClassName" :data="tableData2.list" @selection-change="handleSelectionChange2"
  232. style="width: 100%" :header-cell-style="{
  233. background: 'rgba(240, 243, 247, 1)',
  234. height: '50px',
  235. border: 0,
  236. }">
  237. <!-- <el-table-column align="center" type="selection" width="80" /> -->
  238. <el-table-column width="80" align="center " type="index" label="序号" />
  239. <el-table-column align="center" prop="schoolName" label="校区" />
  240. <el-table-column align="center" prop="areaName" label="区域" width="210" />
  241. <el-table-column align="center" prop="consumeName" width="150" show-overflow-tooltip label="品名" />
  242. <el-table-column align="center" prop="price" label="单价(元)" width="90" />
  243. <el-table-column align="center" prop="number" label="数量" width="80" />
  244. <el-table-column align="center" prop="totalPrice" label="金额(元)" width="90" />
  245. <!-- <el-table-column align="center" prop="articleName" label="关联故障种类" /> -->
  246. <el-table-column align="center" prop="statu" label="状态" width="90" />
  247. <el-table-column align="center" prop="changeUser" label="改价人" />
  248. <el-table-column align="center" prop="recordNo" label="工单" width="150" />
  249. <el-table-column align="center" prop="reportTime" label="报修时间" />
  250. <el-table-column align="center" prop="updateTime" label="维修时间" />
  251. </el-table>
  252. </div>
  253. <!-- 分页组件 -->
  254. <div class="pageSize">
  255. <span>合计: {{pieceNum}}件&nbsp;&nbsp;&nbsp;{{pieceMoney}}元</span>
  256. <el-pagination background :current-page="currentPage2" :page-size="pageSize2"
  257. layout="total, prev, pager, next, jumper, slot" :total="total2" @update:current-page="handleCurrentChange2" />
  258. </div>
  259. </div>
  260. </div>
  261. </template>
  262. <script setup>
  263. import {
  264. ref,
  265. reactive,
  266. nextTick,
  267. watch,
  268. onBeforeMount,
  269. onUnmounted,
  270. } from "vue";
  271. import { useRouter } from "vue-router";
  272. import { ElMessage, ElMessageBox } from "element-plus";
  273. import { Calendar } from "@element-plus/icons-vue";
  274. import vidiconsApi from "@/api/vidicons.js";
  275. import { dayjs } from "element-plus";
  276. import lodash from "lodash";
  277. import axios from "axios";
  278. import { useStore } from "vuex";
  279. const store = useStore();
  280. const api = ref("");
  281. const router = useRouter();
  282. // 表格数据
  283. const tableData = reactive({ list: [] });
  284. const tableData2 = reactive({ list: [] });
  285. const themeIndex = ref(2); // 切换 耗材管理 和 耗材记录
  286. const keyIndex = ref(1) // 切换时将key改变使组件重新加载
  287. // 添加耗材 弹窗数据 (------------------------------------)
  288. const dialongTitle = ref("添加耗材"); // 弹窗标题
  289. // const checkAll = ref(false); // 判断物品种类是否全选
  290. // const isIndeterminate = ref(true); // 不确定状态,表示只选择一部分
  291. // const checkedCities = ref(["泥工", "木工"]); // 选中的数据
  292. // const cities = ["水电类", "泥工", "木工", "其他"]; // 种类列表
  293. const articleIdsList = ref(); // 关联物品种类
  294. const articleIdsRef = ref(); // 关联物品种类ref
  295. const searchInput = reactive({
  296. name: "",
  297. createTime: "",
  298. schoolId: ""
  299. }); // 搜索按钮数据
  300. const searchInput2 = reactive({
  301. name: "",
  302. createTime: "",
  303. schoolId: ""
  304. }); // 搜索按钮数据
  305. 5;
  306. // 耗材管理页面(---------------------------------------------)
  307. const currentPage = ref(1); // 当前页
  308. const pageSize = ref(10);
  309. const total = ref(); // 当前总数
  310. const selectData = reactive({ list: [] }); // 多选框选择的数据
  311. const upload = ref(); // 导入按钮ref
  312. const fileXlsx = ref(); // 导入的文件file
  313. const importXlsx = ref(false); // 导入弹窗
  314. const addDialogVisible = ref(false); // 控制添加员工弹窗
  315. // 耗材管理表单数据
  316. const formSize = ref("default");
  317. const ruleFormRef = ref();
  318. const ruleForm = reactive({
  319. name: "",
  320. articleIds: "",
  321. price: "",
  322. content: "",
  323. schoolId: "",
  324. id: "",
  325. });
  326. // 表单验证
  327. const rules = reactive({
  328. // serial: [{ required: true, message: "序列号不能为空", trigger: "blur" }],
  329. name: [{ required: true, message: "耗材名称", trigger: "blur" }],
  330. price: [{ required: true, message: "耗材单价", trigger: "blur" }],
  331. schoolId: [{ required: true, message: "校区不能为空", trigger: "blur" }],
  332. articleIds: [
  333. { required: true, message: "关联物品种类不能为空", trigger: "blur" },
  334. ],
  335. });
  336. // 耗材记录页面(---------------------------------------------)
  337. const currentPage2 = ref(1); // 当前页
  338. const pageSize2 = ref(10);
  339. const total2 = ref(30); // 当前总数
  340. const pieceNum=ref()// 耗材记录件数
  341. const pieceMoney=ref()// 耗材记录金额
  342. watch(
  343. () => searchInput.createTime,
  344. (newVal, oldVal) => {
  345. console.log("监听时间:", newVal);
  346. if (newVal == null) {
  347. searchBtn();
  348. }
  349. }
  350. );
  351. watch(
  352. () => searchInput2.createTime,
  353. (newVal, oldVal) => {
  354. console.log("监听时间:", newVal);
  355. if (newVal == null) {
  356. searchBtn();
  357. }
  358. }
  359. );
  360. // 查看耗材管理列表
  361. const getList = async (flag) => {
  362. keyIndex.value++;
  363. // 耗材管理(-----------------------------------------------)
  364. if (flag == 1) {
  365. themeIndex.value = 1;
  366. let data = {
  367. currentPage: currentPage.value,
  368. pageCount: pageSize.value,
  369. name: searchInput.name,
  370. };
  371. if (searchInput.createTime) {
  372. data.startTime = searchInput.createTime[0];
  373. data.endTime = searchInput.createTime[1];
  374. }
  375. let res = await axios({
  376. method: "get",
  377. url: api.value + "/repairConsume/queryPageRepairConsume",
  378. headers: {
  379. token: sessionStorage.getItem("token"),
  380. user_head: sessionStorage.getItem("userhead"),
  381. },
  382. params: data,
  383. });
  384. console.log(res, "耗材管理");
  385. if (res.data.code == 200) {
  386. tableData.list = res.data.data.list;
  387. total.value = res.data.data.totalCount;
  388. // ElMessage({
  389. // type: "success",
  390. // showClose: true,
  391. // message: res.data.message,
  392. // center: true,
  393. // });
  394. } else {
  395. ElMessage({
  396. type: "error",
  397. showClose: true,
  398. message: res.data.message,
  399. center: true,
  400. });
  401. if (res.data.code == 570) {
  402. sessionStorage.removeItem("token")
  403. router.push({
  404. path: `/login`,
  405. });
  406. }
  407. }
  408. } else if (flag == 2) {
  409. themeIndex.value = 2;
  410. let data = {
  411. currentPage: currentPage2.value,
  412. pageCount: pageSize2.value,
  413. keyWord: searchInput2.name,
  414. };
  415. if (searchInput2.createTime) {
  416. data.startTime = searchInput2.createTime[0];
  417. data.endTime = searchInput2.createTime[1];
  418. }
  419. let res = await axios({
  420. method: "get",
  421. url: api.value + "/repairConsumables/queryRepairConsumablePageList",
  422. headers: {
  423. token: sessionStorage.getItem("token"),
  424. user_head: sessionStorage.getItem("userhead"),
  425. },
  426. params: data,
  427. });
  428. console.log(res, "耗材记录");
  429. if (res.data.code == 200) {
  430. tableData2.list = res.data.data.list;
  431. total2.value = res.data.data.totalCount;
  432. pieceNum.value = res.data.data.tcont;
  433. pieceMoney.value = res.data.data.tprice;
  434. } else {
  435. ElMessage({
  436. type: "error",
  437. showClose: true,
  438. message: res.data.message,
  439. center: true,
  440. });
  441. }
  442. }
  443. };
  444. // 搜索功能
  445. const searchBtn = lodash.debounce(async () => {
  446. getList(themeIndex.value);
  447. }, 300);
  448. //新增添加耗材 (--------------------------------------)
  449. const addlist = () => {
  450. dialongTitle.value = "添加耗材";
  451. ruleForm.schoolId = 1;
  452. changeSchool(ruleForm.schoolId);
  453. addDialogVisible.value = true;
  454. ruleForm.name = "";
  455. ruleForm.price = "";
  456. ruleForm.articleIds = [];
  457. ruleForm.content = "";
  458. nextTick(() => {
  459. articleIdsRef.value.setCheckedKeys([]);
  460. });
  461. };
  462. // // 种类是否全选按钮
  463. // const handleCheckAllChange = (val) => {
  464. // console.log(val);
  465. // checkedCities.value = val ? cities : [];
  466. // isIndeterminate.value = false;
  467. // };
  468. // //单独勾选种类
  469. // const handleCheckedCitiesChange = (value) => {
  470. // console.log(value);
  471. // const checkedCount = value.length;
  472. // checkAll.value = checkedCount === cities.length;
  473. // isIndeterminate.value = checkedCount > 0 && checkedCount < cities.length;
  474. // };
  475. // 关联报修类型 当复选框被点击的时候触发
  476. const handleArticleIds = (data, checked, indeterminate) => {
  477. console.log(data, checked, indeterminate);
  478. // let keys = articleIdsRef.value.getCheckedNodes();
  479. let keys = articleIdsRef.value.getCheckedKeys();
  480. // console.log(keys);
  481. // let arr = [];
  482. // keys.forEach((item) => {
  483. // if (item.parentId != 1) {
  484. // arr.push(item.id);
  485. // }
  486. // });
  487. ruleForm.articleIds = keys;
  488. };
  489. // 改变校区 关联楼栋和关联报修类型也改变(---------------)
  490. const changeSchool = async (val) => {
  491. if (val == 1) {
  492. ruleForm.schoolId = 1;
  493. } else {
  494. ruleForm.schoolId = 2;
  495. }
  496. // 报修(故障类型)类型关联 (接口-------)
  497. let data = {
  498. schoolId: val,
  499. };
  500. let resss = await axios({
  501. method: "get",
  502. url: api.value + "/repairArticleType/queryRepairArticleType",
  503. headers: {
  504. token: sessionStorage.getItem("token"),
  505. user_head: sessionStorage.getItem("userhead"),
  506. },
  507. params: data,
  508. });
  509. console.log(resss, "报修(故障类型)类型关联数据");
  510. articleIdsList.value = resss.data.data;
  511. };
  512. //编辑按钮 (-------------------------------------------)
  513. const edit = (row) => {
  514. dialongTitle.value = "编辑耗材";
  515. addDialogVisible.value = true;
  516. changeSchool(row.schoolId);
  517. ruleForm.name = row.name;
  518. ruleForm.price = row.price;
  519. ruleForm.articleIds = row.articleIds;
  520. ruleForm.content = row.content;
  521. ruleForm.schoolId = row.schoolId;
  522. nextTick(() => {
  523. articleIdsRef.value.setCheckedKeys(row.articleIds);
  524. });
  525. ruleForm.id = row.id;
  526. };
  527. // 取消 编辑/添加耗材
  528. const cancelAdd = () => {
  529. addDialogVisible.value = false;
  530. ruleFormRef.value.resetFields();
  531. };
  532. // 确认 编辑/添加耗材
  533. const submitAdd = async (formEl) => {
  534. if (!formEl) return;
  535. await formEl.validate(async (valid, fields) => {
  536. if (valid) {
  537. if (dialongTitle.value == "添加耗材") {
  538. // 添加耗材接口(++++++++)
  539. let data = {
  540. name: ruleForm.name,
  541. price: ruleForm.price,
  542. articleIds: ruleForm.articleIds,
  543. content: ruleForm.content,
  544. schoolId: ruleForm.schoolId,
  545. };
  546. let res = await axios({
  547. method: "post",
  548. url: api.value + "/repairConsume/insertRepairConsume",
  549. headers: {
  550. token: sessionStorage.getItem("token"),
  551. user_head: sessionStorage.getItem("userhead"),
  552. },
  553. data: data,
  554. });
  555. console.log(res, "添加耗材");
  556. if (res.data.code == 200) {
  557. getList(themeIndex.value);
  558. ElMessage({
  559. type: "success",
  560. showClose: true,
  561. message: res.data.message,
  562. center: true,
  563. });
  564. addDialogVisible.value = false;
  565. ruleFormRef.value.resetFields();
  566. } else {
  567. ElMessage({
  568. type: "error",
  569. showClose: true,
  570. message: res.data.message,
  571. center: true,
  572. });
  573. }
  574. } else {
  575. // 编辑耗材接口(++++++++)
  576. let data = {
  577. name: ruleForm.name,
  578. price: ruleForm.price,
  579. articleIds: ruleForm.articleIds,
  580. content: ruleForm.content,
  581. schoolId: ruleForm.schoolId,
  582. id: ruleForm.id,
  583. };
  584. let res = await axios({
  585. method: "post",
  586. url: api.value + "/repairConsume/updateRepairConsumeById",
  587. headers: {
  588. user_head: sessionStorage.getItem("userhead"),
  589. token: sessionStorage.getItem("token"),
  590. },
  591. data: data,
  592. });
  593. // console.log(res, "修改账号");
  594. if (res.data.code == 200) {
  595. getList(themeIndex.value);
  596. ElMessage({
  597. type: "success",
  598. showClose: true,
  599. message: res.data.message,
  600. center: true,
  601. });
  602. addDialogVisible.value = false;
  603. ruleFormRef.value.resetFields();
  604. } else {
  605. ElMessage({
  606. type: "error",
  607. showClose: true,
  608. message: res.data.message,
  609. center: true,
  610. });
  611. }
  612. }
  613. } else {
  614. console.log("error submit!", fields);
  615. }
  616. });
  617. };
  618. // 耗材管理删除按钮
  619. const del = async (row) => {
  620. let data = {
  621. id: row.id,
  622. };
  623. let res = await axios({
  624. method: "get",
  625. url: api.value + "/repairConsume/deleteRepairConsumeById",
  626. headers: {
  627. token: sessionStorage.getItem("token"),
  628. user_head: sessionStorage.getItem("userhead"),
  629. },
  630. params: data,
  631. });
  632. if (res.data.code == 200) {
  633. if (tableData.list.length == 1 && currentPage.value != 1) {
  634. currentPage.value = currentPage.value - 1;
  635. }
  636. getList(themeIndex.value);
  637. ElMessage({
  638. type: "success",
  639. showClose: true,
  640. message: res.data.message,
  641. center: true,
  642. });
  643. } else {
  644. ElMessage({
  645. type: "error",
  646. showClose: true,
  647. message: res.data.message,
  648. center: true,
  649. });
  650. }
  651. };
  652. // 取消删除
  653. const cancelEvent = () => {
  654. ElMessage({
  655. type: "info",
  656. showClose: true,
  657. message: "取消删除",
  658. center: true,
  659. });
  660. };
  661. //导出功能
  662. const importExcel1 = async () => {
  663. let datas;
  664. if (searchInput.createTime) {
  665. datas = {
  666. name: searchInput.name,
  667. startTime: searchInput.createTime[0],
  668. endTime: searchInput.createTime[1],
  669. };
  670. } else {
  671. datas = {
  672. name: searchInput.name,
  673. };
  674. }
  675. let res = await axios({
  676. method: "get",
  677. url: api.value + "/repairConsume/downloadRepairConsumeExcel",
  678. headers: {
  679. token: sessionStorage.getItem("token"),
  680. user_head: sessionStorage.getItem("userhead"),
  681. },
  682. params: datas,
  683. responseType: "blob",
  684. });
  685. console.log(res, "导出耗材");
  686. if (res.status == 200) {
  687. let name = `耗材数据`;
  688. var content = res.data;
  689. // var data = new Blob([content],{type:"application/octet-stream;charset=utf-8"});
  690. // var data = new Blob([content], {
  691. // type: "application/vnd.ms-excel;charset=utf-8",
  692. // });
  693. var data = new Blob([content]);
  694. var downloadUrl = window.URL.createObjectURL(data);
  695. var anchor = document.createElement("a");
  696. anchor.href = downloadUrl;
  697. anchor.download = name + ".xlsx";
  698. anchor.click();
  699. window.URL.revokeObjectURL(data);
  700. ElMessage({
  701. type: "success",
  702. showClose: true,
  703. message: "导出成功",
  704. center: true,
  705. });
  706. } else {
  707. ElMessage({
  708. type: "error",
  709. showClose: true,
  710. message: "导出失败",
  711. center: true,
  712. });
  713. }
  714. };
  715. //导出功能
  716. const importExcel2 = async () => {
  717. let datas = {
  718. keyWord: searchInput2.name,
  719. };
  720. if (searchInput2.createTime) {
  721. datas.startTime = searchInput2.createTime[0];
  722. datas.endTime = searchInput2.createTime[1];
  723. }
  724. let res = await axios({
  725. method: "get",
  726. url: api.value + "/repairConsumables/downloadRepairConsumableExcel",
  727. headers: {
  728. token: sessionStorage.getItem("token"),
  729. user_head: sessionStorage.getItem("userhead"),
  730. },
  731. params: datas,
  732. responseType: "blob",
  733. });
  734. console.log(res, "导出耗材记录");
  735. if (res.status == 200) {
  736. let name = `耗材记录数据`;
  737. var content = res.data;
  738. // var data = new Blob([content],{type:"application/octet-stream;charset=utf-8"});
  739. // var data = new Blob([content], {
  740. // type: "application/vnd.ms-excel;charset=utf-8",
  741. // });
  742. var data = new Blob([content]);
  743. var downloadUrl = window.URL.createObjectURL(data);
  744. var anchor = document.createElement("a");
  745. anchor.href = downloadUrl;
  746. anchor.download = name + ".xlsx";
  747. anchor.click();
  748. window.URL.revokeObjectURL(data);
  749. ElMessage({
  750. type: "success",
  751. showClose: true,
  752. message: "导出成功",
  753. center: true,
  754. });
  755. } else {
  756. ElMessage({
  757. type: "error",
  758. showClose: true,
  759. message: "导出失败",
  760. center: true,
  761. });
  762. }
  763. };
  764. // 导入弹窗
  765. const importFile = () => {
  766. importXlsx.value = true;
  767. };
  768. const closeXlsx = () => {
  769. importXlsx.value = false;
  770. upload.value.clearFiles();
  771. fileXlsx.value = "";
  772. };
  773. // 导出模板
  774. const importTemp = async () => {
  775. let res = await axios({
  776. method: "get",
  777. url: api.value + "/repairConsume/downloadRepairConsumeModelExcel",
  778. headers: {
  779. token: sessionStorage.getItem("token"),
  780. user_head: sessionStorage.getItem("userhead"),
  781. },
  782. responseType: "blob",
  783. });
  784. console.log(res, "导出模板");
  785. if (res.status == 200) {
  786. let name = `耗材数据导入模板`;
  787. var content = res.data;
  788. var data = new Blob([content]);
  789. var downloadUrl = window.URL.createObjectURL(data);
  790. var anchor = document.createElement("a");
  791. anchor.href = downloadUrl;
  792. anchor.download = name + ".xlsx";
  793. anchor.click();
  794. window.URL.revokeObjectURL(data);
  795. ElMessage({
  796. type: "success",
  797. showClose: true,
  798. message: "导出成功",
  799. center: true,
  800. });
  801. } else {
  802. ElMessage({
  803. type: "error",
  804. showClose: true,
  805. message: "导出失败",
  806. center: true,
  807. });
  808. }
  809. };
  810. // 添导入文件功能
  811. const handleChange = (file, fileLists) => {
  812. console.log(file, "file11111");
  813. // let formData = new FormData(); //声明一个FormDate对象
  814. // formData.append("formFile", file.raw);
  815. // fileXlsx.value = formData;
  816. fileXlsx.value = file.raw;
  817. };
  818. // 可以获取文件参数(封面图上传图片)
  819. const handleUpload = (file) => {
  820. console.log(file, "file22222");
  821. };
  822. // 移出文件
  823. const handleRemove = (uploadFile, uploadFiles) => {
  824. console.log(uploadFile, uploadFiles);
  825. fileXlsx.value = "";
  826. };
  827. // 限制上传图片的大小类型
  828. const beforeAvatarUpload = (rawFile) => {
  829. console.log(rawFile.type);
  830. if (
  831. rawFile.type !==
  832. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  833. ) {
  834. ElMessage.error("文件必须为xlsx格式!");
  835. return false;
  836. }
  837. return true;
  838. };
  839. // 上传文件时多次上传会替换前一个文件
  840. const handleExceed = (files) => {
  841. console.log(files, "替换文件");
  842. upload.value.clearFiles();
  843. const file = files[0];
  844. upload.value.handleStart(file);
  845. fileXlsx.value = files.raw;
  846. };
  847. // 确定导入文件
  848. const importSuc = async () => {
  849. console.log("确定导入");
  850. let data = new FormData(); //声明一个FormDate对象
  851. data.set("file", fileXlsx.value);
  852. let res = await axios({
  853. method: "post",
  854. url: api.value + "/repairConsume/importRepairConsumeExcel",
  855. headers: {
  856. token: sessionStorage.getItem("token"),
  857. user_head: sessionStorage.getItem("userhead"),
  858. "Content-Type": "multipart/form-data;charset=UTF-8",
  859. },
  860. data: data,
  861. });
  862. console.log(res);
  863. if (res.data.code == 200) {
  864. importXlsx.value = false;
  865. getList();
  866. ElMessage({
  867. type: "success",
  868. showClose: true,
  869. message: res.data.message,
  870. center: true,
  871. });
  872. } else {
  873. ElMessage({
  874. type: "error",
  875. showClose: true,
  876. message: res.data.message,
  877. center: true,
  878. });
  879. }
  880. };
  881. // 表格多选框多选框功能
  882. const handleSelectionChange = (val) => {
  883. console.log(val);
  884. selectData.list = val;
  885. };
  886. // 表格斑马纹颜色修改
  887. const tableRowClassName = ({ row, rowIndex }) => {
  888. if (rowIndex % 2 === 0) {
  889. return "even";
  890. } else if (rowIndex % 2 !== 0) {
  891. return "odd";
  892. }
  893. return "";
  894. };
  895. // 耗材管理分页
  896. const handleCurrentChange = (value) => {
  897. // console.log(value);
  898. currentPage.value = value;
  899. getList(themeIndex.value);
  900. };
  901. // 耗材记录分页
  902. const handleCurrentChange2 = (value) => {
  903. // console.log(value);
  904. currentPage2.value = value;
  905. getList(themeIndex.value);
  906. };
  907. onBeforeMount(() => {
  908. api.value = store.state.user.api;
  909. getList(themeIndex.value);
  910. });
  911. onUnmounted(() => {
  912. // document.removeEventListener("keyup", Enters);
  913. });
  914. </script>
  915. <style scoped lang="scss">
  916. .content-box {
  917. width: 97.5%;
  918. height: 89%;
  919. margin: 20px auto;
  920. background-color: #fff;
  921. color: #fff;
  922. display: flex;
  923. flex-direction: column;
  924. box-shadow: 0px 3px 10px rgba(213, 228, 252, 1);
  925. .left {
  926. // width: calc(100wh - 40px);
  927. display: flex;
  928. align-items: center;
  929. height: 60px;
  930. margin: 0 30px;
  931. border-bottom: 1px solid #ccc;
  932. color: rgb(0, 0, 0);
  933. font-size: 18px;
  934. font-weight: 600;
  935. span {
  936. margin-right: 20px;
  937. cursor: pointer;
  938. }
  939. .is_active {
  940. color: rgba(111, 182, 184, 1);
  941. }
  942. }
  943. .middle {
  944. width: 96%;
  945. margin: 0 auto;
  946. color: #000;
  947. // border-bottom: 1px solid rgb(231, 231, 231);
  948. .filter {
  949. display: flex;
  950. flex-wrap: wrap;
  951. align-items: center;
  952. margin: 10px 0 0 0;
  953. .search {
  954. color: #fff;
  955. }
  956. .condition {
  957. display: flex;
  958. align-items: center;
  959. margin: 10px 30px 10px 0;
  960. :deep(.el-input .el-input__inner) {
  961. font-size: 16px;
  962. }
  963. span {
  964. margin: 0 10px 0 0;
  965. }
  966. }
  967. }
  968. .gongneng {
  969. margin: 10px 0 20px 0;
  970. span {
  971. color: #fff;
  972. }
  973. }
  974. :deep(.cont) {
  975. width: 60%;
  976. margin: 20px auto;
  977. }
  978. :deep(.download) {
  979. display: flex;
  980. align-items: center;
  981. margin: 10px;
  982. }
  983. :deep(.download span) {
  984. font-size: 16px;
  985. margin-left: 20px;
  986. }
  987. :deep(.cont .el-button) {
  988. margin-left: 60px;
  989. margin-bottom: 30px;
  990. }
  991. :deep(.cont .accomplish) {
  992. width: 100%;
  993. display: flex;
  994. justify-content: center;
  995. }
  996. :deep(.cont .accomplish .el-button) {
  997. width: 50%;
  998. margin: 0;
  999. }
  1000. }
  1001. .footer {
  1002. width: 96%;
  1003. height: 550px;
  1004. margin: 10px auto 30px;
  1005. .el-table--fit {
  1006. height: 100%;
  1007. :deep(.el-table__header-wrapper) {
  1008. background-color: #000;
  1009. font-size: 16px;
  1010. tr {
  1011. color: #000;
  1012. }
  1013. }
  1014. :deep(.el-table__row) {
  1015. height: 50px;
  1016. font-size: 16px;
  1017. color: #000;
  1018. }
  1019. :deep(.el-table__row td) {
  1020. padding: 0;
  1021. border: 0;
  1022. }
  1023. .el-button--primary {
  1024. margin-left: 5px;
  1025. }
  1026. :deep(.el-table__body .even) {
  1027. background-color: #fff;
  1028. }
  1029. :deep(.el-table__body .odd) {
  1030. background-color: rgba(240, 243, 247, 1);
  1031. }
  1032. :deep(.edit) {
  1033. display: flex;
  1034. align-items: center;
  1035. justify-content: center;
  1036. color: rgba(111, 182, 184, 1);
  1037. }
  1038. :deep(.look) {
  1039. padding: 0 10px;
  1040. cursor: pointer;
  1041. }
  1042. :deep(.look):hover {
  1043. color: red;
  1044. }
  1045. }
  1046. // 添加员工弹窗样式
  1047. :deep(.addStaff) {
  1048. // height: 420px;
  1049. border-radius: 11px;
  1050. .el-dialog__header {
  1051. border-radius: 11px 11px 0 0;
  1052. background: rgba(237, 241, 245, 1);
  1053. font-weight: 600;
  1054. margin: 0;
  1055. .el-dialog__headerbtn {
  1056. outline: none;
  1057. }
  1058. }
  1059. .el-dialog__body {
  1060. padding: 30px 20px 10px 20px;
  1061. .el-input {
  1062. width: 200px;
  1063. }
  1064. .checkbox {
  1065. .el-form-item__content {
  1066. display: flex;
  1067. flex-direction: column;
  1068. align-items: flex-start;
  1069. .el-checkbox-group {
  1070. display: flex;
  1071. flex-direction: column;
  1072. }
  1073. }
  1074. }
  1075. .options {
  1076. .el-form-item__content {
  1077. .queding {
  1078. margin-left: 20px;
  1079. color: #fff;
  1080. }
  1081. display: flex;
  1082. flex-direction: row-reverse;
  1083. }
  1084. }
  1085. }
  1086. }
  1087. // 导入弹窗样式
  1088. :deep(.importXlsx) {
  1089. // height: 420px;
  1090. border-radius: 11px;
  1091. .el-dialog__header {
  1092. border-radius: 11px 11px 0 0;
  1093. background: rgba(237, 241, 245, 1);
  1094. font-weight: 600;
  1095. margin: 0;
  1096. .el-dialog__headerbtn {
  1097. outline: none;
  1098. }
  1099. }
  1100. .el-dialog__body {
  1101. padding: 20px 20px 10px 20px;
  1102. .el_btn {
  1103. display: flex;
  1104. // align-items: center;
  1105. // justify-content: space-between;
  1106. }
  1107. .avatar-uploader {
  1108. width: 100%;
  1109. margin: 0 10px;
  1110. }
  1111. .options {
  1112. margin: 15px 0;
  1113. .queding {
  1114. margin-left: 20px;
  1115. color: #fff;
  1116. }
  1117. display: flex;
  1118. flex-direction: row-reverse;
  1119. }
  1120. }
  1121. }
  1122. }
  1123. .pageSize {
  1124. display: flex;
  1125. align-items: center;
  1126. justify-content: space-between;
  1127. margin: 0 30px;
  1128. span {
  1129. color: #000;
  1130. }
  1131. .el-pagination {
  1132. // width: 1600px;
  1133. :deep(.el-pagination__total) {
  1134. color: #000;
  1135. }
  1136. :deep(.el-pagination__goto) {
  1137. color: #000;
  1138. }
  1139. :deep(.el-pagination__classifier) {
  1140. color: #000;
  1141. }
  1142. :deep(.el-input__wrapper) {
  1143. border: 1px solid rgba(0, 0, 0, 1);
  1144. border-radius: 5px;
  1145. box-shadow: none;
  1146. }
  1147. :deep(.el-pager li) {
  1148. margin: 0 5px;
  1149. border: 1px solid rgba(0, 0, 0, 1);
  1150. border-radius: 5px;
  1151. background-color: transparent;
  1152. }
  1153. :deep(.el-pager li.is-active) {
  1154. background-color: rgba(111, 182, 184, 1);
  1155. }
  1156. :deep(.btn-prev) {
  1157. margin-right: 5px;
  1158. border: 1px solid rgba(0, 0, 0, 1);
  1159. border-radius: 5px;
  1160. background-color: transparent;
  1161. }
  1162. :deep(.btn-next) {
  1163. margin-left: 5px;
  1164. border: 1px solid rgba(0, 0, 0, 1);
  1165. border-radius: 5px;
  1166. background-color: transparent;
  1167. }
  1168. }
  1169. }
  1170. }
  1171. .el-input {
  1172. width: 192px;
  1173. }
  1174. </style>