consumable.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  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>合计:100件 30000元</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. watch(
  341. () => searchInput.createTime,
  342. (newVal, oldVal) => {
  343. console.log("监听时间:", newVal);
  344. if (newVal == null) {
  345. searchBtn();
  346. }
  347. }
  348. );
  349. watch(
  350. () => searchInput2.createTime,
  351. (newVal, oldVal) => {
  352. console.log("监听时间:", newVal);
  353. if (newVal == null) {
  354. searchBtn();
  355. }
  356. }
  357. );
  358. // 查看耗材管理列表
  359. const getList = async (flag) => {
  360. keyIndex.value++;
  361. // 耗材管理(-----------------------------------------------)
  362. if (flag == 1) {
  363. themeIndex.value = 1;
  364. let data = {
  365. currentPage: currentPage.value,
  366. pageCount: pageSize.value,
  367. name: searchInput.name,
  368. };
  369. if (searchInput.createTime) {
  370. data.startTime = searchInput.createTime[0];
  371. data.endTime = searchInput.createTime[1];
  372. }
  373. let res = await axios({
  374. method: "get",
  375. url: api.value + "/repairConsume/queryPageRepairConsume",
  376. headers: {
  377. token: sessionStorage.getItem("token"),
  378. user_head: sessionStorage.getItem("userhead"),
  379. },
  380. params: data,
  381. });
  382. console.log(res, "耗材管理");
  383. if (res.data.code == 200) {
  384. tableData.list = res.data.data.list;
  385. total.value = res.data.data.totalCount;
  386. // ElMessage({
  387. // type: "success",
  388. // showClose: true,
  389. // message: res.data.message,
  390. // center: true,
  391. // });
  392. } else {
  393. ElMessage({
  394. type: "error",
  395. showClose: true,
  396. message: res.data.message,
  397. center: true,
  398. });
  399. if (res.data.code == 570) {
  400. sessionStorage.removeItem("token")
  401. router.push({
  402. path: `/login`,
  403. });
  404. }
  405. }
  406. } else if (flag == 2) {
  407. themeIndex.value = 2;
  408. let data = {
  409. currentPage: currentPage2.value,
  410. pageCount: pageSize2.value,
  411. keyWord: searchInput2.name,
  412. };
  413. if (searchInput2.createTime) {
  414. data.startTime = searchInput2.createTime[0];
  415. data.endTime = searchInput2.createTime[1];
  416. }
  417. let res = await axios({
  418. method: "get",
  419. url: api.value + "/repairConsumables/queryRepairConsumablePageList",
  420. headers: {
  421. token: sessionStorage.getItem("token"),
  422. user_head: sessionStorage.getItem("userhead"),
  423. },
  424. params: data,
  425. });
  426. console.log(res, "耗材记录");
  427. if (res.data.code == 200) {
  428. tableData2.list = res.data.data.list;
  429. total2.value = res.data.data.totalCount;
  430. } else {
  431. ElMessage({
  432. type: "error",
  433. showClose: true,
  434. message: res.data.message,
  435. center: true,
  436. });
  437. }
  438. }
  439. };
  440. // 搜索功能
  441. const searchBtn = lodash.debounce(async () => {
  442. getList(themeIndex.value);
  443. }, 300);
  444. //新增添加耗材 (--------------------------------------)
  445. const addlist = () => {
  446. dialongTitle.value = "添加耗材";
  447. ruleForm.schoolId = 1;
  448. changeSchool(ruleForm.schoolId);
  449. addDialogVisible.value = true;
  450. ruleForm.name = "";
  451. ruleForm.price = "";
  452. ruleForm.articleIds = [];
  453. ruleForm.content = "";
  454. nextTick(() => {
  455. articleIdsRef.value.setCheckedKeys([]);
  456. });
  457. };
  458. // // 种类是否全选按钮
  459. // const handleCheckAllChange = (val) => {
  460. // console.log(val);
  461. // checkedCities.value = val ? cities : [];
  462. // isIndeterminate.value = false;
  463. // };
  464. // //单独勾选种类
  465. // const handleCheckedCitiesChange = (value) => {
  466. // console.log(value);
  467. // const checkedCount = value.length;
  468. // checkAll.value = checkedCount === cities.length;
  469. // isIndeterminate.value = checkedCount > 0 && checkedCount < cities.length;
  470. // };
  471. // 关联报修类型 当复选框被点击的时候触发
  472. const handleArticleIds = (data, checked, indeterminate) => {
  473. console.log(data, checked, indeterminate);
  474. // let keys = articleIdsRef.value.getCheckedNodes();
  475. let keys = articleIdsRef.value.getCheckedKeys();
  476. // console.log(keys);
  477. // let arr = [];
  478. // keys.forEach((item) => {
  479. // if (item.parentId != 1) {
  480. // arr.push(item.id);
  481. // }
  482. // });
  483. ruleForm.articleIds = keys;
  484. };
  485. // 改变校区 关联楼栋和关联报修类型也改变(---------------)
  486. const changeSchool = async (val) => {
  487. if (val == 1) {
  488. ruleForm.schoolId = 1;
  489. } else {
  490. ruleForm.schoolId = 2;
  491. }
  492. // 报修(故障类型)类型关联 (接口-------)
  493. let data = {
  494. schoolId: val,
  495. };
  496. let resss = await axios({
  497. method: "get",
  498. url: api.value + "/repairArticleType/queryRepairArticleType",
  499. headers: {
  500. token: sessionStorage.getItem("token"),
  501. user_head: sessionStorage.getItem("userhead"),
  502. },
  503. params: data,
  504. });
  505. console.log(resss, "报修(故障类型)类型关联数据");
  506. articleIdsList.value = resss.data.data;
  507. };
  508. //编辑按钮 (-------------------------------------------)
  509. const edit = (row) => {
  510. dialongTitle.value = "编辑耗材";
  511. addDialogVisible.value = true;
  512. changeSchool(row.schoolId);
  513. ruleForm.name = row.name;
  514. ruleForm.price = row.price;
  515. ruleForm.articleIds = row.articleIds;
  516. ruleForm.content = row.content;
  517. ruleForm.schoolId = row.schoolId;
  518. nextTick(() => {
  519. articleIdsRef.value.setCheckedKeys(row.articleIds);
  520. });
  521. ruleForm.id = row.id;
  522. };
  523. // 取消 编辑/添加耗材
  524. const cancelAdd = () => {
  525. addDialogVisible.value = false;
  526. ruleFormRef.value.resetFields();
  527. };
  528. // 确认 编辑/添加耗材
  529. const submitAdd = async (formEl) => {
  530. if (!formEl) return;
  531. await formEl.validate(async (valid, fields) => {
  532. if (valid) {
  533. if (dialongTitle.value == "添加耗材") {
  534. // 添加耗材接口(++++++++)
  535. let data = {
  536. name: ruleForm.name,
  537. price: ruleForm.price,
  538. articleIds: ruleForm.articleIds,
  539. content: ruleForm.content,
  540. schoolId: ruleForm.schoolId,
  541. };
  542. let res = await axios({
  543. method: "post",
  544. url: api.value + "/repairConsume/insertRepairConsume",
  545. headers: {
  546. token: sessionStorage.getItem("token"),
  547. user_head: sessionStorage.getItem("userhead"),
  548. },
  549. data: data,
  550. });
  551. console.log(res, "添加耗材");
  552. if (res.data.code == 200) {
  553. getList(themeIndex.value);
  554. ElMessage({
  555. type: "success",
  556. showClose: true,
  557. message: res.data.message,
  558. center: true,
  559. });
  560. addDialogVisible.value = false;
  561. ruleFormRef.value.resetFields();
  562. } else {
  563. ElMessage({
  564. type: "error",
  565. showClose: true,
  566. message: res.data.message,
  567. center: true,
  568. });
  569. }
  570. } else {
  571. // 编辑耗材接口(++++++++)
  572. let data = {
  573. name: ruleForm.name,
  574. price: ruleForm.price,
  575. articleIds: ruleForm.articleIds,
  576. content: ruleForm.content,
  577. schoolId: ruleForm.schoolId,
  578. id: ruleForm.id,
  579. };
  580. let res = await axios({
  581. method: "post",
  582. url: api.value + "/repairConsume/updateRepairConsumeById",
  583. headers: {
  584. user_head: sessionStorage.getItem("userhead"),
  585. token: sessionStorage.getItem("token"),
  586. },
  587. data: data,
  588. });
  589. // console.log(res, "修改账号");
  590. if (res.data.code == 200) {
  591. getList(themeIndex.value);
  592. ElMessage({
  593. type: "success",
  594. showClose: true,
  595. message: res.data.message,
  596. center: true,
  597. });
  598. addDialogVisible.value = false;
  599. ruleFormRef.value.resetFields();
  600. } else {
  601. ElMessage({
  602. type: "error",
  603. showClose: true,
  604. message: res.data.message,
  605. center: true,
  606. });
  607. }
  608. }
  609. } else {
  610. console.log("error submit!", fields);
  611. }
  612. });
  613. };
  614. // 耗材管理删除按钮
  615. const del = async (row) => {
  616. let data = {
  617. id: row.id,
  618. };
  619. let res = await axios({
  620. method: "get",
  621. url: api.value + "/repairConsume/deleteRepairConsumeById",
  622. headers: {
  623. token: sessionStorage.getItem("token"),
  624. user_head: sessionStorage.getItem("userhead"),
  625. },
  626. params: data,
  627. });
  628. if (res.data.code == 200) {
  629. if (tableData.list.length == 1 && currentPage.value != 1) {
  630. currentPage.value = currentPage.value - 1;
  631. }
  632. getList(themeIndex.value);
  633. ElMessage({
  634. type: "success",
  635. showClose: true,
  636. message: res.data.message,
  637. center: true,
  638. });
  639. } else {
  640. ElMessage({
  641. type: "error",
  642. showClose: true,
  643. message: res.data.message,
  644. center: true,
  645. });
  646. }
  647. };
  648. // 取消删除
  649. const cancelEvent = () => {
  650. ElMessage({
  651. type: "info",
  652. showClose: true,
  653. message: "取消删除",
  654. center: true,
  655. });
  656. };
  657. //导出功能
  658. const importExcel1 = async () => {
  659. let datas;
  660. if (searchInput.createTime) {
  661. datas = {
  662. name: searchInput.name,
  663. startTime: searchInput.createTime[0],
  664. endTime: searchInput.createTime[1],
  665. };
  666. } else {
  667. datas = {
  668. name: searchInput.name,
  669. };
  670. }
  671. let res = await axios({
  672. method: "get",
  673. url: api.value + "/repairConsume/downloadRepairConsumeExcel",
  674. headers: {
  675. token: sessionStorage.getItem("token"),
  676. user_head: sessionStorage.getItem("userhead"),
  677. },
  678. params: datas,
  679. responseType: "blob",
  680. });
  681. console.log(res, "导出耗材");
  682. if (res.status == 200) {
  683. let name = `耗材数据`;
  684. var content = res.data;
  685. // var data = new Blob([content],{type:"application/octet-stream;charset=utf-8"});
  686. // var data = new Blob([content], {
  687. // type: "application/vnd.ms-excel;charset=utf-8",
  688. // });
  689. var data = new Blob([content]);
  690. var downloadUrl = window.URL.createObjectURL(data);
  691. var anchor = document.createElement("a");
  692. anchor.href = downloadUrl;
  693. anchor.download = name + ".xlsx";
  694. anchor.click();
  695. window.URL.revokeObjectURL(data);
  696. ElMessage({
  697. type: "success",
  698. showClose: true,
  699. message: "导出成功",
  700. center: true,
  701. });
  702. } else {
  703. ElMessage({
  704. type: "error",
  705. showClose: true,
  706. message: "导出失败",
  707. center: true,
  708. });
  709. }
  710. };
  711. //导出功能
  712. const importExcel2 = async () => {
  713. let datas = {
  714. keyWord: searchInput2.name,
  715. };
  716. if (searchInput2.createTime) {
  717. datas.startTime = searchInput2.createTime[0];
  718. datas.endTime = searchInput2.createTime[1];
  719. }
  720. let res = await axios({
  721. method: "get",
  722. url: api.value + "/repairConsumables/downloadRepairConsumableExcel",
  723. headers: {
  724. token: sessionStorage.getItem("token"),
  725. user_head: sessionStorage.getItem("userhead"),
  726. },
  727. params: datas,
  728. responseType: "blob",
  729. });
  730. console.log(res, "导出耗材记录");
  731. if (res.status == 200) {
  732. let name = `耗材记录数据`;
  733. var content = res.data;
  734. // var data = new Blob([content],{type:"application/octet-stream;charset=utf-8"});
  735. // var data = new Blob([content], {
  736. // type: "application/vnd.ms-excel;charset=utf-8",
  737. // });
  738. var data = new Blob([content]);
  739. var downloadUrl = window.URL.createObjectURL(data);
  740. var anchor = document.createElement("a");
  741. anchor.href = downloadUrl;
  742. anchor.download = name + ".xlsx";
  743. anchor.click();
  744. window.URL.revokeObjectURL(data);
  745. ElMessage({
  746. type: "success",
  747. showClose: true,
  748. message: "导出成功",
  749. center: true,
  750. });
  751. } else {
  752. ElMessage({
  753. type: "error",
  754. showClose: true,
  755. message: "导出失败",
  756. center: true,
  757. });
  758. }
  759. };
  760. // 导入弹窗
  761. const importFile = () => {
  762. importXlsx.value = true;
  763. };
  764. const closeXlsx = () => {
  765. importXlsx.value = false;
  766. upload.value.clearFiles();
  767. fileXlsx.value = "";
  768. };
  769. // 导出模板
  770. const importTemp = async () => {
  771. let res = await axios({
  772. method: "get",
  773. url: api.value + "/repairConsume/downloadRepairConsumeModelExcel",
  774. headers: {
  775. token: sessionStorage.getItem("token"),
  776. user_head: sessionStorage.getItem("userhead"),
  777. },
  778. responseType: "blob",
  779. });
  780. console.log(res, "导出模板");
  781. if (res.status == 200) {
  782. let name = `耗材数据导入模板`;
  783. var content = res.data;
  784. var data = new Blob([content]);
  785. var downloadUrl = window.URL.createObjectURL(data);
  786. var anchor = document.createElement("a");
  787. anchor.href = downloadUrl;
  788. anchor.download = name + ".xlsx";
  789. anchor.click();
  790. window.URL.revokeObjectURL(data);
  791. ElMessage({
  792. type: "success",
  793. showClose: true,
  794. message: "导出成功",
  795. center: true,
  796. });
  797. } else {
  798. ElMessage({
  799. type: "error",
  800. showClose: true,
  801. message: "导出失败",
  802. center: true,
  803. });
  804. }
  805. };
  806. // 添导入文件功能
  807. const handleChange = (file, fileLists) => {
  808. console.log(file, "file11111");
  809. // let formData = new FormData(); //声明一个FormDate对象
  810. // formData.append("formFile", file.raw);
  811. // fileXlsx.value = formData;
  812. fileXlsx.value = file.raw;
  813. };
  814. // 可以获取文件参数(封面图上传图片)
  815. const handleUpload = (file) => {
  816. console.log(file, "file22222");
  817. };
  818. // 移出文件
  819. const handleRemove = (uploadFile, uploadFiles) => {
  820. console.log(uploadFile, uploadFiles);
  821. fileXlsx.value = "";
  822. };
  823. // 限制上传图片的大小类型
  824. const beforeAvatarUpload = (rawFile) => {
  825. console.log(rawFile.type);
  826. if (
  827. rawFile.type !==
  828. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  829. ) {
  830. ElMessage.error("文件必须为xlsx格式!");
  831. return false;
  832. }
  833. return true;
  834. };
  835. // 上传文件时多次上传会替换前一个文件
  836. const handleExceed = (files) => {
  837. console.log(files, "替换文件");
  838. upload.value.clearFiles();
  839. const file = files[0];
  840. upload.value.handleStart(file);
  841. fileXlsx.value = files.raw;
  842. };
  843. // 确定导入文件
  844. const importSuc = async () => {
  845. console.log("确定导入");
  846. let data = new FormData(); //声明一个FormDate对象
  847. data.set("file", fileXlsx.value);
  848. let res = await axios({
  849. method: "post",
  850. url: api.value + "/repairConsume/importRepairConsumeExcel",
  851. headers: {
  852. token: sessionStorage.getItem("token"),
  853. user_head: sessionStorage.getItem("userhead"),
  854. "Content-Type": "multipart/form-data;charset=UTF-8",
  855. },
  856. data: data,
  857. });
  858. console.log(res);
  859. if (res.data.code == 200) {
  860. importXlsx.value = false;
  861. getList();
  862. ElMessage({
  863. type: "success",
  864. showClose: true,
  865. message: res.data.message,
  866. center: true,
  867. });
  868. } else {
  869. ElMessage({
  870. type: "error",
  871. showClose: true,
  872. message: res.data.message,
  873. center: true,
  874. });
  875. }
  876. };
  877. // 表格多选框多选框功能
  878. const handleSelectionChange = (val) => {
  879. console.log(val);
  880. selectData.list = val;
  881. };
  882. // 表格斑马纹颜色修改
  883. const tableRowClassName = ({ row, rowIndex }) => {
  884. if (rowIndex % 2 === 0) {
  885. return "even";
  886. } else if (rowIndex % 2 !== 0) {
  887. return "odd";
  888. }
  889. return "";
  890. };
  891. // 耗材管理分页
  892. const handleCurrentChange = (value) => {
  893. // console.log(value);
  894. currentPage.value = value;
  895. getList(themeIndex.value);
  896. };
  897. // 耗材记录分页
  898. const handleCurrentChange2 = (value) => {
  899. // console.log(value);
  900. currentPage2.value = value;
  901. getList(themeIndex.value);
  902. };
  903. onBeforeMount(() => {
  904. api.value = store.state.user.api;
  905. getList(themeIndex.value);
  906. });
  907. onUnmounted(() => {
  908. // document.removeEventListener("keyup", Enters);
  909. });
  910. </script>
  911. <style scoped lang="scss">
  912. .content-box {
  913. width: 97.5%;
  914. height: 89%;
  915. margin: 20px auto;
  916. background-color: #fff;
  917. color: #fff;
  918. display: flex;
  919. flex-direction: column;
  920. box-shadow: 0px 3px 10px rgba(213, 228, 252, 1);
  921. .left {
  922. // width: calc(100wh - 40px);
  923. display: flex;
  924. align-items: center;
  925. height: 60px;
  926. margin: 0 30px;
  927. border-bottom: 1px solid #ccc;
  928. color: rgb(0, 0, 0);
  929. font-size: 18px;
  930. font-weight: 600;
  931. span {
  932. margin-right: 20px;
  933. cursor: pointer;
  934. }
  935. .is_active {
  936. color: rgba(111, 182, 184, 1);
  937. }
  938. }
  939. .middle {
  940. width: 96%;
  941. margin: 0 auto;
  942. color: #000;
  943. // border-bottom: 1px solid rgb(231, 231, 231);
  944. .filter {
  945. display: flex;
  946. flex-wrap: wrap;
  947. align-items: center;
  948. margin: 10px 0 0 0;
  949. .search {
  950. color: #fff;
  951. }
  952. .condition {
  953. display: flex;
  954. align-items: center;
  955. margin: 10px 30px 10px 0;
  956. :deep(.el-input .el-input__inner) {
  957. font-size: 16px;
  958. }
  959. span {
  960. margin: 0 10px 0 0;
  961. }
  962. }
  963. }
  964. .gongneng {
  965. margin: 10px 0 20px 0;
  966. span {
  967. color: #fff;
  968. }
  969. }
  970. :deep(.cont) {
  971. width: 60%;
  972. margin: 20px auto;
  973. }
  974. :deep(.download) {
  975. display: flex;
  976. align-items: center;
  977. margin: 10px;
  978. }
  979. :deep(.download span) {
  980. font-size: 16px;
  981. margin-left: 20px;
  982. }
  983. :deep(.cont .el-button) {
  984. margin-left: 60px;
  985. margin-bottom: 30px;
  986. }
  987. :deep(.cont .accomplish) {
  988. width: 100%;
  989. display: flex;
  990. justify-content: center;
  991. }
  992. :deep(.cont .accomplish .el-button) {
  993. width: 50%;
  994. margin: 0;
  995. }
  996. }
  997. .footer {
  998. width: 96%;
  999. height: 550px;
  1000. margin: 10px auto 30px;
  1001. .el-table--fit {
  1002. height: 100%;
  1003. :deep(.el-table__header-wrapper) {
  1004. background-color: #000;
  1005. font-size: 16px;
  1006. tr {
  1007. color: #000;
  1008. }
  1009. }
  1010. :deep(.el-table__row) {
  1011. height: 50px;
  1012. font-size: 16px;
  1013. color: #000;
  1014. }
  1015. :deep(.el-table__row td) {
  1016. padding: 0;
  1017. border: 0;
  1018. }
  1019. .el-button--primary {
  1020. margin-left: 5px;
  1021. }
  1022. :deep(.el-table__body .even) {
  1023. background-color: #fff;
  1024. }
  1025. :deep(.el-table__body .odd) {
  1026. background-color: rgba(240, 243, 247, 1);
  1027. }
  1028. :deep(.edit) {
  1029. display: flex;
  1030. align-items: center;
  1031. justify-content: center;
  1032. color: rgba(111, 182, 184, 1);
  1033. }
  1034. :deep(.look) {
  1035. padding: 0 10px;
  1036. cursor: pointer;
  1037. }
  1038. :deep(.look):hover {
  1039. color: red;
  1040. }
  1041. }
  1042. // 添加员工弹窗样式
  1043. :deep(.addStaff) {
  1044. // height: 420px;
  1045. border-radius: 11px;
  1046. .el-dialog__header {
  1047. border-radius: 11px 11px 0 0;
  1048. background: rgba(237, 241, 245, 1);
  1049. font-weight: 600;
  1050. margin: 0;
  1051. .el-dialog__headerbtn {
  1052. outline: none;
  1053. }
  1054. }
  1055. .el-dialog__body {
  1056. padding: 30px 20px 10px 20px;
  1057. .el-input {
  1058. width: 200px;
  1059. }
  1060. .checkbox {
  1061. .el-form-item__content {
  1062. display: flex;
  1063. flex-direction: column;
  1064. align-items: flex-start;
  1065. .el-checkbox-group {
  1066. display: flex;
  1067. flex-direction: column;
  1068. }
  1069. }
  1070. }
  1071. .options {
  1072. .el-form-item__content {
  1073. .queding {
  1074. margin-left: 20px;
  1075. color: #fff;
  1076. }
  1077. display: flex;
  1078. flex-direction: row-reverse;
  1079. }
  1080. }
  1081. }
  1082. }
  1083. // 导入弹窗样式
  1084. :deep(.importXlsx) {
  1085. // height: 420px;
  1086. border-radius: 11px;
  1087. .el-dialog__header {
  1088. border-radius: 11px 11px 0 0;
  1089. background: rgba(237, 241, 245, 1);
  1090. font-weight: 600;
  1091. margin: 0;
  1092. .el-dialog__headerbtn {
  1093. outline: none;
  1094. }
  1095. }
  1096. .el-dialog__body {
  1097. padding: 20px 20px 10px 20px;
  1098. .el_btn {
  1099. display: flex;
  1100. // align-items: center;
  1101. // justify-content: space-between;
  1102. }
  1103. .avatar-uploader {
  1104. width: 100%;
  1105. margin: 0 10px;
  1106. }
  1107. .options {
  1108. margin: 15px 0;
  1109. .queding {
  1110. margin-left: 20px;
  1111. color: #fff;
  1112. }
  1113. display: flex;
  1114. flex-direction: row-reverse;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. .pageSize {
  1120. display: flex;
  1121. align-items: center;
  1122. justify-content: space-between;
  1123. margin: 0 30px;
  1124. span {
  1125. color: #000;
  1126. }
  1127. .el-pagination {
  1128. // width: 1600px;
  1129. :deep(.el-pagination__total) {
  1130. color: #000;
  1131. }
  1132. :deep(.el-pagination__goto) {
  1133. color: #000;
  1134. }
  1135. :deep(.el-pagination__classifier) {
  1136. color: #000;
  1137. }
  1138. :deep(.el-input__wrapper) {
  1139. border: 1px solid rgba(0, 0, 0, 1);
  1140. border-radius: 5px;
  1141. box-shadow: none;
  1142. }
  1143. :deep(.el-pager li) {
  1144. margin: 0 5px;
  1145. border: 1px solid rgba(0, 0, 0, 1);
  1146. border-radius: 5px;
  1147. background-color: transparent;
  1148. }
  1149. :deep(.el-pager li.is-active) {
  1150. background-color: rgba(111, 182, 184, 1);
  1151. }
  1152. :deep(.btn-prev) {
  1153. margin-right: 5px;
  1154. border: 1px solid rgba(0, 0, 0, 1);
  1155. border-radius: 5px;
  1156. background-color: transparent;
  1157. }
  1158. :deep(.btn-next) {
  1159. margin-left: 5px;
  1160. border: 1px solid rgba(0, 0, 0, 1);
  1161. border-radius: 5px;
  1162. background-color: transparent;
  1163. }
  1164. }
  1165. }
  1166. }
  1167. .el-input {
  1168. width: 192px;
  1169. }
  1170. </style>