You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.vue 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <div>
  3. <crud-template v-if="itemStart" class="as-weight" :ref="(el) => crudRef = el" :home-data="field"
  4. @btnSearch="btnSearch" @refreshLeft="refreshLeft" :initData="initItem" :tableData="tableData"
  5. @handleEdit="handleEdit" @cancel="cancel" @importData="importData" @CurrentChange="handleCurrentChange">
  6. <template #search>
  7. <el-form
  8. :model="searchForm"
  9. :rules="rules"
  10. :ref="(el) => (searchFormRef = el)"
  11. v-loading="formLoding"
  12. >
  13. <el-form-item
  14. label="签号:"
  15. prop="obuId"
  16. >
  17. <el-input
  18. maxlength="60"
  19. v-trim
  20. clearable
  21. v-model="searchForm.obuId"
  22. style="width: 200px"
  23. placeholder="请输入签号"
  24. />
  25. </el-form-item>
  26. </el-form>
  27. <el-input maxlength="60" v-trim clearable v-model="searchForm.vehiclePlate" placeholder="请输入车牌号"
  28. style="width: 320px;">
  29. <template #append>
  30. <el-select clearable v-model="searchForm.vehiclePlateColor" placeholder="请选择车牌颜色"
  31. style="width: 150px">
  32. <el-option :label="item.label" :key="item.label" :value="item.value"
  33. v-for="item in VEHICLE_COLOR_TYPE" />
  34. </el-select>
  35. </template>
  36. </el-input>
  37. </template>
  38. <template #tableOperation>
  39. <el-button type="primary" v-if="IsPermission(route, 'LOWER_BLACK')" @click="addBlack">下黑</el-button>
  40. </template>
  41. <template #dialog>
  42. <el-form label-position="right" label-width="110px" :model="addForm" :rules="rules"
  43. :ref="(el) => dataFormRef = el" v-loading="formLoding">
  44. <el-form-item label='签号:' prop="obuId" v-if="typeOption === '下黑'">
  45. <el-input maxlength="60" v-trim clearable v-model="addForm.obuId" placeholder="请输入签号"
  46. type="text" />
  47. </el-form-item>
  48. <el-form-item label='黑名单类型:' prop="type" v-if="typeOption === '下黑'">
  49. <el-select clearable v-model="addForm.type" style="width: 100%" placeholder="请选择黑名单类型">
  50. <el-option v-for="item in typeList" :key="item.value" :label="item.label"
  51. :value="item.value" />
  52. </el-select>
  53. </el-form-item>
  54. <el-form-item label='原因:' prop="reason">
  55. <el-input maxlength="200" v-trim clearable v-model="addForm.reason" placeholder="请输入原因"
  56. :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
  57. </el-form-item>
  58. <el-form-item label='解决方案:' prop="solution" v-if="typeOption === '下黑'">
  59. <el-input maxlength="200" v-trim clearable v-model="addForm.solution" placeholder="请输入解决方案"
  60. :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
  61. </el-form-item>
  62. </el-form>
  63. </template>
  64. <template #operation="{ scope }">
  65. <el-button type="primary" @click="handleEdit(scope.row, '反白')" size="small"
  66. v-if="scope.row.status === 1 && IsPermission(route, 'REVERSE')">反白</el-button>
  67. </template>
  68. <template #footer>
  69. <el-button type="default" @click="cancel">取消</el-button>
  70. <el-button type="primary" @click="submitHandle()">确定</el-button>
  71. </template>
  72. </crud-template>
  73. </div>
  74. </template>
  75. <!-- 签黑名单管理 -->
  76. <script lang="ts" setup>
  77. // @ts-ignore crudFrom模板
  78. import CrudTemplate from '@/crud/index.vue'
  79. import { ref, onMounted, computed } from 'vue'
  80. import { ElMessage } from "element-plus";
  81. import { useDebounce, getDictLabel } from "@/utils/utils";
  82. import BaseService from "@/utils/baseService";
  83. import $storeinitData from "@/store/initData"; //引入tab vuex
  84. import { obuBlacklistApi, obuInversionApi } from "@/api/onlineBusinessHall/afterSales"
  85. import { useRoute } from 'vue-router';
  86. import { IsPermission } from "@/router/routerUtil";
  87. //车牌颜色
  88. const VEHICLE_COLOR_TYPE = computed(() => {
  89. return $storeinitData.state.dictData['VEHICLE_COLOR_TYPE'] || []
  90. })
  91. const SOURCE_TYPE = computed(() => {
  92. return $storeinitData.state.dictData['SOURCE_TYPE'] || []
  93. })
  94. //或取路由传入过来的对象数据
  95. const route = useRoute();
  96. const dataFormRef = ref()
  97. const searchFormRef = ref()
  98. const crudRef = ref()
  99. const itemStart = ref(true)
  100. const searchForm = ref({
  101. obuId: "",
  102. vehiclePlate: '',
  103. vehiclePlateColor: '',
  104. })
  105. const typeOption = ref(""); // 新增下黑或者反白操作
  106. const initItem = {
  107. type: "",
  108. obuId: "",
  109. status: "",
  110. reason: "", //反白原因
  111. }
  112. const addForm: any = ref({
  113. ...initItem
  114. })
  115. const formLoding = ref(false);
  116. const rules = {
  117. reason: [{ required: true, message: "请输入原因", trigger: "blur" }],
  118. solution: [{ required: true, message: '请输入解决方案', trigger: 'blur' }],
  119. type: [{ required: true, message: "请选择类型", trigger: "change" }],
  120. obuId: [{ required: true, message: "请输入签号", trigger: "blur" }],
  121. }
  122. const tableData = ref([] as any[]);
  123. const typeList = computed(() => {
  124. return $storeinitData.state.dictData['OBU_BLACK_TYPE'] || []
  125. })
  126. //表单数据配置
  127. const field = ref({
  128. tabSize: 'small', //Table 的尺寸 large / default /small (默认default)
  129. searchShow: IsPermission(route, 'QUERY_BASE'), //是否显示搜索模块(默认false)
  130. border: true, //是否添加边框(默认false)
  131. dialogCustom: true, //自定义Dialog (默认false)
  132. dialogFooter: true, //隐藏弹窗页脚显示 (默认false)
  133. dialogWidth: '40%', //dialog宽度 (默认40%)
  134. crudShow: true, //是否显示CURD操作栏 (默认true)
  135. crudChildShow: true, //是否显示CURD子操作栏 (默认true)
  136. paginStart: true, //是否显示分页查询 (默认false)
  137. titleDialog: "", //table 标题
  138. tableOperation: true,
  139. paging: {
  140. pageSize: 10,
  141. currentPage: 1,
  142. total: 0
  143. },
  144. crud: {
  145. add: false,
  146. edit: false,
  147. delete: false,
  148. derive: false,
  149. search: false,
  150. refresh: false,
  151. },
  152. searchOperation: {
  153. isDownload: false,
  154. isAdd: false,
  155. isTransferMachine: false,
  156. isToLead: true, // 导入
  157. isTemplate: true,
  158. templateUrl:
  159. import.meta.env.VITE_APP_UPLOAD_URL +
  160. 'zhywpt-issuer/template/managew/签批量下黑反白模板.xlsx',
  161. templateFileName: '签批量下黑反白模板',
  162. },
  163. tableSize: -1,
  164. operateShow: true, //是否为表格添加操作栏(默认true)
  165. operateTitle: '操作', //操作栏标题(默认为"")
  166. operateFixed: true, //操作栏是否固定(默认false)
  167. operateWidth: '150', //操作栏宽度
  168. operate: {
  169. info: true,
  170. edit: false, //是否编辑(默认true)
  171. delete: false, //是否删除(默认true)
  172. announcement: false, // 公告
  173. remark: false, // 详情
  174. forbidden: false, // 禁用
  175. enable: false, // 启用
  176. authorization: false, // 授权
  177. cancel: false,// 取消订单
  178. writeOff: false,// 注销
  179. make: false,// 补缴
  180. },
  181. extend: [
  182. {
  183. label: '序号',
  184. type: 'index', //类型:selection,index,expand
  185. width: '', //表头宽度
  186. },
  187. ],
  188. field: [
  189. {
  190. prop: 'obuId',
  191. label: '签号',
  192. width: 170,
  193. form: {
  194. width: '45%',
  195. type: 'input',
  196. }
  197. },
  198. {
  199. prop: 'agencyId',
  200. label: '渠道编号',
  201. width: 170,
  202. form: {
  203. width: '45%',
  204. type: 'input',
  205. }
  206. },
  207. {
  208. prop: 'type',
  209. label: '类型',
  210. funRuleStarts: true,
  211. funRule: (val: any) => {
  212. return getDictLabel(typeList, val)
  213. },
  214. form: {
  215. width: '45%',
  216. type: 'select',
  217. listData: typeList
  218. }
  219. },
  220. {
  221. prop: 'status',
  222. label: '状态',
  223. funRuleStarts: true,
  224. width: 120,
  225. funRule: (val: any) => {
  226. //1-在黑,2-已反白
  227. if (val == 1) {
  228. return '在黑'
  229. } else if (val == 2) {
  230. return '已反白'
  231. }
  232. return val
  233. },
  234. form: {
  235. width: '45%',
  236. type: 'input',
  237. funRuleStarts: true,
  238. funRule: (val: any) => {
  239. //1-在黑,2-已反白
  240. if (val == 1) {
  241. return '在黑'
  242. } else if (val == 2) {
  243. return '已反白'
  244. }
  245. return val
  246. },
  247. }
  248. },
  249. {
  250. prop: 'vehiclePlate',
  251. label: '车牌号',
  252. width: 170,
  253. form: {
  254. width: '45%',
  255. type: 'input',
  256. }
  257. },
  258. {
  259. prop: 'vehiclePlateColor',
  260. label: '车牌颜色',
  261. width: 170,
  262. listData: VEHICLE_COLOR_TYPE,
  263. form: {
  264. width: '45%',
  265. type: 'select',
  266. listData: VEHICLE_COLOR_TYPE
  267. }
  268. },
  269. {
  270. prop: 'createTime',
  271. label: '下黑时间',
  272. width: '170px',
  273. funRuleStarts: true,
  274. funRule: (val: any) => {
  275. if (val) {
  276. return val.replaceAll('T', ' ')
  277. }
  278. return val
  279. },
  280. form: {
  281. width: '45%',
  282. type: 'input',
  283. funRuleStarts: true,
  284. funRule: (val: any) => {
  285. if (val) {
  286. return val.replaceAll('T', ' ')
  287. }
  288. return val
  289. },
  290. }
  291. },
  292. {
  293. prop: 'reasonIn',
  294. label: '下黑原因',
  295. form: {
  296. width: '45%',
  297. type: 'input',
  298. }
  299. },
  300. {
  301. prop: 'staffIdIn',
  302. label: '下黑操作工号',
  303. width: 120,
  304. hide: true,
  305. form: {
  306. width: '45%',
  307. type: 'input',
  308. }
  309. },
  310. {
  311. label: '下黑来源',
  312. prop: 'sourceIn',
  313. listData: SOURCE_TYPE,
  314. hide: true,
  315. form: {
  316. width: '45%',
  317. type: 'select',
  318. listData: SOURCE_TYPE,
  319. },
  320. },
  321. {
  322. prop: 'releaseTime',
  323. label: '反白时间',
  324. width: '170px',
  325. funRuleStarts: true,
  326. funRule: (val: any) => {
  327. if (val) {
  328. return val.replaceAll('T', ' ')
  329. }
  330. return val
  331. },
  332. form: {
  333. width: '45%',
  334. type: 'input',
  335. funRuleStarts: true,
  336. funRule: (val: any) => {
  337. if (val) {
  338. return val.replaceAll('T', ' ')
  339. }
  340. return val
  341. },
  342. }
  343. },
  344. {
  345. prop: 'reasonOut',
  346. label: '反白原因',
  347. form: {
  348. width: '45%',
  349. type: 'input',
  350. }
  351. },
  352. {
  353. prop: 'staffIdOut',
  354. label: '反白操作工号',
  355. width: 170,
  356. hide: true,
  357. form: {
  358. width: '45%',
  359. type: 'input',
  360. }
  361. },
  362. {
  363. label: '反白来源',
  364. prop: 'sourceOut',
  365. listData: SOURCE_TYPE,
  366. hide: true,
  367. form: {
  368. width: '45%',
  369. type: 'select',
  370. listData: SOURCE_TYPE,
  371. },
  372. },
  373. ],
  374. })
  375. // 搜索按钮
  376. function btnSearch() {
  377. searchFormRef.value.validate((valid: boolean) => {
  378. if (!valid) {
  379. return false
  380. }
  381. field.value.paging.currentPage = 1;
  382. getList();
  383. });
  384. }
  385. // 搜索重置
  386. function refreshLeft() {
  387. searchForm.value = {
  388. obuId: "",
  389. vehiclePlate: '',
  390. vehiclePlateColor: '',
  391. }
  392. field.value.paging.currentPage = 1;
  393. //因为必须传obuId,所在列表置空,不请求
  394. //getList();
  395. tableData.value = [];
  396. }
  397. //反白
  398. function handleEdit(row: any, text) {
  399. addForm.value.type = row.type;
  400. addForm.value.obuId = row.obuId;
  401. addForm.value.status = 2; // 2是反白
  402. crudRef.value.dialogFormVisible = true;
  403. crudRef.value.title = text;
  404. typeOption.value = text
  405. console.log("====", addForm.value)
  406. }
  407. // 取消
  408. function cancel() {
  409. addForm.value = {
  410. ...initItem
  411. }//清空数据
  412. crudRef.value.reset();
  413. crudRef.value.dialogFormVisible = false;
  414. crudRef.value.title = "";
  415. typeOption.value = ""
  416. }
  417. function handleCurrentChange(val: number) {
  418. field.value.paging.currentPage = val;
  419. getList();
  420. }
  421. // 提交
  422. function submitClick() {
  423. dataFormRef.value.validate((valid: boolean) => {
  424. if (!valid) {
  425. return false;
  426. }
  427. let api = '/managew/api/bls/obu/obuIn';
  428. let params = {
  429. ...addForm.value
  430. }
  431. if(params.status == 2){
  432. api = '/managew/api/bls/obu/obuOut'
  433. }
  434. BaseService.post(api, params).then((res: any) => {
  435. if (res && res.statusCode === 0) {
  436. let bizContent = res.data
  437. console.log(bizContent, 'bizContentbizContentbizContent')
  438. if (bizContent.uploadStatus == 1) {
  439. let msg = '操作成功';
  440. //兼容后端把一些报错返回在info里面
  441. if (bizContent.info && !bizContent.info.info) {
  442. msg = bizContent.info
  443. }
  444. ElMessage.success(msg);
  445. //因为需求查询列表必须传obuId,所以为了方便用户查看最新操作的数据,更新查询框的obuId
  446. searchForm.value.obuId = addForm.value.obuId
  447. getList();
  448. cancel();
  449. } else {
  450. ElMessage.error(bizContent.message)
  451. }
  452. } else {
  453. ElMessage.error(res.message)
  454. }
  455. })
  456. });
  457. }
  458. const submitHandle = useDebounce(submitClick)
  459. function getList() {
  460. crudRef.value.tableLoding = true;
  461. let params: any = {
  462. methods: "page",
  463. pageNo: field.value.paging.currentPage,
  464. pageSize: field.value.paging.pageSize,
  465. }
  466. let searchFormList = { ...searchForm.value }
  467. for (let key in searchFormList) {
  468. if (searchFormList[key]) {
  469. params[key] = searchFormList[key]
  470. }
  471. }
  472. BaseService.post('/managew/api/bls/obu/query', params).then((res: any) => {
  473. if (res && res.statusCode === 0) {
  474. let bizContent = res.data
  475. let data = bizContent.results || [];
  476. console.log("===bizContentData", data)
  477. tableData.value = data;
  478. crudRef.value.tableLoding = false;
  479. field.value.paging.total = bizContent.totalCount;
  480. } else {
  481. crudRef.value.tableLoding = false;
  482. ElMessage.error(res.message)
  483. }
  484. })
  485. crudRef.value.tableLoding = false;
  486. tableData.value = [
  487. {
  488. id: 1
  489. }
  490. ]
  491. }
  492. function importData(url) {
  493. BaseService.postN('/managew/api/bls/obu/obuImport', { excelUrl: url }).then((res: any) => {
  494. if (res && res.code === 0) {
  495. console.log(res)
  496. const errUrl = res.data?.excelUrl ?? ''
  497. if (errUrl) {
  498. ElMessage.error("导入失败,请查看下载到本地文件的具体错误信息");
  499. BaseService.getDownload(
  500. import.meta.env.VITE_APP_UPLOAD_URL + errUrl,
  501. '错误信息文件'
  502. )
  503. } else {
  504. ElMessage.success("导入成功");
  505. }
  506. }
  507. });
  508. }
  509. // 新增下黑
  510. function addBlack() {
  511. addForm.value.status = 1; //下黑
  512. crudRef.value.dialogFormVisible = true;
  513. crudRef.value.title = "下黑";
  514. typeOption.value = "下黑";
  515. }
  516. onMounted(() => {
  517. //getList();
  518. })
  519. </script>
  520. <style scoped></style>