Commit 9ee00993fab8dbc457d262e25becec03706e2881

Authored by 王强
2 parents 45201ff7 7043c73b

Merge branch 'bug_fix' of gitlab.feewee.cn:FEV2/fw-cms into ehr-ability

config/routers/capital.ts
... ... @@ -28,11 +28,19 @@ export default [
28 28 component: './capital/StandardName'
29 29 },
30 30 {
  31 + path: '/ams/maintenance/stock', // 运维库存池查询
  32 + component: './capital/Maintenance/StockQuery'
  33 + },
  34 + {
  35 + path: '/ams/maintenance/standard/config/:disabled?', // 运维物品标准查询
  36 + component: './capital/StandardMange'
  37 + },
  38 + {
31 39 path: '/ams/standardMange/receive/rules/goods/:id?/:name?', // 按物品领用规则
32 40 component: './capital/ReceiveRules/subPages/GoodsDimension'
33 41 },
34 42 {
35   - path: '/ams/standardMange/auth/goods/:id?', // 按物品授权分页列表
  43 + path: '/ams/standardMange/auth/goods/:id?/:disabled?', // 按物品授权分页列表
36 44 component: './capital/ReceiveRules/subPages/GoodsDimension/components/PageAuthEdit'
37 45 },
38 46 {
... ...
src/pages/attendance/FieldService/subpages/WorkAddress/components/TravelAddressModal.tsx
... ... @@ -46,6 +46,9 @@ export default function ModalIndex(props: Props) {
46 46 if ((current.maxStayMinute || 0) >= 60) {
47 47 maxStayMinute = (current.maxStayMinute || 0) % 60;
48 48 maxStayHour = Math.floor((current.maxStayMinute || 0) / 60)
  49 + } else {
  50 + maxStayMinute = (current.maxStayMinute || 0)
  51 + maxStayHour = 0
49 52 }
50 53 let feildsValue: any = {
51 54 ...current,
... ... @@ -87,7 +90,7 @@ export default function ModalIndex(props: Props) {
87 90 // return;
88 91 // }
89 92 // }
90   - const maxStayMinute = params.maxStayMinute + params.maxStayHour * 60;
  93 + const maxStayMinute = (params.maxStayMinute || 0)+ (params.maxStayHour || 0) * 60;
91 94 setLoading(true);
92 95 let _param = {
93 96 ...params,
... ...
src/pages/capital/Maintenance/StockQuery/api.ts 0 → 100644
  1 +import request from '@/utils/request';
  2 +import { AMS_HOST } from '@/utils/host';
  3 +import { http } from '@/typing/http';
  4 +
  5 +export interface ListParams {
  6 + /**是否代管物品 1代管 0被领用 */
  7 + agent?: boolean;
  8 + /**资产类型 1固定资产 2低质品 3易耗品 */
  9 + type?: number;
  10 + /**关键字 */
  11 + keywords?: string;
  12 + /**库存来源类型 1.资产 2.配件 3.市场物料 */
  13 + sourceType?: number;
  14 + /**状态 1正常2已报废3已变卖 */
  15 + status?: number;
  16 + /**是否维修中 0正常1处理中 */
  17 + repair?: boolean;
  18 + /**是否报废中 0正常1处理中 */
  19 + scrap?: boolean;
  20 + /**是否变卖中 0正常1处理中 */
  21 + sell?: boolean;
  22 + /**是否调拨中 0正常1处理中 */
  23 + allocate?: boolean;
  24 + /**是否退回中 0正常1处理中 */
  25 + transfer?: boolean;
  26 + /**管理人员姓名
  27 + 216 */
  28 + staffName?: string;
  29 + /** 物品唯一标识 */
  30 + uniqueCode?: string;
  31 + pageSize?: number;
  32 + current?: number;
  33 +}
  34 +export interface ListItems {
  35 + poolId: number;
  36 + fids: string;
  37 + name: string;
  38 + type: number;
  39 + standardId: number;
  40 + code: string;
  41 + uniqueCode: string;
  42 + unit: string;
  43 + specList: StanderList.AuthSpecList,
  44 + assetShopId: number;
  45 + assetShopName: string;
  46 + useShopId: number;
  47 + useShopName: string;
  48 + storageTime: number;
  49 + receiveTime: number;
  50 + storageNum: number;
  51 + staffId: number;
  52 + staffName: string;
  53 + manager: string;
  54 + unitPrice: number;
  55 +}
  56 +
  57 +export function getDateApi(params: ListParams): http.PromisePageResp<ListItems> {
  58 + return request.get(`${AMS_HOST}/erp/operations/inventory/pool/page`, { params });
  59 +}
... ...
src/pages/capital/Maintenance/StockQuery/components/Filter.tsx 0 → 100644
  1 +import React from 'react';
  2 +import { Input, Radio, Row, Select } from 'antd';
  3 +import { debounce } from 'lodash';
  4 +import useInitail from '@/hooks/useInitail';
  5 +import { getShopApi } from '@/common/api';
  6 +
  7 +const Option = Select.Option;
  8 +interface Props {
  9 + setParams: Function;
  10 + innerParams: AmsSpec.ListParams;
  11 +}
  12 +export default function SeriesFilter({ setParams, innerParams }: Props) {
  13 + const { data: shopList } = useInitail<Array<CommonApi.OptionVO>, CommonApi.ShopParam>(getShopApi, [], {});
  14 +
  15 + const fetchListByName = debounce(value => {
  16 + setParams({ ...value, current: 1 }, true);
  17 + }, 500);
  18 +
  19 + const onSearch = (value: object) => setParams({ ...value, current: 1 }, true);
  20 + return (
  21 + <div>
  22 + <Row justify="space-between" style={{ flexWrap: "wrap" }}>
  23 + <Input.Search
  24 + allowClear
  25 + style={{ flex: 1, marginRight: 10 }}
  26 + onChange={e => fetchListByName({ keywords: e.target.value })}
  27 + onSearch={v => setParams({ keywords: v }, true)}
  28 + placeholder="物品名称/编码"
  29 + />
  30 + {/* <Input.Search
  31 + allowClear
  32 + style={{ flex: 1, marginRight: 10 }}
  33 + onChange={e => fetchListByName({ uniqueCode: e.target.value })}
  34 + onSearch={v => setParams({ uniqueCode: v }, true)}
  35 + placeholder="物品唯一标识"
  36 + /> */}
  37 + <Input.Search
  38 + allowClear
  39 + style={{ flex: 1, marginRight: 10 }}
  40 + onChange={e => fetchListByName({ staffName: e.target.value })}
  41 + onSearch={v => setParams({ staffName: v }, true)}
  42 + placeholder="管理人员姓名"
  43 + />
  44 + <Select
  45 + optionFilterProp="children"
  46 + showSearch
  47 + allowClear
  48 + placeholder="物品使用门店"
  49 + style={{ flex: 1, marginRight: 10 }}
  50 + onChange={(value) => onSearch({ useShopId: value })}
  51 + >
  52 + {shopList.map((item) => (
  53 + <Option key={item.id} value={item.id}>
  54 + {item.name}
  55 + </Option>
  56 + ))}
  57 + </Select>
  58 + <Select
  59 + optionFilterProp="children"
  60 + showSearch
  61 + allowClear
  62 + placeholder="物品归属门店"
  63 + style={{ flex: 1, marginRight: 10 }}
  64 + onChange={(value) => onSearch({ assetShopId: value })}
  65 + >
  66 + {shopList.map((item) => (
  67 + <Option key={item.id} value={item.id}>
  68 + {item.name}
  69 + </Option>
  70 + ))}
  71 + </Select>
  72 + </Row>
  73 +
  74 + <Row justify="space-between" style={{ marginTop: 10 }}>
  75 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ type: v })} placeholder="资产类型">
  76 + <Option value={1} key={1}>固定资产</Option>
  77 + <Option value={2} key={2}>低值品</Option>
  78 + <Option value={3} key={3}>易耗品</Option>
  79 + </Select>
  80 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ agent: v })} placeholder="是否代管物品">
  81 + <Option value={1} key={1}>代管</Option>
  82 + <Option value={0} key={0}>被领用</Option>
  83 + </Select>
  84 + {/* <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ sourceType: v })} placeholder="库存来源类型">
  85 + <Option value={1} key={1}>资产</Option>
  86 + <Option value={2} key={2}>配件</Option>
  87 + <Option value={3} key={3}>市场物料</Option>
  88 + </Select> */}
  89 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ status: v })} placeholder="状态">
  90 + <Option value={1} key={1}>正常</Option>
  91 + <Option value={2} key={2}>已报废</Option>
  92 + <Option value={3} key={3}>已变卖</Option>
  93 + </Select>
  94 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ repair: v })} placeholder="是否维修中">
  95 + <Option value={0} key={0}>正常</Option>
  96 + <Option value={1} key={1}>处理中</Option>
  97 + </Select>
  98 + </Row>
  99 +
  100 + <Row justify="space-between" style={{ marginTop: 10, marginBottom: 15 }}>
  101 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ sell: v })} placeholder="是否变卖中">
  102 + <Option value={0} key={0}>正常</Option>
  103 + <Option value={1} key={1}>处理中</Option>
  104 + </Select>
  105 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ allocate: v })} placeholder="是否调拨中">
  106 + <Option value={0} key={0}>正常</Option>
  107 + <Option value={1} key={1}>处理中</Option>
  108 + </Select>
  109 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ transfer: v })} placeholder="是否退回中">
  110 + <Option value={0} key={0}>正常</Option>
  111 + <Option value={1} key={1}>处理中</Option>
  112 + </Select>
  113 + <Select style={{ flex: 1, marginRight: 10 }} allowClear onChange={(v) => onSearch({ scrap: v })} placeholder="是否报废中">
  114 + <Option value={0} key={0}>正常</Option>
  115 + <Option value={1} key={1}>处理中</Option>
  116 + </Select>
  117 + </Row>
  118 + </div>
  119 + );
  120 +}
0 121 \ No newline at end of file
... ...
src/pages/capital/Maintenance/StockQuery/index.tsx 0 → 100644
  1 +import React from 'react';
  2 +import { PageHeaderWrapper } from '@ant-design/pro-layout';
  3 +import { Card, Table } from 'antd';
  4 +import * as api from './api';
  5 +import Column from 'antd/lib/table/Column';
  6 +import Filter from './components/Filter';
  7 +import moment from 'moment';
  8 +import usePagination from '@/hooks/usePagination';
  9 +import RenderGoodsSpec from '@/pages/capital/components/RenderGoodsSpec';
  10 +import { AssetTypeEnum } from '@/pages/capital/entity';
  11 +
  12 +export default function SpecConfig() {
  13 + const { list, loading, paginationConfig, setParams, innerParams, setLoading } = usePagination(api.getDateApi, { status: 1 });
  14 +
  15 + return (
  16 + <PageHeaderWrapper title="库存池查询">
  17 + <Card>
  18 + <Filter setParams={setParams} innerParams={innerParams} />
  19 + <Table
  20 + dataSource={list}
  21 + loading={loading}
  22 + pagination={paginationConfig}
  23 + rowKey="poolId"
  24 + size="small"
  25 + >
  26 + <Column title="物品名称" dataIndex="name" />
  27 + <Column title="物品编码" dataIndex="code" />
  28 + <Column title="唯一标识" dataIndex="uniqueCode" />
  29 + <Column
  30 + title="型号规格"
  31 + dataIndex="specList"
  32 + width="16%"
  33 + ellipsis
  34 + render={(text, record) => <RenderGoodsSpec specList={text} />}
  35 + />
  36 + <Column
  37 + title="物品类型"
  38 + dataIndex="type"
  39 + render={(value) => (
  40 + <span>{AssetTypeEnum[value]}</span>
  41 + )}
  42 + />
  43 + <Column title="资产归属门店" dataIndex="assetShopName" />
  44 + <Column title="使用门店" dataIndex="useShopName" />
  45 + <Column title="是否代管" dataIndex="agent" render={t => (t ? "是" : "否")} />
  46 + <Column title="库存数量" dataIndex="storageNum" render={(t, record: api.ListItems) => `${t || 0}${record.unit}`} />
  47 + <Column title="管理员工" dataIndex="staffName" />
  48 + <Column title="入库时间" dataIndex="storageTime" render={(t) => t && moment(t).format("YYYY-MM-DD hh:mm") || '--'} />
  49 + <Column title="领用时间" dataIndex="receiveTime" render={(t) => t && moment(t).format("YYYY-MM-DD hh:mm") || '--'} />
  50 + {/* <Column title="采购单价金额(元)" dataIndex="unitPrice" /> */}
  51 + </Table>
  52 + </Card>
  53 + </PageHeaderWrapper>
  54 + );
  55 +}
0 56 \ No newline at end of file
... ...
src/pages/capital/ReceiveRules/subPages/GoodsDimension/components/PageAuthEdit/index.tsx
... ... @@ -18,7 +18,7 @@ interface Props {
18 18  
19 19 export default function SpecConfig(props: Props) {
20 20 const { match } = props;
21   - const { id } = match.params;
  21 + const { id, disabled } = match.params;
22 22 const { list, loading, setLoading, paginationConfig, innerParams, setParams } = usePagination(getGoodsAuthDetail, { standardId: id });
23 23 const [confirLoaing, setConfirLoading] = useState<boolean>(false);
24 24 const [modalPa, setModalPa] = useState({ visible: false, rowValue: undefined });
... ... @@ -82,7 +82,7 @@ export default function SpecConfig(props: Props) {
82 82 />
83 83 </div>
84 84 </Row>
85   - <Button type="primary" icon={<PlusOutlined />} onClick={() => setModalPa({ visible: true })}>新增</Button>
  85 + {!disabled && (<Button type="primary" icon={<PlusOutlined />} onClick={() => setModalPa({ visible: true })}>新增</Button>)}
86 86 </Row>
87 87 <Table
88 88 dataSource={list}
... ... @@ -118,7 +118,7 @@ export default function SpecConfig(props: Props) {
118 118 align="center"
119 119 title="操作"
120 120 render={(value) => {
121   - return (
  121 + return !disabled ? (
122 122 <>
123 123 <Button type="link" onClick={() => edit(value)}>
124 124 编辑
... ... @@ -130,7 +130,7 @@ export default function SpecConfig(props: Props) {
130 130 </Button>
131 131 </Popconfirm>
132 132 </>
133   - );
  133 + ) : null;
134 134 }}
135 135 />
136 136 </Table>
... ...
src/pages/capital/ReceiveRules/subPages/GoodsDimension/index.tsx
... ... @@ -53,9 +53,10 @@ export default function Index(props: Props) {
53 53 <RenderSelectGoos />
54 54 </Form.Item>
55 55 ) : (
56   - <Form.Item label="物品名称">
57   - <Input bordered={false} value={name} />
58   - </Form.Item>
  56 + // <Form.Item label="物品名称">
  57 + // <Input bordered={false} value={name} />
  58 + // </Form.Item>
  59 + null
59 60 )}
60 61 <Form.Item label="按门店授权" name="shopAuthPostList" rules={[{ required: true, message: '添加授权信息' }]}>
61 62 <AuthTableList />
... ...
src/pages/capital/StandardMange/components/Add/index.tsx
... ... @@ -17,10 +17,13 @@ const Option = Select.Option;
17 17 const RadioGroup = Radio.Group;
18 18  
19 19 export default function AddItem() {
20   - const { typeName, data = [], currentItem = {}, unitItem, setBreadcrumbs, setLoading, setCurrentBreadcrumb, setIsPart } = useStore()
  20 + const { typeName, data = [], currentItem = {}, unitItem, setBreadcrumbs, setLoading, setCurrentBreadcrumb, setIsPart, editDisabled } = useStore();
21 21 const [saveConfig, setSaveConfig] = useState<boolean>(false);
22 22 const [nameId, setNameId] = useState<number>();
23 23 const [visible, setVisible] = useState(false);
  24 + const [partValue, setPartValue] = useState<{
  25 + partId?: number, partCode?: string,
  26 + }>({});
24 27 const [form] = Form.useForm();
25 28  
26 29 useEffect(() => {
... ... @@ -33,11 +36,13 @@ export default function AddItem() {
33 36 part: Number(currentItem.part) || 0,
34 37 purchaseChannelList: currentItem.purchaseChannelList && JSON.stringify(currentItem) != '{}' ? currentItem.purchaseChannelList.map(i => ({ value: i.subjectId, label: i.subjectName })) : undefined,
35 38 });
  39 + currentItem.partCode && setPartValue({ partCode: currentItem.partCode, partId: currentItem.partId });
36 40 }, []);
37 41  
38 42 function save(feildValue: any) {
39 43 const params = {
40 44 ...feildValue,
  45 + ...partValue,
41 46 id: currentItem.id,
42 47 name: currentItem.name || feildValue.name.label || feildValue.name,
43 48 nameId: currentItem.nameId || feildValue.name.value || nameId,
... ... @@ -49,6 +54,7 @@ export default function AddItem() {
49 54 api.saveForm(params).then(res => {
50 55 setSaveConfig(false);
51 56 setNameId(undefined);
  57 + setPartValue({});
52 58 if (res.data && !currentItem.id) {
53 59 Modal.confirm({
54 60 title: '保存成功',
... ... @@ -57,7 +63,7 @@ export default function AddItem() {
57 63 okText: '去授权',
58 64 cancelText: '返回',
59 65 onOk() {
60   - history.push(`/ams/standardMange/receive/rules/goods/${res.data}/${params.name}`);
  66 + history.push(`/ams/standardMange/receive/rules/goods/${res.data}/name`);
61 67 },
62 68 onCancel() {
63 69 setLoading(true);
... ... @@ -104,7 +110,8 @@ export default function AddItem() {
104 110 }).catch(e => {
105 111 message.error(e.message);
106 112 });
107   - form.setFieldsValue({ name: item.partName, specList: spec, type: 2 });
  113 + setPartValue({ partCode: item.partCode, partId: item.id });
  114 + form.setFieldsValue({ name: item.partName, partCode: item.partCode, partId: item.id, specList: spec, type: 2 });
108 115 }
109 116  
110 117 return (
... ... @@ -112,7 +119,7 @@ export default function AddItem() {
112 119 <h1 style={{ marginBottom: 20 }}>1.基本信息</h1>
113 120 <Form {...layout} form={form} onFinish={save}>
114 121 <Form.Item label="是否配件" name="part" rules={[{ required: true, message: '请选择' }]}>
115   - <RadioGroup onChange={(e) => { changeSpc(e.target.value); }}>
  122 + <RadioGroup disabled={!!editDisabled} onChange={(e) => { changeSpc(e.target.value); }}>
116 123 <Radio value={1}>是</Radio>
117 124 <Radio value={0}>否</Radio>
118 125 </RadioGroup>
... ... @@ -147,6 +154,7 @@ export default function AddItem() {
147 154 labelInValue
148 155 optionFilterProp="children"
149 156 showSearch
  157 + disabled={!!editDisabled}
150 158 >
151 159 {unitItem.map((i: StanderList.UnitItem) => (
152 160 <Option value={i.id} key={i.id}>{i.unitName}</Option>
... ... @@ -154,19 +162,19 @@ export default function AddItem() {
154 162 </Select>
155 163 </Form.Item>
156 164 <Form.Item label="状态" name="status" valuePropName="checked" rules={[{ required: true, message: '请选择' }]}>
157   - <Switch checkedChildren="启用" unCheckedChildren="禁用" />
  165 + <Switch disabled={!!editDisabled} checkedChildren="启用" unCheckedChildren="禁用" />
158 166 </Form.Item>
159 167 <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.type != currentValues.type}>
160 168 {({ getFieldValue }): any => {
161 169 return getFieldValue("type") === 1 ? (
162 170 <Form.Item label="摊销周期 (月)" name="amortizePeriod" rules={[{ required: true, message: '请输入摊销周期' }]}>
163   - <InputNumber min={0} style={{ width: '100%' }} placeholder="请输入" />
  171 + <InputNumber disabled={!!editDisabled} min={0} style={{ width: '100%' }} placeholder="请输入" />
164 172 </Form.Item>
165 173 ) : null;
166 174 }}
167 175 </Form.Item>
168 176 <Form.Item label="备注" name="remark">
169   - <Input.TextArea placeholder="请输入" allowClear />
  177 + <Input.TextArea disabled={!!editDisabled} placeholder="请输入" allowClear />
170 178 </Form.Item>
171 179 <h1 style={{ marginBottom: 20 }}>2.规格型号</h1>
172 180  
... ... @@ -180,7 +188,7 @@ export default function AddItem() {
180 188 noStyle
181 189 rules={[{ required: true, message: '最大采购金额(单个物品)' }]}
182 190 >
183   - <InputNumber style={{ width: 150 }} min={0} precision={4} placeholder="请输入金额" />
  191 + <InputNumber disabled={!!editDisabled} style={{ width: 150 }} min={0} precision={4} placeholder="请输入金额" />
184 192 </Form.Item>
185 193 <span style={{ marginLeft: 10 }}>元</span>
186 194 </Form.Item>
... ... @@ -188,16 +196,16 @@ export default function AddItem() {
188 196 {({ getFieldValue }): any => {
189 197 return getFieldValue("type") === 3 ? (
190 198 <Form.Item label="最小单位采购数量" name="minNum" {...layout} rules={[{ required: true, message: '请输入最小采购数量' }]}>
191   - <InputNumber style={{ width: 150 }} min={0} placeholder="请输入单位数量" />
  199 + <InputNumber disabled={!!editDisabled} style={{ width: 150 }} min={0} placeholder="请输入单位数量" />
192 200 </Form.Item>
193 201 ) : null;
194 202 }}
195 203 </Form.Item>
196 204 <Form.Item label="计划提前天数" name="planAheadDay" {...layout}>
197   - <InputNumber style={{ width: 150 }} min={0} placeholder="请输入" />
  205 + <InputNumber disabled={!!editDisabled} style={{ width: 150 }} min={0} placeholder="请输入" />
198 206 </Form.Item>
199 207 <Form.Item label="采购渠道" name="purchaseChannelList" rules={[{ required: true, message: '请选择采购渠道' }]}>
200   - <Select placeholder="请选择采购渠道" allowClear labelInValue mode="multiple" showSearch optionFilterProp="children">
  208 + <Select disabled={!!editDisabled} placeholder="请选择采购渠道" allowClear labelInValue mode="multiple" showSearch optionFilterProp="children">
201 209 {(data || []).map((i: any) => (
202 210 <Option value={i.id} key={i.id}>{i.name}</Option>
203 211 ))}
... ... @@ -205,7 +213,7 @@ export default function AddItem() {
205 213 </Form.Item>
206 214 <h1 style={{ marginBottom: 20 }}>4.领用条件</h1>
207 215 <Form.Item label="领用前提条件" name="premise" rules={[{ required: true, message: '请选择' }]}>
208   - <Select placeholder="请选择">
  216 + <Select disabled={!!editDisabled} placeholder="请选择">
209 217 <Option value={0} key={0}>无限制</Option>
210 218 <Option value={1} key={1}>入职后</Option>
211 219 <Option value={2} key={2}>转正后</Option>
... ... @@ -215,15 +223,15 @@ export default function AddItem() {
215 223 {({ getFieldValue }): any => {
216 224 const premise = getFieldValue("premise");
217 225 return premise ? (
218   - <Form.Item label={premise === 1 ? "入职后" :"转正后"} name="premiseValue" {...layout} rules={[{ required: true, message: '请输入' }]}>
219   - <InputNumber style={{ width: '100%' }} addonAfter="月" min={0} placeholder="请输入领取前提条件值" />
  226 + <Form.Item label={premise === 1 ? "入职后" : "转正后"} name="premiseValue" {...layout} rules={[{ required: true, message: '请输入' }]}>
  227 + <InputNumber disabled={!!editDisabled} style={{ width: '100%' }} addonAfter="月" min={0} placeholder="请输入领取前提条件值" />
220 228 </Form.Item>
221 229 ) : null;
222 230 }}
223 231 </Form.Item>
224 232 <Row justify="center">
225 233 <Button type="primary" onClick={() => { setBreadcrumbs([{ name: '列表', key: 'list' }]); setCurrentBreadcrumb({ name: '列表', key: 'list' }); }}>返回</Button>
226   - <Button style={{ marginLeft: 25 }} type="primary" loading={saveConfig} onClick={() => form.submit()}>保存</Button>
  234 + <Button style={{ marginLeft: 25 }} type="primary" disabled={!!editDisabled} loading={saveConfig} onClick={() => form.submit()}>保存</Button>
227 235 </Row>
228 236 </Form>
229 237 <SelectPartsTable
... ...
src/pages/capital/StandardMange/components/List/index.tsx
... ... @@ -17,7 +17,8 @@ import { AssetTypeEnum } from &#39;@/pages/capital/entity&#39;;
17 17 const Option = Select.Option;
18 18  
19 19 export default function List() {
20   - const { typeName, setIsPart, breadcrumbs, MenuItems, setCurrentItem, innerParams, list, setBreadcrumbs, setLoading, setParams, paginationConfig, loading, setCurrentBreadcrumb } = useStore();
  20 + const { typeName, setIsPart, breadcrumbs, MenuItems, setCurrentItem, innerParams,
  21 + list, setBreadcrumbs, setLoading, setParams, paginationConfig, loading, setCurrentBreadcrumb, editDisabled } = useStore();
21 22 const [switchLoading, setSwitchLoading] = useState(false);
22 23  
23 24 function editAdd(value?: any) {
... ... @@ -51,7 +52,6 @@ export default function List() {
51 52 });
52 53  
53 54 const handleMenuClick: MenuProps['onClick'] = (e) => {
54   - console.log("handleMenuClick", e.key);
55 55 switch (e.key) {
56 56 case '1':
57 57 history.push("/ams/standardMange/receive/rules/goods");
... ... @@ -68,8 +68,9 @@ export default function List() {
68 68 };
69 69  
70 70 const clickToAuth = (item: StanderList.ListVO) => {
71   - history.push(`/ams/standardMange/auth/goods/${item.id}`);
  71 + history.push(`/ams/standardMange/auth/goods/${item.id}/${editDisabled || ''}`);
72 72 };
  73 +
73 74 return (
74 75 <Card>
75 76 <Row justify="space-between">
... ... @@ -85,29 +86,35 @@ export default function List() {
85 86 禁用
86 87 </Radio.Button>
87 88 </Radio.Group>
88   - <Select style={{ width: 200 }} allowClear onChange={(e) => _onChangeType({ type: e })} placeholder="请选择类型">
  89 + <Select allowClear onChange={(e) => _onChangeType({ type: e })} placeholder="请选择类型">
89 90 {typeName.map(i => (
90 91 <Option value={i.type} key={i.type}>{i.name}</Option>
91 92 ))}
92 93 </Select>
  94 + <Select allowClear onChange={(v) => _onChangeType({ part: v })} placeholder="是否配件">
  95 + <Option value={1} key={1}>是</Option>
  96 + <Option value={0} key={0}>否</Option>
  97 + </Select>
93 98 <Search
94 99 style={{ width: 260 }}
95 100 placeholder="搜索资产名称/型号"
96 101 allowClear
97 102 onChange={(e) => _onChange(e.target.value)}
98 103 />
99   - <div>
100   - <Dropdown
101   - overlay={
102   - <Menu onClick={handleMenuClick} items={MenuItems} />
103   - }
104   - >
105   - <Button icon={<SnippetsOutlined />} type="primary" style={{ width: 100, marginRight: 20 }}>
106   - 领用授权
107   - </Button>
108   - </Dropdown>
109   - <Button type="primary" icon={<PlusOutlined />} onClick={() => editAdd(undefined)}>新增</Button>
110   - </div>
  104 + {!editDisabled && (
  105 + <div>
  106 + <Dropdown
  107 + overlay={
  108 + <Menu onClick={handleMenuClick} items={MenuItems} />
  109 + }
  110 + >
  111 + <Button icon={<SnippetsOutlined />} type="primary" style={{ width: 100, marginRight: 20 }}>
  112 + 领用授权
  113 + </Button>
  114 + </Dropdown>
  115 + <Button type="primary" icon={<PlusOutlined />} onClick={() => editAdd(undefined)}>新增</Button>
  116 + </div>
  117 + )}
111 118 </Row>
112 119  
113 120 <Table
... ... @@ -146,6 +153,7 @@ export default function List() {
146 153 unCheckedChildren="关闭"
147 154 checked={!!value.status}
148 155 loading={switchLoading}
  156 + disabled={!!editDisabled}
149 157 onChange={() => changeSwich(value)}
150 158 />
151 159 )}
... ... @@ -166,7 +174,7 @@ export default function List() {
166 174 align="center"
167 175 render={(record: StanderList.ListVO) => (
168 176 <>
169   - <Button type="link" style={{ padding: 0 }} onClick={() => { editAdd(record); }}>编辑</Button>
  177 + <Button type="link" style={{ padding: 0 }} onClick={() => { editAdd(record); }}> {!editDisabled ? "编辑" : "查看"}</Button>
170 178 <Divider type="vertical" />
171 179 <Button type="link" style={{ padding: 0 }} onClick={() => { clickToAuth(record); }}>授权</Button>
172 180 </>
... ...
src/pages/capital/StandardMange/index.tsx
... ... @@ -8,9 +8,15 @@ import AddItem from &#39;./components/Add&#39;;
8 8  
9 9 export const { Provider, useStore } = createStore(store);
10 10  
11   -function EditMange() {
  11 +function EditMange(props: any) {
  12 + const { match } = props;
  13 + const { disabled } = match.params;
12 14 const [IndexDOM, setIndexDOM] = useState(<List />);
13   - const { setLoading, currentItem, breadcrumbs, currentBreadcrumb, setCurrentItem, setBreadcrumbs, setCurrentBreadcrumb } = useStore();
  15 + const { setLoading, currentItem, breadcrumbs, currentBreadcrumb, setCurrentItem, setBreadcrumbs, setEditDisabled, setCurrentBreadcrumb } = useStore();
  16 +
  17 + useEffect(() => {
  18 + setEditDisabled(!!disabled);
  19 + }, [disabled]);
14 20  
15 21 useEffect(() => {
16 22 switch (currentBreadcrumb.key) {
... ... @@ -49,4 +55,4 @@ function EditMange() {
49 55 );
50 56 }
51 57  
52   -export default () => <Provider><EditMange /></Provider>;
53 58 \ No newline at end of file
  59 +export default (props: any) => <Provider><EditMange {...props} /></Provider>;
54 60 \ No newline at end of file
... ...
src/pages/capital/StandardMange/interface.d.ts
... ... @@ -6,6 +6,8 @@ declare namespace StanderList {
6 6 type?: number, //物品类型 1固定资产2低值品3易耗品
7 7 name?: string, //物品名称
8 8 nameId?: number,
  9 + partCode?: string,
  10 + partId?: number,
9 11 unit?: number, //单位 1个2只3把4枚5台6包7车8瓶9壶10套11张12打13担
10 12 unitName?: string,
11 13 spec?: string, //型号规格
... ...
src/pages/capital/StandardMange/store.ts
... ... @@ -22,6 +22,8 @@ export default function useStore() {
22 22 const { list: postList, loading: postLoading } = usePagination(api.getPostList, {});
23 23 const { list, setParams, paginationConfig, innerParams, loading, setLoading } = usePagination(api.getListApi, { status: 1 });
24 24 const [isPart, setIsPart] = useState<boolean>(false);
  25 + /**是否可编辑 */
  26 + const [editDisabled, setEditDisabled] = useState<boolean>(false);
25 27  
26 28 const typeName = [
27 29 { name: '固定资产', type: 1 },
... ... @@ -60,6 +62,8 @@ export default function useStore() {
60 62 setLoading,
61 63 isPart,
62 64 setIsPart,
63   - MenuItems
  65 + MenuItems,
  66 + editDisabled,
  67 + setEditDisabled
64 68 };
65 69 }
66 70 \ No newline at end of file
... ...
src/pages/capital/components/RenderGoodsSpec.tsx
1   -import React from 'react';
2   -import { Popover } from 'antd';
  1 +import React, { useCallback, useState } from 'react';
  2 +import { Button, Modal, Popover, Table } from 'antd';
3 3  
4 4 interface Props {
5 5 specList: StanderList.AuthSpecList[]
6 6 }
7 7  
8 8 export default function RenderGoodsSpec({ specList }: Props) {
  9 + const [visible, setVisible] = useState(false);
9 10 const items = (specList || []).map(i => `${i.standardSpecName}:${i.specDetails}`);
  11 + const RenderSpecModal = useCallback(() => (visible ? (
  12 + <SpecModal
  13 + visible={visible}
  14 + onCancel={() => setVisible(false)}
  15 + items={specList}
  16 + />
  17 + ) : null), [visible]);
10 18 return (
11   - <Popover
12   - placement="topLeft"
13   - content={<div style={{ maxWidth: 260 }}>{items.join(';')}</div>}
14   - >
15   - <div>
16   - {items.slice(0, 3).map((i: string) => {
17   - return (
18   - <p key={i} style={{ margin: 0, fontSize: 12 }}>{i}</p>
19   - );
20   - })}
21   - {items.length > 3 ? (<span>...</span>) : null}
22   - </div>
23   - </Popover>
  19 + <>
  20 + <Popover
  21 + placement="topLeft"
  22 + content={<div style={{ maxWidth: 260 }}>{items.join(';')}</div>}
  23 + >
  24 + <div>
  25 + {items.slice(0, 3).map((i: string) => {
  26 + return (
  27 + <p key={i} style={{ margin: 0, fontSize: 12 }}>{i}</p>
  28 + );
  29 + })}
  30 + {items.length > 3 ? (<span>...</span>) : null}
  31 + </div>
  32 + <Button type="link" style={{ fontSize: 12, padding: 0 }} onClick={() => setVisible(true)}>查看</Button>
  33 + </Popover>
  34 + {RenderSpecModal()}
  35 + </>
  36 + );
  37 +}
  38 +
  39 +function SpecModal({ items, onCancel, visible }: any) {
  40 + const columns = [
  41 + {
  42 + title: '规格名称',
  43 + dataIndex: 'standardSpecName',
  44 + },
  45 + {
  46 + title: '规格内容',
  47 + dataIndex: 'specDetails',
  48 + },
  49 + {
  50 + title: '排序',
  51 + dataIndex: 'sort',
  52 + },
  53 + ];
  54 +
  55 + return (
  56 + <Modal title="规格属性" open={visible} onCancel={onCancel} footer={false}>
  57 + <Table
  58 + pagination={false}
  59 + bordered
  60 + rowKey="standardSpecName"
  61 + dataSource={items}
  62 + size="small"
  63 + columns={columns}
  64 + />
  65 + </Modal>
24 66 );
25 67 }
26 68 \ No newline at end of file
... ...
src/pages/order3/RetailTask/api.ts
... ... @@ -18,6 +18,7 @@ export interface ShopTaskList {
18 18 clueDealTaskCount?: number // 线索到店零售数量
19 19 clueDealTaskRate?: number // 线索到店零售占比
20 20 staffTaskList?: StaffTaskList[]//员工任务列表
  21 + addedValueTask?: number
21 22 }
22 23  
23 24 interface StaffTaskList {
... ... @@ -26,6 +27,7 @@ interface StaffTaskList {
26 27 taskCount?: number//任务数量
27 28 clueDealTaskCount?: number // 线索到店零售数量
28 29 regularMonth?: number//转正几个月
  30 + addedValueTask?: number
29 31 }
30 32 export interface saveParams {
31 33 id?: number,
... ...
src/pages/pms/entity.ts
... ... @@ -190,12 +190,12 @@ export const planPoolTypeData = [
190 190 export const typeReceiverObj: {[key: string]: string} = {
191 191 '售后工单锁定': '服务',
192 192 '装潢零售锁定': '销售',
193   - '调锁定': '',
  193 + '调锁定': '',
194 194 '': '',
195 195 };
196 196 export const typeSenderObj: {[key: string]: string} = {
197   - '售后工单锁定': '送修人',
198   - '装潢零售锁定': '下单人',
199   - '调件锁定': '',
  197 + '售后工单锁定': '送修人:',
  198 + '装潢零售锁定': '下单人:',
  199 + '调出锁定': '',
200 200 '': '',
201 201 };
... ...
src/pages/pms/part/Repertory/components/EPCModal.tsx
... ... @@ -4,7 +4,6 @@ import { useStore } from &#39;../index&#39;;
4 4 import usePagination from '@/hooks/usePagination';
5 5 import { getEpcdetailApi, deleteApi } from '../api';
6 6 import AddepcModal from './AddepcModal';
7   -import debounce from 'lodash/debounce';
8 7  
9 8 const { Column } = Table;
10 9  
... ... @@ -14,9 +13,9 @@ export default function FactoryEpcDetailModal() {
14 13 const [addVisible, setAddVisible] = useState(false);
15 14 const { list, loading, setLoading, setParams, paginationConfig } = usePagination(getEpcdetailApi, { partCode: currentItem.partCode }, { delay });
16 15  
17   - const _onChange = debounce((param: string) => {
  16 + const _onChange = (param: string) => {
18 17 setParams({ partCode: currentItem.partCode, current: 1, keywords: param }, true);
19   - }, 500);
  18 + };
20 19  
21 20 useEffect(() => {
22 21 if (currentItem.partCode) {
... ... @@ -81,7 +80,8 @@ export default function FactoryEpcDetailModal() {
81 80 placeholder="搜索车型代码"
82 81 allowClear
83 82 style={{ width: 200 }}
84   - onChange={(e) => _onChange(e.target.value)}
  83 + onSearch={v => _onChange(v)}
  84 + enterButton
85 85 />
86 86 <Button type="primary" onClick={() => { setAddVisible(true); setCurrentInfo({}); }}>新增</Button>
87 87 </div>
... ...
src/pages/pms/part/Repertory/components/SpecEpcModal.tsx
... ... @@ -79,11 +79,11 @@ export default function specEcpModal() {
79 79 <Card title="知识库信息">
80 80 <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
81 81 <Input.Search
82   - placeholder="输入关键词"
  82 + placeholder="搜索配件编码/名称"
83 83 allowClear
84   - style={{ width: 200 }}
  84 + style={{ width: 240 }}
85 85 onSearch={(v) => _onChange(v)}
86   - onChange={e => _onChange(e.target.value)}
  86 + enterButton
87 87 />
88 88 <Button type="primary" onClick={() => { setAddVisible(true); setCurrentInfo({}); }}>新增</Button>
89 89 </div>
... ...
src/pages/pms/partPlan/PlanPool/api.ts
... ... @@ -13,6 +13,7 @@ export interface Params {
13 13 storageId?: number; // Form
14 14 isOil?: boolean;
15 15 keywords?: string
  16 + poolType?:number
16 17 }
17 18  
18 19 export interface ListVO {
... ... @@ -40,6 +41,8 @@ export interface ListVO {
40 41 unit?: string; // 采购规格(配件展示)
41 42 splitUnit?: string; // 拆分件规格(配件展示)
42 43 splitCnt?: number; // 拆分件数量(配件展示)
  44 + typeName?:string
  45 + partType?:number
43 46 }
44 47  
45 48 /**
... ...
src/pages/pms/partPlan/PlanPool/components/Filter.tsx
... ... @@ -7,7 +7,6 @@ import usePagination from &quot;@/hooks/usePagination&quot;;
7 7 import {getStoragePage} from "@/pages/pms/storage/StorageManage/api";
8 8 import useInitail from "@/hooks/useInitail";
9 9 import * as api from "@/pages/pms/storage/partShop/api";
10   -import {getPartTypeApi} from '@/pages/pms/part/Repertory/api';
11 10 import PmsSelect from '@/pages/pms/comonents/PmsSelect';
12 11  
13 12 const { Search } = Input;
... ... @@ -15,8 +14,7 @@ const { Search } = Input;
15 14 export default function Filter() {
16 15 const { list: storages } = usePagination<PartStorageSpace.PageVO>(getStoragePage, {pageSize: 1000});
17 16 const { data: shops } = useInitail<PmsStoragePartShop.Option[], {}>(api.getShopApi, [], {});
18   - const { dfParams, setDfParams } = useStore();
19   - const { data: partTypeData } = useInitail(getPartTypeApi, [], {});
  17 + const { dfParams, setDfParams, partTypeData } = useStore();
20 18  
21 19 const handleChangeKeywords = debounce((value: string) => {
22 20 setDfParams({ ...dfParams, current: 1, keywords: value });
... ...
src/pages/pms/partPlan/PlanPool/components/PartTable.tsx
... ... @@ -16,7 +16,7 @@ interface Props {
16 16 id?: number, // 上一个列表ID
17 17 }
18 18 export default function Index(props: Props = {}) {
19   - const { dfParams, key } = useStore();
  19 + const { dfParams, key, partTypeData } = useStore();
20 20 const {showAnalyse=true} = props;
21 21 const { data: parts, setParams } = useInitial(getList, [], {...dfParams, ...props});
22 22 const [visible, setVisible] = useState(false);
... ... @@ -35,6 +35,8 @@ export default function Index(props: Props = {}) {
35 35 <Table rowKey={(v: ListVO) => `${v.id}`} scroll={{y: 500, x: 2000}} dataSource={parts || []} pagination={false}>
36 36 <Column title="配件编码" dataIndex="code" fixed="left" />
37 37 <Column title="配件名称" dataIndex="name" />
  38 + <Column title="来源类型" dataIndex="typeName" />
  39 + <Column title="配件类型" dataIndex="partType" render={t => partTypeData.find(i => i.value == t)?.label} />
38 40 <Column title="采购单价" dataIndex="price" />
39 41 <Column title="采购数量" dataIndex="cnt" />
40 42 <Column title="采购规格" dataIndex="unit" />
... ... @@ -82,8 +84,6 @@ export default function Index(props: Props = {}) {
82 84 </a>
83 85 )}
84 86 />
85   - <Column title="拆分件规格" dataIndex="splitUnit" />
86   - <Column title="拆分件数量" dataIndex="splitCnt" />
87 87 </>
88 88 )}
89 89 </Table>
... ...
src/pages/pms/partPlan/PlanPool/components/StoragePartTable.tsx
... ... @@ -12,7 +12,7 @@ interface Props {
12 12 type?: number, // 类型1区域库2库房3车系4车型5配件
13 13 }
14 14 export default function Index(props: Props = {}) {
15   - const { dfParams, key } = useStore();
  15 + const { dfParams, key, partTypeData } = useStore();
16 16 const [form] = Form.useForm();
17 17 const { data: parts, setParams } = useInitial(getList, [], dfParams);
18 18 const [visible, setVisible] = useState(false);
... ... @@ -40,6 +40,7 @@ export default function Index(props: Props = {}) {
40 40 <Column title="库房名称" dataIndex="storageName" />
41 41 <Column title="门店名称" dataIndex="shopName" />
42 42 <Column title="来源类型" dataIndex="typeName" />
  43 + <Column title="配件类型" dataIndex="partType" render={t => partTypeData.find(i => i.value == t)?.label} />
43 44 <Column title="采购规格" dataIndex="unit" render={t => t || '--'} />
44 45 <Column title="采购数量" dataIndex="cnt" />
45 46 <Column title="采购单价" dataIndex="price" />
... ...
src/pages/pms/partPlan/PlanPool/useStore.ts
1 1 import { useState } from 'react';
  2 +import useInitail from "@/hooks/useInitail";
  3 +import { getPartTypeApi } from '@/pages/pms/part/Repertory/api';
2 4  
3 5 export default function useStore() {
4 6 const [dfParams, setDfParams] = useState<any>({});
5 7 const [key, setKey] = useState<any>('1');
  8 + const { data: partTypeData } = useInitail(getPartTypeApi, [], {});
  9 +
6 10 return {
7 11 dfParams,
8 12 setDfParams,
9 13 key,
10   - setKey
  14 + setKey,
  15 + partTypeData
11 16 };
12 17 }
... ...
src/pages/pms/purchase/PurchaseRecord/comonents/AddPurchaseModal.tsx
... ... @@ -10,6 +10,9 @@ import {purchaseApply, getrelationlist, EditItem} from &#39;../api&#39;;
10 10 import {getList, ListVO, Params} from '@/pages/pms/partPlan/PlanPool/api';
11 11 import _ from 'lodash';
12 12 import useInitial from '@/hooks/useInitail';
  13 +import PmsSelect from '@/pages/pms/comonents/PmsSelect';
  14 +import { getPartTypeApi } from '@/pages/pms/part/Repertory/api';
  15 +import {planPoolTypeData} from '@/pages/pms/entity';
13 16  
14 17 const Option = Select.Option;
15 18 const {Item} = Form;
... ... @@ -33,7 +36,8 @@ export default function PartStorageModal({ onCancel, visible, itemData, setItemD
33 36 const {data: planeData, setParams, setData: setPlaneData} = useInitial<ListVO[], Params>(getList, [], {}, delay);
34 37 const {data: casData, setParams: casSetParams, setData: casSetData} = useInitial<poolitem[], Params>(getPurchasePool, [], {}, delay);
35 38 const [planePart, setPlanePart] = useState<ListVO[]>([]);
36   -
  39 + const { data: partTypeData } = useInitial(getPartTypeApi, [], {});
  40 +
37 41 const [choosePartVisable, setChoosePartVisable] = useState(false);
38 42 const [selectedParts, setSelectedParts] = useState<any[]>([]);
39 43 const [form] = Form.useForm();
... ... @@ -259,7 +263,23 @@ export default function PartStorageModal({ onCancel, visible, itemData, setItemD
259 263 allowClear
260 264 placeholder="请输入配件名称/编码"
261 265 onChange={e => setParams({keywords: e.target.value}, true)}
262   - style={{ width: 240 }}
  266 + style={{ width: 210 }}
  267 + />
  268 + <PmsSelect
  269 + allowClear
  270 + style={{ width: 180, marginRight: 10, marginLeft: 10}}
  271 + onChange={v => {
  272 + setParams({poolType: v}, true);
  273 + }}
  274 + placeholder="请选择来源类型"
  275 + options={planPoolTypeData.map(i => ({value: i.value, label: i.label}))}
  276 + />
  277 + <PmsSelect
  278 + allowClear
  279 + style={{ width: 180}}
  280 + onChange={v => setParams({partType: v}, true)}
  281 + placeholder="请选择配件类型"
  282 + options={partTypeData.map(i => ({value: i.value, label: i.label}))}
263 283 />
264 284 </div>
265 285 <Table
... ... @@ -278,6 +298,8 @@ export default function PartStorageModal({ onCancel, visible, itemData, setItemD
278 298 >
279 299 <Column title="配件名称" dataIndex="partName" />
280 300 <Column title="配件编码" dataIndex="partCode" />
  301 + <Column title="数据来源" dataIndex="typeName" />
  302 + <Column title="配件类型" dataIndex="partType" render={t => partTypeData.find(i => i.value == t)?.label} />
281 303 <Column title="采购单价(元)" dataIndex="price" />
282 304 <Column title="采购数量" dataIndex="cnt" />
283 305 <Column title="总价(元)" render={r => _.ceil((r.cnt * r.price), 2)} />
... ...
src/pages/pms/storage/partShop/components/LockDetailModal.tsx
... ... @@ -60,7 +60,7 @@ export default function Index({ item = {}, visible, onCancel }: Props) {
60 60 <div>{`锁定库存数: ${it.lockCnt || 0}件`}</div>
61 61 <div>{`锁库天数: ${(it.days || 0).toFixed(0)}天`}</div>
62 62 {!!obj.receiverName && <div>{`${typeReceiverObj[it.type || '']}顾问: ${obj.receiverName}`}</div>}
63   - {!!obj.senderName && <div>{`${typeSenderObj[it.type || '']}: ${obj.senderName}`}</div>}
  63 + {!!obj.senderName && !!typeSenderObj[it.type || ''] && <div>{`${typeSenderObj[it.type || '']}${obj.senderName}`}</div>}
64 64 {!!obj.ownerName && <div>{`车主: ${obj.ownerName}`}</div>}
65 65 {!!obj.senderTime && <div>{`进站时间: ${moment(obj.senderTime).format('YYYY-MM-DD HH:mm')}`}</div>}
66 66 {!!obj.plateNo && <div>{`车牌号: ${obj.plateNo}`}</div>}
... ...